]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-arm.c
gprofng: fix build with --disable-shared
[thirdparty/binutils-gdb.git] / gas / config / tc-arm.c
CommitLineData
b99bd4ef 1/* tc-arm.c -- Assemble for the ARM
a2c58332 2 Copyright (C) 1994-2022 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 34#include "opcode/arm.h"
f37164d7 35#include "cpu-arm.h"
f263249b 36
b99bd4ef
NC
37#ifdef OBJ_ELF
38#include "elf/arm.h"
a394c00f 39#include "dw2gencfi.h"
b99bd4ef
NC
40#endif
41
f0927246
NC
42#include "dwarf2dbg.h"
43
7ed4c4c5
NC
44#ifdef OBJ_ELF
45/* Must be at least the size of the largest unwind opcode (currently two). */
46#define ARM_OPCODE_CHUNK_SIZE 8
47
48/* This structure holds the unwinding state. */
49
50static struct
51{
c19d1205
ZW
52 symbolS * proc_start;
53 symbolS * table_entry;
54 symbolS * personality_routine;
55 int personality_index;
7ed4c4c5 56 /* The segment containing the function. */
c19d1205
ZW
57 segT saved_seg;
58 subsegT saved_subseg;
7ed4c4c5
NC
59 /* Opcodes generated from this function. */
60 unsigned char * opcodes;
c19d1205
ZW
61 int opcode_count;
62 int opcode_alloc;
7ed4c4c5 63 /* The number of bytes pushed to the stack. */
c19d1205 64 offsetT frame_size;
7ed4c4c5
NC
65 /* We don't add stack adjustment opcodes immediately so that we can merge
66 multiple adjustments. We can also omit the final adjustment
67 when using a frame pointer. */
c19d1205 68 offsetT pending_offset;
7ed4c4c5 69 /* These two fields are set by both unwind_movsp and unwind_setfp. They
c19d1205
ZW
70 hold the reg+offset to use when restoring sp from a frame pointer. */
71 offsetT fp_offset;
72 int fp_reg;
7ed4c4c5 73 /* Nonzero if an unwind_setfp directive has been seen. */
c19d1205 74 unsigned fp_used:1;
7ed4c4c5 75 /* Nonzero if the last opcode restores sp from fp_reg. */
c19d1205 76 unsigned sp_restored:1;
7ed4c4c5
NC
77} unwind;
78
18a20338
CL
79/* Whether --fdpic was given. */
80static int arm_fdpic;
81
8b1ad454
NC
82#endif /* OBJ_ELF */
83
4962c51a
MS
84/* Results from operand parsing worker functions. */
85
86typedef enum
87{
88 PARSE_OPERAND_SUCCESS,
89 PARSE_OPERAND_FAIL,
90 PARSE_OPERAND_FAIL_NO_BACKTRACK
91} parse_operand_result;
92
33a392fb
PB
93enum arm_float_abi
94{
95 ARM_FLOAT_ABI_HARD,
96 ARM_FLOAT_ABI_SOFTFP,
97 ARM_FLOAT_ABI_SOFT
98};
99
c19d1205 100/* Types of processor to assemble for. */
b99bd4ef 101#ifndef CPU_DEFAULT
8a59fff3 102/* The code that was here used to select a default CPU depending on compiler
fa94de6b 103 pre-defines which were only present when doing native builds, thus
8a59fff3
MGD
104 changing gas' default behaviour depending upon the build host.
105
106 If you have a target that requires a default CPU option then the you
107 should define CPU_DEFAULT here. */
b99bd4ef
NC
108#endif
109
e8f8842d
TC
110/* Perform range checks on positive and negative overflows by checking if the
111 VALUE given fits within the range of an BITS sized immediate. */
5b7c81bd 112static bool out_of_range_p (offsetT value, offsetT bits)
e8f8842d
TC
113 {
114 gas_assert (bits < (offsetT)(sizeof (value) * 8));
115 return (value & ~((1 << bits)-1))
116 && ((value & ~((1 << bits)-1)) != ~((1 << bits)-1));
117}
118
b99bd4ef 119#ifndef FPU_DEFAULT
c820d418
MM
120# ifdef TE_LINUX
121# define FPU_DEFAULT FPU_ARCH_FPA
122# elif defined (TE_NetBSD)
123# ifdef OBJ_ELF
124# define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, but VFP order. */
125# else
126 /* Legacy a.out format. */
127# define FPU_DEFAULT FPU_ARCH_FPA /* Soft-float, but FPA order. */
128# endif
4e7fd91e
PB
129# elif defined (TE_VXWORKS)
130# define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, VFP order. */
c820d418
MM
131# else
132 /* For backwards compatibility, default to FPA. */
133# define FPU_DEFAULT FPU_ARCH_FPA
134# endif
135#endif /* ifndef FPU_DEFAULT */
b99bd4ef 136
c19d1205 137#define streq(a, b) (strcmp (a, b) == 0)
b99bd4ef 138
4d354d8b
TP
139/* Current set of feature bits available (CPU+FPU). Different from
140 selected_cpu + selected_fpu in case of autodetection since the CPU
141 feature bits are then all set. */
e74cfd16 142static arm_feature_set cpu_variant;
4d354d8b
TP
143/* Feature bits used in each execution state. Used to set build attribute
144 (in particular Tag_*_ISA_use) in CPU autodetection mode. */
e74cfd16
PB
145static arm_feature_set arm_arch_used;
146static arm_feature_set thumb_arch_used;
b99bd4ef 147
b99bd4ef 148/* Flags stored in private area of BFD structure. */
5b7c81bd
AM
149static int uses_apcs_26 = false;
150static int atpcs = false;
151static int support_interwork = false;
152static int uses_apcs_float = false;
153static int pic_code = false;
154static int fix_v4bx = false;
278df34e 155/* Warn on using deprecated features. */
5b7c81bd
AM
156static int warn_on_deprecated = true;
157static int warn_on_restrict_it = false;
278df34e 158
2e6976a8 159/* Understand CodeComposer Studio assembly syntax. */
5b7c81bd 160bool codecomposer_syntax = false;
03b1477f
RE
161
162/* Variables that we set while parsing command-line options. Once all
163 options have been read we re-process these values to set the real
164 assembly flags. */
4d354d8b
TP
165
166/* CPU and FPU feature bits set for legacy CPU and FPU options (eg. -marm1
167 instead of -mcpu=arm1). */
168static const arm_feature_set *legacy_cpu = NULL;
169static const arm_feature_set *legacy_fpu = NULL;
170
171/* CPU, extension and FPU feature bits selected by -mcpu. */
172static const arm_feature_set *mcpu_cpu_opt = NULL;
173static arm_feature_set *mcpu_ext_opt = NULL;
174static const arm_feature_set *mcpu_fpu_opt = NULL;
175
176/* CPU, extension and FPU feature bits selected by -march. */
177static const arm_feature_set *march_cpu_opt = NULL;
178static arm_feature_set *march_ext_opt = NULL;
179static const arm_feature_set *march_fpu_opt = NULL;
180
181/* Feature bits selected by -mfpu. */
182static const arm_feature_set *mfpu_opt = NULL;
e74cfd16
PB
183
184/* Constants for known architecture features. */
185static const arm_feature_set fpu_default = FPU_DEFAULT;
f85d59c3 186static const arm_feature_set fpu_arch_vfp_v1 ATTRIBUTE_UNUSED = FPU_ARCH_VFP_V1;
e74cfd16 187static const arm_feature_set fpu_arch_vfp_v2 = FPU_ARCH_VFP_V2;
f85d59c3
KT
188static const arm_feature_set fpu_arch_vfp_v3 ATTRIBUTE_UNUSED = FPU_ARCH_VFP_V3;
189static const arm_feature_set fpu_arch_neon_v1 ATTRIBUTE_UNUSED = FPU_ARCH_NEON_V1;
e74cfd16
PB
190static const arm_feature_set fpu_arch_fpa = FPU_ARCH_FPA;
191static const arm_feature_set fpu_any_hard = FPU_ANY_HARD;
69c9e028 192#ifdef OBJ_ELF
e74cfd16 193static const arm_feature_set fpu_arch_maverick = FPU_ARCH_MAVERICK;
69c9e028 194#endif
e74cfd16
PB
195static const arm_feature_set fpu_endian_pure = FPU_ARCH_ENDIAN_PURE;
196
197#ifdef CPU_DEFAULT
198static const arm_feature_set cpu_default = CPU_DEFAULT;
199#endif
200
823d2571 201static const arm_feature_set arm_ext_v1 = ARM_FEATURE_CORE_LOW (ARM_EXT_V1);
4070243b 202static const arm_feature_set arm_ext_v2 = ARM_FEATURE_CORE_LOW (ARM_EXT_V2);
823d2571
TG
203static const arm_feature_set arm_ext_v2s = ARM_FEATURE_CORE_LOW (ARM_EXT_V2S);
204static const arm_feature_set arm_ext_v3 = ARM_FEATURE_CORE_LOW (ARM_EXT_V3);
205static const arm_feature_set arm_ext_v3m = ARM_FEATURE_CORE_LOW (ARM_EXT_V3M);
206static const arm_feature_set arm_ext_v4 = ARM_FEATURE_CORE_LOW (ARM_EXT_V4);
207static const arm_feature_set arm_ext_v4t = ARM_FEATURE_CORE_LOW (ARM_EXT_V4T);
208static const arm_feature_set arm_ext_v5 = ARM_FEATURE_CORE_LOW (ARM_EXT_V5);
e74cfd16 209static const arm_feature_set arm_ext_v4t_5 =
823d2571
TG
210 ARM_FEATURE_CORE_LOW (ARM_EXT_V4T | ARM_EXT_V5);
211static const arm_feature_set arm_ext_v5t = ARM_FEATURE_CORE_LOW (ARM_EXT_V5T);
212static const arm_feature_set arm_ext_v5e = ARM_FEATURE_CORE_LOW (ARM_EXT_V5E);
213static const arm_feature_set arm_ext_v5exp = ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP);
214static const arm_feature_set arm_ext_v5j = ARM_FEATURE_CORE_LOW (ARM_EXT_V5J);
215static const arm_feature_set arm_ext_v6 = ARM_FEATURE_CORE_LOW (ARM_EXT_V6);
216static const arm_feature_set arm_ext_v6k = ARM_FEATURE_CORE_LOW (ARM_EXT_V6K);
217static const arm_feature_set arm_ext_v6t2 = ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2);
55e8aae7
SP
218/* Only for compatability of hint instructions. */
219static const arm_feature_set arm_ext_v6k_v6t2 =
220 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K | ARM_EXT_V6T2);
823d2571
TG
221static const arm_feature_set arm_ext_v6_notm =
222 ARM_FEATURE_CORE_LOW (ARM_EXT_V6_NOTM);
223static const arm_feature_set arm_ext_v6_dsp =
224 ARM_FEATURE_CORE_LOW (ARM_EXT_V6_DSP);
225static const arm_feature_set arm_ext_barrier =
226 ARM_FEATURE_CORE_LOW (ARM_EXT_BARRIER);
227static const arm_feature_set arm_ext_msr =
228 ARM_FEATURE_CORE_LOW (ARM_EXT_THUMB_MSR);
229static const arm_feature_set arm_ext_div = ARM_FEATURE_CORE_LOW (ARM_EXT_DIV);
230static const arm_feature_set arm_ext_v7 = ARM_FEATURE_CORE_LOW (ARM_EXT_V7);
231static const arm_feature_set arm_ext_v7a = ARM_FEATURE_CORE_LOW (ARM_EXT_V7A);
232static const arm_feature_set arm_ext_v7r = ARM_FEATURE_CORE_LOW (ARM_EXT_V7R);
164446e0 233static const arm_feature_set arm_ext_v8r = ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8R);
69c9e028 234#ifdef OBJ_ELF
e7d39ed3 235static const arm_feature_set ATTRIBUTE_UNUSED arm_ext_v7m = ARM_FEATURE_CORE_LOW (ARM_EXT_V7M);
69c9e028 236#endif
823d2571 237static const arm_feature_set arm_ext_v8 = ARM_FEATURE_CORE_LOW (ARM_EXT_V8);
7e806470 238static const arm_feature_set arm_ext_m =
173205ca 239 ARM_FEATURE_CORE (ARM_EXT_V6M | ARM_EXT_V7M,
16a1fa25 240 ARM_EXT2_V8M | ARM_EXT2_V8M_MAIN);
823d2571
TG
241static const arm_feature_set arm_ext_mp = ARM_FEATURE_CORE_LOW (ARM_EXT_MP);
242static const arm_feature_set arm_ext_sec = ARM_FEATURE_CORE_LOW (ARM_EXT_SEC);
243static const arm_feature_set arm_ext_os = ARM_FEATURE_CORE_LOW (ARM_EXT_OS);
244static const arm_feature_set arm_ext_adiv = ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV);
245static const arm_feature_set arm_ext_virt = ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT);
ddfded2f 246static const arm_feature_set arm_ext_pan = ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN);
4ed7ed8d 247static const arm_feature_set arm_ext_v8m = ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M);
16a1fa25
TP
248static const arm_feature_set arm_ext_v8m_main =
249 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M_MAIN);
e12437dc
AV
250static const arm_feature_set arm_ext_v8_1m_main =
251ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN);
16a1fa25
TP
252/* Instructions in ARMv8-M only found in M profile architectures. */
253static const arm_feature_set arm_ext_v8m_m_only =
254 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M | ARM_EXT2_V8M_MAIN);
ff8646ee
TP
255static const arm_feature_set arm_ext_v6t2_v8m =
256 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M);
4ed7ed8d
TP
257/* Instructions shared between ARMv8-A and ARMv8-M. */
258static const arm_feature_set arm_ext_atomics =
259 ARM_FEATURE_CORE_HIGH (ARM_EXT2_ATOMICS);
69c9e028 260#ifdef OBJ_ELF
15afaa63
TP
261/* DSP instructions Tag_DSP_extension refers to. */
262static const arm_feature_set arm_ext_dsp =
263 ARM_FEATURE_CORE_LOW (ARM_EXT_V5E | ARM_EXT_V5ExP | ARM_EXT_V6_DSP);
69c9e028 264#endif
4d1464f2
MW
265static const arm_feature_set arm_ext_ras =
266 ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS);
b8ec4e87
JW
267/* FP16 instructions. */
268static const arm_feature_set arm_ext_fp16 =
269 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST);
01f48020
TC
270static const arm_feature_set arm_ext_fp16_fml =
271 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_FML);
dec41383
JW
272static const arm_feature_set arm_ext_v8_2 =
273 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_2A);
49e8a725
SN
274static const arm_feature_set arm_ext_v8_3 =
275 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A);
7fadb25d
SD
276static const arm_feature_set arm_ext_sb =
277 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB);
dad0c3bf
SD
278static const arm_feature_set arm_ext_predres =
279 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES);
aab2c27d
MM
280static const arm_feature_set arm_ext_bf16 =
281 ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16);
616ce08e
MM
282static const arm_feature_set arm_ext_i8mm =
283 ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM);
8b301fbb
MI
284static const arm_feature_set arm_ext_crc =
285 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC);
4934a27c
MM
286static const arm_feature_set arm_ext_cde =
287 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE);
288static const arm_feature_set arm_ext_cde0 =
289 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE0);
290static const arm_feature_set arm_ext_cde1 =
291 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE1);
292static const arm_feature_set arm_ext_cde2 =
293 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE2);
294static const arm_feature_set arm_ext_cde3 =
295 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE3);
296static const arm_feature_set arm_ext_cde4 =
297 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE4);
298static const arm_feature_set arm_ext_cde5 =
299 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE5);
300static const arm_feature_set arm_ext_cde6 =
301 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE6);
302static const arm_feature_set arm_ext_cde7 =
303 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE7);
e74cfd16
PB
304
305static const arm_feature_set arm_arch_any = ARM_ANY;
2c6b98ea 306static const arm_feature_set fpu_any = FPU_ANY;
f85d59c3 307static const arm_feature_set arm_arch_full ATTRIBUTE_UNUSED = ARM_FEATURE (-1, -1, -1);
e74cfd16
PB
308static const arm_feature_set arm_arch_t2 = ARM_ARCH_THUMB2;
309static const arm_feature_set arm_arch_none = ARM_ARCH_NONE;
310
2d447fca 311static const arm_feature_set arm_cext_iwmmxt2 =
823d2571 312 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2);
e74cfd16 313static const arm_feature_set arm_cext_iwmmxt =
823d2571 314 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT);
e74cfd16 315static const arm_feature_set arm_cext_xscale =
823d2571 316 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE);
e74cfd16 317static const arm_feature_set arm_cext_maverick =
823d2571
TG
318 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK);
319static const arm_feature_set fpu_fpa_ext_v1 =
320 ARM_FEATURE_COPROC (FPU_FPA_EXT_V1);
321static const arm_feature_set fpu_fpa_ext_v2 =
322 ARM_FEATURE_COPROC (FPU_FPA_EXT_V2);
e74cfd16 323static const arm_feature_set fpu_vfp_ext_v1xd =
823d2571
TG
324 ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD);
325static const arm_feature_set fpu_vfp_ext_v1 =
326 ARM_FEATURE_COPROC (FPU_VFP_EXT_V1);
327static const arm_feature_set fpu_vfp_ext_v2 =
328 ARM_FEATURE_COPROC (FPU_VFP_EXT_V2);
329static const arm_feature_set fpu_vfp_ext_v3xd =
330 ARM_FEATURE_COPROC (FPU_VFP_EXT_V3xD);
331static const arm_feature_set fpu_vfp_ext_v3 =
332 ARM_FEATURE_COPROC (FPU_VFP_EXT_V3);
b1cc4aeb 333static const arm_feature_set fpu_vfp_ext_d32 =
823d2571
TG
334 ARM_FEATURE_COPROC (FPU_VFP_EXT_D32);
335static const arm_feature_set fpu_neon_ext_v1 =
336 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1);
5287ad62 337static const arm_feature_set fpu_vfp_v3_or_neon_ext =
823d2571 338 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_VFP_EXT_V3);
a7ad558c 339static const arm_feature_set mve_ext =
2da2eaf4 340 ARM_FEATURE_CORE_HIGH (ARM_EXT2_MVE);
a7ad558c 341static const arm_feature_set mve_fp_ext =
2da2eaf4 342 ARM_FEATURE_CORE_HIGH (ARM_EXT2_MVE_FP);
5aae9ae9
MM
343/* Note: This has more than one bit set, which means using it with
344 mark_feature_used (which returns if *any* of the bits are set in the current
345 cpu variant) can give surprising results. */
346static const arm_feature_set armv8m_fp =
347 ARM_FEATURE_COPROC (FPU_VFP_V5_SP_D16);
69c9e028 348#ifdef OBJ_ELF
823d2571
TG
349static const arm_feature_set fpu_vfp_fp16 =
350 ARM_FEATURE_COPROC (FPU_VFP_EXT_FP16);
351static const arm_feature_set fpu_neon_ext_fma =
352 ARM_FEATURE_COPROC (FPU_NEON_EXT_FMA);
69c9e028 353#endif
823d2571
TG
354static const arm_feature_set fpu_vfp_ext_fma =
355 ARM_FEATURE_COPROC (FPU_VFP_EXT_FMA);
bca38921 356static const arm_feature_set fpu_vfp_ext_armv8 =
823d2571 357 ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8);
a715796b 358static const arm_feature_set fpu_vfp_ext_armv8xd =
823d2571 359 ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8xD);
bca38921 360static const arm_feature_set fpu_neon_ext_armv8 =
823d2571 361 ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8);
bca38921 362static const arm_feature_set fpu_crypto_ext_armv8 =
823d2571 363 ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8);
d6b4b13e 364static const arm_feature_set fpu_neon_ext_v8_1 =
643afb90 365 ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA);
c604a79a
JW
366static const arm_feature_set fpu_neon_ext_dotprod =
367 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD);
5a0c7a81
AC
368static const arm_feature_set pacbti_ext =
369 ARM_FEATURE_CORE_HIGH_HIGH (ARM_EXT3_PACBTI);
e74cfd16 370
33a392fb 371static int mfloat_abi_opt = -1;
4d354d8b
TP
372/* Architecture feature bits selected by the last -mcpu/-march or .cpu/.arch
373 directive. */
374static arm_feature_set selected_arch = ARM_ARCH_NONE;
375/* Extension feature bits selected by the last -mcpu/-march or .arch_extension
376 directive. */
377static arm_feature_set selected_ext = ARM_ARCH_NONE;
378/* Feature bits selected by the last -mcpu/-march or by the combination of the
379 last .cpu/.arch directive .arch_extension directives since that
380 directive. */
e74cfd16 381static arm_feature_set selected_cpu = ARM_ARCH_NONE;
4d354d8b
TP
382/* FPU feature bits selected by the last -mfpu or .fpu directive. */
383static arm_feature_set selected_fpu = FPU_NONE;
384/* Feature bits selected by the last .object_arch directive. */
385static arm_feature_set selected_object_arch = ARM_ARCH_NONE;
ee065d83 386/* Must be long enough to hold any of the names in arm_cpus. */
e20f9590 387static const struct arm_ext_table * selected_ctx_ext_table = NULL;
ef8e6722 388static char selected_cpu_name[20];
8d67f500 389
aacf0b33
KT
390extern FLONUM_TYPE generic_floating_point_number;
391
8d67f500 392/* Return if no cpu was selected on command-line. */
5b7c81bd 393static bool
8d67f500
NC
394no_cpu_selected (void)
395{
823d2571 396 return ARM_FEATURE_EQUAL (selected_cpu, arm_arch_none);
8d67f500
NC
397}
398
7cc69913 399#ifdef OBJ_ELF
deeaaff8
DJ
400# ifdef EABI_DEFAULT
401static int meabi_flags = EABI_DEFAULT;
402# else
d507cf36 403static int meabi_flags = EF_ARM_EABI_UNKNOWN;
deeaaff8 404# endif
e1da3f5b 405
ee3c0378
AS
406static int attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
407
5b7c81bd 408bool
5f4273c7 409arm_is_eabi (void)
e1da3f5b
PB
410{
411 return (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4);
412}
7cc69913 413#endif
b99bd4ef 414
b99bd4ef 415#ifdef OBJ_ELF
c19d1205 416/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
b99bd4ef
NC
417symbolS * GOT_symbol;
418#endif
419
b99bd4ef
NC
420/* 0: assemble for ARM,
421 1: assemble for Thumb,
422 2: assemble for Thumb even though target CPU does not support thumb
423 instructions. */
424static int thumb_mode = 0;
8dc2430f
NC
425/* A value distinct from the possible values for thumb_mode that we
426 can use to record whether thumb_mode has been copied into the
427 tc_frag_data field of a frag. */
428#define MODE_RECORDED (1 << 4)
b99bd4ef 429
e07e6e58
NC
430/* Specifies the intrinsic IT insn behavior mode. */
431enum implicit_it_mode
432{
433 IMPLICIT_IT_MODE_NEVER = 0x00,
434 IMPLICIT_IT_MODE_ARM = 0x01,
435 IMPLICIT_IT_MODE_THUMB = 0x02,
436 IMPLICIT_IT_MODE_ALWAYS = (IMPLICIT_IT_MODE_ARM | IMPLICIT_IT_MODE_THUMB)
437};
438static int implicit_it_mode = IMPLICIT_IT_MODE_ARM;
439
c19d1205
ZW
440/* If unified_syntax is true, we are processing the new unified
441 ARM/Thumb syntax. Important differences from the old ARM mode:
442
443 - Immediate operands do not require a # prefix.
444 - Conditional affixes always appear at the end of the
445 instruction. (For backward compatibility, those instructions
446 that formerly had them in the middle, continue to accept them
447 there.)
448 - The IT instruction may appear, and if it does is validated
449 against subsequent conditional affixes. It does not generate
450 machine code.
451
452 Important differences from the old Thumb mode:
453
454 - Immediate operands do not require a # prefix.
455 - Most of the V6T2 instructions are only available in unified mode.
456 - The .N and .W suffixes are recognized and honored (it is an error
457 if they cannot be honored).
458 - All instructions set the flags if and only if they have an 's' affix.
459 - Conditional affixes may be used. They are validated against
460 preceding IT instructions. Unlike ARM mode, you cannot use a
461 conditional affix except in the scope of an IT instruction. */
462
5b7c81bd 463static bool unified_syntax = false;
b99bd4ef 464
bacebabc
RM
465/* An immediate operand can start with #, and ld*, st*, pld operands
466 can contain [ and ]. We need to tell APP not to elide whitespace
477330fc
RM
467 before a [, which can appear as the first operand for pld.
468 Likewise, a { can appear as the first operand for push, pop, vld*, etc. */
469const char arm_symbol_chars[] = "#[]{}";
bacebabc 470
5287ad62
JB
471enum neon_el_type
472{
dcbf9037 473 NT_invtype,
5287ad62
JB
474 NT_untyped,
475 NT_integer,
476 NT_float,
477 NT_poly,
478 NT_signed,
aab2c27d 479 NT_bfloat,
dcbf9037 480 NT_unsigned
5287ad62
JB
481};
482
483struct neon_type_el
484{
485 enum neon_el_type type;
486 unsigned size;
487};
488
5aae9ae9 489#define NEON_MAX_TYPE_ELS 5
5287ad62
JB
490
491struct neon_type
492{
493 struct neon_type_el el[NEON_MAX_TYPE_ELS];
494 unsigned elems;
495};
496
5ee91343 497enum pred_instruction_type
e07e6e58 498{
5ee91343
AV
499 OUTSIDE_PRED_INSN,
500 INSIDE_VPT_INSN,
e07e6e58
NC
501 INSIDE_IT_INSN,
502 INSIDE_IT_LAST_INSN,
503 IF_INSIDE_IT_LAST_INSN, /* Either outside or inside;
477330fc 504 if inside, should be the last one. */
e07e6e58 505 NEUTRAL_IT_INSN, /* This could be either inside or outside,
477330fc 506 i.e. BKPT and NOP. */
5ee91343
AV
507 IT_INSN, /* The IT insn has been parsed. */
508 VPT_INSN, /* The VPT/VPST insn has been parsed. */
35c228db 509 MVE_OUTSIDE_PRED_INSN , /* Instruction to indicate a MVE instruction without
5ee91343 510 a predication code. */
4934a27c 511 MVE_UNPREDICABLE_INSN, /* MVE instruction that is non-predicable. */
e07e6e58
NC
512};
513
ad6cec43
MGD
514/* The maximum number of operands we need. */
515#define ARM_IT_MAX_OPERANDS 6
e2b0ab59 516#define ARM_IT_MAX_RELOCS 3
ad6cec43 517
b99bd4ef
NC
518struct arm_it
519{
c19d1205 520 const char * error;
b99bd4ef 521 unsigned long instruction;
7af67752
AM
522 unsigned int size;
523 unsigned int size_req;
524 unsigned int cond;
037e8744 525 /* "uncond_value" is set to the value in place of the conditional field in
7af67752 526 unconditional versions of the instruction, or -1u if nothing is
037e8744 527 appropriate. */
7af67752 528 unsigned int uncond_value;
5287ad62 529 struct neon_type vectype;
88714cb8
DG
530 /* This does not indicate an actual NEON instruction, only that
531 the mnemonic accepts neon-style type suffixes. */
532 int is_neon;
0110f2b8
PB
533 /* Set to the opcode if the instruction needs relaxation.
534 Zero if the instruction is not relaxed. */
535 unsigned long relax;
b99bd4ef
NC
536 struct
537 {
538 bfd_reloc_code_real_type type;
c19d1205
ZW
539 expressionS exp;
540 int pc_rel;
e2b0ab59 541 } relocs[ARM_IT_MAX_RELOCS];
b99bd4ef 542
5ee91343 543 enum pred_instruction_type pred_insn_type;
e07e6e58 544
c19d1205
ZW
545 struct
546 {
547 unsigned reg;
ca3f61f7 548 signed int imm;
dcbf9037 549 struct neon_type_el vectype;
ca3f61f7
NC
550 unsigned present : 1; /* Operand present. */
551 unsigned isreg : 1; /* Operand was a register. */
f5f10c66
AV
552 unsigned immisreg : 2; /* .imm field is a second register.
553 0: imm, 1: gpr, 2: MVE Q-register. */
57785aa2
AV
554 unsigned isscalar : 2; /* Operand is a (SIMD) scalar:
555 0) not scalar,
556 1) Neon scalar,
557 2) MVE scalar. */
5287ad62 558 unsigned immisalign : 1; /* Immediate is an alignment specifier. */
c96612cc 559 unsigned immisfloat : 1; /* Immediate was parsed as a float. */
5287ad62
JB
560 /* Note: we abuse "regisimm" to mean "is Neon register" in VMOV
561 instructions. This allows us to disambiguate ARM <-> vector insns. */
562 unsigned regisimm : 1; /* 64-bit immediate, reg forms high 32 bits. */
037e8744 563 unsigned isvec : 1; /* Is a single, double or quad VFP/Neon reg. */
5ee91343 564 unsigned isquad : 1; /* Operand is SIMD quad register. */
037e8744 565 unsigned issingle : 1; /* Operand is VFP single-precision register. */
1b883319 566 unsigned iszr : 1; /* Operand is ZR register. */
ca3f61f7
NC
567 unsigned hasreloc : 1; /* Operand has relocation suffix. */
568 unsigned writeback : 1; /* Operand has trailing ! */
569 unsigned preind : 1; /* Preindexed address. */
570 unsigned postind : 1; /* Postindexed address. */
571 unsigned negative : 1; /* Index register was negated. */
572 unsigned shifted : 1; /* Shift applied to operation. */
573 unsigned shift_kind : 3; /* Shift operation (enum shift_kind). */
ad6cec43 574 } operands[ARM_IT_MAX_OPERANDS];
b99bd4ef
NC
575};
576
c19d1205 577static struct arm_it inst;
b99bd4ef
NC
578
579#define NUM_FLOAT_VALS 8
580
05d2d07e 581const char * fp_const[] =
b99bd4ef
NC
582{
583 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
584};
585
b99bd4ef
NC
586LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
587
588#define FAIL (-1)
589#define SUCCESS (0)
590
591#define SUFF_S 1
592#define SUFF_D 2
593#define SUFF_E 3
594#define SUFF_P 4
595
c19d1205
ZW
596#define CP_T_X 0x00008000
597#define CP_T_Y 0x00400000
b99bd4ef 598
c19d1205
ZW
599#define CONDS_BIT 0x00100000
600#define LOAD_BIT 0x00100000
b99bd4ef
NC
601
602#define DOUBLE_LOAD_FLAG 0x00000001
603
604struct asm_cond
605{
d3ce72d0 606 const char * template_name;
c921be7d 607 unsigned long value;
b99bd4ef
NC
608};
609
c19d1205 610#define COND_ALWAYS 0xE
b99bd4ef 611
b99bd4ef
NC
612struct asm_psr
613{
d3ce72d0 614 const char * template_name;
c921be7d 615 unsigned long field;
b99bd4ef
NC
616};
617
62b3e311
PB
618struct asm_barrier_opt
619{
e797f7e0
MGD
620 const char * template_name;
621 unsigned long value;
622 const arm_feature_set arch;
62b3e311
PB
623};
624
2d2255b5 625/* The bit that distinguishes CPSR and SPSR. */
b99bd4ef
NC
626#define SPSR_BIT (1 << 22)
627
c19d1205
ZW
628/* The individual PSR flag bits. */
629#define PSR_c (1 << 16)
630#define PSR_x (1 << 17)
631#define PSR_s (1 << 18)
632#define PSR_f (1 << 19)
b99bd4ef 633
c19d1205 634struct reloc_entry
bfae80f2 635{
0198d5e6 636 const char * name;
c921be7d 637 bfd_reloc_code_real_type reloc;
bfae80f2
RE
638};
639
5287ad62 640enum vfp_reg_pos
bfae80f2 641{
5287ad62
JB
642 VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn,
643 VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
bfae80f2
RE
644};
645
646enum vfp_ldstm_type
647{
648 VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
649};
650
dcbf9037
JB
651/* Bits for DEFINED field in neon_typed_alias. */
652#define NTA_HASTYPE 1
653#define NTA_HASINDEX 2
654
655struct neon_typed_alias
656{
c921be7d
NC
657 unsigned char defined;
658 unsigned char index;
659 struct neon_type_el eltype;
dcbf9037
JB
660};
661
c19d1205 662/* ARM register categories. This includes coprocessor numbers and various
5aa75429
TP
663 architecture extensions' registers. Each entry should have an error message
664 in reg_expected_msgs below. */
c19d1205 665enum arm_reg_type
bfae80f2 666{
c19d1205
ZW
667 REG_TYPE_RN,
668 REG_TYPE_CP,
669 REG_TYPE_CN,
670 REG_TYPE_FN,
671 REG_TYPE_VFS,
672 REG_TYPE_VFD,
5287ad62 673 REG_TYPE_NQ,
037e8744 674 REG_TYPE_VFSD,
5287ad62 675 REG_TYPE_NDQ,
dec41383 676 REG_TYPE_NSD,
037e8744 677 REG_TYPE_NSDQ,
c19d1205
ZW
678 REG_TYPE_VFC,
679 REG_TYPE_MVF,
680 REG_TYPE_MVD,
681 REG_TYPE_MVFX,
682 REG_TYPE_MVDX,
683 REG_TYPE_MVAX,
5ee91343 684 REG_TYPE_MQ,
c19d1205
ZW
685 REG_TYPE_DSPSC,
686 REG_TYPE_MMXWR,
687 REG_TYPE_MMXWC,
688 REG_TYPE_MMXWCG,
689 REG_TYPE_XSCALE,
5ee91343 690 REG_TYPE_RNB,
8c299995
TB
691 REG_TYPE_ZR,
692 REG_TYPE_PSEUDO
bfae80f2
RE
693};
694
dcbf9037
JB
695/* Structure for a hash table entry for a register.
696 If TYPE is REG_TYPE_VFD or REG_TYPE_NQ, the NEON field can point to extra
697 information which states whether a vector type or index is specified (for a
698 register alias created with .dn or .qn). Otherwise NEON should be NULL. */
6c43fab6
RE
699struct reg_entry
700{
c921be7d 701 const char * name;
90ec0d68 702 unsigned int number;
c921be7d
NC
703 unsigned char type;
704 unsigned char builtin;
705 struct neon_typed_alias * neon;
6c43fab6
RE
706};
707
c19d1205 708/* Diagnostics used when we don't get a register of the expected type. */
c921be7d 709const char * const reg_expected_msgs[] =
c19d1205 710{
5aa75429
TP
711 [REG_TYPE_RN] = N_("ARM register expected"),
712 [REG_TYPE_CP] = N_("bad or missing co-processor number"),
713 [REG_TYPE_CN] = N_("co-processor register expected"),
714 [REG_TYPE_FN] = N_("FPA register expected"),
715 [REG_TYPE_VFS] = N_("VFP single precision register expected"),
716 [REG_TYPE_VFD] = N_("VFP/Neon double precision register expected"),
717 [REG_TYPE_NQ] = N_("Neon quad precision register expected"),
718 [REG_TYPE_VFSD] = N_("VFP single or double precision register expected"),
719 [REG_TYPE_NDQ] = N_("Neon double or quad precision register expected"),
720 [REG_TYPE_NSD] = N_("Neon single or double precision register expected"),
721 [REG_TYPE_NSDQ] = N_("VFP single, double or Neon quad precision register"
722 " expected"),
723 [REG_TYPE_VFC] = N_("VFP system register expected"),
724 [REG_TYPE_MVF] = N_("Maverick MVF register expected"),
725 [REG_TYPE_MVD] = N_("Maverick MVD register expected"),
726 [REG_TYPE_MVFX] = N_("Maverick MVFX register expected"),
727 [REG_TYPE_MVDX] = N_("Maverick MVDX register expected"),
728 [REG_TYPE_MVAX] = N_("Maverick MVAX register expected"),
729 [REG_TYPE_DSPSC] = N_("Maverick DSPSC register expected"),
730 [REG_TYPE_MMXWR] = N_("iWMMXt data register expected"),
731 [REG_TYPE_MMXWC] = N_("iWMMXt control register expected"),
732 [REG_TYPE_MMXWCG] = N_("iWMMXt scalar register expected"),
733 [REG_TYPE_XSCALE] = N_("XScale accumulator register expected"),
5ee91343 734 [REG_TYPE_MQ] = N_("MVE vector register expected"),
e925962f
JB
735 [REG_TYPE_RNB] = "",
736 [REG_TYPE_ZR] = N_("ZR register expected"),
8c299995 737 [REG_TYPE_PSEUDO] = N_("Pseudo register expected"),
6c43fab6
RE
738};
739
c19d1205 740/* Some well known registers that we refer to directly elsewhere. */
bd340a04 741#define REG_R12 12
c19d1205
ZW
742#define REG_SP 13
743#define REG_LR 14
744#define REG_PC 15
404ff6b5 745
b99bd4ef
NC
746/* ARM instructions take 4bytes in the object file, Thumb instructions
747 take 2: */
c19d1205 748#define INSN_SIZE 4
b99bd4ef
NC
749
750struct asm_opcode
751{
752 /* Basic string to match. */
d3ce72d0 753 const char * template_name;
c19d1205
ZW
754
755 /* Parameters to instruction. */
5be8be5d 756 unsigned int operands[8];
c19d1205
ZW
757
758 /* Conditional tag - see opcode_lookup. */
759 unsigned int tag : 4;
b99bd4ef
NC
760
761 /* Basic instruction code. */
a302e574 762 unsigned int avalue;
b99bd4ef 763
c19d1205
ZW
764 /* Thumb-format instruction code. */
765 unsigned int tvalue;
b99bd4ef 766
90e4755a 767 /* Which architecture variant provides this instruction. */
c921be7d
NC
768 const arm_feature_set * avariant;
769 const arm_feature_set * tvariant;
c19d1205
ZW
770
771 /* Function to call to encode instruction in ARM format. */
772 void (* aencode) (void);
b99bd4ef 773
c19d1205
ZW
774 /* Function to call to encode instruction in Thumb format. */
775 void (* tencode) (void);
5ee91343
AV
776
777 /* Indicates whether this instruction may be vector predicated. */
778 unsigned int mayBeVecPred : 1;
b99bd4ef
NC
779};
780
a737bd4d
NC
781/* Defines for various bits that we will want to toggle. */
782#define INST_IMMEDIATE 0x02000000
783#define OFFSET_REG 0x02000000
c19d1205 784#define HWOFFSET_IMM 0x00400000
a737bd4d
NC
785#define SHIFT_BY_REG 0x00000010
786#define PRE_INDEX 0x01000000
787#define INDEX_UP 0x00800000
788#define WRITE_BACK 0x00200000
789#define LDM_TYPE_2_OR_3 0x00400000
a028a6f5 790#define CPSI_MMOD 0x00020000
90e4755a 791
a737bd4d
NC
792#define LITERAL_MASK 0xf000f000
793#define OPCODE_MASK 0xfe1fffff
794#define V4_STR_BIT 0x00000020
8335d6aa 795#define VLDR_VMOV_SAME 0x0040f000
90e4755a 796
efd81785
PB
797#define T2_SUBS_PC_LR 0xf3de8f00
798
a737bd4d 799#define DATA_OP_SHIFT 21
bada4342 800#define SBIT_SHIFT 20
90e4755a 801
ef8d22e6
PB
802#define T2_OPCODE_MASK 0xfe1fffff
803#define T2_DATA_OP_SHIFT 21
bada4342 804#define T2_SBIT_SHIFT 20
ef8d22e6 805
6530b175
NC
806#define A_COND_MASK 0xf0000000
807#define A_PUSH_POP_OP_MASK 0x0fff0000
808
809/* Opcodes for pushing/poping registers to/from the stack. */
810#define A1_OPCODE_PUSH 0x092d0000
811#define A2_OPCODE_PUSH 0x052d0004
812#define A2_OPCODE_POP 0x049d0004
813
a737bd4d
NC
814/* Codes to distinguish the arithmetic instructions. */
815#define OPCODE_AND 0
816#define OPCODE_EOR 1
817#define OPCODE_SUB 2
818#define OPCODE_RSB 3
819#define OPCODE_ADD 4
820#define OPCODE_ADC 5
821#define OPCODE_SBC 6
822#define OPCODE_RSC 7
823#define OPCODE_TST 8
824#define OPCODE_TEQ 9
825#define OPCODE_CMP 10
826#define OPCODE_CMN 11
827#define OPCODE_ORR 12
828#define OPCODE_MOV 13
829#define OPCODE_BIC 14
830#define OPCODE_MVN 15
90e4755a 831
ef8d22e6
PB
832#define T2_OPCODE_AND 0
833#define T2_OPCODE_BIC 1
834#define T2_OPCODE_ORR 2
835#define T2_OPCODE_ORN 3
836#define T2_OPCODE_EOR 4
837#define T2_OPCODE_ADD 8
838#define T2_OPCODE_ADC 10
839#define T2_OPCODE_SBC 11
840#define T2_OPCODE_SUB 13
841#define T2_OPCODE_RSB 14
842
a737bd4d
NC
843#define T_OPCODE_MUL 0x4340
844#define T_OPCODE_TST 0x4200
845#define T_OPCODE_CMN 0x42c0
846#define T_OPCODE_NEG 0x4240
847#define T_OPCODE_MVN 0x43c0
90e4755a 848
a737bd4d
NC
849#define T_OPCODE_ADD_R3 0x1800
850#define T_OPCODE_SUB_R3 0x1a00
851#define T_OPCODE_ADD_HI 0x4400
852#define T_OPCODE_ADD_ST 0xb000
853#define T_OPCODE_SUB_ST 0xb080
854#define T_OPCODE_ADD_SP 0xa800
855#define T_OPCODE_ADD_PC 0xa000
856#define T_OPCODE_ADD_I8 0x3000
857#define T_OPCODE_SUB_I8 0x3800
858#define T_OPCODE_ADD_I3 0x1c00
859#define T_OPCODE_SUB_I3 0x1e00
b99bd4ef 860
a737bd4d
NC
861#define T_OPCODE_ASR_R 0x4100
862#define T_OPCODE_LSL_R 0x4080
c19d1205
ZW
863#define T_OPCODE_LSR_R 0x40c0
864#define T_OPCODE_ROR_R 0x41c0
a737bd4d
NC
865#define T_OPCODE_ASR_I 0x1000
866#define T_OPCODE_LSL_I 0x0000
867#define T_OPCODE_LSR_I 0x0800
b99bd4ef 868
a737bd4d
NC
869#define T_OPCODE_MOV_I8 0x2000
870#define T_OPCODE_CMP_I8 0x2800
871#define T_OPCODE_CMP_LR 0x4280
872#define T_OPCODE_MOV_HR 0x4600
873#define T_OPCODE_CMP_HR 0x4500
b99bd4ef 874
a737bd4d
NC
875#define T_OPCODE_LDR_PC 0x4800
876#define T_OPCODE_LDR_SP 0x9800
877#define T_OPCODE_STR_SP 0x9000
878#define T_OPCODE_LDR_IW 0x6800
879#define T_OPCODE_STR_IW 0x6000
880#define T_OPCODE_LDR_IH 0x8800
881#define T_OPCODE_STR_IH 0x8000
882#define T_OPCODE_LDR_IB 0x7800
883#define T_OPCODE_STR_IB 0x7000
884#define T_OPCODE_LDR_RW 0x5800
885#define T_OPCODE_STR_RW 0x5000
886#define T_OPCODE_LDR_RH 0x5a00
887#define T_OPCODE_STR_RH 0x5200
888#define T_OPCODE_LDR_RB 0x5c00
889#define T_OPCODE_STR_RB 0x5400
c9b604bd 890
a737bd4d
NC
891#define T_OPCODE_PUSH 0xb400
892#define T_OPCODE_POP 0xbc00
b99bd4ef 893
2fc8bdac 894#define T_OPCODE_BRANCH 0xe000
b99bd4ef 895
a737bd4d 896#define THUMB_SIZE 2 /* Size of thumb instruction. */
a737bd4d 897#define THUMB_PP_PC_LR 0x0100
c19d1205 898#define THUMB_LOAD_BIT 0x0800
53365c0d 899#define THUMB2_LOAD_BIT 0x00100000
c19d1205 900
5ee91343 901#define BAD_SYNTAX _("syntax error")
c19d1205 902#define BAD_ARGS _("bad arguments to instruction")
fdfde340 903#define BAD_SP _("r13 not allowed here")
c19d1205 904#define BAD_PC _("r15 not allowed here")
a302e574
AV
905#define BAD_ODD _("Odd register not allowed here")
906#define BAD_EVEN _("Even register not allowed here")
c19d1205
ZW
907#define BAD_COND _("instruction cannot be conditional")
908#define BAD_OVERLAP _("registers may not be the same")
909#define BAD_HIREG _("lo register required")
910#define BAD_THUMB32 _("instruction not supported in Thumb16 mode")
35c228db 911#define BAD_ADDR_MODE _("instruction does not accept this addressing mode")
dfa9f0d5 912#define BAD_BRANCH _("branch must be last instruction in IT block")
e12437dc 913#define BAD_BRANCH_OFF _("branch out of range or not a multiple of 2")
4934a27c 914#define BAD_NO_VPT _("instruction not allowed in VPT block")
dfa9f0d5 915#define BAD_NOT_IT _("instruction not allowed in IT block")
5ee91343 916#define BAD_NOT_VPT _("instruction missing MVE vector predication code")
037e8744 917#define BAD_FPU _("selected FPU does not support instruction")
e07e6e58 918#define BAD_OUT_IT _("thumb conditional instruction should be in IT block")
5ee91343
AV
919#define BAD_OUT_VPT \
920 _("vector predicated instruction should be in VPT/VPST block")
e07e6e58 921#define BAD_IT_COND _("incorrect condition in IT block")
5ee91343 922#define BAD_VPT_COND _("incorrect condition in VPT/VPST block")
e07e6e58 923#define BAD_IT_IT _("IT falling in the range of a previous IT block")
921e5f0a 924#define MISSING_FNSTART _("missing .fnstart before unwinding directive")
5be8be5d
DG
925#define BAD_PC_ADDRESSING \
926 _("cannot use register index with PC-relative addressing")
927#define BAD_PC_WRITEBACK \
928 _("cannot use writeback with PC-relative addressing")
9db2f6b4
RL
929#define BAD_RANGE _("branch out of range")
930#define BAD_FP16 _("selected processor does not support fp16 instruction")
aab2c27d 931#define BAD_BF16 _("selected processor does not support bf16 instruction")
4934a27c
MM
932#define BAD_CDE _("selected processor does not support cde instruction")
933#define BAD_CDE_COPROC _("coprocessor for insn is not enabled for cde")
dd5181d5 934#define UNPRED_REG(R) _("using " R " results in unpredictable behaviour")
a9f02af8 935#define THUMB1_RELOC_ONLY _("relocation valid in thumb1 code only")
5ee91343
AV
936#define MVE_NOT_IT _("Warning: instruction is UNPREDICTABLE in an IT " \
937 "block")
938#define MVE_NOT_VPT _("Warning: instruction is UNPREDICTABLE in a VPT " \
939 "block")
940#define MVE_BAD_PC _("Warning: instruction is UNPREDICTABLE with PC" \
941 " operand")
942#define MVE_BAD_SP _("Warning: instruction is UNPREDICTABLE with SP" \
943 " operand")
a302e574 944#define BAD_SIMD_TYPE _("bad type in SIMD instruction")
886e1c73
AV
945#define BAD_MVE_AUTO \
946 _("GAS auto-detection mode and -march=all is deprecated for MVE, please" \
947 " use a valid -march or -mcpu option.")
948#define BAD_MVE_SRCDEST _("Warning: 32-bit element size and same destination "\
949 "and source operands makes instruction UNPREDICTABLE")
35c228db 950#define BAD_EL_TYPE _("bad element type for instruction")
1b883319 951#define MVE_BAD_QREG _("MVE vector register Q[0..7] expected")
5a0c7a81 952#define BAD_PACBTI _("selected processor does not support PACBTI extention")
c19d1205 953
629310ab
ML
954static htab_t arm_ops_hsh;
955static htab_t arm_cond_hsh;
956static htab_t arm_vcond_hsh;
957static htab_t arm_shift_hsh;
958static htab_t arm_psr_hsh;
959static htab_t arm_v7m_psr_hsh;
960static htab_t arm_reg_hsh;
961static htab_t arm_reloc_hsh;
962static htab_t arm_barrier_opt_hsh;
b99bd4ef 963
b99bd4ef
NC
964/* Stuff needed to resolve the label ambiguity
965 As:
966 ...
967 label: <insn>
968 may differ from:
969 ...
970 label:
5f4273c7 971 <insn> */
b99bd4ef
NC
972
973symbolS * last_label_seen;
5b7c81bd 974static int label_is_thumb_function_name = false;
e07e6e58 975
3d0c9500
NC
976/* Literal pool structure. Held on a per-section
977 and per-sub-section basis. */
a737bd4d 978
c19d1205 979#define MAX_LITERAL_POOL_SIZE 1024
3d0c9500 980typedef struct literal_pool
b99bd4ef 981{
c921be7d
NC
982 expressionS literals [MAX_LITERAL_POOL_SIZE];
983 unsigned int next_free_entry;
984 unsigned int id;
985 symbolS * symbol;
986 segT section;
987 subsegT sub_section;
a8040cf2
NC
988#ifdef OBJ_ELF
989 struct dwarf2_line_info locs [MAX_LITERAL_POOL_SIZE];
990#endif
c921be7d 991 struct literal_pool * next;
8335d6aa 992 unsigned int alignment;
3d0c9500 993} literal_pool;
b99bd4ef 994
3d0c9500
NC
995/* Pointer to a linked list of literal pools. */
996literal_pool * list_of_pools = NULL;
e27ec89e 997
2e6976a8
DG
998typedef enum asmfunc_states
999{
1000 OUTSIDE_ASMFUNC,
1001 WAITING_ASMFUNC_NAME,
1002 WAITING_ENDASMFUNC
1003} asmfunc_states;
1004
1005static asmfunc_states asmfunc_state = OUTSIDE_ASMFUNC;
1006
e07e6e58 1007#ifdef OBJ_ELF
5ee91343 1008# define now_pred seg_info (now_seg)->tc_segment_info_data.current_pred
e07e6e58 1009#else
5ee91343 1010static struct current_pred now_pred;
e07e6e58
NC
1011#endif
1012
1013static inline int
5ee91343 1014now_pred_compatible (int cond)
e07e6e58 1015{
5ee91343 1016 return (cond & ~1) == (now_pred.cc & ~1);
e07e6e58
NC
1017}
1018
1019static inline int
1020conditional_insn (void)
1021{
1022 return inst.cond != COND_ALWAYS;
1023}
1024
5ee91343 1025static int in_pred_block (void);
e07e6e58 1026
5ee91343 1027static int handle_pred_state (void);
e07e6e58
NC
1028
1029static void force_automatic_it_block_close (void);
1030
c921be7d
NC
1031static void it_fsm_post_encode (void);
1032
5ee91343 1033#define set_pred_insn_type(type) \
e07e6e58
NC
1034 do \
1035 { \
5ee91343
AV
1036 inst.pred_insn_type = type; \
1037 if (handle_pred_state () == FAIL) \
477330fc 1038 return; \
e07e6e58
NC
1039 } \
1040 while (0)
1041
5ee91343 1042#define set_pred_insn_type_nonvoid(type, failret) \
c921be7d
NC
1043 do \
1044 { \
5ee91343
AV
1045 inst.pred_insn_type = type; \
1046 if (handle_pred_state () == FAIL) \
477330fc 1047 return failret; \
c921be7d
NC
1048 } \
1049 while(0)
1050
5ee91343 1051#define set_pred_insn_type_last() \
e07e6e58
NC
1052 do \
1053 { \
1054 if (inst.cond == COND_ALWAYS) \
5ee91343 1055 set_pred_insn_type (IF_INSIDE_IT_LAST_INSN); \
e07e6e58 1056 else \
5ee91343 1057 set_pred_insn_type (INSIDE_IT_LAST_INSN); \
e07e6e58
NC
1058 } \
1059 while (0)
1060
e39c1607
SD
1061/* Toggle value[pos]. */
1062#define TOGGLE_BIT(value, pos) (value ^ (1 << pos))
1063
c19d1205 1064/* Pure syntax. */
b99bd4ef 1065
c19d1205
ZW
1066/* This array holds the chars that always start a comment. If the
1067 pre-processor is disabled, these aren't very useful. */
2e6976a8 1068char arm_comment_chars[] = "@";
3d0c9500 1069
c19d1205
ZW
1070/* This array holds the chars that only start a comment at the beginning of
1071 a line. If the line seems to have the form '# 123 filename'
1072 .line and .file directives will appear in the pre-processed output. */
1073/* Note that input_file.c hand checks for '#' at the beginning of the
1074 first line of the input file. This is because the compiler outputs
1075 #NO_APP at the beginning of its output. */
1076/* Also note that comments like this one will always work. */
1077const char line_comment_chars[] = "#";
3d0c9500 1078
2e6976a8 1079char arm_line_separator_chars[] = ";";
b99bd4ef 1080
c19d1205
ZW
1081/* Chars that can be used to separate mant
1082 from exp in floating point numbers. */
1083const char EXP_CHARS[] = "eE";
3d0c9500 1084
c19d1205
ZW
1085/* Chars that mean this number is a floating point constant. */
1086/* As in 0f12.456 */
1087/* or 0d1.2345e12 */
b99bd4ef 1088
5312fe52 1089const char FLT_CHARS[] = "rRsSfFdDxXeEpPHh";
3d0c9500 1090
c19d1205
ZW
1091/* Prefix characters that indicate the start of an immediate
1092 value. */
1093#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
3d0c9500 1094
c19d1205
ZW
1095/* Separator character handling. */
1096
1097#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
1098
5312fe52
BW
1099enum fp_16bit_format
1100{
1101 ARM_FP16_FORMAT_IEEE = 0x1,
1102 ARM_FP16_FORMAT_ALTERNATIVE = 0x2,
1103 ARM_FP16_FORMAT_DEFAULT = 0x3
1104};
1105
1106static enum fp_16bit_format fp16_format = ARM_FP16_FORMAT_DEFAULT;
1107
1108
c19d1205
ZW
1109static inline int
1110skip_past_char (char ** str, char c)
1111{
8ab8155f
NC
1112 /* PR gas/14987: Allow for whitespace before the expected character. */
1113 skip_whitespace (*str);
427d0db6 1114
c19d1205
ZW
1115 if (**str == c)
1116 {
1117 (*str)++;
1118 return SUCCESS;
3d0c9500 1119 }
c19d1205
ZW
1120 else
1121 return FAIL;
1122}
c921be7d 1123
c19d1205 1124#define skip_past_comma(str) skip_past_char (str, ',')
3d0c9500 1125
c19d1205
ZW
1126/* Arithmetic expressions (possibly involving symbols). */
1127
1128/* Return TRUE if anything in the expression is a bignum. */
1129
5b7c81bd 1130static bool
c19d1205
ZW
1131walk_no_bignums (symbolS * sp)
1132{
1133 if (symbol_get_value_expression (sp)->X_op == O_big)
5b7c81bd 1134 return true;
c19d1205
ZW
1135
1136 if (symbol_get_value_expression (sp)->X_add_symbol)
3d0c9500 1137 {
c19d1205
ZW
1138 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
1139 || (symbol_get_value_expression (sp)->X_op_symbol
1140 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
3d0c9500
NC
1141 }
1142
5b7c81bd 1143 return false;
3d0c9500
NC
1144}
1145
5b7c81bd 1146static bool in_my_get_expression = false;
c19d1205
ZW
1147
1148/* Third argument to my_get_expression. */
1149#define GE_NO_PREFIX 0
1150#define GE_IMM_PREFIX 1
1151#define GE_OPT_PREFIX 2
5287ad62
JB
1152/* This is a bit of a hack. Use an optional prefix, and also allow big (64-bit)
1153 immediates, as can be used in Neon VMVN and VMOV immediate instructions. */
1154#define GE_OPT_PREFIX_BIG 3
a737bd4d 1155
b99bd4ef 1156static int
c19d1205 1157my_get_expression (expressionS * ep, char ** str, int prefix_mode)
b99bd4ef 1158{
c19d1205 1159 char * save_in;
b99bd4ef 1160
c19d1205
ZW
1161 /* In unified syntax, all prefixes are optional. */
1162 if (unified_syntax)
5287ad62 1163 prefix_mode = (prefix_mode == GE_OPT_PREFIX_BIG) ? prefix_mode
477330fc 1164 : GE_OPT_PREFIX;
b99bd4ef 1165
c19d1205 1166 switch (prefix_mode)
b99bd4ef 1167 {
c19d1205
ZW
1168 case GE_NO_PREFIX: break;
1169 case GE_IMM_PREFIX:
1170 if (!is_immediate_prefix (**str))
1171 {
1172 inst.error = _("immediate expression requires a # prefix");
1173 return FAIL;
1174 }
1175 (*str)++;
1176 break;
1177 case GE_OPT_PREFIX:
5287ad62 1178 case GE_OPT_PREFIX_BIG:
c19d1205
ZW
1179 if (is_immediate_prefix (**str))
1180 (*str)++;
1181 break;
0198d5e6
TC
1182 default:
1183 abort ();
c19d1205 1184 }
b99bd4ef 1185
c19d1205 1186 memset (ep, 0, sizeof (expressionS));
b99bd4ef 1187
c19d1205
ZW
1188 save_in = input_line_pointer;
1189 input_line_pointer = *str;
5b7c81bd 1190 in_my_get_expression = true;
2ac93be7 1191 expression (ep);
5b7c81bd 1192 in_my_get_expression = false;
c19d1205 1193
f86adc07 1194 if (ep->X_op == O_illegal || ep->X_op == O_absent)
b99bd4ef 1195 {
f86adc07 1196 /* We found a bad or missing expression in md_operand(). */
c19d1205
ZW
1197 *str = input_line_pointer;
1198 input_line_pointer = save_in;
1199 if (inst.error == NULL)
f86adc07
NS
1200 inst.error = (ep->X_op == O_absent
1201 ? _("missing expression") :_("bad expression"));
c19d1205
ZW
1202 return 1;
1203 }
b99bd4ef 1204
c19d1205
ZW
1205 /* Get rid of any bignums now, so that we don't generate an error for which
1206 we can't establish a line number later on. Big numbers are never valid
1207 in instructions, which is where this routine is always called. */
5287ad62
JB
1208 if (prefix_mode != GE_OPT_PREFIX_BIG
1209 && (ep->X_op == O_big
477330fc 1210 || (ep->X_add_symbol
5287ad62 1211 && (walk_no_bignums (ep->X_add_symbol)
477330fc 1212 || (ep->X_op_symbol
5287ad62 1213 && walk_no_bignums (ep->X_op_symbol))))))
c19d1205
ZW
1214 {
1215 inst.error = _("invalid constant");
1216 *str = input_line_pointer;
1217 input_line_pointer = save_in;
1218 return 1;
1219 }
b99bd4ef 1220
c19d1205
ZW
1221 *str = input_line_pointer;
1222 input_line_pointer = save_in;
0198d5e6 1223 return SUCCESS;
b99bd4ef
NC
1224}
1225
c19d1205
ZW
1226/* Turn a string in input_line_pointer into a floating point constant
1227 of type TYPE, and store the appropriate bytes in *LITP. The number
1228 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1229 returned, or NULL on OK.
b99bd4ef 1230
c19d1205
ZW
1231 Note that fp constants aren't represent in the normal way on the ARM.
1232 In big endian mode, things are as expected. However, in little endian
1233 mode fp constants are big-endian word-wise, and little-endian byte-wise
1234 within the words. For example, (double) 1.1 in big endian mode is
1235 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
1236 the byte sequence 99 99 f1 3f 9a 99 99 99.
b99bd4ef 1237
c19d1205 1238 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
b99bd4ef 1239
6d4af3c2 1240const char *
c19d1205
ZW
1241md_atof (int type, char * litP, int * sizeP)
1242{
1243 int prec;
1244 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1245 char *t;
1246 int i;
b99bd4ef 1247
c19d1205
ZW
1248 switch (type)
1249 {
5312fe52
BW
1250 case 'H':
1251 case 'h':
2557e081
JB
1252 /* bfloat16, despite not being part of the IEEE specification, can also
1253 be handled by atof_ieee(). */
1254 case 'b':
5312fe52
BW
1255 prec = 1;
1256 break;
1257
c19d1205
ZW
1258 case 'f':
1259 case 'F':
1260 case 's':
1261 case 'S':
1262 prec = 2;
1263 break;
b99bd4ef 1264
c19d1205
ZW
1265 case 'd':
1266 case 'D':
1267 case 'r':
1268 case 'R':
1269 prec = 4;
1270 break;
b99bd4ef 1271
c19d1205
ZW
1272 case 'x':
1273 case 'X':
499ac353 1274 prec = 5;
c19d1205 1275 break;
b99bd4ef 1276
c19d1205
ZW
1277 case 'p':
1278 case 'P':
499ac353 1279 prec = 5;
c19d1205 1280 break;
a737bd4d 1281
c19d1205
ZW
1282 default:
1283 *sizeP = 0;
499ac353 1284 return _("Unrecognized or unsupported floating point constant");
c19d1205 1285 }
b99bd4ef 1286
c19d1205
ZW
1287 t = atof_ieee (input_line_pointer, type, words);
1288 if (t)
1289 input_line_pointer = t;
499ac353 1290 *sizeP = prec * sizeof (LITTLENUM_TYPE);
b99bd4ef 1291
72c03e30
BW
1292 if (target_big_endian || prec == 1)
1293 for (i = 0; i < prec; i++)
1294 {
1295 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1296 litP += sizeof (LITTLENUM_TYPE);
1297 }
1298 else if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
1299 for (i = prec - 1; i >= 0; i--)
1300 {
1301 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1302 litP += sizeof (LITTLENUM_TYPE);
1303 }
c19d1205 1304 else
72c03e30
BW
1305 /* For a 4 byte float the order of elements in `words' is 1 0.
1306 For an 8 byte float the order is 1 0 3 2. */
1307 for (i = 0; i < prec; i += 2)
1308 {
1309 md_number_to_chars (litP, (valueT) words[i + 1],
1310 sizeof (LITTLENUM_TYPE));
1311 md_number_to_chars (litP + sizeof (LITTLENUM_TYPE),
1312 (valueT) words[i], sizeof (LITTLENUM_TYPE));
1313 litP += 2 * sizeof (LITTLENUM_TYPE);
1314 }
b99bd4ef 1315
499ac353 1316 return NULL;
c19d1205 1317}
b99bd4ef 1318
c19d1205
ZW
1319/* We handle all bad expressions here, so that we can report the faulty
1320 instruction in the error message. */
0198d5e6 1321
c19d1205 1322void
91d6fa6a 1323md_operand (expressionS * exp)
c19d1205
ZW
1324{
1325 if (in_my_get_expression)
91d6fa6a 1326 exp->X_op = O_illegal;
b99bd4ef
NC
1327}
1328
c19d1205 1329/* Immediate values. */
b99bd4ef 1330
0198d5e6 1331#ifdef OBJ_ELF
c19d1205
ZW
1332/* Generic immediate-value read function for use in directives.
1333 Accepts anything that 'expression' can fold to a constant.
1334 *val receives the number. */
0198d5e6 1335
c19d1205
ZW
1336static int
1337immediate_for_directive (int *val)
b99bd4ef 1338{
c19d1205
ZW
1339 expressionS exp;
1340 exp.X_op = O_illegal;
b99bd4ef 1341
c19d1205
ZW
1342 if (is_immediate_prefix (*input_line_pointer))
1343 {
1344 input_line_pointer++;
1345 expression (&exp);
1346 }
b99bd4ef 1347
c19d1205
ZW
1348 if (exp.X_op != O_constant)
1349 {
1350 as_bad (_("expected #constant"));
1351 ignore_rest_of_line ();
1352 return FAIL;
1353 }
1354 *val = exp.X_add_number;
1355 return SUCCESS;
b99bd4ef 1356}
c19d1205 1357#endif
b99bd4ef 1358
c19d1205 1359/* Register parsing. */
b99bd4ef 1360
c19d1205
ZW
1361/* Generic register parser. CCP points to what should be the
1362 beginning of a register name. If it is indeed a valid register
1363 name, advance CCP over it and return the reg_entry structure;
1364 otherwise return NULL. Does not issue diagnostics. */
1365
1366static struct reg_entry *
1367arm_reg_parse_multi (char **ccp)
b99bd4ef 1368{
c19d1205
ZW
1369 char *start = *ccp;
1370 char *p;
1371 struct reg_entry *reg;
b99bd4ef 1372
477330fc
RM
1373 skip_whitespace (start);
1374
c19d1205
ZW
1375#ifdef REGISTER_PREFIX
1376 if (*start != REGISTER_PREFIX)
01cfc07f 1377 return NULL;
c19d1205
ZW
1378 start++;
1379#endif
1380#ifdef OPTIONAL_REGISTER_PREFIX
1381 if (*start == OPTIONAL_REGISTER_PREFIX)
1382 start++;
1383#endif
b99bd4ef 1384
c19d1205
ZW
1385 p = start;
1386 if (!ISALPHA (*p) || !is_name_beginner (*p))
1387 return NULL;
b99bd4ef 1388
c19d1205
ZW
1389 do
1390 p++;
1391 while (ISALPHA (*p) || ISDIGIT (*p) || *p == '_');
1392
629310ab 1393 reg = (struct reg_entry *) str_hash_find_n (arm_reg_hsh, start, p - start);
c19d1205
ZW
1394
1395 if (!reg)
1396 return NULL;
1397
1398 *ccp = p;
1399 return reg;
b99bd4ef
NC
1400}
1401
1402static int
dcbf9037 1403arm_reg_alt_syntax (char **ccp, char *start, struct reg_entry *reg,
477330fc 1404 enum arm_reg_type type)
b99bd4ef 1405{
c19d1205
ZW
1406 /* Alternative syntaxes are accepted for a few register classes. */
1407 switch (type)
1408 {
1409 case REG_TYPE_MVF:
1410 case REG_TYPE_MVD:
1411 case REG_TYPE_MVFX:
1412 case REG_TYPE_MVDX:
1413 /* Generic coprocessor register names are allowed for these. */
79134647 1414 if (reg && reg->type == REG_TYPE_CN)
c19d1205
ZW
1415 return reg->number;
1416 break;
69b97547 1417
c19d1205
ZW
1418 case REG_TYPE_CP:
1419 /* For backward compatibility, a bare number is valid here. */
1420 {
1421 unsigned long processor = strtoul (start, ccp, 10);
1422 if (*ccp != start && processor <= 15)
1423 return processor;
1424 }
1a0670f3 1425 /* Fall through. */
6057a28f 1426
c19d1205
ZW
1427 case REG_TYPE_MMXWC:
1428 /* WC includes WCG. ??? I'm not sure this is true for all
1429 instructions that take WC registers. */
79134647 1430 if (reg && reg->type == REG_TYPE_MMXWCG)
c19d1205 1431 return reg->number;
6057a28f 1432 break;
c19d1205 1433
6057a28f 1434 default:
c19d1205 1435 break;
6057a28f
NC
1436 }
1437
dcbf9037
JB
1438 return FAIL;
1439}
1440
1441/* As arm_reg_parse_multi, but the register must be of type TYPE, and the
1442 return value is the register number or FAIL. */
1443
1444static int
1445arm_reg_parse (char **ccp, enum arm_reg_type type)
1446{
1447 char *start = *ccp;
1448 struct reg_entry *reg = arm_reg_parse_multi (ccp);
1449 int ret;
1450
1451 /* Do not allow a scalar (reg+index) to parse as a register. */
1452 if (reg && reg->neon && (reg->neon->defined & NTA_HASINDEX))
1453 return FAIL;
1454
1455 if (reg && reg->type == type)
1456 return reg->number;
1457
1458 if ((ret = arm_reg_alt_syntax (ccp, start, reg, type)) != FAIL)
1459 return ret;
1460
c19d1205
ZW
1461 *ccp = start;
1462 return FAIL;
1463}
69b97547 1464
dcbf9037
JB
1465/* Parse a Neon type specifier. *STR should point at the leading '.'
1466 character. Does no verification at this stage that the type fits the opcode
1467 properly. E.g.,
1468
1469 .i32.i32.s16
1470 .s32.f32
1471 .u16
1472
1473 Can all be legally parsed by this function.
1474
1475 Fills in neon_type struct pointer with parsed information, and updates STR
1476 to point after the parsed type specifier. Returns SUCCESS if this was a legal
1477 type, FAIL if not. */
1478
1479static int
1480parse_neon_type (struct neon_type *type, char **str)
1481{
1482 char *ptr = *str;
1483
1484 if (type)
1485 type->elems = 0;
1486
1487 while (type->elems < NEON_MAX_TYPE_ELS)
1488 {
1489 enum neon_el_type thistype = NT_untyped;
1490 unsigned thissize = -1u;
1491
1492 if (*ptr != '.')
1493 break;
1494
1495 ptr++;
1496
1497 /* Just a size without an explicit type. */
1498 if (ISDIGIT (*ptr))
1499 goto parsesize;
1500
1501 switch (TOLOWER (*ptr))
1502 {
1503 case 'i': thistype = NT_integer; break;
1504 case 'f': thistype = NT_float; break;
1505 case 'p': thistype = NT_poly; break;
1506 case 's': thistype = NT_signed; break;
1507 case 'u': thistype = NT_unsigned; break;
477330fc
RM
1508 case 'd':
1509 thistype = NT_float;
1510 thissize = 64;
1511 ptr++;
1512 goto done;
aab2c27d
MM
1513 case 'b':
1514 thistype = NT_bfloat;
1515 switch (TOLOWER (*(++ptr)))
1516 {
1517 case 'f':
1518 ptr += 1;
1519 thissize = strtoul (ptr, &ptr, 10);
1520 if (thissize != 16)
1521 {
1522 as_bad (_("bad size %d in type specifier"), thissize);
1523 return FAIL;
1524 }
1525 goto done;
1526 case '0': case '1': case '2': case '3': case '4':
1527 case '5': case '6': case '7': case '8': case '9':
1528 case ' ': case '.':
1529 as_bad (_("unexpected type character `b' -- did you mean `bf'?"));
1530 return FAIL;
1531 default:
1532 break;
1533 }
1534 break;
dcbf9037
JB
1535 default:
1536 as_bad (_("unexpected character `%c' in type specifier"), *ptr);
1537 return FAIL;
1538 }
1539
1540 ptr++;
1541
1542 /* .f is an abbreviation for .f32. */
1543 if (thistype == NT_float && !ISDIGIT (*ptr))
1544 thissize = 32;
1545 else
1546 {
1547 parsesize:
1548 thissize = strtoul (ptr, &ptr, 10);
1549
1550 if (thissize != 8 && thissize != 16 && thissize != 32
477330fc
RM
1551 && thissize != 64)
1552 {
1553 as_bad (_("bad size %d in type specifier"), thissize);
dcbf9037
JB
1554 return FAIL;
1555 }
1556 }
1557
037e8744 1558 done:
dcbf9037 1559 if (type)
477330fc
RM
1560 {
1561 type->el[type->elems].type = thistype;
dcbf9037
JB
1562 type->el[type->elems].size = thissize;
1563 type->elems++;
1564 }
1565 }
1566
1567 /* Empty/missing type is not a successful parse. */
1568 if (type->elems == 0)
1569 return FAIL;
1570
1571 *str = ptr;
1572
1573 return SUCCESS;
1574}
1575
1576/* Errors may be set multiple times during parsing or bit encoding
1577 (particularly in the Neon bits), but usually the earliest error which is set
1578 will be the most meaningful. Avoid overwriting it with later (cascading)
1579 errors by calling this function. */
1580
1581static void
1582first_error (const char *err)
1583{
1584 if (!inst.error)
1585 inst.error = err;
1586}
1587
1588/* Parse a single type, e.g. ".s32", leading period included. */
1589static int
1590parse_neon_operand_type (struct neon_type_el *vectype, char **ccp)
1591{
1592 char *str = *ccp;
1593 struct neon_type optype;
1594
1595 if (*str == '.')
1596 {
1597 if (parse_neon_type (&optype, &str) == SUCCESS)
477330fc
RM
1598 {
1599 if (optype.elems == 1)
1600 *vectype = optype.el[0];
1601 else
1602 {
1603 first_error (_("only one type should be specified for operand"));
1604 return FAIL;
1605 }
1606 }
dcbf9037 1607 else
477330fc
RM
1608 {
1609 first_error (_("vector type expected"));
1610 return FAIL;
1611 }
dcbf9037
JB
1612 }
1613 else
1614 return FAIL;
5f4273c7 1615
dcbf9037 1616 *ccp = str;
5f4273c7 1617
dcbf9037
JB
1618 return SUCCESS;
1619}
1620
1621/* Special meanings for indices (which have a range of 0-7), which will fit into
1622 a 4-bit integer. */
1623
1624#define NEON_ALL_LANES 15
1625#define NEON_INTERLEAVE_LANES 14
1626
5ee91343
AV
1627/* Record a use of the given feature. */
1628static void
1629record_feature_use (const arm_feature_set *feature)
1630{
1631 if (thumb_mode)
1632 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, *feature);
1633 else
1634 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, *feature);
1635}
1636
1637/* If the given feature available in the selected CPU, mark it as used.
1638 Returns TRUE iff feature is available. */
5b7c81bd 1639static bool
5ee91343
AV
1640mark_feature_used (const arm_feature_set *feature)
1641{
886e1c73
AV
1642
1643 /* Do not support the use of MVE only instructions when in auto-detection or
1644 -march=all. */
1645 if (((feature == &mve_ext) || (feature == &mve_fp_ext))
1646 && ARM_CPU_IS_ANY (cpu_variant))
1647 {
1648 first_error (BAD_MVE_AUTO);
5b7c81bd 1649 return false;
886e1c73 1650 }
5ee91343
AV
1651 /* Ensure the option is valid on the current architecture. */
1652 if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
5b7c81bd 1653 return false;
5ee91343
AV
1654
1655 /* Add the appropriate architecture feature for the barrier option used.
1656 */
1657 record_feature_use (feature);
1658
5b7c81bd 1659 return true;
5ee91343
AV
1660}
1661
dcbf9037
JB
1662/* Parse either a register or a scalar, with an optional type. Return the
1663 register number, and optionally fill in the actual type of the register
1664 when multiple alternatives were given (NEON_TYPE_NDQ) in *RTYPE, and
1665 type/index information in *TYPEINFO. */
1666
1667static int
1668parse_typed_reg_or_scalar (char **ccp, enum arm_reg_type type,
477330fc
RM
1669 enum arm_reg_type *rtype,
1670 struct neon_typed_alias *typeinfo)
dcbf9037
JB
1671{
1672 char *str = *ccp;
1673 struct reg_entry *reg = arm_reg_parse_multi (&str);
1674 struct neon_typed_alias atype;
1675 struct neon_type_el parsetype;
1676
1677 atype.defined = 0;
1678 atype.index = -1;
1679 atype.eltype.type = NT_invtype;
1680 atype.eltype.size = -1;
1681
1682 /* Try alternate syntax for some types of register. Note these are mutually
1683 exclusive with the Neon syntax extensions. */
1684 if (reg == NULL)
1685 {
1686 int altreg = arm_reg_alt_syntax (&str, *ccp, reg, type);
1687 if (altreg != FAIL)
477330fc 1688 *ccp = str;
dcbf9037 1689 if (typeinfo)
477330fc 1690 *typeinfo = atype;
dcbf9037
JB
1691 return altreg;
1692 }
1693
037e8744
JB
1694 /* Undo polymorphism when a set of register types may be accepted. */
1695 if ((type == REG_TYPE_NDQ
1696 && (reg->type == REG_TYPE_NQ || reg->type == REG_TYPE_VFD))
1697 || (type == REG_TYPE_VFSD
477330fc 1698 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
037e8744 1699 || (type == REG_TYPE_NSDQ
477330fc
RM
1700 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD
1701 || reg->type == REG_TYPE_NQ))
dec41383
JW
1702 || (type == REG_TYPE_NSD
1703 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
f512f76f
NC
1704 || (type == REG_TYPE_MMXWC
1705 && (reg->type == REG_TYPE_MMXWCG)))
21d799b5 1706 type = (enum arm_reg_type) reg->type;
dcbf9037 1707
5ee91343
AV
1708 if (type == REG_TYPE_MQ)
1709 {
1710 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
1711 return FAIL;
1712
1713 if (!reg || reg->type != REG_TYPE_NQ)
1714 return FAIL;
1715
1716 if (reg->number > 14 && !mark_feature_used (&fpu_vfp_ext_d32))
1717 {
1718 first_error (_("expected MVE register [q0..q7]"));
1719 return FAIL;
1720 }
1721 type = REG_TYPE_NQ;
1722 }
1723 else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
1724 && (type == REG_TYPE_NQ))
1725 return FAIL;
1726
1727
dcbf9037
JB
1728 if (type != reg->type)
1729 return FAIL;
1730
1731 if (reg->neon)
1732 atype = *reg->neon;
5f4273c7 1733
dcbf9037
JB
1734 if (parse_neon_operand_type (&parsetype, &str) == SUCCESS)
1735 {
1736 if ((atype.defined & NTA_HASTYPE) != 0)
477330fc
RM
1737 {
1738 first_error (_("can't redefine type for operand"));
1739 return FAIL;
1740 }
dcbf9037
JB
1741 atype.defined |= NTA_HASTYPE;
1742 atype.eltype = parsetype;
1743 }
5f4273c7 1744
dcbf9037
JB
1745 if (skip_past_char (&str, '[') == SUCCESS)
1746 {
dec41383
JW
1747 if (type != REG_TYPE_VFD
1748 && !(type == REG_TYPE_VFS
57785aa2
AV
1749 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_2))
1750 && !(type == REG_TYPE_NQ
1751 && ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)))
477330fc 1752 {
57785aa2
AV
1753 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
1754 first_error (_("only D and Q registers may be indexed"));
1755 else
1756 first_error (_("only D registers may be indexed"));
477330fc
RM
1757 return FAIL;
1758 }
5f4273c7 1759
dcbf9037 1760 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
1761 {
1762 first_error (_("can't change index for operand"));
1763 return FAIL;
1764 }
dcbf9037
JB
1765
1766 atype.defined |= NTA_HASINDEX;
1767
1768 if (skip_past_char (&str, ']') == SUCCESS)
477330fc 1769 atype.index = NEON_ALL_LANES;
dcbf9037 1770 else
477330fc
RM
1771 {
1772 expressionS exp;
dcbf9037 1773
477330fc 1774 my_get_expression (&exp, &str, GE_NO_PREFIX);
dcbf9037 1775
477330fc
RM
1776 if (exp.X_op != O_constant)
1777 {
1778 first_error (_("constant expression required"));
1779 return FAIL;
1780 }
dcbf9037 1781
477330fc
RM
1782 if (skip_past_char (&str, ']') == FAIL)
1783 return FAIL;
dcbf9037 1784
477330fc
RM
1785 atype.index = exp.X_add_number;
1786 }
dcbf9037 1787 }
5f4273c7 1788
dcbf9037
JB
1789 if (typeinfo)
1790 *typeinfo = atype;
5f4273c7 1791
dcbf9037
JB
1792 if (rtype)
1793 *rtype = type;
5f4273c7 1794
dcbf9037 1795 *ccp = str;
5f4273c7 1796
dcbf9037
JB
1797 return reg->number;
1798}
1799
efd6b359 1800/* Like arm_reg_parse, but also allow the following extra features:
dcbf9037
JB
1801 - If RTYPE is non-zero, return the (possibly restricted) type of the
1802 register (e.g. Neon double or quad reg when either has been requested).
1803 - If this is a Neon vector type with additional type information, fill
1804 in the struct pointed to by VECTYPE (if non-NULL).
5f4273c7 1805 This function will fault on encountering a scalar. */
dcbf9037
JB
1806
1807static int
1808arm_typed_reg_parse (char **ccp, enum arm_reg_type type,
477330fc 1809 enum arm_reg_type *rtype, struct neon_type_el *vectype)
dcbf9037
JB
1810{
1811 struct neon_typed_alias atype;
1812 char *str = *ccp;
1813 int reg = parse_typed_reg_or_scalar (&str, type, rtype, &atype);
1814
1815 if (reg == FAIL)
1816 return FAIL;
1817
0855e32b
NS
1818 /* Do not allow regname(... to parse as a register. */
1819 if (*str == '(')
1820 return FAIL;
1821
dcbf9037
JB
1822 /* Do not allow a scalar (reg+index) to parse as a register. */
1823 if ((atype.defined & NTA_HASINDEX) != 0)
1824 {
1825 first_error (_("register operand expected, but got scalar"));
1826 return FAIL;
1827 }
1828
1829 if (vectype)
1830 *vectype = atype.eltype;
1831
1832 *ccp = str;
1833
1834 return reg;
1835}
1836
1837#define NEON_SCALAR_REG(X) ((X) >> 4)
1838#define NEON_SCALAR_INDEX(X) ((X) & 15)
1839
5287ad62
JB
1840/* Parse a Neon scalar. Most of the time when we're parsing a scalar, we don't
1841 have enough information to be able to do a good job bounds-checking. So, we
1842 just do easy checks here, and do further checks later. */
1843
1844static int
57785aa2
AV
1845parse_scalar (char **ccp, int elsize, struct neon_type_el *type, enum
1846 arm_reg_type reg_type)
5287ad62 1847{
dcbf9037 1848 int reg;
5287ad62 1849 char *str = *ccp;
dcbf9037 1850 struct neon_typed_alias atype;
57785aa2 1851 unsigned reg_size;
5f4273c7 1852
dec41383 1853 reg = parse_typed_reg_or_scalar (&str, reg_type, NULL, &atype);
5f4273c7 1854
57785aa2
AV
1855 switch (reg_type)
1856 {
1857 case REG_TYPE_VFS:
1858 reg_size = 32;
1859 break;
1860 case REG_TYPE_VFD:
1861 reg_size = 64;
1862 break;
1863 case REG_TYPE_MQ:
1864 reg_size = 128;
1865 break;
1866 default:
1867 gas_assert (0);
1868 return FAIL;
1869 }
1870
dcbf9037 1871 if (reg == FAIL || (atype.defined & NTA_HASINDEX) == 0)
5287ad62 1872 return FAIL;
5f4273c7 1873
57785aa2 1874 if (reg_type != REG_TYPE_MQ && atype.index == NEON_ALL_LANES)
5287ad62 1875 {
dcbf9037 1876 first_error (_("scalar must have an index"));
5287ad62
JB
1877 return FAIL;
1878 }
57785aa2 1879 else if (atype.index >= reg_size / elsize)
5287ad62 1880 {
dcbf9037 1881 first_error (_("scalar index out of range"));
5287ad62
JB
1882 return FAIL;
1883 }
5f4273c7 1884
dcbf9037
JB
1885 if (type)
1886 *type = atype.eltype;
5f4273c7 1887
5287ad62 1888 *ccp = str;
5f4273c7 1889
dcbf9037 1890 return reg * 16 + atype.index;
5287ad62
JB
1891}
1892
4b5a202f
AV
1893/* Types of registers in a list. */
1894
1895enum reg_list_els
1896{
1897 REGLIST_RN,
8c299995 1898 REGLIST_PSEUDO,
4b5a202f
AV
1899 REGLIST_CLRM,
1900 REGLIST_VFP_S,
efd6b359 1901 REGLIST_VFP_S_VPR,
4b5a202f 1902 REGLIST_VFP_D,
efd6b359 1903 REGLIST_VFP_D_VPR,
4b5a202f
AV
1904 REGLIST_NEON_D
1905};
1906
c19d1205 1907/* Parse an ARM register list. Returns the bitmask, or FAIL. */
e07e6e58 1908
c19d1205 1909static long
4b5a202f 1910parse_reg_list (char ** strp, enum reg_list_els etype)
c19d1205 1911{
4b5a202f
AV
1912 char *str = *strp;
1913 long range = 0;
1914 int another_range;
1915
8c299995
TB
1916 gas_assert (etype == REGLIST_RN || etype == REGLIST_CLRM
1917 || etype == REGLIST_PSEUDO);
a737bd4d 1918
c19d1205
ZW
1919 /* We come back here if we get ranges concatenated by '+' or '|'. */
1920 do
6057a28f 1921 {
477330fc
RM
1922 skip_whitespace (str);
1923
c19d1205 1924 another_range = 0;
a737bd4d 1925
c19d1205
ZW
1926 if (*str == '{')
1927 {
1928 int in_range = 0;
1929 int cur_reg = -1;
a737bd4d 1930
c19d1205
ZW
1931 str++;
1932 do
1933 {
1934 int reg;
4b5a202f
AV
1935 const char apsr_str[] = "apsr";
1936 int apsr_str_len = strlen (apsr_str);
8c299995 1937 enum arm_reg_type rt;
6057a28f 1938
8c299995
TB
1939 if (etype == REGLIST_RN || etype == REGLIST_CLRM)
1940 rt = REG_TYPE_RN;
1941 else
1942 rt = REG_TYPE_PSEUDO;
1943
1944 reg = arm_reg_parse (&str, rt);
3363d856
VDN
1945
1946 /* Skip over allowed registers of alternative types in mixed-type
1947 register lists. */
1948 if (reg == FAIL && rt == REG_TYPE_PSEUDO
1949 && ((reg = arm_reg_parse (&str, REG_TYPE_RN)) != FAIL))
1950 {
1951 cur_reg = reg;
1952 continue;
1953 }
1954 else if (reg == FAIL && rt == REG_TYPE_RN
1955 && ((reg = arm_reg_parse (&str, REG_TYPE_PSEUDO)) != FAIL))
1956 {
1957 cur_reg = reg;
1958 continue;
1959 }
1960
4b5a202f 1961 if (etype == REGLIST_CLRM)
c19d1205 1962 {
4b5a202f
AV
1963 if (reg == REG_SP || reg == REG_PC)
1964 reg = FAIL;
1965 else if (reg == FAIL
1966 && !strncasecmp (str, apsr_str, apsr_str_len)
1967 && !ISALPHA (*(str + apsr_str_len)))
1968 {
1969 reg = 15;
1970 str += apsr_str_len;
1971 }
1972
1973 if (reg == FAIL)
1974 {
1975 first_error (_("r0-r12, lr or APSR expected"));
1976 return FAIL;
1977 }
1978 }
8c299995
TB
1979 else if (etype == REGLIST_PSEUDO)
1980 {
1981 if (reg == FAIL)
1982 {
1983 first_error (_(reg_expected_msgs[REG_TYPE_PSEUDO]));
1984 return FAIL;
1985 }
1986 }
4b5a202f
AV
1987 else /* etype == REGLIST_RN. */
1988 {
1989 if (reg == FAIL)
1990 {
1991 first_error (_(reg_expected_msgs[REGLIST_RN]));
1992 return FAIL;
1993 }
c19d1205 1994 }
a737bd4d 1995
c19d1205
ZW
1996 if (in_range)
1997 {
1998 int i;
a737bd4d 1999
c19d1205
ZW
2000 if (reg <= cur_reg)
2001 {
dcbf9037 2002 first_error (_("bad range in register list"));
c19d1205
ZW
2003 return FAIL;
2004 }
40a18ebd 2005
c19d1205
ZW
2006 for (i = cur_reg + 1; i < reg; i++)
2007 {
2008 if (range & (1 << i))
2009 as_tsktsk
2010 (_("Warning: duplicated register (r%d) in register list"),
2011 i);
2012 else
2013 range |= 1 << i;
2014 }
2015 in_range = 0;
2016 }
a737bd4d 2017
c19d1205
ZW
2018 if (range & (1 << reg))
2019 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
2020 reg);
2021 else if (reg <= cur_reg)
2022 as_tsktsk (_("Warning: register range not in ascending order"));
a737bd4d 2023
c19d1205
ZW
2024 range |= 1 << reg;
2025 cur_reg = reg;
2026 }
2027 while (skip_past_comma (&str) != FAIL
2028 || (in_range = 1, *str++ == '-'));
2029 str--;
a737bd4d 2030
d996d970 2031 if (skip_past_char (&str, '}') == FAIL)
c19d1205 2032 {
dcbf9037 2033 first_error (_("missing `}'"));
c19d1205
ZW
2034 return FAIL;
2035 }
2036 }
4b5a202f 2037 else if (etype == REGLIST_RN)
c19d1205 2038 {
91d6fa6a 2039 expressionS exp;
40a18ebd 2040
91d6fa6a 2041 if (my_get_expression (&exp, &str, GE_NO_PREFIX))
c19d1205 2042 return FAIL;
40a18ebd 2043
91d6fa6a 2044 if (exp.X_op == O_constant)
c19d1205 2045 {
91d6fa6a
NC
2046 if (exp.X_add_number
2047 != (exp.X_add_number & 0x0000ffff))
c19d1205
ZW
2048 {
2049 inst.error = _("invalid register mask");
2050 return FAIL;
2051 }
a737bd4d 2052
91d6fa6a 2053 if ((range & exp.X_add_number) != 0)
c19d1205 2054 {
91d6fa6a 2055 int regno = range & exp.X_add_number;
a737bd4d 2056
c19d1205
ZW
2057 regno &= -regno;
2058 regno = (1 << regno) - 1;
2059 as_tsktsk
2060 (_("Warning: duplicated register (r%d) in register list"),
2061 regno);
2062 }
a737bd4d 2063
91d6fa6a 2064 range |= exp.X_add_number;
c19d1205
ZW
2065 }
2066 else
2067 {
e2b0ab59 2068 if (inst.relocs[0].type != 0)
c19d1205
ZW
2069 {
2070 inst.error = _("expression too complex");
2071 return FAIL;
2072 }
a737bd4d 2073
e2b0ab59
AV
2074 memcpy (&inst.relocs[0].exp, &exp, sizeof (expressionS));
2075 inst.relocs[0].type = BFD_RELOC_ARM_MULTI;
2076 inst.relocs[0].pc_rel = 0;
c19d1205
ZW
2077 }
2078 }
a737bd4d 2079
c19d1205
ZW
2080 if (*str == '|' || *str == '+')
2081 {
2082 str++;
2083 another_range = 1;
2084 }
a737bd4d 2085 }
c19d1205 2086 while (another_range);
a737bd4d 2087
c19d1205
ZW
2088 *strp = str;
2089 return range;
a737bd4d
NC
2090}
2091
c19d1205
ZW
2092/* Parse a VFP register list. If the string is invalid return FAIL.
2093 Otherwise return the number of registers, and set PBASE to the first
5287ad62
JB
2094 register. Parses registers of type ETYPE.
2095 If REGLIST_NEON_D is used, several syntax enhancements are enabled:
2096 - Q registers can be used to specify pairs of D registers
2097 - { } can be omitted from around a singleton register list
477330fc
RM
2098 FIXME: This is not implemented, as it would require backtracking in
2099 some cases, e.g.:
2100 vtbl.8 d3,d4,d5
2101 This could be done (the meaning isn't really ambiguous), but doesn't
2102 fit in well with the current parsing framework.
dcbf9037
JB
2103 - 32 D registers may be used (also true for VFPv3).
2104 FIXME: Types are ignored in these register lists, which is probably a
2105 bug. */
6057a28f 2106
c19d1205 2107static int
efd6b359 2108parse_vfp_reg_list (char **ccp, unsigned int *pbase, enum reg_list_els etype,
5b7c81bd 2109 bool *partial_match)
6057a28f 2110{
037e8744 2111 char *str = *ccp;
c19d1205
ZW
2112 int base_reg;
2113 int new_base;
21d799b5 2114 enum arm_reg_type regtype = (enum arm_reg_type) 0;
5287ad62 2115 int max_regs = 0;
c19d1205
ZW
2116 int count = 0;
2117 int warned = 0;
2118 unsigned long mask = 0;
a737bd4d 2119 int i;
5b7c81bd
AM
2120 bool vpr_seen = false;
2121 bool expect_vpr =
efd6b359 2122 (etype == REGLIST_VFP_S_VPR) || (etype == REGLIST_VFP_D_VPR);
6057a28f 2123
477330fc 2124 if (skip_past_char (&str, '{') == FAIL)
5287ad62
JB
2125 {
2126 inst.error = _("expecting {");
2127 return FAIL;
2128 }
6057a28f 2129
5287ad62 2130 switch (etype)
c19d1205 2131 {
5287ad62 2132 case REGLIST_VFP_S:
efd6b359 2133 case REGLIST_VFP_S_VPR:
c19d1205
ZW
2134 regtype = REG_TYPE_VFS;
2135 max_regs = 32;
5287ad62 2136 break;
5f4273c7 2137
5287ad62 2138 case REGLIST_VFP_D:
efd6b359 2139 case REGLIST_VFP_D_VPR:
5287ad62 2140 regtype = REG_TYPE_VFD;
b7fc2769 2141 break;
5f4273c7 2142
b7fc2769
JB
2143 case REGLIST_NEON_D:
2144 regtype = REG_TYPE_NDQ;
2145 break;
4b5a202f
AV
2146
2147 default:
2148 gas_assert (0);
b7fc2769
JB
2149 }
2150
efd6b359 2151 if (etype != REGLIST_VFP_S && etype != REGLIST_VFP_S_VPR)
b7fc2769 2152 {
b1cc4aeb
PB
2153 /* VFPv3 allows 32 D registers, except for the VFPv3-D16 variant. */
2154 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
2155 {
2156 max_regs = 32;
2157 if (thumb_mode)
2158 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
2159 fpu_vfp_ext_d32);
2160 else
2161 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
2162 fpu_vfp_ext_d32);
2163 }
5287ad62 2164 else
477330fc 2165 max_regs = 16;
c19d1205 2166 }
6057a28f 2167
c19d1205 2168 base_reg = max_regs;
5b7c81bd 2169 *partial_match = false;
a737bd4d 2170
c19d1205
ZW
2171 do
2172 {
7af67752 2173 unsigned int setmask = 1, addregs = 1;
efd6b359 2174 const char vpr_str[] = "vpr";
7af67752 2175 size_t vpr_str_len = strlen (vpr_str);
dcbf9037 2176
037e8744 2177 new_base = arm_typed_reg_parse (&str, regtype, &regtype, NULL);
dcbf9037 2178
efd6b359
AV
2179 if (expect_vpr)
2180 {
2181 if (new_base == FAIL
2182 && !strncasecmp (str, vpr_str, vpr_str_len)
2183 && !ISALPHA (*(str + vpr_str_len))
2184 && !vpr_seen)
2185 {
5b7c81bd 2186 vpr_seen = true;
efd6b359
AV
2187 str += vpr_str_len;
2188 if (count == 0)
2189 base_reg = 0; /* Canonicalize VPR only on d0 with 0 regs. */
2190 }
2191 else if (vpr_seen)
2192 {
2193 first_error (_("VPR expected last"));
2194 return FAIL;
2195 }
2196 else if (new_base == FAIL)
2197 {
2198 if (regtype == REG_TYPE_VFS)
2199 first_error (_("VFP single precision register or VPR "
2200 "expected"));
2201 else /* regtype == REG_TYPE_VFD. */
2202 first_error (_("VFP/Neon double precision register or VPR "
2203 "expected"));
2204 return FAIL;
2205 }
2206 }
2207 else if (new_base == FAIL)
a737bd4d 2208 {
dcbf9037 2209 first_error (_(reg_expected_msgs[regtype]));
c19d1205
ZW
2210 return FAIL;
2211 }
5f4273c7 2212
5b7c81bd 2213 *partial_match = true;
efd6b359
AV
2214 if (vpr_seen)
2215 continue;
2216
b7fc2769 2217 if (new_base >= max_regs)
477330fc
RM
2218 {
2219 first_error (_("register out of range in list"));
2220 return FAIL;
2221 }
5f4273c7 2222
5287ad62
JB
2223 /* Note: a value of 2 * n is returned for the register Q<n>. */
2224 if (regtype == REG_TYPE_NQ)
477330fc
RM
2225 {
2226 setmask = 3;
2227 addregs = 2;
2228 }
5287ad62 2229
c19d1205
ZW
2230 if (new_base < base_reg)
2231 base_reg = new_base;
a737bd4d 2232
5287ad62 2233 if (mask & (setmask << new_base))
c19d1205 2234 {
dcbf9037 2235 first_error (_("invalid register list"));
c19d1205 2236 return FAIL;
a737bd4d 2237 }
a737bd4d 2238
efd6b359 2239 if ((mask >> new_base) != 0 && ! warned && !vpr_seen)
c19d1205
ZW
2240 {
2241 as_tsktsk (_("register list not in ascending order"));
2242 warned = 1;
2243 }
0bbf2aa4 2244
5287ad62
JB
2245 mask |= setmask << new_base;
2246 count += addregs;
0bbf2aa4 2247
037e8744 2248 if (*str == '-') /* We have the start of a range expression */
c19d1205
ZW
2249 {
2250 int high_range;
0bbf2aa4 2251
037e8744 2252 str++;
0bbf2aa4 2253
037e8744 2254 if ((high_range = arm_typed_reg_parse (&str, regtype, NULL, NULL))
477330fc 2255 == FAIL)
c19d1205
ZW
2256 {
2257 inst.error = gettext (reg_expected_msgs[regtype]);
2258 return FAIL;
2259 }
0bbf2aa4 2260
477330fc
RM
2261 if (high_range >= max_regs)
2262 {
2263 first_error (_("register out of range in list"));
2264 return FAIL;
2265 }
b7fc2769 2266
477330fc
RM
2267 if (regtype == REG_TYPE_NQ)
2268 high_range = high_range + 1;
5287ad62 2269
c19d1205
ZW
2270 if (high_range <= new_base)
2271 {
2272 inst.error = _("register range not in ascending order");
2273 return FAIL;
2274 }
0bbf2aa4 2275
5287ad62 2276 for (new_base += addregs; new_base <= high_range; new_base += addregs)
0bbf2aa4 2277 {
5287ad62 2278 if (mask & (setmask << new_base))
0bbf2aa4 2279 {
c19d1205
ZW
2280 inst.error = _("invalid register list");
2281 return FAIL;
0bbf2aa4 2282 }
c19d1205 2283
5287ad62
JB
2284 mask |= setmask << new_base;
2285 count += addregs;
0bbf2aa4 2286 }
0bbf2aa4 2287 }
0bbf2aa4 2288 }
037e8744 2289 while (skip_past_comma (&str) != FAIL);
0bbf2aa4 2290
037e8744 2291 str++;
0bbf2aa4 2292
c19d1205 2293 /* Sanity check -- should have raised a parse error above. */
efd6b359 2294 if ((!vpr_seen && count == 0) || count > max_regs)
c19d1205
ZW
2295 abort ();
2296
2297 *pbase = base_reg;
2298
efd6b359
AV
2299 if (expect_vpr && !vpr_seen)
2300 {
2301 first_error (_("VPR expected last"));
2302 return FAIL;
2303 }
2304
c19d1205
ZW
2305 /* Final test -- the registers must be consecutive. */
2306 mask >>= base_reg;
2307 for (i = 0; i < count; i++)
2308 {
2309 if ((mask & (1u << i)) == 0)
2310 {
2311 inst.error = _("non-contiguous register range");
2312 return FAIL;
2313 }
2314 }
2315
037e8744
JB
2316 *ccp = str;
2317
c19d1205 2318 return count;
b99bd4ef
NC
2319}
2320
dcbf9037
JB
2321/* True if two alias types are the same. */
2322
5b7c81bd 2323static bool
dcbf9037
JB
2324neon_alias_types_same (struct neon_typed_alias *a, struct neon_typed_alias *b)
2325{
2326 if (!a && !b)
5b7c81bd 2327 return true;
5f4273c7 2328
dcbf9037 2329 if (!a || !b)
5b7c81bd 2330 return false;
dcbf9037
JB
2331
2332 if (a->defined != b->defined)
5b7c81bd 2333 return false;
5f4273c7 2334
dcbf9037
JB
2335 if ((a->defined & NTA_HASTYPE) != 0
2336 && (a->eltype.type != b->eltype.type
477330fc 2337 || a->eltype.size != b->eltype.size))
5b7c81bd 2338 return false;
dcbf9037
JB
2339
2340 if ((a->defined & NTA_HASINDEX) != 0
2341 && (a->index != b->index))
5b7c81bd 2342 return false;
5f4273c7 2343
5b7c81bd 2344 return true;
dcbf9037
JB
2345}
2346
5287ad62
JB
2347/* Parse element/structure lists for Neon VLD<n> and VST<n> instructions.
2348 The base register is put in *PBASE.
dcbf9037 2349 The lane (or one of the NEON_*_LANES constants) is placed in bits [3:0] of
5287ad62
JB
2350 the return value.
2351 The register stride (minus one) is put in bit 4 of the return value.
dcbf9037
JB
2352 Bits [6:5] encode the list length (minus one).
2353 The type of the list elements is put in *ELTYPE, if non-NULL. */
5287ad62 2354
5287ad62 2355#define NEON_LANE(X) ((X) & 0xf)
dcbf9037 2356#define NEON_REG_STRIDE(X) ((((X) >> 4) & 1) + 1)
5287ad62
JB
2357#define NEON_REGLIST_LENGTH(X) ((((X) >> 5) & 3) + 1)
2358
2359static int
dcbf9037 2360parse_neon_el_struct_list (char **str, unsigned *pbase,
35c228db 2361 int mve,
477330fc 2362 struct neon_type_el *eltype)
5287ad62
JB
2363{
2364 char *ptr = *str;
2365 int base_reg = -1;
2366 int reg_incr = -1;
2367 int count = 0;
2368 int lane = -1;
2369 int leading_brace = 0;
2370 enum arm_reg_type rtype = REG_TYPE_NDQ;
35c228db
AV
2371 const char *const incr_error = mve ? _("register stride must be 1") :
2372 _("register stride must be 1 or 2");
20203fb9 2373 const char *const type_error = _("mismatched element/structure types in list");
dcbf9037 2374 struct neon_typed_alias firsttype;
f85d59c3
KT
2375 firsttype.defined = 0;
2376 firsttype.eltype.type = NT_invtype;
2377 firsttype.eltype.size = -1;
2378 firsttype.index = -1;
5f4273c7 2379
5287ad62
JB
2380 if (skip_past_char (&ptr, '{') == SUCCESS)
2381 leading_brace = 1;
5f4273c7 2382
5287ad62
JB
2383 do
2384 {
dcbf9037 2385 struct neon_typed_alias atype;
35c228db
AV
2386 if (mve)
2387 rtype = REG_TYPE_MQ;
dcbf9037
JB
2388 int getreg = parse_typed_reg_or_scalar (&ptr, rtype, &rtype, &atype);
2389
5287ad62 2390 if (getreg == FAIL)
477330fc
RM
2391 {
2392 first_error (_(reg_expected_msgs[rtype]));
2393 return FAIL;
2394 }
5f4273c7 2395
5287ad62 2396 if (base_reg == -1)
477330fc
RM
2397 {
2398 base_reg = getreg;
2399 if (rtype == REG_TYPE_NQ)
2400 {
2401 reg_incr = 1;
2402 }
2403 firsttype = atype;
2404 }
5287ad62 2405 else if (reg_incr == -1)
477330fc
RM
2406 {
2407 reg_incr = getreg - base_reg;
2408 if (reg_incr < 1 || reg_incr > 2)
2409 {
2410 first_error (_(incr_error));
2411 return FAIL;
2412 }
2413 }
5287ad62 2414 else if (getreg != base_reg + reg_incr * count)
477330fc
RM
2415 {
2416 first_error (_(incr_error));
2417 return FAIL;
2418 }
dcbf9037 2419
c921be7d 2420 if (! neon_alias_types_same (&atype, &firsttype))
477330fc
RM
2421 {
2422 first_error (_(type_error));
2423 return FAIL;
2424 }
5f4273c7 2425
5287ad62 2426 /* Handle Dn-Dm or Qn-Qm syntax. Can only be used with non-indexed list
477330fc 2427 modes. */
5287ad62 2428 if (ptr[0] == '-')
477330fc
RM
2429 {
2430 struct neon_typed_alias htype;
2431 int hireg, dregs = (rtype == REG_TYPE_NQ) ? 2 : 1;
2432 if (lane == -1)
2433 lane = NEON_INTERLEAVE_LANES;
2434 else if (lane != NEON_INTERLEAVE_LANES)
2435 {
2436 first_error (_(type_error));
2437 return FAIL;
2438 }
2439 if (reg_incr == -1)
2440 reg_incr = 1;
2441 else if (reg_incr != 1)
2442 {
2443 first_error (_("don't use Rn-Rm syntax with non-unit stride"));
2444 return FAIL;
2445 }
2446 ptr++;
2447 hireg = parse_typed_reg_or_scalar (&ptr, rtype, NULL, &htype);
2448 if (hireg == FAIL)
2449 {
2450 first_error (_(reg_expected_msgs[rtype]));
2451 return FAIL;
2452 }
2453 if (! neon_alias_types_same (&htype, &firsttype))
2454 {
2455 first_error (_(type_error));
2456 return FAIL;
2457 }
2458 count += hireg + dregs - getreg;
2459 continue;
2460 }
5f4273c7 2461
5287ad62
JB
2462 /* If we're using Q registers, we can't use [] or [n] syntax. */
2463 if (rtype == REG_TYPE_NQ)
477330fc
RM
2464 {
2465 count += 2;
2466 continue;
2467 }
5f4273c7 2468
dcbf9037 2469 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
2470 {
2471 if (lane == -1)
2472 lane = atype.index;
2473 else if (lane != atype.index)
2474 {
2475 first_error (_(type_error));
2476 return FAIL;
2477 }
2478 }
5287ad62 2479 else if (lane == -1)
477330fc 2480 lane = NEON_INTERLEAVE_LANES;
5287ad62 2481 else if (lane != NEON_INTERLEAVE_LANES)
477330fc
RM
2482 {
2483 first_error (_(type_error));
2484 return FAIL;
2485 }
5287ad62
JB
2486 count++;
2487 }
2488 while ((count != 1 || leading_brace) && skip_past_comma (&ptr) != FAIL);
5f4273c7 2489
5287ad62
JB
2490 /* No lane set by [x]. We must be interleaving structures. */
2491 if (lane == -1)
2492 lane = NEON_INTERLEAVE_LANES;
5f4273c7 2493
5287ad62 2494 /* Sanity check. */
35c228db 2495 if (lane == -1 || base_reg == -1 || count < 1 || (!mve && count > 4)
5287ad62
JB
2496 || (count > 1 && reg_incr == -1))
2497 {
dcbf9037 2498 first_error (_("error parsing element/structure list"));
5287ad62
JB
2499 return FAIL;
2500 }
2501
2502 if ((count > 1 || leading_brace) && skip_past_char (&ptr, '}') == FAIL)
2503 {
dcbf9037 2504 first_error (_("expected }"));
5287ad62
JB
2505 return FAIL;
2506 }
5f4273c7 2507
5287ad62
JB
2508 if (reg_incr == -1)
2509 reg_incr = 1;
2510
dcbf9037
JB
2511 if (eltype)
2512 *eltype = firsttype.eltype;
2513
5287ad62
JB
2514 *pbase = base_reg;
2515 *str = ptr;
5f4273c7 2516
5287ad62
JB
2517 return lane | ((reg_incr - 1) << 4) | ((count - 1) << 5);
2518}
2519
c19d1205
ZW
2520/* Parse an explicit relocation suffix on an expression. This is
2521 either nothing, or a word in parentheses. Note that if !OBJ_ELF,
2522 arm_reloc_hsh contains no entries, so this function can only
2523 succeed if there is no () after the word. Returns -1 on error,
2524 BFD_RELOC_UNUSED if there wasn't any suffix. */
3da1d841 2525
c19d1205
ZW
2526static int
2527parse_reloc (char **str)
b99bd4ef 2528{
c19d1205
ZW
2529 struct reloc_entry *r;
2530 char *p, *q;
b99bd4ef 2531
c19d1205
ZW
2532 if (**str != '(')
2533 return BFD_RELOC_UNUSED;
b99bd4ef 2534
c19d1205
ZW
2535 p = *str + 1;
2536 q = p;
2537
2538 while (*q && *q != ')' && *q != ',')
2539 q++;
2540 if (*q != ')')
2541 return -1;
2542
21d799b5 2543 if ((r = (struct reloc_entry *)
629310ab 2544 str_hash_find_n (arm_reloc_hsh, p, q - p)) == NULL)
c19d1205
ZW
2545 return -1;
2546
2547 *str = q + 1;
2548 return r->reloc;
b99bd4ef
NC
2549}
2550
c19d1205
ZW
2551/* Directives: register aliases. */
2552
dcbf9037 2553static struct reg_entry *
90ec0d68 2554insert_reg_alias (char *str, unsigned number, int type)
b99bd4ef 2555{
d3ce72d0 2556 struct reg_entry *new_reg;
c19d1205 2557 const char *name;
b99bd4ef 2558
629310ab 2559 if ((new_reg = (struct reg_entry *) str_hash_find (arm_reg_hsh, str)) != 0)
c19d1205 2560 {
d3ce72d0 2561 if (new_reg->builtin)
c19d1205 2562 as_warn (_("ignoring attempt to redefine built-in register '%s'"), str);
b99bd4ef 2563
c19d1205
ZW
2564 /* Only warn about a redefinition if it's not defined as the
2565 same register. */
d3ce72d0 2566 else if (new_reg->number != number || new_reg->type != type)
c19d1205 2567 as_warn (_("ignoring redefinition of register alias '%s'"), str);
69b97547 2568
d929913e 2569 return NULL;
c19d1205 2570 }
b99bd4ef 2571
c19d1205 2572 name = xstrdup (str);
325801bd 2573 new_reg = XNEW (struct reg_entry);
b99bd4ef 2574
d3ce72d0
NC
2575 new_reg->name = name;
2576 new_reg->number = number;
2577 new_reg->type = type;
5b7c81bd 2578 new_reg->builtin = false;
d3ce72d0 2579 new_reg->neon = NULL;
b99bd4ef 2580
fe0e921f 2581 str_hash_insert (arm_reg_hsh, name, new_reg, 0);
5f4273c7 2582
d3ce72d0 2583 return new_reg;
dcbf9037
JB
2584}
2585
2586static void
2587insert_neon_reg_alias (char *str, int number, int type,
477330fc 2588 struct neon_typed_alias *atype)
dcbf9037
JB
2589{
2590 struct reg_entry *reg = insert_reg_alias (str, number, type);
5f4273c7 2591
dcbf9037
JB
2592 if (!reg)
2593 {
2594 first_error (_("attempt to redefine typed alias"));
2595 return;
2596 }
5f4273c7 2597
dcbf9037
JB
2598 if (atype)
2599 {
325801bd 2600 reg->neon = XNEW (struct neon_typed_alias);
dcbf9037
JB
2601 *reg->neon = *atype;
2602 }
c19d1205 2603}
b99bd4ef 2604
c19d1205 2605/* Look for the .req directive. This is of the form:
b99bd4ef 2606
c19d1205 2607 new_register_name .req existing_register_name
b99bd4ef 2608
c19d1205 2609 If we find one, or if it looks sufficiently like one that we want to
d929913e 2610 handle any error here, return TRUE. Otherwise return FALSE. */
b99bd4ef 2611
5b7c81bd 2612static bool
c19d1205
ZW
2613create_register_alias (char * newname, char *p)
2614{
2615 struct reg_entry *old;
2616 char *oldname, *nbuf;
2617 size_t nlen;
b99bd4ef 2618
c19d1205
ZW
2619 /* The input scrubber ensures that whitespace after the mnemonic is
2620 collapsed to single spaces. */
2621 oldname = p;
d34049e8 2622 if (!startswith (oldname, " .req "))
5b7c81bd 2623 return false;
b99bd4ef 2624
c19d1205
ZW
2625 oldname += 6;
2626 if (*oldname == '\0')
5b7c81bd 2627 return false;
b99bd4ef 2628
629310ab 2629 old = (struct reg_entry *) str_hash_find (arm_reg_hsh, oldname);
c19d1205 2630 if (!old)
b99bd4ef 2631 {
c19d1205 2632 as_warn (_("unknown register '%s' -- .req ignored"), oldname);
5b7c81bd 2633 return true;
b99bd4ef
NC
2634 }
2635
c19d1205
ZW
2636 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2637 the desired alias name, and p points to its end. If not, then
2638 the desired alias name is in the global original_case_string. */
2639#ifdef TC_CASE_SENSITIVE
2640 nlen = p - newname;
2641#else
2642 newname = original_case_string;
2643 nlen = strlen (newname);
2644#endif
b99bd4ef 2645
29a2809e 2646 nbuf = xmemdup0 (newname, nlen);
b99bd4ef 2647
c19d1205
ZW
2648 /* Create aliases under the new name as stated; an all-lowercase
2649 version of the new name; and an all-uppercase version of the new
2650 name. */
d929913e
NC
2651 if (insert_reg_alias (nbuf, old->number, old->type) != NULL)
2652 {
2653 for (p = nbuf; *p; p++)
2654 *p = TOUPPER (*p);
c19d1205 2655
d929913e
NC
2656 if (strncmp (nbuf, newname, nlen))
2657 {
2658 /* If this attempt to create an additional alias fails, do not bother
2659 trying to create the all-lower case alias. We will fail and issue
2660 a second, duplicate error message. This situation arises when the
2661 programmer does something like:
2662 foo .req r0
2663 Foo .req r1
2664 The second .req creates the "Foo" alias but then fails to create
5f4273c7 2665 the artificial FOO alias because it has already been created by the
d929913e
NC
2666 first .req. */
2667 if (insert_reg_alias (nbuf, old->number, old->type) == NULL)
e1fa0163
NC
2668 {
2669 free (nbuf);
5b7c81bd 2670 return true;
e1fa0163 2671 }
d929913e 2672 }
c19d1205 2673
d929913e
NC
2674 for (p = nbuf; *p; p++)
2675 *p = TOLOWER (*p);
c19d1205 2676
d929913e
NC
2677 if (strncmp (nbuf, newname, nlen))
2678 insert_reg_alias (nbuf, old->number, old->type);
2679 }
c19d1205 2680
e1fa0163 2681 free (nbuf);
5b7c81bd 2682 return true;
b99bd4ef
NC
2683}
2684
dcbf9037
JB
2685/* Create a Neon typed/indexed register alias using directives, e.g.:
2686 X .dn d5.s32[1]
2687 Y .qn 6.s16
2688 Z .dn d7
2689 T .dn Z[0]
2690 These typed registers can be used instead of the types specified after the
2691 Neon mnemonic, so long as all operands given have types. Types can also be
2692 specified directly, e.g.:
5f4273c7 2693 vadd d0.s32, d1.s32, d2.s32 */
dcbf9037 2694
5b7c81bd 2695static bool
dcbf9037
JB
2696create_neon_reg_alias (char *newname, char *p)
2697{
2698 enum arm_reg_type basetype;
2699 struct reg_entry *basereg;
2700 struct reg_entry mybasereg;
2701 struct neon_type ntype;
2702 struct neon_typed_alias typeinfo;
12d6b0b7 2703 char *namebuf, *nameend ATTRIBUTE_UNUSED;
dcbf9037 2704 int namelen;
5f4273c7 2705
dcbf9037
JB
2706 typeinfo.defined = 0;
2707 typeinfo.eltype.type = NT_invtype;
2708 typeinfo.eltype.size = -1;
2709 typeinfo.index = -1;
5f4273c7 2710
dcbf9037 2711 nameend = p;
5f4273c7 2712
d34049e8 2713 if (startswith (p, " .dn "))
dcbf9037 2714 basetype = REG_TYPE_VFD;
d34049e8 2715 else if (startswith (p, " .qn "))
dcbf9037
JB
2716 basetype = REG_TYPE_NQ;
2717 else
5b7c81bd 2718 return false;
5f4273c7 2719
dcbf9037 2720 p += 5;
5f4273c7 2721
dcbf9037 2722 if (*p == '\0')
5b7c81bd 2723 return false;
5f4273c7 2724
dcbf9037
JB
2725 basereg = arm_reg_parse_multi (&p);
2726
2727 if (basereg && basereg->type != basetype)
2728 {
2729 as_bad (_("bad type for register"));
5b7c81bd 2730 return false;
dcbf9037
JB
2731 }
2732
2733 if (basereg == NULL)
2734 {
2735 expressionS exp;
2736 /* Try parsing as an integer. */
2737 my_get_expression (&exp, &p, GE_NO_PREFIX);
2738 if (exp.X_op != O_constant)
477330fc
RM
2739 {
2740 as_bad (_("expression must be constant"));
5b7c81bd 2741 return false;
477330fc 2742 }
dcbf9037
JB
2743 basereg = &mybasereg;
2744 basereg->number = (basetype == REG_TYPE_NQ) ? exp.X_add_number * 2
477330fc 2745 : exp.X_add_number;
dcbf9037
JB
2746 basereg->neon = 0;
2747 }
2748
2749 if (basereg->neon)
2750 typeinfo = *basereg->neon;
2751
2752 if (parse_neon_type (&ntype, &p) == SUCCESS)
2753 {
2754 /* We got a type. */
2755 if (typeinfo.defined & NTA_HASTYPE)
477330fc
RM
2756 {
2757 as_bad (_("can't redefine the type of a register alias"));
5b7c81bd 2758 return false;
477330fc 2759 }
5f4273c7 2760
dcbf9037
JB
2761 typeinfo.defined |= NTA_HASTYPE;
2762 if (ntype.elems != 1)
477330fc
RM
2763 {
2764 as_bad (_("you must specify a single type only"));
5b7c81bd 2765 return false;
477330fc 2766 }
dcbf9037
JB
2767 typeinfo.eltype = ntype.el[0];
2768 }
5f4273c7 2769
dcbf9037
JB
2770 if (skip_past_char (&p, '[') == SUCCESS)
2771 {
2772 expressionS exp;
2773 /* We got a scalar index. */
5f4273c7 2774
dcbf9037 2775 if (typeinfo.defined & NTA_HASINDEX)
477330fc
RM
2776 {
2777 as_bad (_("can't redefine the index of a scalar alias"));
5b7c81bd 2778 return false;
477330fc 2779 }
5f4273c7 2780
dcbf9037 2781 my_get_expression (&exp, &p, GE_NO_PREFIX);
5f4273c7 2782
dcbf9037 2783 if (exp.X_op != O_constant)
477330fc
RM
2784 {
2785 as_bad (_("scalar index must be constant"));
5b7c81bd 2786 return false;
477330fc 2787 }
5f4273c7 2788
dcbf9037
JB
2789 typeinfo.defined |= NTA_HASINDEX;
2790 typeinfo.index = exp.X_add_number;
5f4273c7 2791
dcbf9037 2792 if (skip_past_char (&p, ']') == FAIL)
477330fc
RM
2793 {
2794 as_bad (_("expecting ]"));
5b7c81bd 2795 return false;
477330fc 2796 }
dcbf9037
JB
2797 }
2798
15735687
NS
2799 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2800 the desired alias name, and p points to its end. If not, then
2801 the desired alias name is in the global original_case_string. */
2802#ifdef TC_CASE_SENSITIVE
dcbf9037 2803 namelen = nameend - newname;
15735687
NS
2804#else
2805 newname = original_case_string;
2806 namelen = strlen (newname);
2807#endif
2808
29a2809e 2809 namebuf = xmemdup0 (newname, namelen);
5f4273c7 2810
dcbf9037 2811 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2812 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2813
dcbf9037
JB
2814 /* Insert name in all uppercase. */
2815 for (p = namebuf; *p; p++)
2816 *p = TOUPPER (*p);
5f4273c7 2817
dcbf9037
JB
2818 if (strncmp (namebuf, newname, namelen))
2819 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2820 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2821
dcbf9037
JB
2822 /* Insert name in all lowercase. */
2823 for (p = namebuf; *p; p++)
2824 *p = TOLOWER (*p);
5f4273c7 2825
dcbf9037
JB
2826 if (strncmp (namebuf, newname, namelen))
2827 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2828 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2829
e1fa0163 2830 free (namebuf);
5b7c81bd 2831 return true;
dcbf9037
JB
2832}
2833
c19d1205
ZW
2834/* Should never be called, as .req goes between the alias and the
2835 register name, not at the beginning of the line. */
c921be7d 2836
b99bd4ef 2837static void
c19d1205 2838s_req (int a ATTRIBUTE_UNUSED)
b99bd4ef 2839{
c19d1205
ZW
2840 as_bad (_("invalid syntax for .req directive"));
2841}
b99bd4ef 2842
dcbf9037
JB
2843static void
2844s_dn (int a ATTRIBUTE_UNUSED)
2845{
2846 as_bad (_("invalid syntax for .dn directive"));
2847}
2848
2849static void
2850s_qn (int a ATTRIBUTE_UNUSED)
2851{
2852 as_bad (_("invalid syntax for .qn directive"));
2853}
2854
c19d1205
ZW
2855/* The .unreq directive deletes an alias which was previously defined
2856 by .req. For example:
b99bd4ef 2857
c19d1205
ZW
2858 my_alias .req r11
2859 .unreq my_alias */
b99bd4ef
NC
2860
2861static void
c19d1205 2862s_unreq (int a ATTRIBUTE_UNUSED)
b99bd4ef 2863{
c19d1205
ZW
2864 char * name;
2865 char saved_char;
b99bd4ef 2866
c19d1205
ZW
2867 name = input_line_pointer;
2868
2869 while (*input_line_pointer != 0
2870 && *input_line_pointer != ' '
2871 && *input_line_pointer != '\n')
2872 ++input_line_pointer;
2873
2874 saved_char = *input_line_pointer;
2875 *input_line_pointer = 0;
2876
2877 if (!*name)
2878 as_bad (_("invalid syntax for .unreq directive"));
2879 else
2880 {
fe0e921f
AM
2881 struct reg_entry *reg
2882 = (struct reg_entry *) str_hash_find (arm_reg_hsh, name);
c19d1205
ZW
2883
2884 if (!reg)
2885 as_bad (_("unknown register alias '%s'"), name);
2886 else if (reg->builtin)
a1727c1a 2887 as_warn (_("ignoring attempt to use .unreq on fixed register name: '%s'"),
c19d1205
ZW
2888 name);
2889 else
2890 {
d929913e
NC
2891 char * p;
2892 char * nbuf;
2893
629310ab 2894 str_hash_delete (arm_reg_hsh, name);
c19d1205 2895 free ((char *) reg->name);
9fbb53c7 2896 free (reg->neon);
c19d1205 2897 free (reg);
d929913e
NC
2898
2899 /* Also locate the all upper case and all lower case versions.
2900 Do not complain if we cannot find one or the other as it
2901 was probably deleted above. */
5f4273c7 2902
d929913e
NC
2903 nbuf = strdup (name);
2904 for (p = nbuf; *p; p++)
2905 *p = TOUPPER (*p);
629310ab 2906 reg = (struct reg_entry *) str_hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2907 if (reg)
2908 {
629310ab 2909 str_hash_delete (arm_reg_hsh, nbuf);
d929913e 2910 free ((char *) reg->name);
9fbb53c7 2911 free (reg->neon);
d929913e
NC
2912 free (reg);
2913 }
2914
2915 for (p = nbuf; *p; p++)
2916 *p = TOLOWER (*p);
629310ab 2917 reg = (struct reg_entry *) str_hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2918 if (reg)
2919 {
629310ab 2920 str_hash_delete (arm_reg_hsh, nbuf);
d929913e 2921 free ((char *) reg->name);
9fbb53c7 2922 free (reg->neon);
d929913e
NC
2923 free (reg);
2924 }
2925
2926 free (nbuf);
c19d1205
ZW
2927 }
2928 }
b99bd4ef 2929
c19d1205 2930 *input_line_pointer = saved_char;
b99bd4ef
NC
2931 demand_empty_rest_of_line ();
2932}
2933
c19d1205
ZW
2934/* Directives: Instruction set selection. */
2935
2936#ifdef OBJ_ELF
2937/* This code is to handle mapping symbols as defined in the ARM ELF spec.
2938 (See "Mapping symbols", section 4.5.5, ARM AAELF version 1.0).
2939 Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
2940 and $d has type STT_OBJECT (BSF_OBJECT flag). Now all three are untyped. */
2941
cd000bff
DJ
2942/* Create a new mapping symbol for the transition to STATE. */
2943
2944static void
2945make_mapping_symbol (enum mstate state, valueT value, fragS *frag)
b99bd4ef 2946{
a737bd4d 2947 symbolS * symbolP;
c19d1205
ZW
2948 const char * symname;
2949 int type;
b99bd4ef 2950
c19d1205 2951 switch (state)
b99bd4ef 2952 {
c19d1205
ZW
2953 case MAP_DATA:
2954 symname = "$d";
2955 type = BSF_NO_FLAGS;
2956 break;
2957 case MAP_ARM:
2958 symname = "$a";
2959 type = BSF_NO_FLAGS;
2960 break;
2961 case MAP_THUMB:
2962 symname = "$t";
2963 type = BSF_NO_FLAGS;
2964 break;
c19d1205
ZW
2965 default:
2966 abort ();
2967 }
2968
e01e1cee 2969 symbolP = symbol_new (symname, now_seg, frag, value);
c19d1205
ZW
2970 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2971
2972 switch (state)
2973 {
2974 case MAP_ARM:
2975 THUMB_SET_FUNC (symbolP, 0);
2976 ARM_SET_THUMB (symbolP, 0);
2977 ARM_SET_INTERWORK (symbolP, support_interwork);
2978 break;
2979
2980 case MAP_THUMB:
2981 THUMB_SET_FUNC (symbolP, 1);
2982 ARM_SET_THUMB (symbolP, 1);
2983 ARM_SET_INTERWORK (symbolP, support_interwork);
2984 break;
2985
2986 case MAP_DATA:
2987 default:
cd000bff
DJ
2988 break;
2989 }
2990
2991 /* Save the mapping symbols for future reference. Also check that
2992 we do not place two mapping symbols at the same offset within a
2993 frag. We'll handle overlap between frags in
2de7820f
JZ
2994 check_mapping_symbols.
2995
2996 If .fill or other data filling directive generates zero sized data,
2997 the mapping symbol for the following code will have the same value
2998 as the one generated for the data filling directive. In this case,
2999 we replace the old symbol with the new one at the same address. */
cd000bff
DJ
3000 if (value == 0)
3001 {
2de7820f
JZ
3002 if (frag->tc_frag_data.first_map != NULL)
3003 {
3004 know (S_GET_VALUE (frag->tc_frag_data.first_map) == 0);
3005 symbol_remove (frag->tc_frag_data.first_map, &symbol_rootP, &symbol_lastP);
3006 }
cd000bff
DJ
3007 frag->tc_frag_data.first_map = symbolP;
3008 }
3009 if (frag->tc_frag_data.last_map != NULL)
0f020cef
JZ
3010 {
3011 know (S_GET_VALUE (frag->tc_frag_data.last_map) <= S_GET_VALUE (symbolP));
0f020cef
JZ
3012 if (S_GET_VALUE (frag->tc_frag_data.last_map) == S_GET_VALUE (symbolP))
3013 symbol_remove (frag->tc_frag_data.last_map, &symbol_rootP, &symbol_lastP);
3014 }
cd000bff
DJ
3015 frag->tc_frag_data.last_map = symbolP;
3016}
3017
3018/* We must sometimes convert a region marked as code to data during
3019 code alignment, if an odd number of bytes have to be padded. The
3020 code mapping symbol is pushed to an aligned address. */
3021
3022static void
3023insert_data_mapping_symbol (enum mstate state,
3024 valueT value, fragS *frag, offsetT bytes)
3025{
3026 /* If there was already a mapping symbol, remove it. */
3027 if (frag->tc_frag_data.last_map != NULL
3028 && S_GET_VALUE (frag->tc_frag_data.last_map) == frag->fr_address + value)
3029 {
3030 symbolS *symp = frag->tc_frag_data.last_map;
3031
3032 if (value == 0)
3033 {
3034 know (frag->tc_frag_data.first_map == symp);
3035 frag->tc_frag_data.first_map = NULL;
3036 }
3037 frag->tc_frag_data.last_map = NULL;
3038 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
c19d1205 3039 }
cd000bff
DJ
3040
3041 make_mapping_symbol (MAP_DATA, value, frag);
3042 make_mapping_symbol (state, value + bytes, frag);
3043}
3044
3045static void mapping_state_2 (enum mstate state, int max_chars);
3046
3047/* Set the mapping state to STATE. Only call this when about to
3048 emit some STATE bytes to the file. */
3049
4e9aaefb 3050#define TRANSITION(from, to) (mapstate == (from) && state == (to))
cd000bff
DJ
3051void
3052mapping_state (enum mstate state)
3053{
940b5ce0
DJ
3054 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
3055
cd000bff
DJ
3056 if (mapstate == state)
3057 /* The mapping symbol has already been emitted.
3058 There is nothing else to do. */
3059 return;
49c62a33
NC
3060
3061 if (state == MAP_ARM || state == MAP_THUMB)
3062 /* PR gas/12931
3063 All ARM instructions require 4-byte alignment.
3064 (Almost) all Thumb instructions require 2-byte alignment.
3065
3066 When emitting instructions into any section, mark the section
3067 appropriately.
3068
3069 Some Thumb instructions are alignment-sensitive modulo 4 bytes,
3070 but themselves require 2-byte alignment; this applies to some
33eaf5de 3071 PC- relative forms. However, these cases will involve implicit
49c62a33
NC
3072 literal pool generation or an explicit .align >=2, both of
3073 which will cause the section to me marked with sufficient
3074 alignment. Thus, we don't handle those cases here. */
3075 record_alignment (now_seg, state == MAP_ARM ? 2 : 1);
3076
3077 if (TRANSITION (MAP_UNDEFINED, MAP_DATA))
4e9aaefb 3078 /* This case will be evaluated later. */
cd000bff 3079 return;
cd000bff
DJ
3080
3081 mapping_state_2 (state, 0);
cd000bff
DJ
3082}
3083
3084/* Same as mapping_state, but MAX_CHARS bytes have already been
3085 allocated. Put the mapping symbol that far back. */
3086
3087static void
3088mapping_state_2 (enum mstate state, int max_chars)
3089{
940b5ce0
DJ
3090 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
3091
3092 if (!SEG_NORMAL (now_seg))
3093 return;
3094
cd000bff
DJ
3095 if (mapstate == state)
3096 /* The mapping symbol has already been emitted.
3097 There is nothing else to do. */
3098 return;
3099
4e9aaefb
SA
3100 if (TRANSITION (MAP_UNDEFINED, MAP_ARM)
3101 || TRANSITION (MAP_UNDEFINED, MAP_THUMB))
3102 {
3103 struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
3104 const int add_symbol = (frag_now != frag_first) || (frag_now_fix () > 0);
3105
3106 if (add_symbol)
3107 make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
3108 }
3109
cd000bff
DJ
3110 seg_info (now_seg)->tc_segment_info_data.mapstate = state;
3111 make_mapping_symbol (state, (valueT) frag_now_fix () - max_chars, frag_now);
c19d1205 3112}
4e9aaefb 3113#undef TRANSITION
c19d1205 3114#else
d3106081
NS
3115#define mapping_state(x) ((void)0)
3116#define mapping_state_2(x, y) ((void)0)
c19d1205
ZW
3117#endif
3118
3119/* Find the real, Thumb encoded start of a Thumb function. */
3120
4343666d 3121#ifdef OBJ_COFF
c19d1205
ZW
3122static symbolS *
3123find_real_start (symbolS * symbolP)
3124{
3125 char * real_start;
3126 const char * name = S_GET_NAME (symbolP);
3127 symbolS * new_target;
3128
3129 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
3130#define STUB_NAME ".real_start_of"
3131
3132 if (name == NULL)
3133 abort ();
3134
37f6032b
ZW
3135 /* The compiler may generate BL instructions to local labels because
3136 it needs to perform a branch to a far away location. These labels
3137 do not have a corresponding ".real_start_of" label. We check
3138 both for S_IS_LOCAL and for a leading dot, to give a way to bypass
3139 the ".real_start_of" convention for nonlocal branches. */
3140 if (S_IS_LOCAL (symbolP) || name[0] == '.')
c19d1205
ZW
3141 return symbolP;
3142
e1fa0163 3143 real_start = concat (STUB_NAME, name, NULL);
c19d1205 3144 new_target = symbol_find (real_start);
e1fa0163 3145 free (real_start);
c19d1205
ZW
3146
3147 if (new_target == NULL)
3148 {
bd3ba5d1 3149 as_warn (_("Failed to find real start of function: %s\n"), name);
c19d1205
ZW
3150 new_target = symbolP;
3151 }
3152
c19d1205
ZW
3153 return new_target;
3154}
4343666d 3155#endif
c19d1205
ZW
3156
3157static void
3158opcode_select (int width)
3159{
3160 switch (width)
3161 {
3162 case 16:
3163 if (! thumb_mode)
3164 {
e74cfd16 3165 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
c19d1205
ZW
3166 as_bad (_("selected processor does not support THUMB opcodes"));
3167
3168 thumb_mode = 1;
3169 /* No need to force the alignment, since we will have been
3170 coming from ARM mode, which is word-aligned. */
3171 record_alignment (now_seg, 1);
3172 }
c19d1205
ZW
3173 break;
3174
3175 case 32:
3176 if (thumb_mode)
3177 {
e74cfd16 3178 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205
ZW
3179 as_bad (_("selected processor does not support ARM opcodes"));
3180
3181 thumb_mode = 0;
3182
3183 if (!need_pass_2)
3184 frag_align (2, 0, 0);
3185
3186 record_alignment (now_seg, 1);
3187 }
c19d1205
ZW
3188 break;
3189
3190 default:
3191 as_bad (_("invalid instruction size selected (%d)"), width);
3192 }
3193}
3194
3195static void
3196s_arm (int ignore ATTRIBUTE_UNUSED)
3197{
3198 opcode_select (32);
3199 demand_empty_rest_of_line ();
3200}
3201
3202static void
3203s_thumb (int ignore ATTRIBUTE_UNUSED)
3204{
3205 opcode_select (16);
3206 demand_empty_rest_of_line ();
3207}
3208
3209static void
3210s_code (int unused ATTRIBUTE_UNUSED)
3211{
3212 int temp;
3213
3214 temp = get_absolute_expression ();
3215 switch (temp)
3216 {
3217 case 16:
3218 case 32:
3219 opcode_select (temp);
3220 break;
3221
3222 default:
3223 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3224 }
3225}
3226
3227static void
3228s_force_thumb (int ignore ATTRIBUTE_UNUSED)
3229{
3230 /* If we are not already in thumb mode go into it, EVEN if
3231 the target processor does not support thumb instructions.
3232 This is used by gcc/config/arm/lib1funcs.asm for example
3233 to compile interworking support functions even if the
3234 target processor should not support interworking. */
3235 if (! thumb_mode)
3236 {
3237 thumb_mode = 2;
3238 record_alignment (now_seg, 1);
3239 }
3240
3241 demand_empty_rest_of_line ();
3242}
3243
3244static void
3245s_thumb_func (int ignore ATTRIBUTE_UNUSED)
3246{
3247 s_thumb (0);
3248
3249 /* The following label is the name/address of the start of a Thumb function.
3250 We need to know this for the interworking support. */
5b7c81bd 3251 label_is_thumb_function_name = true;
c19d1205
ZW
3252}
3253
3254/* Perform a .set directive, but also mark the alias as
3255 being a thumb function. */
3256
3257static void
3258s_thumb_set (int equiv)
3259{
3260 /* XXX the following is a duplicate of the code for s_set() in read.c
3261 We cannot just call that code as we need to get at the symbol that
3262 is created. */
3263 char * name;
3264 char delim;
3265 char * end_name;
3266 symbolS * symbolP;
3267
3268 /* Especial apologies for the random logic:
3269 This just grew, and could be parsed much more simply!
3270 Dean - in haste. */
d02603dc 3271 delim = get_symbol_name (& name);
c19d1205 3272 end_name = input_line_pointer;
d02603dc 3273 (void) restore_line_pointer (delim);
c19d1205
ZW
3274
3275 if (*input_line_pointer != ',')
3276 {
3277 *end_name = 0;
3278 as_bad (_("expected comma after name \"%s\""), name);
b99bd4ef
NC
3279 *end_name = delim;
3280 ignore_rest_of_line ();
3281 return;
3282 }
3283
3284 input_line_pointer++;
3285 *end_name = 0;
3286
3287 if (name[0] == '.' && name[1] == '\0')
3288 {
3289 /* XXX - this should not happen to .thumb_set. */
3290 abort ();
3291 }
3292
3293 if ((symbolP = symbol_find (name)) == NULL
3294 && (symbolP = md_undefined_symbol (name)) == NULL)
3295 {
3296#ifndef NO_LISTING
3297 /* When doing symbol listings, play games with dummy fragments living
3298 outside the normal fragment chain to record the file and line info
c19d1205 3299 for this symbol. */
b99bd4ef
NC
3300 if (listing & LISTING_SYMBOLS)
3301 {
3302 extern struct list_info_struct * listing_tail;
21d799b5 3303 fragS * dummy_frag = (fragS * ) xmalloc (sizeof (fragS));
b99bd4ef
NC
3304
3305 memset (dummy_frag, 0, sizeof (fragS));
3306 dummy_frag->fr_type = rs_fill;
3307 dummy_frag->line = listing_tail;
e01e1cee 3308 symbolP = symbol_new (name, undefined_section, dummy_frag, 0);
b99bd4ef
NC
3309 dummy_frag->fr_symbol = symbolP;
3310 }
3311 else
3312#endif
e01e1cee 3313 symbolP = symbol_new (name, undefined_section, &zero_address_frag, 0);
b99bd4ef
NC
3314
3315#ifdef OBJ_COFF
3316 /* "set" symbols are local unless otherwise specified. */
3317 SF_SET_LOCAL (symbolP);
3318#endif /* OBJ_COFF */
3319 } /* Make a new symbol. */
3320
3321 symbol_table_insert (symbolP);
3322
3323 * end_name = delim;
3324
3325 if (equiv
3326 && S_IS_DEFINED (symbolP)
3327 && S_GET_SEGMENT (symbolP) != reg_section)
3328 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3329
3330 pseudo_set (symbolP);
3331
3332 demand_empty_rest_of_line ();
3333
c19d1205 3334 /* XXX Now we come to the Thumb specific bit of code. */
b99bd4ef
NC
3335
3336 THUMB_SET_FUNC (symbolP, 1);
3337 ARM_SET_THUMB (symbolP, 1);
3338#if defined OBJ_ELF || defined OBJ_COFF
3339 ARM_SET_INTERWORK (symbolP, support_interwork);
3340#endif
3341}
3342
c19d1205 3343/* Directives: Mode selection. */
b99bd4ef 3344
c19d1205
ZW
3345/* .syntax [unified|divided] - choose the new unified syntax
3346 (same for Arm and Thumb encoding, modulo slight differences in what
3347 can be represented) or the old divergent syntax for each mode. */
b99bd4ef 3348static void
c19d1205 3349s_syntax (int unused ATTRIBUTE_UNUSED)
b99bd4ef 3350{
c19d1205
ZW
3351 char *name, delim;
3352
d02603dc 3353 delim = get_symbol_name (& name);
c19d1205
ZW
3354
3355 if (!strcasecmp (name, "unified"))
5b7c81bd 3356 unified_syntax = true;
c19d1205 3357 else if (!strcasecmp (name, "divided"))
5b7c81bd 3358 unified_syntax = false;
c19d1205
ZW
3359 else
3360 {
3361 as_bad (_("unrecognized syntax mode \"%s\""), name);
3362 return;
3363 }
d02603dc 3364 (void) restore_line_pointer (delim);
b99bd4ef
NC
3365 demand_empty_rest_of_line ();
3366}
3367
c19d1205
ZW
3368/* Directives: sectioning and alignment. */
3369
c19d1205
ZW
3370static void
3371s_bss (int ignore ATTRIBUTE_UNUSED)
b99bd4ef 3372{
c19d1205
ZW
3373 /* We don't support putting frags in the BSS segment, we fake it by
3374 marking in_bss, then looking at s_skip for clues. */
3375 subseg_set (bss_section, 0);
3376 demand_empty_rest_of_line ();
cd000bff
DJ
3377
3378#ifdef md_elf_section_change_hook
3379 md_elf_section_change_hook ();
3380#endif
c19d1205 3381}
b99bd4ef 3382
c19d1205
ZW
3383static void
3384s_even (int ignore ATTRIBUTE_UNUSED)
3385{
3386 /* Never make frag if expect extra pass. */
3387 if (!need_pass_2)
3388 frag_align (1, 0, 0);
b99bd4ef 3389
c19d1205 3390 record_alignment (now_seg, 1);
b99bd4ef 3391
c19d1205 3392 demand_empty_rest_of_line ();
b99bd4ef
NC
3393}
3394
2e6976a8
DG
3395/* Directives: CodeComposer Studio. */
3396
3397/* .ref (for CodeComposer Studio syntax only). */
3398static void
3399s_ccs_ref (int unused ATTRIBUTE_UNUSED)
3400{
3401 if (codecomposer_syntax)
3402 ignore_rest_of_line ();
3403 else
3404 as_bad (_(".ref pseudo-op only available with -mccs flag."));
3405}
3406
3407/* If name is not NULL, then it is used for marking the beginning of a
2b0f3761 3408 function, whereas if it is NULL then it means the function end. */
2e6976a8
DG
3409static void
3410asmfunc_debug (const char * name)
3411{
3412 static const char * last_name = NULL;
3413
3414 if (name != NULL)
3415 {
3416 gas_assert (last_name == NULL);
3417 last_name = name;
3418
3419 if (debug_type == DEBUG_STABS)
3420 stabs_generate_asm_func (name, name);
3421 }
3422 else
3423 {
3424 gas_assert (last_name != NULL);
3425
3426 if (debug_type == DEBUG_STABS)
3427 stabs_generate_asm_endfunc (last_name, last_name);
3428
3429 last_name = NULL;
3430 }
3431}
3432
3433static void
3434s_ccs_asmfunc (int unused ATTRIBUTE_UNUSED)
3435{
3436 if (codecomposer_syntax)
3437 {
3438 switch (asmfunc_state)
3439 {
3440 case OUTSIDE_ASMFUNC:
3441 asmfunc_state = WAITING_ASMFUNC_NAME;
3442 break;
3443
3444 case WAITING_ASMFUNC_NAME:
3445 as_bad (_(".asmfunc repeated."));
3446 break;
3447
3448 case WAITING_ENDASMFUNC:
3449 as_bad (_(".asmfunc without function."));
3450 break;
3451 }
3452 demand_empty_rest_of_line ();
3453 }
3454 else
3455 as_bad (_(".asmfunc pseudo-op only available with -mccs flag."));
3456}
3457
3458static void
3459s_ccs_endasmfunc (int unused ATTRIBUTE_UNUSED)
3460{
3461 if (codecomposer_syntax)
3462 {
3463 switch (asmfunc_state)
3464 {
3465 case OUTSIDE_ASMFUNC:
3466 as_bad (_(".endasmfunc without a .asmfunc."));
3467 break;
3468
3469 case WAITING_ASMFUNC_NAME:
3470 as_bad (_(".endasmfunc without function."));
3471 break;
3472
3473 case WAITING_ENDASMFUNC:
3474 asmfunc_state = OUTSIDE_ASMFUNC;
3475 asmfunc_debug (NULL);
3476 break;
3477 }
3478 demand_empty_rest_of_line ();
3479 }
3480 else
3481 as_bad (_(".endasmfunc pseudo-op only available with -mccs flag."));
3482}
3483
3484static void
3485s_ccs_def (int name)
3486{
3487 if (codecomposer_syntax)
3488 s_globl (name);
3489 else
3490 as_bad (_(".def pseudo-op only available with -mccs flag."));
3491}
3492
c19d1205 3493/* Directives: Literal pools. */
a737bd4d 3494
c19d1205
ZW
3495static literal_pool *
3496find_literal_pool (void)
a737bd4d 3497{
c19d1205 3498 literal_pool * pool;
a737bd4d 3499
c19d1205 3500 for (pool = list_of_pools; pool != NULL; pool = pool->next)
a737bd4d 3501 {
c19d1205
ZW
3502 if (pool->section == now_seg
3503 && pool->sub_section == now_subseg)
3504 break;
a737bd4d
NC
3505 }
3506
c19d1205 3507 return pool;
a737bd4d
NC
3508}
3509
c19d1205
ZW
3510static literal_pool *
3511find_or_make_literal_pool (void)
a737bd4d 3512{
c19d1205
ZW
3513 /* Next literal pool ID number. */
3514 static unsigned int latest_pool_num = 1;
3515 literal_pool * pool;
a737bd4d 3516
c19d1205 3517 pool = find_literal_pool ();
a737bd4d 3518
c19d1205 3519 if (pool == NULL)
a737bd4d 3520 {
c19d1205 3521 /* Create a new pool. */
325801bd 3522 pool = XNEW (literal_pool);
c19d1205
ZW
3523 if (! pool)
3524 return NULL;
a737bd4d 3525
c19d1205
ZW
3526 pool->next_free_entry = 0;
3527 pool->section = now_seg;
3528 pool->sub_section = now_subseg;
3529 pool->next = list_of_pools;
3530 pool->symbol = NULL;
8335d6aa 3531 pool->alignment = 2;
c19d1205
ZW
3532
3533 /* Add it to the list. */
3534 list_of_pools = pool;
a737bd4d 3535 }
a737bd4d 3536
c19d1205
ZW
3537 /* New pools, and emptied pools, will have a NULL symbol. */
3538 if (pool->symbol == NULL)
a737bd4d 3539 {
c19d1205 3540 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
e01e1cee 3541 &zero_address_frag, 0);
c19d1205 3542 pool->id = latest_pool_num ++;
a737bd4d
NC
3543 }
3544
c19d1205
ZW
3545 /* Done. */
3546 return pool;
a737bd4d
NC
3547}
3548
c19d1205 3549/* Add the literal in the global 'inst'
5f4273c7 3550 structure to the relevant literal pool. */
b99bd4ef
NC
3551
3552static int
8335d6aa 3553add_to_lit_pool (unsigned int nbytes)
b99bd4ef 3554{
8335d6aa
JW
3555#define PADDING_SLOT 0x1
3556#define LIT_ENTRY_SIZE_MASK 0xFF
c19d1205 3557 literal_pool * pool;
8335d6aa 3558 unsigned int entry, pool_size = 0;
5b7c81bd 3559 bool padding_slot_p = false;
e56c722b 3560 unsigned imm1 = 0;
8335d6aa
JW
3561 unsigned imm2 = 0;
3562
3563 if (nbytes == 8)
3564 {
3565 imm1 = inst.operands[1].imm;
3566 imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
e2b0ab59 3567 : inst.relocs[0].exp.X_unsigned ? 0
2569ceb0 3568 : ((bfd_int64_t) inst.operands[1].imm) >> 32);
8335d6aa
JW
3569 if (target_big_endian)
3570 {
3571 imm1 = imm2;
3572 imm2 = inst.operands[1].imm;
3573 }
3574 }
b99bd4ef 3575
c19d1205
ZW
3576 pool = find_or_make_literal_pool ();
3577
3578 /* Check if this literal value is already in the pool. */
3579 for (entry = 0; entry < pool->next_free_entry; entry ++)
b99bd4ef 3580 {
8335d6aa
JW
3581 if (nbytes == 4)
3582 {
e2b0ab59
AV
3583 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3584 && (inst.relocs[0].exp.X_op == O_constant)
8335d6aa 3585 && (pool->literals[entry].X_add_number
e2b0ab59 3586 == inst.relocs[0].exp.X_add_number)
8335d6aa
JW
3587 && (pool->literals[entry].X_md == nbytes)
3588 && (pool->literals[entry].X_unsigned
e2b0ab59 3589 == inst.relocs[0].exp.X_unsigned))
8335d6aa
JW
3590 break;
3591
e2b0ab59
AV
3592 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3593 && (inst.relocs[0].exp.X_op == O_symbol)
8335d6aa 3594 && (pool->literals[entry].X_add_number
e2b0ab59 3595 == inst.relocs[0].exp.X_add_number)
8335d6aa 3596 && (pool->literals[entry].X_add_symbol
e2b0ab59 3597 == inst.relocs[0].exp.X_add_symbol)
8335d6aa 3598 && (pool->literals[entry].X_op_symbol
e2b0ab59 3599 == inst.relocs[0].exp.X_op_symbol)
8335d6aa
JW
3600 && (pool->literals[entry].X_md == nbytes))
3601 break;
3602 }
3603 else if ((nbytes == 8)
3604 && !(pool_size & 0x7)
3605 && ((entry + 1) != pool->next_free_entry)
3606 && (pool->literals[entry].X_op == O_constant)
19f2f6a9 3607 && (pool->literals[entry].X_add_number == (offsetT) imm1)
8335d6aa 3608 && (pool->literals[entry].X_unsigned
e2b0ab59 3609 == inst.relocs[0].exp.X_unsigned)
8335d6aa 3610 && (pool->literals[entry + 1].X_op == O_constant)
19f2f6a9 3611 && (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
8335d6aa 3612 && (pool->literals[entry + 1].X_unsigned
e2b0ab59 3613 == inst.relocs[0].exp.X_unsigned))
c19d1205
ZW
3614 break;
3615
8335d6aa
JW
3616 padding_slot_p = ((pool->literals[entry].X_md >> 8) == PADDING_SLOT);
3617 if (padding_slot_p && (nbytes == 4))
c19d1205 3618 break;
8335d6aa
JW
3619
3620 pool_size += 4;
b99bd4ef
NC
3621 }
3622
c19d1205
ZW
3623 /* Do we need to create a new entry? */
3624 if (entry == pool->next_free_entry)
3625 {
3626 if (entry >= MAX_LITERAL_POOL_SIZE)
3627 {
3628 inst.error = _("literal pool overflow");
3629 return FAIL;
3630 }
3631
8335d6aa
JW
3632 if (nbytes == 8)
3633 {
3634 /* For 8-byte entries, we align to an 8-byte boundary,
3635 and split it into two 4-byte entries, because on 32-bit
3636 host, 8-byte constants are treated as big num, thus
3637 saved in "generic_bignum" which will be overwritten
3638 by later assignments.
3639
3640 We also need to make sure there is enough space for
3641 the split.
3642
3643 We also check to make sure the literal operand is a
3644 constant number. */
e2b0ab59
AV
3645 if (!(inst.relocs[0].exp.X_op == O_constant
3646 || inst.relocs[0].exp.X_op == O_big))
8335d6aa
JW
3647 {
3648 inst.error = _("invalid type for literal pool");
3649 return FAIL;
3650 }
3651 else if (pool_size & 0x7)
3652 {
3653 if ((entry + 2) >= MAX_LITERAL_POOL_SIZE)
3654 {
3655 inst.error = _("literal pool overflow");
3656 return FAIL;
3657 }
3658
e2b0ab59 3659 pool->literals[entry] = inst.relocs[0].exp;
a6684f0d 3660 pool->literals[entry].X_op = O_constant;
8335d6aa
JW
3661 pool->literals[entry].X_add_number = 0;
3662 pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
3663 pool->next_free_entry += 1;
3664 pool_size += 4;
3665 }
3666 else if ((entry + 1) >= MAX_LITERAL_POOL_SIZE)
3667 {
3668 inst.error = _("literal pool overflow");
3669 return FAIL;
3670 }
3671
e2b0ab59 3672 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3673 pool->literals[entry].X_op = O_constant;
3674 pool->literals[entry].X_add_number = imm1;
e2b0ab59 3675 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa 3676 pool->literals[entry++].X_md = 4;
e2b0ab59 3677 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3678 pool->literals[entry].X_op = O_constant;
3679 pool->literals[entry].X_add_number = imm2;
e2b0ab59 3680 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa
JW
3681 pool->literals[entry].X_md = 4;
3682 pool->alignment = 3;
3683 pool->next_free_entry += 1;
3684 }
3685 else
3686 {
e2b0ab59 3687 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3688 pool->literals[entry].X_md = 4;
3689 }
3690
a8040cf2
NC
3691#ifdef OBJ_ELF
3692 /* PR ld/12974: Record the location of the first source line to reference
3693 this entry in the literal pool. If it turns out during linking that the
3694 symbol does not exist we will be able to give an accurate line number for
3695 the (first use of the) missing reference. */
3696 if (debug_type == DEBUG_DWARF2)
3697 dwarf2_where (pool->locs + entry);
3698#endif
c19d1205
ZW
3699 pool->next_free_entry += 1;
3700 }
8335d6aa
JW
3701 else if (padding_slot_p)
3702 {
e2b0ab59 3703 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3704 pool->literals[entry].X_md = nbytes;
3705 }
b99bd4ef 3706
e2b0ab59
AV
3707 inst.relocs[0].exp.X_op = O_symbol;
3708 inst.relocs[0].exp.X_add_number = pool_size;
3709 inst.relocs[0].exp.X_add_symbol = pool->symbol;
b99bd4ef 3710
c19d1205 3711 return SUCCESS;
b99bd4ef
NC
3712}
3713
5b7c81bd 3714bool
2e57ce7b 3715tc_start_label_without_colon (void)
2e6976a8 3716{
5b7c81bd 3717 bool ret = true;
2e6976a8
DG
3718
3719 if (codecomposer_syntax && asmfunc_state == WAITING_ASMFUNC_NAME)
3720 {
2e57ce7b 3721 const char *label = input_line_pointer;
2e6976a8
DG
3722
3723 while (!is_end_of_line[(int) label[-1]])
3724 --label;
3725
3726 if (*label == '.')
3727 {
3728 as_bad (_("Invalid label '%s'"), label);
5b7c81bd 3729 ret = false;
2e6976a8
DG
3730 }
3731
3732 asmfunc_debug (label);
3733
3734 asmfunc_state = WAITING_ENDASMFUNC;
3735 }
3736
3737 return ret;
3738}
3739
c19d1205 3740/* Can't use symbol_new here, so have to create a symbol and then at
33eaf5de 3741 a later date assign it a value. That's what these functions do. */
e16bb312 3742
c19d1205
ZW
3743static void
3744symbol_locate (symbolS * symbolP,
3745 const char * name, /* It is copied, the caller can modify. */
3746 segT segment, /* Segment identifier (SEG_<something>). */
3747 valueT valu, /* Symbol value. */
3748 fragS * frag) /* Associated fragment. */
3749{
e57e6ddc 3750 size_t name_length;
c19d1205 3751 char * preserved_copy_of_name;
e16bb312 3752
c19d1205
ZW
3753 name_length = strlen (name) + 1; /* +1 for \0. */
3754 obstack_grow (&notes, name, name_length);
21d799b5 3755 preserved_copy_of_name = (char *) obstack_finish (&notes);
e16bb312 3756
c19d1205
ZW
3757#ifdef tc_canonicalize_symbol_name
3758 preserved_copy_of_name =
3759 tc_canonicalize_symbol_name (preserved_copy_of_name);
3760#endif
b99bd4ef 3761
c19d1205 3762 S_SET_NAME (symbolP, preserved_copy_of_name);
b99bd4ef 3763
c19d1205
ZW
3764 S_SET_SEGMENT (symbolP, segment);
3765 S_SET_VALUE (symbolP, valu);
3766 symbol_clear_list_pointers (symbolP);
b99bd4ef 3767
c19d1205 3768 symbol_set_frag (symbolP, frag);
b99bd4ef 3769
c19d1205
ZW
3770 /* Link to end of symbol chain. */
3771 {
3772 extern int symbol_table_frozen;
b99bd4ef 3773
c19d1205
ZW
3774 if (symbol_table_frozen)
3775 abort ();
3776 }
b99bd4ef 3777
c19d1205 3778 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
b99bd4ef 3779
c19d1205 3780 obj_symbol_new_hook (symbolP);
b99bd4ef 3781
c19d1205
ZW
3782#ifdef tc_symbol_new_hook
3783 tc_symbol_new_hook (symbolP);
3784#endif
3785
3786#ifdef DEBUG_SYMS
3787 verify_symbol_chain (symbol_rootP, symbol_lastP);
3788#endif /* DEBUG_SYMS */
b99bd4ef
NC
3789}
3790
c19d1205
ZW
3791static void
3792s_ltorg (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 3793{
c19d1205
ZW
3794 unsigned int entry;
3795 literal_pool * pool;
3796 char sym_name[20];
b99bd4ef 3797
c19d1205
ZW
3798 pool = find_literal_pool ();
3799 if (pool == NULL
3800 || pool->symbol == NULL
3801 || pool->next_free_entry == 0)
3802 return;
b99bd4ef 3803
c19d1205
ZW
3804 /* Align pool as you have word accesses.
3805 Only make a frag if we have to. */
3806 if (!need_pass_2)
8335d6aa 3807 frag_align (pool->alignment, 0, 0);
b99bd4ef 3808
c19d1205 3809 record_alignment (now_seg, 2);
b99bd4ef 3810
aaca88ef 3811#ifdef OBJ_ELF
47fc6e36
WN
3812 seg_info (now_seg)->tc_segment_info_data.mapstate = MAP_DATA;
3813 make_mapping_symbol (MAP_DATA, (valueT) frag_now_fix (), frag_now);
aaca88ef 3814#endif
c19d1205 3815 sprintf (sym_name, "$$lit_\002%x", pool->id);
b99bd4ef 3816
c19d1205
ZW
3817 symbol_locate (pool->symbol, sym_name, now_seg,
3818 (valueT) frag_now_fix (), frag_now);
3819 symbol_table_insert (pool->symbol);
b99bd4ef 3820
c19d1205 3821 ARM_SET_THUMB (pool->symbol, thumb_mode);
b99bd4ef 3822
c19d1205
ZW
3823#if defined OBJ_COFF || defined OBJ_ELF
3824 ARM_SET_INTERWORK (pool->symbol, support_interwork);
3825#endif
6c43fab6 3826
c19d1205 3827 for (entry = 0; entry < pool->next_free_entry; entry ++)
a8040cf2
NC
3828 {
3829#ifdef OBJ_ELF
3830 if (debug_type == DEBUG_DWARF2)
3831 dwarf2_gen_line_info (frag_now_fix (), pool->locs + entry);
3832#endif
3833 /* First output the expression in the instruction to the pool. */
8335d6aa
JW
3834 emit_expr (&(pool->literals[entry]),
3835 pool->literals[entry].X_md & LIT_ENTRY_SIZE_MASK);
a8040cf2 3836 }
b99bd4ef 3837
c19d1205
ZW
3838 /* Mark the pool as empty. */
3839 pool->next_free_entry = 0;
3840 pool->symbol = NULL;
b99bd4ef
NC
3841}
3842
c19d1205
ZW
3843#ifdef OBJ_ELF
3844/* Forward declarations for functions below, in the MD interface
3845 section. */
3846static void fix_new_arm (fragS *, int, short, expressionS *, int, int);
3847static valueT create_unwind_entry (int);
3848static void start_unwind_section (const segT, int);
3849static void add_unwind_opcode (valueT, int);
3850static void flush_pending_unwind (void);
b99bd4ef 3851
c19d1205 3852/* Directives: Data. */
b99bd4ef 3853
c19d1205
ZW
3854static void
3855s_arm_elf_cons (int nbytes)
3856{
3857 expressionS exp;
b99bd4ef 3858
c19d1205
ZW
3859#ifdef md_flush_pending_output
3860 md_flush_pending_output ();
3861#endif
b99bd4ef 3862
c19d1205 3863 if (is_it_end_of_statement ())
b99bd4ef 3864 {
c19d1205
ZW
3865 demand_empty_rest_of_line ();
3866 return;
b99bd4ef
NC
3867 }
3868
c19d1205
ZW
3869#ifdef md_cons_align
3870 md_cons_align (nbytes);
3871#endif
b99bd4ef 3872
c19d1205
ZW
3873 mapping_state (MAP_DATA);
3874 do
b99bd4ef 3875 {
c19d1205
ZW
3876 int reloc;
3877 char *base = input_line_pointer;
b99bd4ef 3878
c19d1205 3879 expression (& exp);
b99bd4ef 3880
c19d1205
ZW
3881 if (exp.X_op != O_symbol)
3882 emit_expr (&exp, (unsigned int) nbytes);
3883 else
3884 {
3885 char *before_reloc = input_line_pointer;
3886 reloc = parse_reloc (&input_line_pointer);
3887 if (reloc == -1)
3888 {
3889 as_bad (_("unrecognized relocation suffix"));
3890 ignore_rest_of_line ();
3891 return;
3892 }
3893 else if (reloc == BFD_RELOC_UNUSED)
3894 emit_expr (&exp, (unsigned int) nbytes);
3895 else
3896 {
21d799b5 3897 reloc_howto_type *howto = (reloc_howto_type *)
477330fc
RM
3898 bfd_reloc_type_lookup (stdoutput,
3899 (bfd_reloc_code_real_type) reloc);
c19d1205 3900 int size = bfd_get_reloc_size (howto);
b99bd4ef 3901
2fc8bdac
ZW
3902 if (reloc == BFD_RELOC_ARM_PLT32)
3903 {
3904 as_bad (_("(plt) is only valid on branch targets"));
3905 reloc = BFD_RELOC_UNUSED;
3906 size = 0;
3907 }
3908
c19d1205 3909 if (size > nbytes)
992a06ee
AM
3910 as_bad (ngettext ("%s relocations do not fit in %d byte",
3911 "%s relocations do not fit in %d bytes",
3912 nbytes),
c19d1205
ZW
3913 howto->name, nbytes);
3914 else
3915 {
3916 /* We've parsed an expression stopping at O_symbol.
3917 But there may be more expression left now that we
3918 have parsed the relocation marker. Parse it again.
3919 XXX Surely there is a cleaner way to do this. */
3920 char *p = input_line_pointer;
3921 int offset;
325801bd 3922 char *save_buf = XNEWVEC (char, input_line_pointer - base);
e1fa0163 3923
c19d1205
ZW
3924 memcpy (save_buf, base, input_line_pointer - base);
3925 memmove (base + (input_line_pointer - before_reloc),
3926 base, before_reloc - base);
3927
3928 input_line_pointer = base + (input_line_pointer-before_reloc);
3929 expression (&exp);
3930 memcpy (base, save_buf, p - base);
3931
3932 offset = nbytes - size;
4b1a927e
AM
3933 p = frag_more (nbytes);
3934 memset (p, 0, nbytes);
c19d1205 3935 fix_new_exp (frag_now, p - frag_now->fr_literal + offset,
21d799b5 3936 size, &exp, 0, (enum bfd_reloc_code_real) reloc);
e1fa0163 3937 free (save_buf);
c19d1205
ZW
3938 }
3939 }
3940 }
b99bd4ef 3941 }
c19d1205 3942 while (*input_line_pointer++ == ',');
b99bd4ef 3943
c19d1205
ZW
3944 /* Put terminator back into stream. */
3945 input_line_pointer --;
3946 demand_empty_rest_of_line ();
b99bd4ef
NC
3947}
3948
c921be7d
NC
3949/* Emit an expression containing a 32-bit thumb instruction.
3950 Implementation based on put_thumb32_insn. */
3951
3952static void
3953emit_thumb32_expr (expressionS * exp)
3954{
3955 expressionS exp_high = *exp;
3956
3957 exp_high.X_add_number = (unsigned long)exp_high.X_add_number >> 16;
3958 emit_expr (& exp_high, (unsigned int) THUMB_SIZE);
3959 exp->X_add_number &= 0xffff;
3960 emit_expr (exp, (unsigned int) THUMB_SIZE);
3961}
3962
3963/* Guess the instruction size based on the opcode. */
3964
3965static int
3966thumb_insn_size (int opcode)
3967{
3968 if ((unsigned int) opcode < 0xe800u)
3969 return 2;
3970 else if ((unsigned int) opcode >= 0xe8000000u)
3971 return 4;
3972 else
3973 return 0;
3974}
3975
5b7c81bd 3976static bool
c921be7d
NC
3977emit_insn (expressionS *exp, int nbytes)
3978{
3979 int size = 0;
3980
3981 if (exp->X_op == O_constant)
3982 {
3983 size = nbytes;
3984
3985 if (size == 0)
3986 size = thumb_insn_size (exp->X_add_number);
3987
3988 if (size != 0)
3989 {
3990 if (size == 2 && (unsigned int)exp->X_add_number > 0xffffu)
3991 {
3992 as_bad (_(".inst.n operand too big. "\
3993 "Use .inst.w instead"));
3994 size = 0;
3995 }
3996 else
3997 {
5ee91343
AV
3998 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
3999 set_pred_insn_type_nonvoid (OUTSIDE_PRED_INSN, 0);
c921be7d 4000 else
5ee91343 4001 set_pred_insn_type_nonvoid (NEUTRAL_IT_INSN, 0);
c921be7d
NC
4002
4003 if (thumb_mode && (size > THUMB_SIZE) && !target_big_endian)
4004 emit_thumb32_expr (exp);
4005 else
4006 emit_expr (exp, (unsigned int) size);
4007
4008 it_fsm_post_encode ();
4009 }
4010 }
4011 else
4012 as_bad (_("cannot determine Thumb instruction size. " \
4013 "Use .inst.n/.inst.w instead"));
4014 }
4015 else
4016 as_bad (_("constant expression required"));
4017
4018 return (size != 0);
4019}
4020
4021/* Like s_arm_elf_cons but do not use md_cons_align and
4022 set the mapping state to MAP_ARM/MAP_THUMB. */
4023
4024static void
4025s_arm_elf_inst (int nbytes)
4026{
4027 if (is_it_end_of_statement ())
4028 {
4029 demand_empty_rest_of_line ();
4030 return;
4031 }
4032
4033 /* Calling mapping_state () here will not change ARM/THUMB,
4034 but will ensure not to be in DATA state. */
4035
4036 if (thumb_mode)
4037 mapping_state (MAP_THUMB);
4038 else
4039 {
4040 if (nbytes != 0)
4041 {
4042 as_bad (_("width suffixes are invalid in ARM mode"));
4043 ignore_rest_of_line ();
4044 return;
4045 }
4046
4047 nbytes = 4;
4048
4049 mapping_state (MAP_ARM);
4050 }
4051
13d414af
JB
4052 dwarf2_emit_insn (0);
4053
c921be7d
NC
4054 do
4055 {
4056 expressionS exp;
4057
4058 expression (& exp);
4059
4060 if (! emit_insn (& exp, nbytes))
4061 {
4062 ignore_rest_of_line ();
4063 return;
4064 }
4065 }
4066 while (*input_line_pointer++ == ',');
4067
4068 /* Put terminator back into stream. */
4069 input_line_pointer --;
4070 demand_empty_rest_of_line ();
4071}
b99bd4ef 4072
c19d1205 4073/* Parse a .rel31 directive. */
b99bd4ef 4074
c19d1205
ZW
4075static void
4076s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
4077{
4078 expressionS exp;
4079 char *p;
4080 valueT highbit;
b99bd4ef 4081
c19d1205
ZW
4082 highbit = 0;
4083 if (*input_line_pointer == '1')
4084 highbit = 0x80000000;
4085 else if (*input_line_pointer != '0')
4086 as_bad (_("expected 0 or 1"));
b99bd4ef 4087
c19d1205
ZW
4088 input_line_pointer++;
4089 if (*input_line_pointer != ',')
4090 as_bad (_("missing comma"));
4091 input_line_pointer++;
b99bd4ef 4092
c19d1205
ZW
4093#ifdef md_flush_pending_output
4094 md_flush_pending_output ();
4095#endif
b99bd4ef 4096
c19d1205
ZW
4097#ifdef md_cons_align
4098 md_cons_align (4);
4099#endif
b99bd4ef 4100
c19d1205 4101 mapping_state (MAP_DATA);
b99bd4ef 4102
c19d1205 4103 expression (&exp);
b99bd4ef 4104
c19d1205
ZW
4105 p = frag_more (4);
4106 md_number_to_chars (p, highbit, 4);
4107 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
4108 BFD_RELOC_ARM_PREL31);
b99bd4ef 4109
c19d1205 4110 demand_empty_rest_of_line ();
b99bd4ef
NC
4111}
4112
c19d1205 4113/* Directives: AEABI stack-unwind tables. */
b99bd4ef 4114
c19d1205 4115/* Parse an unwind_fnstart directive. Simply records the current location. */
b99bd4ef 4116
c19d1205
ZW
4117static void
4118s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
4119{
4120 demand_empty_rest_of_line ();
921e5f0a
PB
4121 if (unwind.proc_start)
4122 {
c921be7d 4123 as_bad (_("duplicate .fnstart directive"));
921e5f0a
PB
4124 return;
4125 }
4126
c19d1205
ZW
4127 /* Mark the start of the function. */
4128 unwind.proc_start = expr_build_dot ();
b99bd4ef 4129
c19d1205
ZW
4130 /* Reset the rest of the unwind info. */
4131 unwind.opcode_count = 0;
4132 unwind.table_entry = NULL;
4133 unwind.personality_routine = NULL;
4134 unwind.personality_index = -1;
4135 unwind.frame_size = 0;
4136 unwind.fp_offset = 0;
fdfde340 4137 unwind.fp_reg = REG_SP;
c19d1205
ZW
4138 unwind.fp_used = 0;
4139 unwind.sp_restored = 0;
4140}
b99bd4ef 4141
b99bd4ef 4142
c19d1205
ZW
4143/* Parse a handlerdata directive. Creates the exception handling table entry
4144 for the function. */
b99bd4ef 4145
c19d1205
ZW
4146static void
4147s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
4148{
4149 demand_empty_rest_of_line ();
921e5f0a 4150 if (!unwind.proc_start)
c921be7d 4151 as_bad (MISSING_FNSTART);
921e5f0a 4152
c19d1205 4153 if (unwind.table_entry)
6decc662 4154 as_bad (_("duplicate .handlerdata directive"));
f02232aa 4155
c19d1205
ZW
4156 create_unwind_entry (1);
4157}
a737bd4d 4158
c19d1205 4159/* Parse an unwind_fnend directive. Generates the index table entry. */
b99bd4ef 4160
c19d1205
ZW
4161static void
4162s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
4163{
4164 long where;
4165 char *ptr;
4166 valueT val;
940b5ce0 4167 unsigned int marked_pr_dependency;
f02232aa 4168
c19d1205 4169 demand_empty_rest_of_line ();
f02232aa 4170
921e5f0a
PB
4171 if (!unwind.proc_start)
4172 {
c921be7d 4173 as_bad (_(".fnend directive without .fnstart"));
921e5f0a
PB
4174 return;
4175 }
4176
c19d1205
ZW
4177 /* Add eh table entry. */
4178 if (unwind.table_entry == NULL)
4179 val = create_unwind_entry (0);
4180 else
4181 val = 0;
f02232aa 4182
c19d1205
ZW
4183 /* Add index table entry. This is two words. */
4184 start_unwind_section (unwind.saved_seg, 1);
4185 frag_align (2, 0, 0);
4186 record_alignment (now_seg, 2);
b99bd4ef 4187
c19d1205 4188 ptr = frag_more (8);
5011093d 4189 memset (ptr, 0, 8);
c19d1205 4190 where = frag_now_fix () - 8;
f02232aa 4191
c19d1205
ZW
4192 /* Self relative offset of the function start. */
4193 fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
4194 BFD_RELOC_ARM_PREL31);
f02232aa 4195
c19d1205
ZW
4196 /* Indicate dependency on EHABI-defined personality routines to the
4197 linker, if it hasn't been done already. */
940b5ce0
DJ
4198 marked_pr_dependency
4199 = seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency;
c19d1205
ZW
4200 if (unwind.personality_index >= 0 && unwind.personality_index < 3
4201 && !(marked_pr_dependency & (1 << unwind.personality_index)))
4202 {
5f4273c7
NC
4203 static const char *const name[] =
4204 {
4205 "__aeabi_unwind_cpp_pr0",
4206 "__aeabi_unwind_cpp_pr1",
4207 "__aeabi_unwind_cpp_pr2"
4208 };
c19d1205
ZW
4209 symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
4210 fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
c19d1205 4211 seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
940b5ce0 4212 |= 1 << unwind.personality_index;
c19d1205 4213 }
f02232aa 4214
c19d1205
ZW
4215 if (val)
4216 /* Inline exception table entry. */
4217 md_number_to_chars (ptr + 4, val, 4);
4218 else
4219 /* Self relative offset of the table entry. */
4220 fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
4221 BFD_RELOC_ARM_PREL31);
f02232aa 4222
c19d1205
ZW
4223 /* Restore the original section. */
4224 subseg_set (unwind.saved_seg, unwind.saved_subseg);
921e5f0a
PB
4225
4226 unwind.proc_start = NULL;
c19d1205 4227}
f02232aa 4228
f02232aa 4229
c19d1205 4230/* Parse an unwind_cantunwind directive. */
b99bd4ef 4231
c19d1205
ZW
4232static void
4233s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
4234{
4235 demand_empty_rest_of_line ();
921e5f0a 4236 if (!unwind.proc_start)
c921be7d 4237 as_bad (MISSING_FNSTART);
921e5f0a 4238
c19d1205
ZW
4239 if (unwind.personality_routine || unwind.personality_index != -1)
4240 as_bad (_("personality routine specified for cantunwind frame"));
b99bd4ef 4241
c19d1205
ZW
4242 unwind.personality_index = -2;
4243}
b99bd4ef 4244
b99bd4ef 4245
c19d1205 4246/* Parse a personalityindex directive. */
b99bd4ef 4247
c19d1205
ZW
4248static void
4249s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
4250{
4251 expressionS exp;
b99bd4ef 4252
921e5f0a 4253 if (!unwind.proc_start)
c921be7d 4254 as_bad (MISSING_FNSTART);
921e5f0a 4255
c19d1205
ZW
4256 if (unwind.personality_routine || unwind.personality_index != -1)
4257 as_bad (_("duplicate .personalityindex directive"));
b99bd4ef 4258
c19d1205 4259 expression (&exp);
b99bd4ef 4260
c19d1205
ZW
4261 if (exp.X_op != O_constant
4262 || exp.X_add_number < 0 || exp.X_add_number > 15)
b99bd4ef 4263 {
c19d1205
ZW
4264 as_bad (_("bad personality routine number"));
4265 ignore_rest_of_line ();
4266 return;
b99bd4ef
NC
4267 }
4268
c19d1205 4269 unwind.personality_index = exp.X_add_number;
b99bd4ef 4270
c19d1205
ZW
4271 demand_empty_rest_of_line ();
4272}
e16bb312 4273
e16bb312 4274
c19d1205 4275/* Parse a personality directive. */
e16bb312 4276
c19d1205
ZW
4277static void
4278s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
4279{
4280 char *name, *p, c;
a737bd4d 4281
921e5f0a 4282 if (!unwind.proc_start)
c921be7d 4283 as_bad (MISSING_FNSTART);
921e5f0a 4284
c19d1205
ZW
4285 if (unwind.personality_routine || unwind.personality_index != -1)
4286 as_bad (_("duplicate .personality directive"));
a737bd4d 4287
d02603dc 4288 c = get_symbol_name (& name);
c19d1205 4289 p = input_line_pointer;
d02603dc
NC
4290 if (c == '"')
4291 ++ input_line_pointer;
c19d1205
ZW
4292 unwind.personality_routine = symbol_find_or_make (name);
4293 *p = c;
4294 demand_empty_rest_of_line ();
4295}
e16bb312 4296
8c299995
TB
4297/* Parse a directive saving pseudo registers. */
4298
4299static void
3363d856 4300s_arm_unwind_save_pseudo (long range)
8c299995
TB
4301{
4302 valueT op;
8c299995 4303
3363d856 4304 if (range & (1 << 12))
8c299995
TB
4305 {
4306 /* Opcode for restoring RA_AUTH_CODE. */
4307 op = 0xb4;
4308 add_unwind_opcode (op, 1);
4309 }
4310}
4311
e16bb312 4312
c19d1205 4313/* Parse a directive saving core registers. */
e16bb312 4314
c19d1205 4315static void
3363d856 4316s_arm_unwind_save_core (long range)
e16bb312 4317{
c19d1205 4318 valueT op;
c19d1205 4319 int n;
e16bb312 4320
c19d1205
ZW
4321 /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
4322 into .unwind_save {..., sp...}. We aren't bothered about the value of
4323 ip because it is clobbered by calls. */
4324 if (unwind.sp_restored && unwind.fp_reg == 12
4325 && (range & 0x3000) == 0x1000)
4326 {
4327 unwind.opcode_count--;
4328 unwind.sp_restored = 0;
4329 range = (range | 0x2000) & ~0x1000;
4330 unwind.pending_offset = 0;
4331 }
e16bb312 4332
01ae4198
DJ
4333 /* Pop r4-r15. */
4334 if (range & 0xfff0)
c19d1205 4335 {
01ae4198
DJ
4336 /* See if we can use the short opcodes. These pop a block of up to 8
4337 registers starting with r4, plus maybe r14. */
4338 for (n = 0; n < 8; n++)
4339 {
4340 /* Break at the first non-saved register. */
4341 if ((range & (1 << (n + 4))) == 0)
4342 break;
4343 }
4344 /* See if there are any other bits set. */
4345 if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
4346 {
4347 /* Use the long form. */
4348 op = 0x8000 | ((range >> 4) & 0xfff);
4349 add_unwind_opcode (op, 2);
4350 }
0dd132b6 4351 else
01ae4198
DJ
4352 {
4353 /* Use the short form. */
4354 if (range & 0x4000)
4355 op = 0xa8; /* Pop r14. */
4356 else
4357 op = 0xa0; /* Do not pop r14. */
4358 op |= (n - 1);
4359 add_unwind_opcode (op, 1);
4360 }
c19d1205 4361 }
0dd132b6 4362
c19d1205
ZW
4363 /* Pop r0-r3. */
4364 if (range & 0xf)
4365 {
4366 op = 0xb100 | (range & 0xf);
4367 add_unwind_opcode (op, 2);
0dd132b6
NC
4368 }
4369
c19d1205
ZW
4370 /* Record the number of bytes pushed. */
4371 for (n = 0; n < 16; n++)
4372 {
4373 if (range & (1 << n))
4374 unwind.frame_size += 4;
4375 }
0dd132b6
NC
4376}
4377
c19d1205
ZW
4378
4379/* Parse a directive saving FPA registers. */
b99bd4ef
NC
4380
4381static void
c19d1205 4382s_arm_unwind_save_fpa (int reg)
b99bd4ef 4383{
c19d1205
ZW
4384 expressionS exp;
4385 int num_regs;
4386 valueT op;
b99bd4ef 4387
c19d1205
ZW
4388 /* Get Number of registers to transfer. */
4389 if (skip_past_comma (&input_line_pointer) != FAIL)
4390 expression (&exp);
4391 else
4392 exp.X_op = O_illegal;
b99bd4ef 4393
c19d1205 4394 if (exp.X_op != O_constant)
b99bd4ef 4395 {
c19d1205
ZW
4396 as_bad (_("expected , <constant>"));
4397 ignore_rest_of_line ();
b99bd4ef
NC
4398 return;
4399 }
4400
c19d1205
ZW
4401 num_regs = exp.X_add_number;
4402
4403 if (num_regs < 1 || num_regs > 4)
b99bd4ef 4404 {
c19d1205
ZW
4405 as_bad (_("number of registers must be in the range [1:4]"));
4406 ignore_rest_of_line ();
b99bd4ef
NC
4407 return;
4408 }
4409
c19d1205 4410 demand_empty_rest_of_line ();
b99bd4ef 4411
c19d1205
ZW
4412 if (reg == 4)
4413 {
4414 /* Short form. */
4415 op = 0xb4 | (num_regs - 1);
4416 add_unwind_opcode (op, 1);
4417 }
b99bd4ef
NC
4418 else
4419 {
c19d1205
ZW
4420 /* Long form. */
4421 op = 0xc800 | (reg << 4) | (num_regs - 1);
4422 add_unwind_opcode (op, 2);
b99bd4ef 4423 }
c19d1205 4424 unwind.frame_size += num_regs * 12;
b99bd4ef
NC
4425}
4426
c19d1205 4427
fa073d69
MS
4428/* Parse a directive saving VFP registers for ARMv6 and above. */
4429
4430static void
4431s_arm_unwind_save_vfp_armv6 (void)
4432{
4433 int count;
4434 unsigned int start;
4435 valueT op;
4436 int num_vfpv3_regs = 0;
4437 int num_regs_below_16;
5b7c81bd 4438 bool partial_match;
fa073d69 4439
efd6b359
AV
4440 count = parse_vfp_reg_list (&input_line_pointer, &start, REGLIST_VFP_D,
4441 &partial_match);
fa073d69
MS
4442 if (count == FAIL)
4443 {
4444 as_bad (_("expected register list"));
4445 ignore_rest_of_line ();
4446 return;
4447 }
4448
4449 demand_empty_rest_of_line ();
4450
4451 /* We always generate FSTMD/FLDMD-style unwinding opcodes (rather
4452 than FSTMX/FLDMX-style ones). */
4453
4454 /* Generate opcode for (VFPv3) registers numbered in the range 16 .. 31. */
4455 if (start >= 16)
4456 num_vfpv3_regs = count;
4457 else if (start + count > 16)
4458 num_vfpv3_regs = start + count - 16;
4459
4460 if (num_vfpv3_regs > 0)
4461 {
4462 int start_offset = start > 16 ? start - 16 : 0;
4463 op = 0xc800 | (start_offset << 4) | (num_vfpv3_regs - 1);
4464 add_unwind_opcode (op, 2);
4465 }
4466
4467 /* Generate opcode for registers numbered in the range 0 .. 15. */
4468 num_regs_below_16 = num_vfpv3_regs > 0 ? 16 - (int) start : count;
9c2799c2 4469 gas_assert (num_regs_below_16 + num_vfpv3_regs == count);
fa073d69
MS
4470 if (num_regs_below_16 > 0)
4471 {
4472 op = 0xc900 | (start << 4) | (num_regs_below_16 - 1);
4473 add_unwind_opcode (op, 2);
4474 }
4475
4476 unwind.frame_size += count * 8;
4477}
4478
4479
4480/* Parse a directive saving VFP registers for pre-ARMv6. */
b99bd4ef
NC
4481
4482static void
c19d1205 4483s_arm_unwind_save_vfp (void)
b99bd4ef 4484{
c19d1205 4485 int count;
ca3f61f7 4486 unsigned int reg;
c19d1205 4487 valueT op;
5b7c81bd 4488 bool partial_match;
b99bd4ef 4489
efd6b359
AV
4490 count = parse_vfp_reg_list (&input_line_pointer, &reg, REGLIST_VFP_D,
4491 &partial_match);
c19d1205 4492 if (count == FAIL)
b99bd4ef 4493 {
c19d1205
ZW
4494 as_bad (_("expected register list"));
4495 ignore_rest_of_line ();
b99bd4ef
NC
4496 return;
4497 }
4498
c19d1205 4499 demand_empty_rest_of_line ();
b99bd4ef 4500
c19d1205 4501 if (reg == 8)
b99bd4ef 4502 {
c19d1205
ZW
4503 /* Short form. */
4504 op = 0xb8 | (count - 1);
4505 add_unwind_opcode (op, 1);
b99bd4ef 4506 }
c19d1205 4507 else
b99bd4ef 4508 {
c19d1205
ZW
4509 /* Long form. */
4510 op = 0xb300 | (reg << 4) | (count - 1);
4511 add_unwind_opcode (op, 2);
b99bd4ef 4512 }
c19d1205
ZW
4513 unwind.frame_size += count * 8 + 4;
4514}
b99bd4ef 4515
b99bd4ef 4516
c19d1205
ZW
4517/* Parse a directive saving iWMMXt data registers. */
4518
4519static void
4520s_arm_unwind_save_mmxwr (void)
4521{
4522 int reg;
4523 int hi_reg;
4524 int i;
4525 unsigned mask = 0;
4526 valueT op;
b99bd4ef 4527
c19d1205
ZW
4528 if (*input_line_pointer == '{')
4529 input_line_pointer++;
b99bd4ef 4530
c19d1205 4531 do
b99bd4ef 4532 {
dcbf9037 4533 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
b99bd4ef 4534
c19d1205 4535 if (reg == FAIL)
b99bd4ef 4536 {
9b7132d3 4537 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205 4538 goto error;
b99bd4ef
NC
4539 }
4540
c19d1205
ZW
4541 if (mask >> reg)
4542 as_tsktsk (_("register list not in ascending order"));
4543 mask |= 1 << reg;
b99bd4ef 4544
c19d1205
ZW
4545 if (*input_line_pointer == '-')
4546 {
4547 input_line_pointer++;
dcbf9037 4548 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
c19d1205
ZW
4549 if (hi_reg == FAIL)
4550 {
9b7132d3 4551 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205
ZW
4552 goto error;
4553 }
4554 else if (reg >= hi_reg)
4555 {
4556 as_bad (_("bad register range"));
4557 goto error;
4558 }
4559 for (; reg < hi_reg; reg++)
4560 mask |= 1 << reg;
4561 }
4562 }
4563 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4564
d996d970 4565 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4566
c19d1205 4567 demand_empty_rest_of_line ();
b99bd4ef 4568
708587a4 4569 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4570 the list. */
4571 flush_pending_unwind ();
b99bd4ef 4572
c19d1205 4573 for (i = 0; i < 16; i++)
b99bd4ef 4574 {
c19d1205
ZW
4575 if (mask & (1 << i))
4576 unwind.frame_size += 8;
b99bd4ef
NC
4577 }
4578
c19d1205
ZW
4579 /* Attempt to combine with a previous opcode. We do this because gcc
4580 likes to output separate unwind directives for a single block of
4581 registers. */
4582 if (unwind.opcode_count > 0)
b99bd4ef 4583 {
c19d1205
ZW
4584 i = unwind.opcodes[unwind.opcode_count - 1];
4585 if ((i & 0xf8) == 0xc0)
4586 {
4587 i &= 7;
4588 /* Only merge if the blocks are contiguous. */
4589 if (i < 6)
4590 {
4591 if ((mask & 0xfe00) == (1 << 9))
4592 {
4593 mask |= ((1 << (i + 11)) - 1) & 0xfc00;
4594 unwind.opcode_count--;
4595 }
4596 }
4597 else if (i == 6 && unwind.opcode_count >= 2)
4598 {
4599 i = unwind.opcodes[unwind.opcode_count - 2];
4600 reg = i >> 4;
4601 i &= 0xf;
b99bd4ef 4602
c19d1205
ZW
4603 op = 0xffff << (reg - 1);
4604 if (reg > 0
87a1fd79 4605 && ((mask & op) == (1u << (reg - 1))))
c19d1205
ZW
4606 {
4607 op = (1 << (reg + i + 1)) - 1;
4608 op &= ~((1 << reg) - 1);
4609 mask |= op;
4610 unwind.opcode_count -= 2;
4611 }
4612 }
4613 }
b99bd4ef
NC
4614 }
4615
c19d1205
ZW
4616 hi_reg = 15;
4617 /* We want to generate opcodes in the order the registers have been
4618 saved, ie. descending order. */
4619 for (reg = 15; reg >= -1; reg--)
b99bd4ef 4620 {
c19d1205
ZW
4621 /* Save registers in blocks. */
4622 if (reg < 0
4623 || !(mask & (1 << reg)))
4624 {
4625 /* We found an unsaved reg. Generate opcodes to save the
5f4273c7 4626 preceding block. */
c19d1205
ZW
4627 if (reg != hi_reg)
4628 {
4629 if (reg == 9)
4630 {
4631 /* Short form. */
4632 op = 0xc0 | (hi_reg - 10);
4633 add_unwind_opcode (op, 1);
4634 }
4635 else
4636 {
4637 /* Long form. */
4638 op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
4639 add_unwind_opcode (op, 2);
4640 }
4641 }
4642 hi_reg = reg - 1;
4643 }
b99bd4ef
NC
4644 }
4645
c19d1205 4646 return;
dc1e8a47 4647 error:
c19d1205 4648 ignore_rest_of_line ();
b99bd4ef
NC
4649}
4650
4651static void
c19d1205 4652s_arm_unwind_save_mmxwcg (void)
b99bd4ef 4653{
c19d1205
ZW
4654 int reg;
4655 int hi_reg;
4656 unsigned mask = 0;
4657 valueT op;
b99bd4ef 4658
c19d1205
ZW
4659 if (*input_line_pointer == '{')
4660 input_line_pointer++;
b99bd4ef 4661
477330fc
RM
4662 skip_whitespace (input_line_pointer);
4663
c19d1205 4664 do
b99bd4ef 4665 {
dcbf9037 4666 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
b99bd4ef 4667
c19d1205
ZW
4668 if (reg == FAIL)
4669 {
9b7132d3 4670 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4671 goto error;
4672 }
b99bd4ef 4673
c19d1205
ZW
4674 reg -= 8;
4675 if (mask >> reg)
4676 as_tsktsk (_("register list not in ascending order"));
4677 mask |= 1 << reg;
b99bd4ef 4678
c19d1205
ZW
4679 if (*input_line_pointer == '-')
4680 {
4681 input_line_pointer++;
dcbf9037 4682 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
c19d1205
ZW
4683 if (hi_reg == FAIL)
4684 {
9b7132d3 4685 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4686 goto error;
4687 }
4688 else if (reg >= hi_reg)
4689 {
4690 as_bad (_("bad register range"));
4691 goto error;
4692 }
4693 for (; reg < hi_reg; reg++)
4694 mask |= 1 << reg;
4695 }
b99bd4ef 4696 }
c19d1205 4697 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4698
d996d970 4699 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4700
c19d1205
ZW
4701 demand_empty_rest_of_line ();
4702
708587a4 4703 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4704 the list. */
4705 flush_pending_unwind ();
b99bd4ef 4706
c19d1205 4707 for (reg = 0; reg < 16; reg++)
b99bd4ef 4708 {
c19d1205
ZW
4709 if (mask & (1 << reg))
4710 unwind.frame_size += 4;
b99bd4ef 4711 }
c19d1205
ZW
4712 op = 0xc700 | mask;
4713 add_unwind_opcode (op, 2);
4714 return;
dc1e8a47 4715 error:
c19d1205 4716 ignore_rest_of_line ();
b99bd4ef
NC
4717}
4718
20d81420
RE
4719/* Convert range and mask_range into a sequence of s_arm_unwind_core
4720 and s_arm_unwind_pseudo operations. We assume that mask_range will
4721 not have consecutive bits set, or that one operation per bit is
4722 acceptable. */
4723
3363d856
VDN
4724static void
4725s_arm_unwind_save_mixed (long range, long mask_range)
4726{
20d81420 4727 while (mask_range)
3363d856 4728 {
20d81420
RE
4729 long mask_bit = mask_range & -mask_range;
4730 long subrange = range & (mask_bit - 1);
3363d856 4731
20d81420
RE
4732 if (subrange)
4733 s_arm_unwind_save_core (subrange);
3363d856 4734
20d81420
RE
4735 s_arm_unwind_save_pseudo (mask_bit);
4736 range &= ~subrange;
4737 mask_range &= ~mask_bit;
3363d856
VDN
4738 }
4739
20d81420
RE
4740 if (range)
4741 s_arm_unwind_save_core (range);
3363d856 4742}
c19d1205 4743
fa073d69
MS
4744/* Parse an unwind_save directive.
4745 If the argument is non-zero, this is a .vsave directive. */
c19d1205 4746
b99bd4ef 4747static void
fa073d69 4748s_arm_unwind_save (int arch_v6)
b99bd4ef 4749{
3363d856
VDN
4750 char *peek, *mask_peek;
4751 long range, mask_range;
c19d1205 4752 struct reg_entry *reg;
5b7c81bd 4753 bool had_brace = false;
b99bd4ef 4754
921e5f0a 4755 if (!unwind.proc_start)
c921be7d 4756 as_bad (MISSING_FNSTART);
921e5f0a 4757
c19d1205 4758 /* Figure out what sort of save we have. */
3363d856 4759 peek = mask_peek = input_line_pointer;
b99bd4ef 4760
c19d1205 4761 if (*peek == '{')
b99bd4ef 4762 {
5b7c81bd 4763 had_brace = true;
c19d1205 4764 peek++;
b99bd4ef
NC
4765 }
4766
c19d1205 4767 reg = arm_reg_parse_multi (&peek);
b99bd4ef 4768
c19d1205 4769 if (!reg)
b99bd4ef 4770 {
c19d1205
ZW
4771 as_bad (_("register expected"));
4772 ignore_rest_of_line ();
b99bd4ef
NC
4773 return;
4774 }
4775
c19d1205 4776 switch (reg->type)
b99bd4ef 4777 {
c19d1205
ZW
4778 case REG_TYPE_FN:
4779 if (had_brace)
4780 {
4781 as_bad (_("FPA .unwind_save does not take a register list"));
4782 ignore_rest_of_line ();
4783 return;
4784 }
93ac2687 4785 input_line_pointer = peek;
c19d1205 4786 s_arm_unwind_save_fpa (reg->number);
b99bd4ef 4787 return;
c19d1205 4788
3363d856 4789 case REG_TYPE_PSEUDO:
1f5afe1c 4790 case REG_TYPE_RN:
3363d856
VDN
4791 mask_range = parse_reg_list (&mask_peek, REGLIST_PSEUDO);
4792 range = parse_reg_list (&input_line_pointer, REGLIST_RN);
1f5afe1c 4793
3363d856
VDN
4794 if (range == FAIL || mask_range == FAIL)
4795 {
4796 as_bad (_("expected register list"));
4797 ignore_rest_of_line ();
4798 return;
4799 }
4800
4801 demand_empty_rest_of_line ();
4802
20d81420
RE
4803 s_arm_unwind_save_mixed (range, mask_range);
4804 return;
8c299995 4805
fa073d69
MS
4806 case REG_TYPE_VFD:
4807 if (arch_v6)
477330fc 4808 s_arm_unwind_save_vfp_armv6 ();
fa073d69 4809 else
477330fc 4810 s_arm_unwind_save_vfp ();
fa073d69 4811 return;
1f5afe1c
NC
4812
4813 case REG_TYPE_MMXWR:
4814 s_arm_unwind_save_mmxwr ();
4815 return;
4816
4817 case REG_TYPE_MMXWCG:
4818 s_arm_unwind_save_mmxwcg ();
4819 return;
c19d1205
ZW
4820
4821 default:
4822 as_bad (_(".unwind_save does not support this kind of register"));
4823 ignore_rest_of_line ();
b99bd4ef 4824 }
c19d1205 4825}
b99bd4ef 4826
b99bd4ef 4827
c19d1205
ZW
4828/* Parse an unwind_movsp directive. */
4829
4830static void
4831s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
4832{
4833 int reg;
4834 valueT op;
4fa3602b 4835 int offset;
c19d1205 4836
921e5f0a 4837 if (!unwind.proc_start)
c921be7d 4838 as_bad (MISSING_FNSTART);
921e5f0a 4839
dcbf9037 4840 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205 4841 if (reg == FAIL)
b99bd4ef 4842 {
9b7132d3 4843 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_RN]));
c19d1205 4844 ignore_rest_of_line ();
b99bd4ef
NC
4845 return;
4846 }
4fa3602b
PB
4847
4848 /* Optional constant. */
4849 if (skip_past_comma (&input_line_pointer) != FAIL)
4850 {
4851 if (immediate_for_directive (&offset) == FAIL)
4852 return;
4853 }
4854 else
4855 offset = 0;
4856
c19d1205 4857 demand_empty_rest_of_line ();
b99bd4ef 4858
c19d1205 4859 if (reg == REG_SP || reg == REG_PC)
b99bd4ef 4860 {
c19d1205 4861 as_bad (_("SP and PC not permitted in .unwind_movsp directive"));
b99bd4ef
NC
4862 return;
4863 }
4864
c19d1205
ZW
4865 if (unwind.fp_reg != REG_SP)
4866 as_bad (_("unexpected .unwind_movsp directive"));
b99bd4ef 4867
c19d1205
ZW
4868 /* Generate opcode to restore the value. */
4869 op = 0x90 | reg;
4870 add_unwind_opcode (op, 1);
4871
4872 /* Record the information for later. */
4873 unwind.fp_reg = reg;
4fa3602b 4874 unwind.fp_offset = unwind.frame_size - offset;
c19d1205 4875 unwind.sp_restored = 1;
b05fe5cf
ZW
4876}
4877
c19d1205
ZW
4878/* Parse an unwind_pad directive. */
4879
b05fe5cf 4880static void
c19d1205 4881s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
b05fe5cf 4882{
c19d1205 4883 int offset;
b05fe5cf 4884
921e5f0a 4885 if (!unwind.proc_start)
c921be7d 4886 as_bad (MISSING_FNSTART);
921e5f0a 4887
c19d1205
ZW
4888 if (immediate_for_directive (&offset) == FAIL)
4889 return;
b99bd4ef 4890
c19d1205
ZW
4891 if (offset & 3)
4892 {
4893 as_bad (_("stack increment must be multiple of 4"));
4894 ignore_rest_of_line ();
4895 return;
4896 }
b99bd4ef 4897
c19d1205
ZW
4898 /* Don't generate any opcodes, just record the details for later. */
4899 unwind.frame_size += offset;
4900 unwind.pending_offset += offset;
4901
4902 demand_empty_rest_of_line ();
4903}
4904
4905/* Parse an unwind_setfp directive. */
4906
4907static void
4908s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 4909{
c19d1205
ZW
4910 int sp_reg;
4911 int fp_reg;
4912 int offset;
4913
921e5f0a 4914 if (!unwind.proc_start)
c921be7d 4915 as_bad (MISSING_FNSTART);
921e5f0a 4916
dcbf9037 4917 fp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205
ZW
4918 if (skip_past_comma (&input_line_pointer) == FAIL)
4919 sp_reg = FAIL;
4920 else
dcbf9037 4921 sp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
b99bd4ef 4922
c19d1205
ZW
4923 if (fp_reg == FAIL || sp_reg == FAIL)
4924 {
4925 as_bad (_("expected <reg>, <reg>"));
4926 ignore_rest_of_line ();
4927 return;
4928 }
b99bd4ef 4929
c19d1205
ZW
4930 /* Optional constant. */
4931 if (skip_past_comma (&input_line_pointer) != FAIL)
4932 {
4933 if (immediate_for_directive (&offset) == FAIL)
4934 return;
4935 }
4936 else
4937 offset = 0;
a737bd4d 4938
c19d1205 4939 demand_empty_rest_of_line ();
a737bd4d 4940
fdfde340 4941 if (sp_reg != REG_SP && sp_reg != unwind.fp_reg)
a737bd4d 4942 {
c19d1205
ZW
4943 as_bad (_("register must be either sp or set by a previous"
4944 "unwind_movsp directive"));
4945 return;
a737bd4d
NC
4946 }
4947
c19d1205
ZW
4948 /* Don't generate any opcodes, just record the information for later. */
4949 unwind.fp_reg = fp_reg;
4950 unwind.fp_used = 1;
fdfde340 4951 if (sp_reg == REG_SP)
c19d1205
ZW
4952 unwind.fp_offset = unwind.frame_size - offset;
4953 else
4954 unwind.fp_offset -= offset;
a737bd4d
NC
4955}
4956
c19d1205
ZW
4957/* Parse an unwind_raw directive. */
4958
4959static void
4960s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
a737bd4d 4961{
c19d1205 4962 expressionS exp;
708587a4 4963 /* This is an arbitrary limit. */
c19d1205
ZW
4964 unsigned char op[16];
4965 int count;
a737bd4d 4966
921e5f0a 4967 if (!unwind.proc_start)
c921be7d 4968 as_bad (MISSING_FNSTART);
921e5f0a 4969
c19d1205
ZW
4970 expression (&exp);
4971 if (exp.X_op == O_constant
4972 && skip_past_comma (&input_line_pointer) != FAIL)
a737bd4d 4973 {
c19d1205
ZW
4974 unwind.frame_size += exp.X_add_number;
4975 expression (&exp);
4976 }
4977 else
4978 exp.X_op = O_illegal;
a737bd4d 4979
c19d1205
ZW
4980 if (exp.X_op != O_constant)
4981 {
4982 as_bad (_("expected <offset>, <opcode>"));
4983 ignore_rest_of_line ();
4984 return;
4985 }
a737bd4d 4986
c19d1205 4987 count = 0;
a737bd4d 4988
c19d1205
ZW
4989 /* Parse the opcode. */
4990 for (;;)
4991 {
4992 if (count >= 16)
4993 {
4994 as_bad (_("unwind opcode too long"));
4995 ignore_rest_of_line ();
a737bd4d 4996 }
c19d1205 4997 if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
a737bd4d 4998 {
c19d1205
ZW
4999 as_bad (_("invalid unwind opcode"));
5000 ignore_rest_of_line ();
5001 return;
a737bd4d 5002 }
c19d1205 5003 op[count++] = exp.X_add_number;
a737bd4d 5004
c19d1205
ZW
5005 /* Parse the next byte. */
5006 if (skip_past_comma (&input_line_pointer) == FAIL)
5007 break;
a737bd4d 5008
c19d1205
ZW
5009 expression (&exp);
5010 }
b99bd4ef 5011
c19d1205
ZW
5012 /* Add the opcode bytes in reverse order. */
5013 while (count--)
5014 add_unwind_opcode (op[count], 1);
b99bd4ef 5015
c19d1205 5016 demand_empty_rest_of_line ();
b99bd4ef 5017}
ee065d83
PB
5018
5019
5020/* Parse a .eabi_attribute directive. */
5021
5022static void
5023s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
5024{
0420f52b 5025 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
ee3c0378 5026
3076e594 5027 if (tag >= 0 && tag < NUM_KNOWN_OBJ_ATTRIBUTES)
ee3c0378 5028 attributes_set_explicitly[tag] = 1;
ee065d83
PB
5029}
5030
0855e32b
NS
5031/* Emit a tls fix for the symbol. */
5032
5033static void
5034s_arm_tls_descseq (int ignored ATTRIBUTE_UNUSED)
5035{
5036 char *p;
5037 expressionS exp;
5038#ifdef md_flush_pending_output
5039 md_flush_pending_output ();
5040#endif
5041
5042#ifdef md_cons_align
5043 md_cons_align (4);
5044#endif
5045
5046 /* Since we're just labelling the code, there's no need to define a
5047 mapping symbol. */
5048 expression (&exp);
5049 p = obstack_next_free (&frchain_now->frch_obstack);
5050 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
5051 thumb_mode ? BFD_RELOC_ARM_THM_TLS_DESCSEQ
5052 : BFD_RELOC_ARM_TLS_DESCSEQ);
5053}
cdf9ccec 5054#endif /* OBJ_ELF */
0855e32b 5055
ee065d83 5056static void s_arm_arch (int);
7a1d4c38 5057static void s_arm_object_arch (int);
ee065d83
PB
5058static void s_arm_cpu (int);
5059static void s_arm_fpu (int);
69133863 5060static void s_arm_arch_extension (int);
b99bd4ef 5061
f0927246
NC
5062#ifdef TE_PE
5063
5064static void
5f4273c7 5065pe_directive_secrel (int dummy ATTRIBUTE_UNUSED)
f0927246
NC
5066{
5067 expressionS exp;
5068
5069 do
5070 {
5071 expression (&exp);
5072 if (exp.X_op == O_symbol)
5073 exp.X_op = O_secrel;
5074
5075 emit_expr (&exp, 4);
5076 }
5077 while (*input_line_pointer++ == ',');
5078
5079 input_line_pointer--;
5080 demand_empty_rest_of_line ();
5081}
5082#endif /* TE_PE */
5083
5312fe52
BW
5084int
5085arm_is_largest_exponent_ok (int precision)
5086{
5087 /* precision == 1 ensures that this will only return
5088 true for 16 bit floats. */
5089 return (precision == 1) && (fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
5090}
5091
5092static void
5093set_fp16_format (int dummy ATTRIBUTE_UNUSED)
5094{
5095 char saved_char;
5096 char* name;
5097 enum fp_16bit_format new_format;
5098
5099 new_format = ARM_FP16_FORMAT_DEFAULT;
5100
5101 name = input_line_pointer;
5102 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
5103 input_line_pointer++;
5104
5105 saved_char = *input_line_pointer;
5106 *input_line_pointer = 0;
5107
5108 if (strcasecmp (name, "ieee") == 0)
5109 new_format = ARM_FP16_FORMAT_IEEE;
5110 else if (strcasecmp (name, "alternative") == 0)
5111 new_format = ARM_FP16_FORMAT_ALTERNATIVE;
5112 else
5113 {
5114 as_bad (_("unrecognised float16 format \"%s\""), name);
5115 goto cleanup;
5116 }
5117
5118 /* Only set fp16_format if it is still the default (aka not already
5119 been set yet). */
5120 if (fp16_format == ARM_FP16_FORMAT_DEFAULT)
5121 fp16_format = new_format;
5122 else
5123 {
5124 if (new_format != fp16_format)
5125 as_warn (_("float16 format cannot be set more than once, ignoring."));
5126 }
5127
dc1e8a47 5128 cleanup:
5312fe52
BW
5129 *input_line_pointer = saved_char;
5130 ignore_rest_of_line ();
5131}
5132
c19d1205
ZW
5133/* This table describes all the machine specific pseudo-ops the assembler
5134 has to support. The fields are:
5135 pseudo-op name without dot
5136 function to call to execute this pseudo-op
5137 Integer arg to pass to the function. */
b99bd4ef 5138
c19d1205 5139const pseudo_typeS md_pseudo_table[] =
b99bd4ef 5140{
c19d1205
ZW
5141 /* Never called because '.req' does not start a line. */
5142 { "req", s_req, 0 },
dcbf9037
JB
5143 /* Following two are likewise never called. */
5144 { "dn", s_dn, 0 },
5145 { "qn", s_qn, 0 },
c19d1205
ZW
5146 { "unreq", s_unreq, 0 },
5147 { "bss", s_bss, 0 },
db2ed2e0 5148 { "align", s_align_ptwo, 2 },
c19d1205
ZW
5149 { "arm", s_arm, 0 },
5150 { "thumb", s_thumb, 0 },
5151 { "code", s_code, 0 },
5152 { "force_thumb", s_force_thumb, 0 },
5153 { "thumb_func", s_thumb_func, 0 },
5154 { "thumb_set", s_thumb_set, 0 },
5155 { "even", s_even, 0 },
5156 { "ltorg", s_ltorg, 0 },
5157 { "pool", s_ltorg, 0 },
5158 { "syntax", s_syntax, 0 },
8463be01
PB
5159 { "cpu", s_arm_cpu, 0 },
5160 { "arch", s_arm_arch, 0 },
7a1d4c38 5161 { "object_arch", s_arm_object_arch, 0 },
8463be01 5162 { "fpu", s_arm_fpu, 0 },
69133863 5163 { "arch_extension", s_arm_arch_extension, 0 },
c19d1205 5164#ifdef OBJ_ELF
c921be7d
NC
5165 { "word", s_arm_elf_cons, 4 },
5166 { "long", s_arm_elf_cons, 4 },
5167 { "inst.n", s_arm_elf_inst, 2 },
5168 { "inst.w", s_arm_elf_inst, 4 },
5169 { "inst", s_arm_elf_inst, 0 },
5170 { "rel31", s_arm_rel31, 0 },
c19d1205
ZW
5171 { "fnstart", s_arm_unwind_fnstart, 0 },
5172 { "fnend", s_arm_unwind_fnend, 0 },
5173 { "cantunwind", s_arm_unwind_cantunwind, 0 },
5174 { "personality", s_arm_unwind_personality, 0 },
5175 { "personalityindex", s_arm_unwind_personalityindex, 0 },
5176 { "handlerdata", s_arm_unwind_handlerdata, 0 },
5177 { "save", s_arm_unwind_save, 0 },
fa073d69 5178 { "vsave", s_arm_unwind_save, 1 },
c19d1205
ZW
5179 { "movsp", s_arm_unwind_movsp, 0 },
5180 { "pad", s_arm_unwind_pad, 0 },
5181 { "setfp", s_arm_unwind_setfp, 0 },
5182 { "unwind_raw", s_arm_unwind_raw, 0 },
ee065d83 5183 { "eabi_attribute", s_arm_eabi_attribute, 0 },
0855e32b 5184 { "tlsdescseq", s_arm_tls_descseq, 0 },
c19d1205
ZW
5185#else
5186 { "word", cons, 4},
f0927246
NC
5187
5188 /* These are used for dwarf. */
5189 {"2byte", cons, 2},
5190 {"4byte", cons, 4},
5191 {"8byte", cons, 8},
5192 /* These are used for dwarf2. */
68d20676 5193 { "file", dwarf2_directive_file, 0 },
f0927246
NC
5194 { "loc", dwarf2_directive_loc, 0 },
5195 { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
c19d1205
ZW
5196#endif
5197 { "extend", float_cons, 'x' },
5198 { "ldouble", float_cons, 'x' },
5199 { "packed", float_cons, 'p' },
27cce866 5200 { "bfloat16", float_cons, 'b' },
f0927246
NC
5201#ifdef TE_PE
5202 {"secrel32", pe_directive_secrel, 0},
5203#endif
2e6976a8
DG
5204
5205 /* These are for compatibility with CodeComposer Studio. */
5206 {"ref", s_ccs_ref, 0},
5207 {"def", s_ccs_def, 0},
5208 {"asmfunc", s_ccs_asmfunc, 0},
5209 {"endasmfunc", s_ccs_endasmfunc, 0},
5210
5312fe52
BW
5211 {"float16", float_cons, 'h' },
5212 {"float16_format", set_fp16_format, 0 },
5213
c19d1205
ZW
5214 { 0, 0, 0 }
5215};
5312fe52 5216
c19d1205 5217/* Parser functions used exclusively in instruction operands. */
b99bd4ef 5218
c19d1205
ZW
5219/* Generic immediate-value read function for use in insn parsing.
5220 STR points to the beginning of the immediate (the leading #);
5221 VAL receives the value; if the value is outside [MIN, MAX]
5222 issue an error. PREFIX_OPT is true if the immediate prefix is
5223 optional. */
b99bd4ef 5224
c19d1205
ZW
5225static int
5226parse_immediate (char **str, int *val, int min, int max,
5b7c81bd 5227 bool prefix_opt)
c19d1205
ZW
5228{
5229 expressionS exp;
0198d5e6 5230
c19d1205
ZW
5231 my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
5232 if (exp.X_op != O_constant)
b99bd4ef 5233 {
c19d1205
ZW
5234 inst.error = _("constant expression required");
5235 return FAIL;
5236 }
b99bd4ef 5237
c19d1205
ZW
5238 if (exp.X_add_number < min || exp.X_add_number > max)
5239 {
5240 inst.error = _("immediate value out of range");
5241 return FAIL;
5242 }
b99bd4ef 5243
c19d1205
ZW
5244 *val = exp.X_add_number;
5245 return SUCCESS;
5246}
b99bd4ef 5247
5287ad62 5248/* Less-generic immediate-value read function with the possibility of loading a
036dc3f7 5249 big (64-bit) immediate, as required by Neon VMOV, VMVN and logic immediate
5287ad62
JB
5250 instructions. Puts the result directly in inst.operands[i]. */
5251
5252static int
8335d6aa 5253parse_big_immediate (char **str, int i, expressionS *in_exp,
5b7c81bd 5254 bool allow_symbol_p)
5287ad62
JB
5255{
5256 expressionS exp;
8335d6aa 5257 expressionS *exp_p = in_exp ? in_exp : &exp;
5287ad62
JB
5258 char *ptr = *str;
5259
8335d6aa 5260 my_get_expression (exp_p, &ptr, GE_OPT_PREFIX_BIG);
5287ad62 5261
8335d6aa 5262 if (exp_p->X_op == O_constant)
036dc3f7 5263 {
8335d6aa 5264 inst.operands[i].imm = exp_p->X_add_number & 0xffffffff;
036dc3f7
PB
5265 /* If we're on a 64-bit host, then a 64-bit number can be returned using
5266 O_constant. We have to be careful not to break compilation for
5267 32-bit X_add_number, though. */
8335d6aa 5268 if ((exp_p->X_add_number & ~(offsetT)(0xffffffffU)) != 0)
036dc3f7 5269 {
8335d6aa
JW
5270 /* X >> 32 is illegal if sizeof (exp_p->X_add_number) == 4. */
5271 inst.operands[i].reg = (((exp_p->X_add_number >> 16) >> 16)
5272 & 0xffffffff);
036dc3f7
PB
5273 inst.operands[i].regisimm = 1;
5274 }
5275 }
8335d6aa
JW
5276 else if (exp_p->X_op == O_big
5277 && LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 32)
5287ad62
JB
5278 {
5279 unsigned parts = 32 / LITTLENUM_NUMBER_OF_BITS, j, idx = 0;
95b75c01 5280
5287ad62 5281 /* Bignums have their least significant bits in
477330fc
RM
5282 generic_bignum[0]. Make sure we put 32 bits in imm and
5283 32 bits in reg, in a (hopefully) portable way. */
9c2799c2 5284 gas_assert (parts != 0);
95b75c01
NC
5285
5286 /* Make sure that the number is not too big.
5287 PR 11972: Bignums can now be sign-extended to the
5288 size of a .octa so check that the out of range bits
5289 are all zero or all one. */
8335d6aa 5290 if (LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 64)
95b75c01
NC
5291 {
5292 LITTLENUM_TYPE m = -1;
5293
5294 if (generic_bignum[parts * 2] != 0
5295 && generic_bignum[parts * 2] != m)
5296 return FAIL;
5297
8335d6aa 5298 for (j = parts * 2 + 1; j < (unsigned) exp_p->X_add_number; j++)
95b75c01
NC
5299 if (generic_bignum[j] != generic_bignum[j-1])
5300 return FAIL;
5301 }
5302
5287ad62
JB
5303 inst.operands[i].imm = 0;
5304 for (j = 0; j < parts; j++, idx++)
7af67752
AM
5305 inst.operands[i].imm |= ((unsigned) generic_bignum[idx]
5306 << (LITTLENUM_NUMBER_OF_BITS * j));
5287ad62
JB
5307 inst.operands[i].reg = 0;
5308 for (j = 0; j < parts; j++, idx++)
7af67752
AM
5309 inst.operands[i].reg |= ((unsigned) generic_bignum[idx]
5310 << (LITTLENUM_NUMBER_OF_BITS * j));
5287ad62
JB
5311 inst.operands[i].regisimm = 1;
5312 }
8335d6aa 5313 else if (!(exp_p->X_op == O_symbol && allow_symbol_p))
5287ad62 5314 return FAIL;
5f4273c7 5315
5287ad62
JB
5316 *str = ptr;
5317
5318 return SUCCESS;
5319}
5320
c19d1205
ZW
5321/* Returns the pseudo-register number of an FPA immediate constant,
5322 or FAIL if there isn't a valid constant here. */
b99bd4ef 5323
c19d1205
ZW
5324static int
5325parse_fpa_immediate (char ** str)
5326{
5327 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5328 char * save_in;
5329 expressionS exp;
5330 int i;
5331 int j;
b99bd4ef 5332
c19d1205
ZW
5333 /* First try and match exact strings, this is to guarantee
5334 that some formats will work even for cross assembly. */
b99bd4ef 5335
c19d1205
ZW
5336 for (i = 0; fp_const[i]; i++)
5337 {
5338 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
b99bd4ef 5339 {
c19d1205 5340 char *start = *str;
b99bd4ef 5341
c19d1205
ZW
5342 *str += strlen (fp_const[i]);
5343 if (is_end_of_line[(unsigned char) **str])
5344 return i + 8;
5345 *str = start;
5346 }
5347 }
b99bd4ef 5348
c19d1205
ZW
5349 /* Just because we didn't get a match doesn't mean that the constant
5350 isn't valid, just that it is in a format that we don't
5351 automatically recognize. Try parsing it with the standard
5352 expression routines. */
b99bd4ef 5353
c19d1205 5354 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
b99bd4ef 5355
c19d1205
ZW
5356 /* Look for a raw floating point number. */
5357 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5358 && is_end_of_line[(unsigned char) *save_in])
5359 {
5360 for (i = 0; i < NUM_FLOAT_VALS; i++)
5361 {
5362 for (j = 0; j < MAX_LITTLENUMS; j++)
b99bd4ef 5363 {
c19d1205
ZW
5364 if (words[j] != fp_values[i][j])
5365 break;
b99bd4ef
NC
5366 }
5367
c19d1205 5368 if (j == MAX_LITTLENUMS)
b99bd4ef 5369 {
c19d1205
ZW
5370 *str = save_in;
5371 return i + 8;
b99bd4ef
NC
5372 }
5373 }
5374 }
b99bd4ef 5375
c19d1205
ZW
5376 /* Try and parse a more complex expression, this will probably fail
5377 unless the code uses a floating point prefix (eg "0f"). */
5378 save_in = input_line_pointer;
5379 input_line_pointer = *str;
5380 if (expression (&exp) == absolute_section
5381 && exp.X_op == O_big
5382 && exp.X_add_number < 0)
5383 {
5384 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5385 Ditto for 15. */
ba592044
AM
5386#define X_PRECISION 5
5387#define E_PRECISION 15L
5388 if (gen_to_words (words, X_PRECISION, E_PRECISION) == 0)
c19d1205
ZW
5389 {
5390 for (i = 0; i < NUM_FLOAT_VALS; i++)
5391 {
5392 for (j = 0; j < MAX_LITTLENUMS; j++)
5393 {
5394 if (words[j] != fp_values[i][j])
5395 break;
5396 }
b99bd4ef 5397
c19d1205
ZW
5398 if (j == MAX_LITTLENUMS)
5399 {
5400 *str = input_line_pointer;
5401 input_line_pointer = save_in;
5402 return i + 8;
5403 }
5404 }
5405 }
b99bd4ef
NC
5406 }
5407
c19d1205
ZW
5408 *str = input_line_pointer;
5409 input_line_pointer = save_in;
5410 inst.error = _("invalid FPA immediate expression");
5411 return FAIL;
b99bd4ef
NC
5412}
5413
136da414
JB
5414/* Returns 1 if a number has "quarter-precision" float format
5415 0baBbbbbbc defgh000 00000000 00000000. */
5416
5417static int
5418is_quarter_float (unsigned imm)
5419{
5420 int bs = (imm & 0x20000000) ? 0x3e000000 : 0x40000000;
5421 return (imm & 0x7ffff) == 0 && ((imm & 0x7e000000) ^ bs) == 0;
5422}
5423
aacf0b33
KT
5424
5425/* Detect the presence of a floating point or integer zero constant,
5426 i.e. #0.0 or #0. */
5427
5b7c81bd 5428static bool
aacf0b33
KT
5429parse_ifimm_zero (char **in)
5430{
5431 int error_code;
5432
5433 if (!is_immediate_prefix (**in))
3c6452ae
TP
5434 {
5435 /* In unified syntax, all prefixes are optional. */
5436 if (!unified_syntax)
5b7c81bd 5437 return false;
3c6452ae
TP
5438 }
5439 else
5440 ++*in;
0900a05b
JW
5441
5442 /* Accept #0x0 as a synonym for #0. */
d34049e8 5443 if (startswith (*in, "0x"))
0900a05b
JW
5444 {
5445 int val;
5b7c81bd
AM
5446 if (parse_immediate (in, &val, 0, 0, true) == FAIL)
5447 return false;
5448 return true;
0900a05b
JW
5449 }
5450
aacf0b33
KT
5451 error_code = atof_generic (in, ".", EXP_CHARS,
5452 &generic_floating_point_number);
5453
5454 if (!error_code
5455 && generic_floating_point_number.sign == '+'
5456 && (generic_floating_point_number.low
5457 > generic_floating_point_number.leader))
5b7c81bd 5458 return true;
aacf0b33 5459
5b7c81bd 5460 return false;
aacf0b33
KT
5461}
5462
136da414
JB
5463/* Parse an 8-bit "quarter-precision" floating point number of the form:
5464 0baBbbbbbc defgh000 00000000 00000000.
c96612cc
JB
5465 The zero and minus-zero cases need special handling, since they can't be
5466 encoded in the "quarter-precision" float format, but can nonetheless be
5467 loaded as integer constants. */
136da414
JB
5468
5469static unsigned
5470parse_qfloat_immediate (char **ccp, int *immed)
5471{
5472 char *str = *ccp;
c96612cc 5473 char *fpnum;
136da414 5474 LITTLENUM_TYPE words[MAX_LITTLENUMS];
c96612cc 5475 int found_fpchar = 0;
5f4273c7 5476
136da414 5477 skip_past_char (&str, '#');
5f4273c7 5478
c96612cc
JB
5479 /* We must not accidentally parse an integer as a floating-point number. Make
5480 sure that the value we parse is not an integer by checking for special
5481 characters '.' or 'e'.
5482 FIXME: This is a horrible hack, but doing better is tricky because type
5483 information isn't in a very usable state at parse time. */
5484 fpnum = str;
5485 skip_whitespace (fpnum);
5486
d34049e8 5487 if (startswith (fpnum, "0x"))
c96612cc
JB
5488 return FAIL;
5489 else
5490 {
5491 for (; *fpnum != '\0' && *fpnum != ' ' && *fpnum != '\n'; fpnum++)
477330fc
RM
5492 if (*fpnum == '.' || *fpnum == 'e' || *fpnum == 'E')
5493 {
5494 found_fpchar = 1;
5495 break;
5496 }
c96612cc
JB
5497
5498 if (!found_fpchar)
477330fc 5499 return FAIL;
c96612cc 5500 }
5f4273c7 5501
136da414
JB
5502 if ((str = atof_ieee (str, 's', words)) != NULL)
5503 {
5504 unsigned fpword = 0;
5505 int i;
5f4273c7 5506
136da414
JB
5507 /* Our FP word must be 32 bits (single-precision FP). */
5508 for (i = 0; i < 32 / LITTLENUM_NUMBER_OF_BITS; i++)
477330fc
RM
5509 {
5510 fpword <<= LITTLENUM_NUMBER_OF_BITS;
5511 fpword |= words[i];
5512 }
5f4273c7 5513
c96612cc 5514 if (is_quarter_float (fpword) || (fpword & 0x7fffffff) == 0)
477330fc 5515 *immed = fpword;
136da414 5516 else
477330fc 5517 return FAIL;
136da414
JB
5518
5519 *ccp = str;
5f4273c7 5520
136da414
JB
5521 return SUCCESS;
5522 }
5f4273c7 5523
136da414
JB
5524 return FAIL;
5525}
5526
c19d1205
ZW
5527/* Shift operands. */
5528enum shift_kind
b99bd4ef 5529{
f5f10c66 5530 SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX, SHIFT_UXTW
c19d1205 5531};
b99bd4ef 5532
c19d1205
ZW
5533struct asm_shift_name
5534{
5535 const char *name;
5536 enum shift_kind kind;
5537};
b99bd4ef 5538
c19d1205
ZW
5539/* Third argument to parse_shift. */
5540enum parse_shift_mode
5541{
5542 NO_SHIFT_RESTRICT, /* Any kind of shift is accepted. */
5543 SHIFT_IMMEDIATE, /* Shift operand must be an immediate. */
5544 SHIFT_LSL_OR_ASR_IMMEDIATE, /* Shift must be LSL or ASR immediate. */
5545 SHIFT_ASR_IMMEDIATE, /* Shift must be ASR immediate. */
5546 SHIFT_LSL_IMMEDIATE, /* Shift must be LSL immediate. */
f5f10c66 5547 SHIFT_UXTW_IMMEDIATE /* Shift must be UXTW immediate. */
c19d1205 5548};
b99bd4ef 5549
c19d1205
ZW
5550/* Parse a <shift> specifier on an ARM data processing instruction.
5551 This has three forms:
b99bd4ef 5552
c19d1205
ZW
5553 (LSL|LSR|ASL|ASR|ROR) Rs
5554 (LSL|LSR|ASL|ASR|ROR) #imm
5555 RRX
b99bd4ef 5556
c19d1205
ZW
5557 Note that ASL is assimilated to LSL in the instruction encoding, and
5558 RRX to ROR #0 (which cannot be written as such). */
b99bd4ef 5559
c19d1205
ZW
5560static int
5561parse_shift (char **str, int i, enum parse_shift_mode mode)
b99bd4ef 5562{
c19d1205
ZW
5563 const struct asm_shift_name *shift_name;
5564 enum shift_kind shift;
5565 char *s = *str;
5566 char *p = s;
5567 int reg;
b99bd4ef 5568
c19d1205
ZW
5569 for (p = *str; ISALPHA (*p); p++)
5570 ;
b99bd4ef 5571
c19d1205 5572 if (p == *str)
b99bd4ef 5573 {
c19d1205
ZW
5574 inst.error = _("shift expression expected");
5575 return FAIL;
b99bd4ef
NC
5576 }
5577
fe0e921f
AM
5578 shift_name
5579 = (const struct asm_shift_name *) str_hash_find_n (arm_shift_hsh, *str,
5580 p - *str);
c19d1205
ZW
5581
5582 if (shift_name == NULL)
b99bd4ef 5583 {
c19d1205
ZW
5584 inst.error = _("shift expression expected");
5585 return FAIL;
b99bd4ef
NC
5586 }
5587
c19d1205 5588 shift = shift_name->kind;
b99bd4ef 5589
c19d1205
ZW
5590 switch (mode)
5591 {
5592 case NO_SHIFT_RESTRICT:
f5f10c66
AV
5593 case SHIFT_IMMEDIATE:
5594 if (shift == SHIFT_UXTW)
5595 {
5596 inst.error = _("'UXTW' not allowed here");
5597 return FAIL;
5598 }
5599 break;
b99bd4ef 5600
c19d1205
ZW
5601 case SHIFT_LSL_OR_ASR_IMMEDIATE:
5602 if (shift != SHIFT_LSL && shift != SHIFT_ASR)
5603 {
5604 inst.error = _("'LSL' or 'ASR' required");
5605 return FAIL;
5606 }
5607 break;
b99bd4ef 5608
c19d1205
ZW
5609 case SHIFT_LSL_IMMEDIATE:
5610 if (shift != SHIFT_LSL)
5611 {
5612 inst.error = _("'LSL' required");
5613 return FAIL;
5614 }
5615 break;
b99bd4ef 5616
c19d1205
ZW
5617 case SHIFT_ASR_IMMEDIATE:
5618 if (shift != SHIFT_ASR)
5619 {
5620 inst.error = _("'ASR' required");
5621 return FAIL;
5622 }
5623 break;
f5f10c66
AV
5624 case SHIFT_UXTW_IMMEDIATE:
5625 if (shift != SHIFT_UXTW)
5626 {
5627 inst.error = _("'UXTW' required");
5628 return FAIL;
5629 }
5630 break;
b99bd4ef 5631
c19d1205
ZW
5632 default: abort ();
5633 }
b99bd4ef 5634
c19d1205
ZW
5635 if (shift != SHIFT_RRX)
5636 {
5637 /* Whitespace can appear here if the next thing is a bare digit. */
5638 skip_whitespace (p);
b99bd4ef 5639
c19d1205 5640 if (mode == NO_SHIFT_RESTRICT
dcbf9037 5641 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5642 {
5643 inst.operands[i].imm = reg;
5644 inst.operands[i].immisreg = 1;
5645 }
e2b0ab59 5646 else if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
c19d1205
ZW
5647 return FAIL;
5648 }
5649 inst.operands[i].shift_kind = shift;
5650 inst.operands[i].shifted = 1;
5651 *str = p;
5652 return SUCCESS;
b99bd4ef
NC
5653}
5654
c19d1205 5655/* Parse a <shifter_operand> for an ARM data processing instruction:
b99bd4ef 5656
c19d1205
ZW
5657 #<immediate>
5658 #<immediate>, <rotate>
5659 <Rm>
5660 <Rm>, <shift>
b99bd4ef 5661
c19d1205
ZW
5662 where <shift> is defined by parse_shift above, and <rotate> is a
5663 multiple of 2 between 0 and 30. Validation of immediate operands
55cf6793 5664 is deferred to md_apply_fix. */
b99bd4ef 5665
c19d1205
ZW
5666static int
5667parse_shifter_operand (char **str, int i)
5668{
5669 int value;
91d6fa6a 5670 expressionS exp;
b99bd4ef 5671
dcbf9037 5672 if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5673 {
5674 inst.operands[i].reg = value;
5675 inst.operands[i].isreg = 1;
b99bd4ef 5676
c19d1205 5677 /* parse_shift will override this if appropriate */
e2b0ab59
AV
5678 inst.relocs[0].exp.X_op = O_constant;
5679 inst.relocs[0].exp.X_add_number = 0;
b99bd4ef 5680
c19d1205
ZW
5681 if (skip_past_comma (str) == FAIL)
5682 return SUCCESS;
b99bd4ef 5683
c19d1205
ZW
5684 /* Shift operation on register. */
5685 return parse_shift (str, i, NO_SHIFT_RESTRICT);
b99bd4ef
NC
5686 }
5687
e2b0ab59 5688 if (my_get_expression (&inst.relocs[0].exp, str, GE_IMM_PREFIX))
c19d1205 5689 return FAIL;
b99bd4ef 5690
c19d1205 5691 if (skip_past_comma (str) == SUCCESS)
b99bd4ef 5692 {
c19d1205 5693 /* #x, y -- ie explicit rotation by Y. */
91d6fa6a 5694 if (my_get_expression (&exp, str, GE_NO_PREFIX))
c19d1205 5695 return FAIL;
b99bd4ef 5696
e2b0ab59 5697 if (exp.X_op != O_constant || inst.relocs[0].exp.X_op != O_constant)
c19d1205
ZW
5698 {
5699 inst.error = _("constant expression expected");
5700 return FAIL;
5701 }
b99bd4ef 5702
91d6fa6a 5703 value = exp.X_add_number;
c19d1205
ZW
5704 if (value < 0 || value > 30 || value % 2 != 0)
5705 {
5706 inst.error = _("invalid rotation");
5707 return FAIL;
5708 }
e2b0ab59
AV
5709 if (inst.relocs[0].exp.X_add_number < 0
5710 || inst.relocs[0].exp.X_add_number > 255)
c19d1205
ZW
5711 {
5712 inst.error = _("invalid constant");
5713 return FAIL;
5714 }
09d92015 5715
a415b1cd 5716 /* Encode as specified. */
e2b0ab59 5717 inst.operands[i].imm = inst.relocs[0].exp.X_add_number | value << 7;
a415b1cd 5718 return SUCCESS;
09d92015
MM
5719 }
5720
e2b0ab59
AV
5721 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
5722 inst.relocs[0].pc_rel = 0;
c19d1205 5723 return SUCCESS;
09d92015
MM
5724}
5725
4962c51a
MS
5726/* Group relocation information. Each entry in the table contains the
5727 textual name of the relocation as may appear in assembler source
5728 and must end with a colon.
5729 Along with this textual name are the relocation codes to be used if
5730 the corresponding instruction is an ALU instruction (ADD or SUB only),
5731 an LDR, an LDRS, or an LDC. */
5732
5733struct group_reloc_table_entry
5734{
5735 const char *name;
5736 int alu_code;
5737 int ldr_code;
5738 int ldrs_code;
5739 int ldc_code;
5740};
5741
5742typedef enum
5743{
5744 /* Varieties of non-ALU group relocation. */
5745
5746 GROUP_LDR,
5747 GROUP_LDRS,
35c228db
AV
5748 GROUP_LDC,
5749 GROUP_MVE
4962c51a
MS
5750} group_reloc_type;
5751
5752static struct group_reloc_table_entry group_reloc_table[] =
5753 { /* Program counter relative: */
5754 { "pc_g0_nc",
5755 BFD_RELOC_ARM_ALU_PC_G0_NC, /* ALU */
5756 0, /* LDR */
5757 0, /* LDRS */
5758 0 }, /* LDC */
5759 { "pc_g0",
5760 BFD_RELOC_ARM_ALU_PC_G0, /* ALU */
5761 BFD_RELOC_ARM_LDR_PC_G0, /* LDR */
5762 BFD_RELOC_ARM_LDRS_PC_G0, /* LDRS */
5763 BFD_RELOC_ARM_LDC_PC_G0 }, /* LDC */
5764 { "pc_g1_nc",
5765 BFD_RELOC_ARM_ALU_PC_G1_NC, /* ALU */
5766 0, /* LDR */
5767 0, /* LDRS */
5768 0 }, /* LDC */
5769 { "pc_g1",
5770 BFD_RELOC_ARM_ALU_PC_G1, /* ALU */
5771 BFD_RELOC_ARM_LDR_PC_G1, /* LDR */
5772 BFD_RELOC_ARM_LDRS_PC_G1, /* LDRS */
5773 BFD_RELOC_ARM_LDC_PC_G1 }, /* LDC */
5774 { "pc_g2",
5775 BFD_RELOC_ARM_ALU_PC_G2, /* ALU */
5776 BFD_RELOC_ARM_LDR_PC_G2, /* LDR */
5777 BFD_RELOC_ARM_LDRS_PC_G2, /* LDRS */
5778 BFD_RELOC_ARM_LDC_PC_G2 }, /* LDC */
5779 /* Section base relative */
5780 { "sb_g0_nc",
5781 BFD_RELOC_ARM_ALU_SB_G0_NC, /* ALU */
5782 0, /* LDR */
5783 0, /* LDRS */
5784 0 }, /* LDC */
5785 { "sb_g0",
5786 BFD_RELOC_ARM_ALU_SB_G0, /* ALU */
5787 BFD_RELOC_ARM_LDR_SB_G0, /* LDR */
5788 BFD_RELOC_ARM_LDRS_SB_G0, /* LDRS */
5789 BFD_RELOC_ARM_LDC_SB_G0 }, /* LDC */
5790 { "sb_g1_nc",
5791 BFD_RELOC_ARM_ALU_SB_G1_NC, /* ALU */
5792 0, /* LDR */
5793 0, /* LDRS */
5794 0 }, /* LDC */
5795 { "sb_g1",
5796 BFD_RELOC_ARM_ALU_SB_G1, /* ALU */
5797 BFD_RELOC_ARM_LDR_SB_G1, /* LDR */
5798 BFD_RELOC_ARM_LDRS_SB_G1, /* LDRS */
5799 BFD_RELOC_ARM_LDC_SB_G1 }, /* LDC */
5800 { "sb_g2",
5801 BFD_RELOC_ARM_ALU_SB_G2, /* ALU */
5802 BFD_RELOC_ARM_LDR_SB_G2, /* LDR */
5803 BFD_RELOC_ARM_LDRS_SB_G2, /* LDRS */
72d98d16
MG
5804 BFD_RELOC_ARM_LDC_SB_G2 }, /* LDC */
5805 /* Absolute thumb alu relocations. */
5806 { "lower0_7",
5807 BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,/* ALU. */
5808 0, /* LDR. */
5809 0, /* LDRS. */
5810 0 }, /* LDC. */
5811 { "lower8_15",
5812 BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,/* ALU. */
5813 0, /* LDR. */
5814 0, /* LDRS. */
5815 0 }, /* LDC. */
5816 { "upper0_7",
5817 BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,/* ALU. */
5818 0, /* LDR. */
5819 0, /* LDRS. */
5820 0 }, /* LDC. */
5821 { "upper8_15",
5822 BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,/* ALU. */
5823 0, /* LDR. */
5824 0, /* LDRS. */
5825 0 } }; /* LDC. */
4962c51a
MS
5826
5827/* Given the address of a pointer pointing to the textual name of a group
5828 relocation as may appear in assembler source, attempt to find its details
5829 in group_reloc_table. The pointer will be updated to the character after
5830 the trailing colon. On failure, FAIL will be returned; SUCCESS
5831 otherwise. On success, *entry will be updated to point at the relevant
5832 group_reloc_table entry. */
5833
5834static int
5835find_group_reloc_table_entry (char **str, struct group_reloc_table_entry **out)
5836{
5837 unsigned int i;
5838 for (i = 0; i < ARRAY_SIZE (group_reloc_table); i++)
5839 {
5840 int length = strlen (group_reloc_table[i].name);
5841
5f4273c7
NC
5842 if (strncasecmp (group_reloc_table[i].name, *str, length) == 0
5843 && (*str)[length] == ':')
477330fc
RM
5844 {
5845 *out = &group_reloc_table[i];
5846 *str += (length + 1);
5847 return SUCCESS;
5848 }
4962c51a
MS
5849 }
5850
5851 return FAIL;
5852}
5853
5854/* Parse a <shifter_operand> for an ARM data processing instruction
5855 (as for parse_shifter_operand) where group relocations are allowed:
5856
5857 #<immediate>
5858 #<immediate>, <rotate>
5859 #:<group_reloc>:<expression>
5860 <Rm>
5861 <Rm>, <shift>
5862
5863 where <group_reloc> is one of the strings defined in group_reloc_table.
5864 The hashes are optional.
5865
5866 Everything else is as for parse_shifter_operand. */
5867
5868static parse_operand_result
5869parse_shifter_operand_group_reloc (char **str, int i)
5870{
5871 /* Determine if we have the sequence of characters #: or just :
5872 coming next. If we do, then we check for a group relocation.
5873 If we don't, punt the whole lot to parse_shifter_operand. */
5874
5875 if (((*str)[0] == '#' && (*str)[1] == ':')
5876 || (*str)[0] == ':')
5877 {
5878 struct group_reloc_table_entry *entry;
5879
5880 if ((*str)[0] == '#')
477330fc 5881 (*str) += 2;
4962c51a 5882 else
477330fc 5883 (*str)++;
4962c51a
MS
5884
5885 /* Try to parse a group relocation. Anything else is an error. */
5886 if (find_group_reloc_table_entry (str, &entry) == FAIL)
477330fc
RM
5887 {
5888 inst.error = _("unknown group relocation");
5889 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5890 }
4962c51a
MS
5891
5892 /* We now have the group relocation table entry corresponding to
477330fc 5893 the name in the assembler source. Next, we parse the expression. */
e2b0ab59 5894 if (my_get_expression (&inst.relocs[0].exp, str, GE_NO_PREFIX))
477330fc 5895 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
4962c51a
MS
5896
5897 /* Record the relocation type (always the ALU variant here). */
e2b0ab59
AV
5898 inst.relocs[0].type = (bfd_reloc_code_real_type) entry->alu_code;
5899 gas_assert (inst.relocs[0].type != 0);
4962c51a
MS
5900
5901 return PARSE_OPERAND_SUCCESS;
5902 }
5903 else
5904 return parse_shifter_operand (str, i) == SUCCESS
477330fc 5905 ? PARSE_OPERAND_SUCCESS : PARSE_OPERAND_FAIL;
4962c51a
MS
5906
5907 /* Never reached. */
5908}
5909
8e560766
MGD
5910/* Parse a Neon alignment expression. Information is written to
5911 inst.operands[i]. We assume the initial ':' has been skipped.
fa94de6b 5912
8e560766
MGD
5913 align .imm = align << 8, .immisalign=1, .preind=0 */
5914static parse_operand_result
5915parse_neon_alignment (char **str, int i)
5916{
5917 char *p = *str;
5918 expressionS exp;
5919
5920 my_get_expression (&exp, &p, GE_NO_PREFIX);
5921
5922 if (exp.X_op != O_constant)
5923 {
5924 inst.error = _("alignment must be constant");
5925 return PARSE_OPERAND_FAIL;
5926 }
5927
5928 inst.operands[i].imm = exp.X_add_number << 8;
5929 inst.operands[i].immisalign = 1;
5930 /* Alignments are not pre-indexes. */
5931 inst.operands[i].preind = 0;
5932
5933 *str = p;
5934 return PARSE_OPERAND_SUCCESS;
5935}
5936
c19d1205 5937/* Parse all forms of an ARM address expression. Information is written
e2b0ab59 5938 to inst.operands[i] and/or inst.relocs[0].
09d92015 5939
c19d1205 5940 Preindexed addressing (.preind=1):
09d92015 5941
e2b0ab59 5942 [Rn, #offset] .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5943 [Rn, +/-Rm] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5944 [Rn, +/-Rm, shift] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5945 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5946
c19d1205 5947 These three may have a trailing ! which causes .writeback to be set also.
09d92015 5948
c19d1205 5949 Postindexed addressing (.postind=1, .writeback=1):
09d92015 5950
e2b0ab59 5951 [Rn], #offset .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5952 [Rn], +/-Rm .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5953 [Rn], +/-Rm, shift .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5954 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5955
c19d1205 5956 Unindexed addressing (.preind=0, .postind=0):
09d92015 5957
c19d1205 5958 [Rn], {option} .reg=Rn .imm=option .immisreg=0
09d92015 5959
c19d1205 5960 Other:
09d92015 5961
c19d1205 5962 [Rn]{!} shorthand for [Rn,#0]{!}
e2b0ab59
AV
5963 =immediate .isreg=0 .relocs[0].exp=immediate
5964 label .reg=PC .relocs[0].pc_rel=1 .relocs[0].exp=label
09d92015 5965
c19d1205 5966 It is the caller's responsibility to check for addressing modes not
e2b0ab59 5967 supported by the instruction, and to set inst.relocs[0].type. */
c19d1205 5968
4962c51a
MS
5969static parse_operand_result
5970parse_address_main (char **str, int i, int group_relocations,
477330fc 5971 group_reloc_type group_type)
09d92015 5972{
c19d1205
ZW
5973 char *p = *str;
5974 int reg;
09d92015 5975
c19d1205 5976 if (skip_past_char (&p, '[') == FAIL)
09d92015 5977 {
79248c83
SP
5978 if (group_type == GROUP_MVE
5979 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
5980 {
5981 /* [r0-r15] expected as argument but receiving r0-r15 without
5982 [] brackets. */
5983 inst.error = BAD_SYNTAX;
5984 return PARSE_OPERAND_FAIL;
5985 }
5986 else if (skip_past_char (&p, '=') == FAIL)
c19d1205 5987 {
974da60d 5988 /* Bare address - translate to PC-relative offset. */
e2b0ab59 5989 inst.relocs[0].pc_rel = 1;
c19d1205
ZW
5990 inst.operands[i].reg = REG_PC;
5991 inst.operands[i].isreg = 1;
5992 inst.operands[i].preind = 1;
09d92015 5993
e2b0ab59 5994 if (my_get_expression (&inst.relocs[0].exp, &p, GE_OPT_PREFIX_BIG))
8335d6aa
JW
5995 return PARSE_OPERAND_FAIL;
5996 }
e2b0ab59 5997 else if (parse_big_immediate (&p, i, &inst.relocs[0].exp,
5b7c81bd 5998 /*allow_symbol_p=*/true))
4962c51a 5999 return PARSE_OPERAND_FAIL;
09d92015 6000
c19d1205 6001 *str = p;
4962c51a 6002 return PARSE_OPERAND_SUCCESS;
09d92015
MM
6003 }
6004
8ab8155f
NC
6005 /* PR gas/14887: Allow for whitespace after the opening bracket. */
6006 skip_whitespace (p);
6007
f5f10c66
AV
6008 if (group_type == GROUP_MVE)
6009 {
6010 enum arm_reg_type rtype = REG_TYPE_MQ;
6011 struct neon_type_el et;
6012 if ((reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
6013 {
6014 inst.operands[i].isquad = 1;
6015 }
6016 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
6017 {
6018 inst.error = BAD_ADDR_MODE;
6019 return PARSE_OPERAND_FAIL;
6020 }
6021 }
6022 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
09d92015 6023 {
35c228db
AV
6024 if (group_type == GROUP_MVE)
6025 inst.error = BAD_ADDR_MODE;
6026 else
6027 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
4962c51a 6028 return PARSE_OPERAND_FAIL;
09d92015 6029 }
c19d1205
ZW
6030 inst.operands[i].reg = reg;
6031 inst.operands[i].isreg = 1;
09d92015 6032
c19d1205 6033 if (skip_past_comma (&p) == SUCCESS)
09d92015 6034 {
c19d1205 6035 inst.operands[i].preind = 1;
09d92015 6036
c19d1205
ZW
6037 if (*p == '+') p++;
6038 else if (*p == '-') p++, inst.operands[i].negative = 1;
6039
f5f10c66
AV
6040 enum arm_reg_type rtype = REG_TYPE_MQ;
6041 struct neon_type_el et;
6042 if (group_type == GROUP_MVE
6043 && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
6044 {
6045 inst.operands[i].immisreg = 2;
6046 inst.operands[i].imm = reg;
6047
6048 if (skip_past_comma (&p) == SUCCESS)
6049 {
6050 if (parse_shift (&p, i, SHIFT_UXTW_IMMEDIATE) == SUCCESS)
6051 {
6052 inst.operands[i].imm |= inst.relocs[0].exp.X_add_number << 5;
6053 inst.relocs[0].exp.X_add_number = 0;
6054 }
6055 else
6056 return PARSE_OPERAND_FAIL;
6057 }
6058 }
6059 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
09d92015 6060 {
c19d1205
ZW
6061 inst.operands[i].imm = reg;
6062 inst.operands[i].immisreg = 1;
6063
6064 if (skip_past_comma (&p) == SUCCESS)
6065 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 6066 return PARSE_OPERAND_FAIL;
c19d1205 6067 }
5287ad62 6068 else if (skip_past_char (&p, ':') == SUCCESS)
8e560766
MGD
6069 {
6070 /* FIXME: '@' should be used here, but it's filtered out by generic
6071 code before we get to see it here. This may be subject to
6072 change. */
6073 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 6074
8e560766
MGD
6075 if (result != PARSE_OPERAND_SUCCESS)
6076 return result;
6077 }
c19d1205
ZW
6078 else
6079 {
6080 if (inst.operands[i].negative)
6081 {
6082 inst.operands[i].negative = 0;
6083 p--;
6084 }
4962c51a 6085
5f4273c7
NC
6086 if (group_relocations
6087 && ((*p == '#' && *(p + 1) == ':') || *p == ':'))
4962c51a
MS
6088 {
6089 struct group_reloc_table_entry *entry;
6090
477330fc
RM
6091 /* Skip over the #: or : sequence. */
6092 if (*p == '#')
6093 p += 2;
6094 else
6095 p++;
4962c51a
MS
6096
6097 /* Try to parse a group relocation. Anything else is an
477330fc 6098 error. */
4962c51a
MS
6099 if (find_group_reloc_table_entry (&p, &entry) == FAIL)
6100 {
6101 inst.error = _("unknown group relocation");
6102 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6103 }
6104
6105 /* We now have the group relocation table entry corresponding to
6106 the name in the assembler source. Next, we parse the
477330fc 6107 expression. */
e2b0ab59 6108 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
4962c51a
MS
6109 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6110
6111 /* Record the relocation type. */
477330fc
RM
6112 switch (group_type)
6113 {
6114 case GROUP_LDR:
e2b0ab59
AV
6115 inst.relocs[0].type
6116 = (bfd_reloc_code_real_type) entry->ldr_code;
477330fc 6117 break;
4962c51a 6118
477330fc 6119 case GROUP_LDRS:
e2b0ab59
AV
6120 inst.relocs[0].type
6121 = (bfd_reloc_code_real_type) entry->ldrs_code;
477330fc 6122 break;
4962c51a 6123
477330fc 6124 case GROUP_LDC:
e2b0ab59
AV
6125 inst.relocs[0].type
6126 = (bfd_reloc_code_real_type) entry->ldc_code;
477330fc 6127 break;
4962c51a 6128
477330fc
RM
6129 default:
6130 gas_assert (0);
6131 }
4962c51a 6132
e2b0ab59 6133 if (inst.relocs[0].type == 0)
4962c51a
MS
6134 {
6135 inst.error = _("this group relocation is not allowed on this instruction");
6136 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6137 }
477330fc
RM
6138 }
6139 else
26d97720
NS
6140 {
6141 char *q = p;
0198d5e6 6142
e2b0ab59 6143 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
26d97720
NS
6144 return PARSE_OPERAND_FAIL;
6145 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
6146 if (inst.relocs[0].exp.X_op == O_constant
6147 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
6148 {
6149 skip_whitespace (q);
6150 if (*q == '#')
6151 {
6152 q++;
6153 skip_whitespace (q);
6154 }
6155 if (*q == '-')
6156 inst.operands[i].negative = 1;
6157 }
6158 }
09d92015
MM
6159 }
6160 }
8e560766
MGD
6161 else if (skip_past_char (&p, ':') == SUCCESS)
6162 {
6163 /* FIXME: '@' should be used here, but it's filtered out by generic code
6164 before we get to see it here. This may be subject to change. */
6165 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 6166
8e560766
MGD
6167 if (result != PARSE_OPERAND_SUCCESS)
6168 return result;
6169 }
09d92015 6170
c19d1205 6171 if (skip_past_char (&p, ']') == FAIL)
09d92015 6172 {
c19d1205 6173 inst.error = _("']' expected");
4962c51a 6174 return PARSE_OPERAND_FAIL;
09d92015
MM
6175 }
6176
c19d1205
ZW
6177 if (skip_past_char (&p, '!') == SUCCESS)
6178 inst.operands[i].writeback = 1;
09d92015 6179
c19d1205 6180 else if (skip_past_comma (&p) == SUCCESS)
09d92015 6181 {
c19d1205
ZW
6182 if (skip_past_char (&p, '{') == SUCCESS)
6183 {
6184 /* [Rn], {expr} - unindexed, with option */
6185 if (parse_immediate (&p, &inst.operands[i].imm,
5b7c81bd 6186 0, 255, true) == FAIL)
4962c51a 6187 return PARSE_OPERAND_FAIL;
09d92015 6188
c19d1205
ZW
6189 if (skip_past_char (&p, '}') == FAIL)
6190 {
6191 inst.error = _("'}' expected at end of 'option' field");
4962c51a 6192 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6193 }
6194 if (inst.operands[i].preind)
6195 {
6196 inst.error = _("cannot combine index with option");
4962c51a 6197 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6198 }
6199 *str = p;
4962c51a 6200 return PARSE_OPERAND_SUCCESS;
09d92015 6201 }
c19d1205
ZW
6202 else
6203 {
6204 inst.operands[i].postind = 1;
6205 inst.operands[i].writeback = 1;
09d92015 6206
c19d1205
ZW
6207 if (inst.operands[i].preind)
6208 {
6209 inst.error = _("cannot combine pre- and post-indexing");
4962c51a 6210 return PARSE_OPERAND_FAIL;
c19d1205 6211 }
09d92015 6212
c19d1205
ZW
6213 if (*p == '+') p++;
6214 else if (*p == '-') p++, inst.operands[i].negative = 1;
a737bd4d 6215
f5f10c66
AV
6216 enum arm_reg_type rtype = REG_TYPE_MQ;
6217 struct neon_type_el et;
6218 if (group_type == GROUP_MVE
6219 && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
6220 {
6221 inst.operands[i].immisreg = 2;
6222 inst.operands[i].imm = reg;
6223 }
6224 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205 6225 {
477330fc
RM
6226 /* We might be using the immediate for alignment already. If we
6227 are, OR the register number into the low-order bits. */
6228 if (inst.operands[i].immisalign)
6229 inst.operands[i].imm |= reg;
6230 else
6231 inst.operands[i].imm = reg;
c19d1205 6232 inst.operands[i].immisreg = 1;
a737bd4d 6233
c19d1205
ZW
6234 if (skip_past_comma (&p) == SUCCESS)
6235 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 6236 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6237 }
6238 else
6239 {
26d97720 6240 char *q = p;
0198d5e6 6241
c19d1205
ZW
6242 if (inst.operands[i].negative)
6243 {
6244 inst.operands[i].negative = 0;
6245 p--;
6246 }
e2b0ab59 6247 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
4962c51a 6248 return PARSE_OPERAND_FAIL;
26d97720 6249 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
6250 if (inst.relocs[0].exp.X_op == O_constant
6251 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
6252 {
6253 skip_whitespace (q);
6254 if (*q == '#')
6255 {
6256 q++;
6257 skip_whitespace (q);
6258 }
6259 if (*q == '-')
6260 inst.operands[i].negative = 1;
6261 }
c19d1205
ZW
6262 }
6263 }
a737bd4d
NC
6264 }
6265
c19d1205
ZW
6266 /* If at this point neither .preind nor .postind is set, we have a
6267 bare [Rn]{!}, which is shorthand for [Rn,#0]{!}. */
6268 if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
6269 {
6270 inst.operands[i].preind = 1;
e2b0ab59
AV
6271 inst.relocs[0].exp.X_op = O_constant;
6272 inst.relocs[0].exp.X_add_number = 0;
c19d1205
ZW
6273 }
6274 *str = p;
4962c51a
MS
6275 return PARSE_OPERAND_SUCCESS;
6276}
6277
6278static int
6279parse_address (char **str, int i)
6280{
21d799b5 6281 return parse_address_main (str, i, 0, GROUP_LDR) == PARSE_OPERAND_SUCCESS
477330fc 6282 ? SUCCESS : FAIL;
4962c51a
MS
6283}
6284
6285static parse_operand_result
6286parse_address_group_reloc (char **str, int i, group_reloc_type type)
6287{
6288 return parse_address_main (str, i, 1, type);
a737bd4d
NC
6289}
6290
b6895b4f
PB
6291/* Parse an operand for a MOVW or MOVT instruction. */
6292static int
6293parse_half (char **str)
6294{
6295 char * p;
5f4273c7 6296
b6895b4f
PB
6297 p = *str;
6298 skip_past_char (&p, '#');
5f4273c7 6299 if (strncasecmp (p, ":lower16:", 9) == 0)
e2b0ab59 6300 inst.relocs[0].type = BFD_RELOC_ARM_MOVW;
b6895b4f 6301 else if (strncasecmp (p, ":upper16:", 9) == 0)
e2b0ab59 6302 inst.relocs[0].type = BFD_RELOC_ARM_MOVT;
b6895b4f 6303
e2b0ab59 6304 if (inst.relocs[0].type != BFD_RELOC_UNUSED)
b6895b4f
PB
6305 {
6306 p += 9;
5f4273c7 6307 skip_whitespace (p);
b6895b4f
PB
6308 }
6309
e2b0ab59 6310 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
b6895b4f
PB
6311 return FAIL;
6312
e2b0ab59 6313 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 6314 {
e2b0ab59 6315 if (inst.relocs[0].exp.X_op != O_constant)
b6895b4f
PB
6316 {
6317 inst.error = _("constant expression expected");
6318 return FAIL;
6319 }
e2b0ab59
AV
6320 if (inst.relocs[0].exp.X_add_number < 0
6321 || inst.relocs[0].exp.X_add_number > 0xffff)
b6895b4f
PB
6322 {
6323 inst.error = _("immediate value out of range");
6324 return FAIL;
6325 }
6326 }
6327 *str = p;
6328 return SUCCESS;
6329}
6330
c19d1205 6331/* Miscellaneous. */
a737bd4d 6332
c19d1205
ZW
6333/* Parse a PSR flag operand. The value returned is FAIL on syntax error,
6334 or a bitmask suitable to be or-ed into the ARM msr instruction. */
6335static int
5b7c81bd 6336parse_psr (char **str, bool lhs)
09d92015 6337{
c19d1205
ZW
6338 char *p;
6339 unsigned long psr_field;
62b3e311
PB
6340 const struct asm_psr *psr;
6341 char *start;
5b7c81bd
AM
6342 bool is_apsr = false;
6343 bool m_profile = ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m);
09d92015 6344
a4482bb6
NC
6345 /* PR gas/12698: If the user has specified -march=all then m_profile will
6346 be TRUE, but we want to ignore it in this case as we are building for any
6347 CPU type, including non-m variants. */
823d2571 6348 if (ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
5b7c81bd 6349 m_profile = false;
a4482bb6 6350
c19d1205
ZW
6351 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
6352 feature for ease of use and backwards compatibility. */
6353 p = *str;
62b3e311 6354 if (strncasecmp (p, "SPSR", 4) == 0)
d2cd1205
JB
6355 {
6356 if (m_profile)
6357 goto unsupported_psr;
fa94de6b 6358
d2cd1205
JB
6359 psr_field = SPSR_BIT;
6360 }
6361 else if (strncasecmp (p, "CPSR", 4) == 0)
6362 {
6363 if (m_profile)
6364 goto unsupported_psr;
6365
6366 psr_field = 0;
6367 }
6368 else if (strncasecmp (p, "APSR", 4) == 0)
6369 {
6370 /* APSR[_<bits>] can be used as a synonym for CPSR[_<flags>] on ARMv7-A
6371 and ARMv7-R architecture CPUs. */
5b7c81bd 6372 is_apsr = true;
d2cd1205
JB
6373 psr_field = 0;
6374 }
6375 else if (m_profile)
62b3e311
PB
6376 {
6377 start = p;
6378 do
6379 p++;
6380 while (ISALNUM (*p) || *p == '_');
6381
d2cd1205
JB
6382 if (strncasecmp (start, "iapsr", 5) == 0
6383 || strncasecmp (start, "eapsr", 5) == 0
6384 || strncasecmp (start, "xpsr", 4) == 0
6385 || strncasecmp (start, "psr", 3) == 0)
6386 p = start + strcspn (start, "rR") + 1;
6387
629310ab 6388 psr = (const struct asm_psr *) str_hash_find_n (arm_v7m_psr_hsh, start,
fe0e921f 6389 p - start);
d2cd1205 6390
62b3e311
PB
6391 if (!psr)
6392 return FAIL;
09d92015 6393
d2cd1205
JB
6394 /* If APSR is being written, a bitfield may be specified. Note that
6395 APSR itself is handled above. */
6396 if (psr->field <= 3)
6397 {
6398 psr_field = psr->field;
5b7c81bd 6399 is_apsr = true;
d2cd1205
JB
6400 goto check_suffix;
6401 }
6402
62b3e311 6403 *str = p;
d2cd1205
JB
6404 /* M-profile MSR instructions have the mask field set to "10", except
6405 *PSR variants which modify APSR, which may use a different mask (and
6406 have been handled already). Do that by setting the PSR_f field
6407 here. */
6408 return psr->field | (lhs ? PSR_f : 0);
62b3e311 6409 }
d2cd1205
JB
6410 else
6411 goto unsupported_psr;
09d92015 6412
62b3e311 6413 p += 4;
dc1e8a47 6414 check_suffix:
c19d1205
ZW
6415 if (*p == '_')
6416 {
6417 /* A suffix follows. */
c19d1205
ZW
6418 p++;
6419 start = p;
a737bd4d 6420
c19d1205
ZW
6421 do
6422 p++;
6423 while (ISALNUM (*p) || *p == '_');
a737bd4d 6424
d2cd1205
JB
6425 if (is_apsr)
6426 {
6427 /* APSR uses a notation for bits, rather than fields. */
6428 unsigned int nzcvq_bits = 0;
6429 unsigned int g_bit = 0;
6430 char *bit;
fa94de6b 6431
d2cd1205
JB
6432 for (bit = start; bit != p; bit++)
6433 {
6434 switch (TOLOWER (*bit))
477330fc 6435 {
d2cd1205
JB
6436 case 'n':
6437 nzcvq_bits |= (nzcvq_bits & 0x01) ? 0x20 : 0x01;
6438 break;
6439
6440 case 'z':
6441 nzcvq_bits |= (nzcvq_bits & 0x02) ? 0x20 : 0x02;
6442 break;
6443
6444 case 'c':
6445 nzcvq_bits |= (nzcvq_bits & 0x04) ? 0x20 : 0x04;
6446 break;
6447
6448 case 'v':
6449 nzcvq_bits |= (nzcvq_bits & 0x08) ? 0x20 : 0x08;
6450 break;
fa94de6b 6451
d2cd1205
JB
6452 case 'q':
6453 nzcvq_bits |= (nzcvq_bits & 0x10) ? 0x20 : 0x10;
6454 break;
fa94de6b 6455
d2cd1205
JB
6456 case 'g':
6457 g_bit |= (g_bit & 0x1) ? 0x2 : 0x1;
6458 break;
fa94de6b 6459
d2cd1205
JB
6460 default:
6461 inst.error = _("unexpected bit specified after APSR");
6462 return FAIL;
6463 }
6464 }
fa94de6b 6465
d2cd1205
JB
6466 if (nzcvq_bits == 0x1f)
6467 psr_field |= PSR_f;
fa94de6b 6468
d2cd1205
JB
6469 if (g_bit == 0x1)
6470 {
6471 if (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp))
477330fc 6472 {
d2cd1205
JB
6473 inst.error = _("selected processor does not "
6474 "support DSP extension");
6475 return FAIL;
6476 }
6477
6478 psr_field |= PSR_s;
6479 }
fa94de6b 6480
d2cd1205
JB
6481 if ((nzcvq_bits & 0x20) != 0
6482 || (nzcvq_bits != 0x1f && nzcvq_bits != 0)
6483 || (g_bit & 0x2) != 0)
6484 {
6485 inst.error = _("bad bitmask specified after APSR");
6486 return FAIL;
6487 }
6488 }
6489 else
477330fc 6490 {
629310ab 6491 psr = (const struct asm_psr *) str_hash_find_n (arm_psr_hsh, start,
fe0e921f 6492 p - start);
d2cd1205 6493 if (!psr)
477330fc 6494 goto error;
a737bd4d 6495
d2cd1205
JB
6496 psr_field |= psr->field;
6497 }
a737bd4d 6498 }
c19d1205 6499 else
a737bd4d 6500 {
c19d1205
ZW
6501 if (ISALNUM (*p))
6502 goto error; /* Garbage after "[CS]PSR". */
6503
d2cd1205 6504 /* Unadorned APSR is equivalent to APSR_nzcvq/CPSR_f (for writes). This
477330fc 6505 is deprecated, but allow it anyway. */
d2cd1205
JB
6506 if (is_apsr && lhs)
6507 {
6508 psr_field |= PSR_f;
6509 as_tsktsk (_("writing to APSR without specifying a bitmask is "
6510 "deprecated"));
6511 }
6512 else if (!m_profile)
6513 /* These bits are never right for M-profile devices: don't set them
6514 (only code paths which read/write APSR reach here). */
6515 psr_field |= (PSR_c | PSR_f);
a737bd4d 6516 }
c19d1205
ZW
6517 *str = p;
6518 return psr_field;
a737bd4d 6519
d2cd1205
JB
6520 unsupported_psr:
6521 inst.error = _("selected processor does not support requested special "
6522 "purpose register");
6523 return FAIL;
6524
c19d1205
ZW
6525 error:
6526 inst.error = _("flag for {c}psr instruction expected");
6527 return FAIL;
a737bd4d
NC
6528}
6529
32c36c3c
AV
6530static int
6531parse_sys_vldr_vstr (char **str)
6532{
6533 unsigned i;
6534 int val = FAIL;
6535 struct {
6536 const char *name;
6537 int regl;
6538 int regh;
6539 } sysregs[] = {
6540 {"FPSCR", 0x1, 0x0},
6541 {"FPSCR_nzcvqc", 0x2, 0x0},
6542 {"VPR", 0x4, 0x1},
6543 {"P0", 0x5, 0x1},
6544 {"FPCXTNS", 0x6, 0x1},
ee3272d4
SP
6545 {"FPCXT_NS", 0x6, 0x1},
6546 {"fpcxtns", 0x6, 0x1},
6547 {"fpcxt_ns", 0x6, 0x1},
6548 {"FPCXTS", 0x7, 0x1},
6549 {"FPCXT_S", 0x7, 0x1},
6550 {"fpcxts", 0x7, 0x1},
6551 {"fpcxt_s", 0x7, 0x1}
32c36c3c
AV
6552 };
6553 char *op_end = strchr (*str, ',');
6554 size_t op_strlen = op_end - *str;
6555
6556 for (i = 0; i < sizeof (sysregs) / sizeof (sysregs[0]); i++)
6557 {
6558 if (!strncmp (*str, sysregs[i].name, op_strlen))
6559 {
6560 val = sysregs[i].regl | (sysregs[i].regh << 3);
6561 *str = op_end;
6562 break;
6563 }
6564 }
6565
6566 return val;
6567}
6568
c19d1205
ZW
6569/* Parse the flags argument to CPSI[ED]. Returns FAIL on error, or a
6570 value suitable for splatting into the AIF field of the instruction. */
a737bd4d 6571
c19d1205
ZW
6572static int
6573parse_cps_flags (char **str)
a737bd4d 6574{
c19d1205
ZW
6575 int val = 0;
6576 int saw_a_flag = 0;
6577 char *s = *str;
a737bd4d 6578
c19d1205
ZW
6579 for (;;)
6580 switch (*s++)
6581 {
6582 case '\0': case ',':
6583 goto done;
a737bd4d 6584
c19d1205
ZW
6585 case 'a': case 'A': saw_a_flag = 1; val |= 0x4; break;
6586 case 'i': case 'I': saw_a_flag = 1; val |= 0x2; break;
6587 case 'f': case 'F': saw_a_flag = 1; val |= 0x1; break;
a737bd4d 6588
c19d1205
ZW
6589 default:
6590 inst.error = _("unrecognized CPS flag");
6591 return FAIL;
6592 }
a737bd4d 6593
c19d1205
ZW
6594 done:
6595 if (saw_a_flag == 0)
a737bd4d 6596 {
c19d1205
ZW
6597 inst.error = _("missing CPS flags");
6598 return FAIL;
a737bd4d 6599 }
a737bd4d 6600
c19d1205
ZW
6601 *str = s - 1;
6602 return val;
a737bd4d
NC
6603}
6604
c19d1205
ZW
6605/* Parse an endian specifier ("BE" or "LE", case insensitive);
6606 returns 0 for big-endian, 1 for little-endian, FAIL for an error. */
a737bd4d
NC
6607
6608static int
c19d1205 6609parse_endian_specifier (char **str)
a737bd4d 6610{
c19d1205
ZW
6611 int little_endian;
6612 char *s = *str;
a737bd4d 6613
c19d1205
ZW
6614 if (strncasecmp (s, "BE", 2))
6615 little_endian = 0;
6616 else if (strncasecmp (s, "LE", 2))
6617 little_endian = 1;
6618 else
a737bd4d 6619 {
c19d1205 6620 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6621 return FAIL;
6622 }
6623
c19d1205 6624 if (ISALNUM (s[2]) || s[2] == '_')
a737bd4d 6625 {
c19d1205 6626 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6627 return FAIL;
6628 }
6629
c19d1205
ZW
6630 *str = s + 2;
6631 return little_endian;
6632}
a737bd4d 6633
c19d1205
ZW
6634/* Parse a rotation specifier: ROR #0, #8, #16, #24. *val receives a
6635 value suitable for poking into the rotate field of an sxt or sxta
6636 instruction, or FAIL on error. */
6637
6638static int
6639parse_ror (char **str)
6640{
6641 int rot;
6642 char *s = *str;
6643
6644 if (strncasecmp (s, "ROR", 3) == 0)
6645 s += 3;
6646 else
a737bd4d 6647 {
c19d1205 6648 inst.error = _("missing rotation field after comma");
a737bd4d
NC
6649 return FAIL;
6650 }
c19d1205 6651
5b7c81bd 6652 if (parse_immediate (&s, &rot, 0, 24, false) == FAIL)
c19d1205
ZW
6653 return FAIL;
6654
6655 switch (rot)
a737bd4d 6656 {
c19d1205
ZW
6657 case 0: *str = s; return 0x0;
6658 case 8: *str = s; return 0x1;
6659 case 16: *str = s; return 0x2;
6660 case 24: *str = s; return 0x3;
6661
6662 default:
6663 inst.error = _("rotation can only be 0, 8, 16, or 24");
a737bd4d
NC
6664 return FAIL;
6665 }
c19d1205 6666}
a737bd4d 6667
c19d1205
ZW
6668/* Parse a conditional code (from conds[] below). The value returned is in the
6669 range 0 .. 14, or FAIL. */
6670static int
6671parse_cond (char **str)
6672{
c462b453 6673 char *q;
c19d1205 6674 const struct asm_cond *c;
c462b453
PB
6675 int n;
6676 /* Condition codes are always 2 characters, so matching up to
6677 3 characters is sufficient. */
6678 char cond[3];
a737bd4d 6679
c462b453
PB
6680 q = *str;
6681 n = 0;
6682 while (ISALPHA (*q) && n < 3)
6683 {
e07e6e58 6684 cond[n] = TOLOWER (*q);
c462b453
PB
6685 q++;
6686 n++;
6687 }
a737bd4d 6688
629310ab 6689 c = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, cond, n);
c19d1205 6690 if (!c)
a737bd4d 6691 {
c19d1205 6692 inst.error = _("condition required");
a737bd4d
NC
6693 return FAIL;
6694 }
6695
c19d1205
ZW
6696 *str = q;
6697 return c->value;
6698}
6699
62b3e311
PB
6700/* Parse an option for a barrier instruction. Returns the encoding for the
6701 option, or FAIL. */
6702static int
6703parse_barrier (char **str)
6704{
6705 char *p, *q;
6706 const struct asm_barrier_opt *o;
6707
6708 p = q = *str;
6709 while (ISALPHA (*q))
6710 q++;
6711
629310ab 6712 o = (const struct asm_barrier_opt *) str_hash_find_n (arm_barrier_opt_hsh, p,
fe0e921f 6713 q - p);
62b3e311
PB
6714 if (!o)
6715 return FAIL;
6716
e797f7e0
MGD
6717 if (!mark_feature_used (&o->arch))
6718 return FAIL;
6719
62b3e311
PB
6720 *str = q;
6721 return o->value;
6722}
6723
92e90b6e
PB
6724/* Parse the operands of a table branch instruction. Similar to a memory
6725 operand. */
6726static int
6727parse_tb (char **str)
6728{
6729 char * p = *str;
6730 int reg;
6731
6732 if (skip_past_char (&p, '[') == FAIL)
ab1eb5fe
PB
6733 {
6734 inst.error = _("'[' expected");
6735 return FAIL;
6736 }
92e90b6e 6737
dcbf9037 6738 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6739 {
6740 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6741 return FAIL;
6742 }
6743 inst.operands[0].reg = reg;
6744
6745 if (skip_past_comma (&p) == FAIL)
ab1eb5fe
PB
6746 {
6747 inst.error = _("',' expected");
6748 return FAIL;
6749 }
5f4273c7 6750
dcbf9037 6751 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6752 {
6753 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6754 return FAIL;
6755 }
6756 inst.operands[0].imm = reg;
6757
6758 if (skip_past_comma (&p) == SUCCESS)
6759 {
6760 if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
6761 return FAIL;
e2b0ab59 6762 if (inst.relocs[0].exp.X_add_number != 1)
92e90b6e
PB
6763 {
6764 inst.error = _("invalid shift");
6765 return FAIL;
6766 }
6767 inst.operands[0].shifted = 1;
6768 }
6769
6770 if (skip_past_char (&p, ']') == FAIL)
6771 {
6772 inst.error = _("']' expected");
6773 return FAIL;
6774 }
6775 *str = p;
6776 return SUCCESS;
6777}
6778
5287ad62
JB
6779/* Parse the operands of a Neon VMOV instruction. See do_neon_mov for more
6780 information on the types the operands can take and how they are encoded.
037e8744
JB
6781 Up to four operands may be read; this function handles setting the
6782 ".present" field for each read operand itself.
5287ad62
JB
6783 Updates STR and WHICH_OPERAND if parsing is successful and returns SUCCESS,
6784 else returns FAIL. */
6785
6786static int
6787parse_neon_mov (char **str, int *which_operand)
6788{
6789 int i = *which_operand, val;
6790 enum arm_reg_type rtype;
6791 char *ptr = *str;
dcbf9037 6792 struct neon_type_el optype;
5f4273c7 6793
57785aa2
AV
6794 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6795 {
6796 /* Cases 17 or 19. */
6797 inst.operands[i].reg = val;
6798 inst.operands[i].isvec = 1;
6799 inst.operands[i].isscalar = 2;
6800 inst.operands[i].vectype = optype;
6801 inst.operands[i++].present = 1;
6802
6803 if (skip_past_comma (&ptr) == FAIL)
6804 goto wanted_comma;
6805
6806 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
6807 {
6808 /* Case 17: VMOV<c>.<dt> <Qd[idx]>, <Rt> */
6809 inst.operands[i].reg = val;
6810 inst.operands[i].isreg = 1;
6811 inst.operands[i].present = 1;
6812 }
6813 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6814 {
6815 /* Case 19: VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2> */
6816 inst.operands[i].reg = val;
6817 inst.operands[i].isvec = 1;
6818 inst.operands[i].isscalar = 2;
6819 inst.operands[i].vectype = optype;
6820 inst.operands[i++].present = 1;
6821
6822 if (skip_past_comma (&ptr) == FAIL)
6823 goto wanted_comma;
6824
6825 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6826 goto wanted_arm;
6827
6828 inst.operands[i].reg = val;
6829 inst.operands[i].isreg = 1;
6830 inst.operands[i++].present = 1;
6831
6832 if (skip_past_comma (&ptr) == FAIL)
6833 goto wanted_comma;
6834
6835 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6836 goto wanted_arm;
6837
6838 inst.operands[i].reg = val;
6839 inst.operands[i].isreg = 1;
6840 inst.operands[i].present = 1;
6841 }
6842 else
6843 {
6844 first_error (_("expected ARM or MVE vector register"));
6845 return FAIL;
6846 }
6847 }
6848 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
5287ad62
JB
6849 {
6850 /* Case 4: VMOV<c><q>.<size> <Dn[x]>, <Rd>. */
6851 inst.operands[i].reg = val;
6852 inst.operands[i].isscalar = 1;
dcbf9037 6853 inst.operands[i].vectype = optype;
5287ad62
JB
6854 inst.operands[i++].present = 1;
6855
6856 if (skip_past_comma (&ptr) == FAIL)
477330fc 6857 goto wanted_comma;
5f4273c7 6858
dcbf9037 6859 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
477330fc 6860 goto wanted_arm;
5f4273c7 6861
5287ad62
JB
6862 inst.operands[i].reg = val;
6863 inst.operands[i].isreg = 1;
6864 inst.operands[i].present = 1;
6865 }
57785aa2
AV
6866 else if (((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype, &optype))
6867 != FAIL)
6868 || ((val = arm_typed_reg_parse (&ptr, REG_TYPE_MQ, &rtype, &optype))
6869 != FAIL))
5287ad62
JB
6870 {
6871 /* Cases 0, 1, 2, 3, 5 (D only). */
6872 if (skip_past_comma (&ptr) == FAIL)
477330fc 6873 goto wanted_comma;
5f4273c7 6874
5287ad62
JB
6875 inst.operands[i].reg = val;
6876 inst.operands[i].isreg = 1;
6877 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
037e8744
JB
6878 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6879 inst.operands[i].isvec = 1;
dcbf9037 6880 inst.operands[i].vectype = optype;
5287ad62
JB
6881 inst.operands[i++].present = 1;
6882
dcbf9037 6883 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc
RM
6884 {
6885 /* Case 5: VMOV<c><q> <Dm>, <Rd>, <Rn>.
6886 Case 13: VMOV <Sd>, <Rm> */
6887 inst.operands[i].reg = val;
6888 inst.operands[i].isreg = 1;
6889 inst.operands[i].present = 1;
6890
6891 if (rtype == REG_TYPE_NQ)
6892 {
6893 first_error (_("can't use Neon quad register here"));
6894 return FAIL;
6895 }
6896 else if (rtype != REG_TYPE_VFS)
6897 {
6898 i++;
6899 if (skip_past_comma (&ptr) == FAIL)
6900 goto wanted_comma;
6901 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6902 goto wanted_arm;
6903 inst.operands[i].reg = val;
6904 inst.operands[i].isreg = 1;
6905 inst.operands[i].present = 1;
6906 }
6907 }
c4a23bf8
SP
6908 else if (((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype,
6909 &optype)) != FAIL)
6910 || ((val = arm_typed_reg_parse (&ptr, REG_TYPE_MQ, &rtype,
6911 &optype)) != FAIL))
477330fc
RM
6912 {
6913 /* Case 0: VMOV<c><q> <Qd>, <Qm>
6914 Case 1: VMOV<c><q> <Dd>, <Dm>
6915 Case 8: VMOV.F32 <Sd>, <Sm>
6916 Case 15: VMOV <Sd>, <Se>, <Rn>, <Rm> */
6917
6918 inst.operands[i].reg = val;
6919 inst.operands[i].isreg = 1;
6920 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
6921 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6922 inst.operands[i].isvec = 1;
6923 inst.operands[i].vectype = optype;
6924 inst.operands[i].present = 1;
6925
6926 if (skip_past_comma (&ptr) == SUCCESS)
6927 {
6928 /* Case 15. */
6929 i++;
6930
6931 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6932 goto wanted_arm;
6933
6934 inst.operands[i].reg = val;
6935 inst.operands[i].isreg = 1;
6936 inst.operands[i++].present = 1;
6937
6938 if (skip_past_comma (&ptr) == FAIL)
6939 goto wanted_comma;
6940
6941 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6942 goto wanted_arm;
6943
6944 inst.operands[i].reg = val;
6945 inst.operands[i].isreg = 1;
6946 inst.operands[i].present = 1;
6947 }
6948 }
4641781c 6949 else if (parse_qfloat_immediate (&ptr, &inst.operands[i].imm) == SUCCESS)
477330fc
RM
6950 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<float-imm>
6951 Case 3: VMOV<c><q>.<dt> <Dd>, #<float-imm>
6952 Case 10: VMOV.F32 <Sd>, #<imm>
6953 Case 11: VMOV.F64 <Dd>, #<imm> */
6954 inst.operands[i].immisfloat = 1;
5b7c81bd 6955 else if (parse_big_immediate (&ptr, i, NULL, /*allow_symbol_p=*/false)
8335d6aa 6956 == SUCCESS)
477330fc
RM
6957 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<imm>
6958 Case 3: VMOV<c><q>.<dt> <Dd>, #<imm> */
6959 ;
5287ad62 6960 else
477330fc
RM
6961 {
6962 first_error (_("expected <Rm> or <Dm> or <Qm> operand"));
6963 return FAIL;
6964 }
5287ad62 6965 }
dcbf9037 6966 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
5287ad62 6967 {
57785aa2 6968 /* Cases 6, 7, 16, 18. */
5287ad62
JB
6969 inst.operands[i].reg = val;
6970 inst.operands[i].isreg = 1;
6971 inst.operands[i++].present = 1;
5f4273c7 6972
5287ad62 6973 if (skip_past_comma (&ptr) == FAIL)
477330fc 6974 goto wanted_comma;
5f4273c7 6975
57785aa2
AV
6976 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6977 {
6978 /* Case 18: VMOV<c>.<dt> <Rt>, <Qn[idx]> */
6979 inst.operands[i].reg = val;
6980 inst.operands[i].isscalar = 2;
6981 inst.operands[i].present = 1;
6982 inst.operands[i].vectype = optype;
6983 }
6984 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
477330fc
RM
6985 {
6986 /* Case 6: VMOV<c><q>.<dt> <Rd>, <Dn[x]> */
6987 inst.operands[i].reg = val;
6988 inst.operands[i].isscalar = 1;
6989 inst.operands[i].present = 1;
6990 inst.operands[i].vectype = optype;
6991 }
dcbf9037 6992 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc 6993 {
477330fc
RM
6994 inst.operands[i].reg = val;
6995 inst.operands[i].isreg = 1;
6996 inst.operands[i++].present = 1;
6997
6998 if (skip_past_comma (&ptr) == FAIL)
6999 goto wanted_comma;
7000
7001 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFSD, &rtype, &optype))
57785aa2 7002 != FAIL)
477330fc 7003 {
57785aa2 7004 /* Case 7: VMOV<c><q> <Rd>, <Rn>, <Dm> */
477330fc 7005
477330fc
RM
7006 inst.operands[i].reg = val;
7007 inst.operands[i].isreg = 1;
7008 inst.operands[i].isvec = 1;
57785aa2 7009 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
477330fc
RM
7010 inst.operands[i].vectype = optype;
7011 inst.operands[i].present = 1;
57785aa2
AV
7012
7013 if (rtype == REG_TYPE_VFS)
7014 {
7015 /* Case 14. */
7016 i++;
7017 if (skip_past_comma (&ptr) == FAIL)
7018 goto wanted_comma;
7019 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL,
7020 &optype)) == FAIL)
7021 {
7022 first_error (_(reg_expected_msgs[REG_TYPE_VFS]));
7023 return FAIL;
7024 }
7025 inst.operands[i].reg = val;
7026 inst.operands[i].isreg = 1;
7027 inst.operands[i].isvec = 1;
7028 inst.operands[i].issingle = 1;
7029 inst.operands[i].vectype = optype;
7030 inst.operands[i].present = 1;
7031 }
7032 }
7033 else
7034 {
7035 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
7036 != FAIL)
7037 {
7038 /* Case 16: VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]> */
7039 inst.operands[i].reg = val;
7040 inst.operands[i].isvec = 1;
7041 inst.operands[i].isscalar = 2;
7042 inst.operands[i].vectype = optype;
7043 inst.operands[i++].present = 1;
7044
7045 if (skip_past_comma (&ptr) == FAIL)
7046 goto wanted_comma;
7047
7048 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
7049 == FAIL)
7050 {
7051 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
7052 return FAIL;
7053 }
7054 inst.operands[i].reg = val;
7055 inst.operands[i].isvec = 1;
7056 inst.operands[i].isscalar = 2;
7057 inst.operands[i].vectype = optype;
7058 inst.operands[i].present = 1;
7059 }
7060 else
7061 {
7062 first_error (_("VFP single, double or MVE vector register"
7063 " expected"));
7064 return FAIL;
7065 }
477330fc
RM
7066 }
7067 }
037e8744 7068 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL, &optype))
477330fc
RM
7069 != FAIL)
7070 {
7071 /* Case 13. */
7072 inst.operands[i].reg = val;
7073 inst.operands[i].isreg = 1;
7074 inst.operands[i].isvec = 1;
7075 inst.operands[i].issingle = 1;
7076 inst.operands[i].vectype = optype;
7077 inst.operands[i].present = 1;
7078 }
5287ad62
JB
7079 }
7080 else
7081 {
dcbf9037 7082 first_error (_("parse error"));
5287ad62
JB
7083 return FAIL;
7084 }
7085
7086 /* Successfully parsed the operands. Update args. */
7087 *which_operand = i;
7088 *str = ptr;
7089 return SUCCESS;
7090
5f4273c7 7091 wanted_comma:
dcbf9037 7092 first_error (_("expected comma"));
5287ad62 7093 return FAIL;
5f4273c7
NC
7094
7095 wanted_arm:
dcbf9037 7096 first_error (_(reg_expected_msgs[REG_TYPE_RN]));
5287ad62 7097 return FAIL;
5287ad62
JB
7098}
7099
5be8be5d
DG
7100/* Use this macro when the operand constraints are different
7101 for ARM and THUMB (e.g. ldrd). */
7102#define MIX_ARM_THUMB_OPERANDS(arm_operand, thumb_operand) \
7103 ((arm_operand) | ((thumb_operand) << 16))
7104
c19d1205
ZW
7105/* Matcher codes for parse_operands. */
7106enum operand_parse_code
7107{
7108 OP_stop, /* end of line */
7109
7110 OP_RR, /* ARM register */
7111 OP_RRnpc, /* ARM register, not r15 */
5be8be5d 7112 OP_RRnpcsp, /* ARM register, neither r15 nor r13 (a.k.a. 'BadReg') */
c19d1205 7113 OP_RRnpcb, /* ARM register, not r15, in square brackets */
fa94de6b 7114 OP_RRnpctw, /* ARM register, not r15 in Thumb-state or with writeback,
55881a11 7115 optional trailing ! */
c19d1205
ZW
7116 OP_RRw, /* ARM register, not r15, optional trailing ! */
7117 OP_RCP, /* Coprocessor number */
7118 OP_RCN, /* Coprocessor register */
7119 OP_RF, /* FPA register */
7120 OP_RVS, /* VFP single precision register */
5287ad62
JB
7121 OP_RVD, /* VFP double precision register (0..15) */
7122 OP_RND, /* Neon double precision register (0..31) */
5ee91343
AV
7123 OP_RNDMQ, /* Neon double precision (0..31) or MVE vector register. */
7124 OP_RNDMQR, /* Neon double precision (0..31), MVE vector or ARM register.
7125 */
66d1f7cc
AV
7126 OP_RNSDMQR, /* Neon single or double precision, MVE vector or ARM register.
7127 */
5287ad62 7128 OP_RNQ, /* Neon quad precision register */
5ee91343 7129 OP_RNQMQ, /* Neon quad or MVE vector register. */
037e8744 7130 OP_RVSD, /* VFP single or double precision register */
1b883319 7131 OP_RVSD_COND, /* VFP single, double precision register or condition code. */
dd9634d9 7132 OP_RVSDMQ, /* VFP single, double precision or MVE vector register. */
dec41383 7133 OP_RNSD, /* Neon single or double precision register */
5287ad62 7134 OP_RNDQ, /* Neon double or quad precision register */
5ee91343 7135 OP_RNDQMQ, /* Neon double, quad or MVE vector register. */
7df54120 7136 OP_RNDQMQR, /* Neon double, quad, MVE vector or ARM register. */
037e8744 7137 OP_RNSDQ, /* Neon single, double or quad precision register */
5287ad62 7138 OP_RNSC, /* Neon scalar D[X] */
c19d1205
ZW
7139 OP_RVC, /* VFP control register */
7140 OP_RMF, /* Maverick F register */
7141 OP_RMD, /* Maverick D register */
7142 OP_RMFX, /* Maverick FX register */
7143 OP_RMDX, /* Maverick DX register */
7144 OP_RMAX, /* Maverick AX register */
7145 OP_RMDS, /* Maverick DSPSC register */
7146 OP_RIWR, /* iWMMXt wR register */
7147 OP_RIWC, /* iWMMXt wC register */
7148 OP_RIWG, /* iWMMXt wCG register */
7149 OP_RXA, /* XScale accumulator register */
7150
5aae9ae9 7151 OP_RNSDMQ, /* Neon single, double or MVE vector register */
5ee91343
AV
7152 OP_RNSDQMQ, /* Neon single, double or quad register or MVE vector register
7153 */
7154 OP_RNSDQMQR, /* Neon single, double or quad register, MVE vector register or
7155 GPR (no SP/SP) */
a302e574 7156 OP_RMQ, /* MVE vector register. */
1b883319 7157 OP_RMQRZ, /* MVE vector or ARM register including ZR. */
35d1cfc2 7158 OP_RMQRR, /* MVE vector or ARM register. */
a302e574 7159
60f993ce
AV
7160 /* New operands for Armv8.1-M Mainline. */
7161 OP_LR, /* ARM LR register */
f1e1d7f3
AC
7162 OP_SP, /* ARM SP register */
7163 OP_R12,
a302e574
AV
7164 OP_RRe, /* ARM register, only even numbered. */
7165 OP_RRo, /* ARM register, only odd numbered, not r13 or r15. */
60f993ce 7166 OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
e39c1607 7167 OP_RR_ZR, /* ARM register or ZR but no PC */
60f993ce 7168
c19d1205 7169 OP_REGLST, /* ARM register list */
4b5a202f 7170 OP_CLRMLST, /* CLRM register list */
c19d1205
ZW
7171 OP_VRSLST, /* VFP single-precision register list */
7172 OP_VRDLST, /* VFP double-precision register list */
037e8744 7173 OP_VRSDLST, /* VFP single or double-precision register list (& quad) */
5287ad62
JB
7174 OP_NRDLST, /* Neon double-precision register list (d0-d31, qN aliases) */
7175 OP_NSTRLST, /* Neon element/structure list */
efd6b359 7176 OP_VRSDVLST, /* VFP single or double-precision register list and VPR */
35c228db
AV
7177 OP_MSTRLST2, /* MVE vector list with two elements. */
7178 OP_MSTRLST4, /* MVE vector list with four elements. */
5287ad62 7179
5287ad62 7180 OP_RNDQ_I0, /* Neon D or Q reg, or immediate zero. */
037e8744 7181 OP_RVSD_I0, /* VFP S or D reg, or immediate zero. */
aacf0b33 7182 OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero. */
1b883319
AV
7183 OP_RSVDMQ_FI0, /* VFP S, D, MVE vector register or floating point immediate
7184 zero. */
5287ad62 7185 OP_RR_RNSC, /* ARM reg or Neon scalar. */
dec41383 7186 OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar. */
037e8744 7187 OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar. */
886e1c73
AV
7188 OP_RNSDQ_RNSC_MQ, /* Vector S, D or Q reg, Neon scalar or MVE vector register.
7189 */
a8465a06
AV
7190 OP_RNSDQ_RNSC_MQ_RR, /* Vector S, D or Q reg, or MVE vector reg , or Neon
7191 scalar, or ARM register. */
5287ad62 7192 OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar. */
42b16635
AV
7193 OP_RNDQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, or ARM register. */
7194 OP_RNDQMQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, MVE vector or ARM
7195 register. */
5d281bf0 7196 OP_RNDQMQ_RNSC, /* Neon D, Q or MVE vector reg, or Neon scalar. */
5287ad62
JB
7197 OP_RND_RNSC, /* Neon D reg, or Neon scalar. */
7198 OP_VMOV, /* Neon VMOV operands. */
4316f0d2 7199 OP_RNDQ_Ibig, /* Neon D or Q reg, or big immediate for logic and VMVN. */
f601a00c
AV
7200 /* Neon D, Q or MVE vector register, or big immediate for logic and VMVN. */
7201 OP_RNDQMQ_Ibig,
5287ad62 7202 OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift. */
5150f0d8
AV
7203 OP_RNDQMQ_I63b_RR, /* Neon D or Q reg, immediate for shift, MVE vector or
7204 ARM register. */
2d447fca 7205 OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2. */
32c36c3c 7206 OP_VLDR, /* VLDR operand. */
5287ad62
JB
7207
7208 OP_I0, /* immediate zero */
c19d1205
ZW
7209 OP_I7, /* immediate value 0 .. 7 */
7210 OP_I15, /* 0 .. 15 */
7211 OP_I16, /* 1 .. 16 */
5287ad62 7212 OP_I16z, /* 0 .. 16 */
c19d1205
ZW
7213 OP_I31, /* 0 .. 31 */
7214 OP_I31w, /* 0 .. 31, optional trailing ! */
7215 OP_I32, /* 1 .. 32 */
5287ad62 7216 OP_I32z, /* 0 .. 32 */
08132bdd 7217 OP_I48_I64, /* 48 or 64 */
5287ad62 7218 OP_I63, /* 0 .. 63 */
c19d1205 7219 OP_I63s, /* -64 .. 63 */
5287ad62
JB
7220 OP_I64, /* 1 .. 64 */
7221 OP_I64z, /* 0 .. 64 */
5aae9ae9 7222 OP_I127, /* 0 .. 127 */
c19d1205 7223 OP_I255, /* 0 .. 255 */
4934a27c 7224 OP_I511, /* 0 .. 511 */
5aae9ae9 7225 OP_I4095, /* 0 .. 4095 */
4934a27c 7226 OP_I8191, /* 0 .. 8191 */
c19d1205
ZW
7227 OP_I4b, /* immediate, prefix optional, 1 .. 4 */
7228 OP_I7b, /* 0 .. 7 */
7229 OP_I15b, /* 0 .. 15 */
7230 OP_I31b, /* 0 .. 31 */
7231
7232 OP_SH, /* shifter operand */
4962c51a 7233 OP_SHG, /* shifter operand with possible group relocation */
c19d1205 7234 OP_ADDR, /* Memory address expression (any mode) */
35c228db 7235 OP_ADDRMVE, /* Memory address expression for MVE's VSTR/VLDR. */
4962c51a
MS
7236 OP_ADDRGLDR, /* Mem addr expr (any mode) with possible LDR group reloc */
7237 OP_ADDRGLDRS, /* Mem addr expr (any mode) with possible LDRS group reloc */
7238 OP_ADDRGLDC, /* Mem addr expr (any mode) with possible LDC group reloc */
c19d1205
ZW
7239 OP_EXP, /* arbitrary expression */
7240 OP_EXPi, /* same, with optional immediate prefix */
7241 OP_EXPr, /* same, with optional relocation suffix */
e2b0ab59 7242 OP_EXPs, /* same, with optional non-first operand relocation suffix */
b6895b4f 7243 OP_HALF, /* 0 .. 65535 or low/high reloc. */
c28eeff2
SN
7244 OP_IROT1, /* VCADD rotate immediate: 90, 270. */
7245 OP_IROT2, /* VCMLA rotate immediate: 0, 90, 180, 270. */
c19d1205
ZW
7246
7247 OP_CPSF, /* CPS flags */
7248 OP_ENDI, /* Endianness specifier */
d2cd1205
JB
7249 OP_wPSR, /* CPSR/SPSR/APSR mask for msr (writing). */
7250 OP_rPSR, /* CPSR/SPSR/APSR mask for msr (reading). */
c19d1205 7251 OP_COND, /* conditional code */
92e90b6e 7252 OP_TB, /* Table branch. */
c19d1205 7253
037e8744
JB
7254 OP_APSR_RR, /* ARM register or "APSR_nzcv". */
7255
c19d1205 7256 OP_RRnpc_I0, /* ARM register or literal 0 */
33eaf5de 7257 OP_RR_EXr, /* ARM register or expression with opt. reloc stuff. */
c19d1205
ZW
7258 OP_RR_EXi, /* ARM register or expression with imm prefix */
7259 OP_RF_IF, /* FPA register or immediate */
7260 OP_RIWR_RIWC, /* iWMMXt R or C reg */
41adaa5c 7261 OP_RIWC_RIWG, /* iWMMXt wC or wCG reg */
c19d1205
ZW
7262
7263 /* Optional operands. */
7264 OP_oI7b, /* immediate, prefix optional, 0 .. 7 */
7265 OP_oI31b, /* 0 .. 31 */
5287ad62 7266 OP_oI32b, /* 1 .. 32 */
5f1af56b 7267 OP_oI32z, /* 0 .. 32 */
c19d1205
ZW
7268 OP_oIffffb, /* 0 .. 65535 */
7269 OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
7270
7271 OP_oRR, /* ARM register */
60f993ce 7272 OP_oLR, /* ARM LR register */
c19d1205 7273 OP_oRRnpc, /* ARM register, not the PC */
5be8be5d 7274 OP_oRRnpcsp, /* ARM register, neither the PC nor the SP (a.k.a. BadReg) */
b6702015 7275 OP_oRRw, /* ARM register, not r15, optional trailing ! */
5287ad62
JB
7276 OP_oRND, /* Optional Neon double precision register */
7277 OP_oRNQ, /* Optional Neon quad precision register */
5ee91343 7278 OP_oRNDQMQ, /* Optional Neon double, quad or MVE vector register. */
5287ad62 7279 OP_oRNDQ, /* Optional Neon double or quad precision register */
037e8744 7280 OP_oRNSDQ, /* Optional single, double or quad precision vector register */
5ee91343
AV
7281 OP_oRNSDQMQ, /* Optional single, double or quad register or MVE vector
7282 register. */
66d1f7cc
AV
7283 OP_oRNSDMQ, /* Optional single, double register or MVE vector
7284 register. */
c19d1205
ZW
7285 OP_oSHll, /* LSL immediate */
7286 OP_oSHar, /* ASR immediate */
7287 OP_oSHllar, /* LSL or ASR immediate */
7288 OP_oROR, /* ROR 0/8/16/24 */
52e7f43d 7289 OP_oBARRIER_I15, /* Option argument for a barrier instruction. */
c19d1205 7290
1b883319
AV
7291 OP_oRMQRZ, /* optional MVE vector or ARM register including ZR. */
7292
5be8be5d
DG
7293 /* Some pre-defined mixed (ARM/THUMB) operands. */
7294 OP_RR_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
7295 OP_RRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
7296 OP_oRRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_oRRnpc, OP_oRRnpcsp),
7297
c19d1205
ZW
7298 OP_FIRST_OPTIONAL = OP_oI7b
7299};
a737bd4d 7300
c19d1205
ZW
7301/* Generic instruction operand parser. This does no encoding and no
7302 semantic validation; it merely squirrels values away in the inst
7303 structure. Returns SUCCESS or FAIL depending on whether the
7304 specified grammar matched. */
7305static int
5b7c81bd 7306parse_operands (char *str, const unsigned int *pattern, bool thumb)
c19d1205 7307{
5be8be5d 7308 unsigned const int *upat = pattern;
c19d1205
ZW
7309 char *backtrack_pos = 0;
7310 const char *backtrack_error = 0;
99aad254 7311 int i, val = 0, backtrack_index = 0;
5287ad62 7312 enum arm_reg_type rtype;
4962c51a 7313 parse_operand_result result;
5be8be5d 7314 unsigned int op_parse_code;
5b7c81bd 7315 bool partial_match;
c19d1205 7316
e07e6e58
NC
7317#define po_char_or_fail(chr) \
7318 do \
7319 { \
7320 if (skip_past_char (&str, chr) == FAIL) \
477330fc 7321 goto bad_args; \
e07e6e58
NC
7322 } \
7323 while (0)
c19d1205 7324
e07e6e58
NC
7325#define po_reg_or_fail(regtype) \
7326 do \
dcbf9037 7327 { \
e07e6e58 7328 val = arm_typed_reg_parse (& str, regtype, & rtype, \
477330fc 7329 & inst.operands[i].vectype); \
e07e6e58 7330 if (val == FAIL) \
477330fc
RM
7331 { \
7332 first_error (_(reg_expected_msgs[regtype])); \
7333 goto failure; \
7334 } \
e07e6e58
NC
7335 inst.operands[i].reg = val; \
7336 inst.operands[i].isreg = 1; \
7337 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7338 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7339 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc
RM
7340 || rtype == REG_TYPE_VFD \
7341 || rtype == REG_TYPE_NQ); \
1b883319 7342 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
dcbf9037 7343 } \
e07e6e58
NC
7344 while (0)
7345
7346#define po_reg_or_goto(regtype, label) \
7347 do \
7348 { \
7349 val = arm_typed_reg_parse (& str, regtype, & rtype, \
7350 & inst.operands[i].vectype); \
7351 if (val == FAIL) \
7352 goto label; \
dcbf9037 7353 \
e07e6e58
NC
7354 inst.operands[i].reg = val; \
7355 inst.operands[i].isreg = 1; \
7356 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7357 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7358 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc 7359 || rtype == REG_TYPE_VFD \
e07e6e58 7360 || rtype == REG_TYPE_NQ); \
1b883319 7361 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
e07e6e58
NC
7362 } \
7363 while (0)
7364
7365#define po_imm_or_fail(min, max, popt) \
7366 do \
7367 { \
7368 if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
7369 goto failure; \
7370 inst.operands[i].imm = val; \
7371 } \
7372 while (0)
7373
08132bdd
SP
7374#define po_imm1_or_imm2_or_fail(imm1, imm2, popt) \
7375 do \
7376 { \
7377 expressionS exp; \
7378 my_get_expression (&exp, &str, popt); \
7379 if (exp.X_op != O_constant) \
7380 { \
7381 inst.error = _("constant expression required"); \
7382 goto failure; \
7383 } \
7384 if (exp.X_add_number != imm1 && exp.X_add_number != imm2) \
7385 { \
7386 inst.error = _("immediate value 48 or 64 expected"); \
7387 goto failure; \
7388 } \
7389 inst.operands[i].imm = exp.X_add_number; \
7390 } \
7391 while (0)
7392
57785aa2 7393#define po_scalar_or_goto(elsz, label, reg_type) \
e07e6e58
NC
7394 do \
7395 { \
57785aa2
AV
7396 val = parse_scalar (& str, elsz, & inst.operands[i].vectype, \
7397 reg_type); \
e07e6e58
NC
7398 if (val == FAIL) \
7399 goto label; \
7400 inst.operands[i].reg = val; \
7401 inst.operands[i].isscalar = 1; \
7402 } \
7403 while (0)
7404
7405#define po_misc_or_fail(expr) \
7406 do \
7407 { \
7408 if (expr) \
7409 goto failure; \
7410 } \
7411 while (0)
7412
7413#define po_misc_or_fail_no_backtrack(expr) \
7414 do \
7415 { \
7416 result = expr; \
7417 if (result == PARSE_OPERAND_FAIL_NO_BACKTRACK) \
7418 backtrack_pos = 0; \
7419 if (result != PARSE_OPERAND_SUCCESS) \
7420 goto failure; \
7421 } \
7422 while (0)
4962c51a 7423
52e7f43d
RE
7424#define po_barrier_or_imm(str) \
7425 do \
7426 { \
7427 val = parse_barrier (&str); \
ccb84d65
JB
7428 if (val == FAIL && ! ISALPHA (*str)) \
7429 goto immediate; \
7430 if (val == FAIL \
7431 /* ISB can only take SY as an option. */ \
7432 || ((inst.instruction & 0xf0) == 0x60 \
7433 && val != 0xf)) \
52e7f43d 7434 { \
ccb84d65
JB
7435 inst.error = _("invalid barrier type"); \
7436 backtrack_pos = 0; \
7437 goto failure; \
52e7f43d
RE
7438 } \
7439 } \
7440 while (0)
7441
c19d1205
ZW
7442 skip_whitespace (str);
7443
7444 for (i = 0; upat[i] != OP_stop; i++)
7445 {
5be8be5d
DG
7446 op_parse_code = upat[i];
7447 if (op_parse_code >= 1<<16)
7448 op_parse_code = thumb ? (op_parse_code >> 16)
7449 : (op_parse_code & ((1<<16)-1));
7450
7451 if (op_parse_code >= OP_FIRST_OPTIONAL)
c19d1205
ZW
7452 {
7453 /* Remember where we are in case we need to backtrack. */
c19d1205
ZW
7454 backtrack_pos = str;
7455 backtrack_error = inst.error;
7456 backtrack_index = i;
7457 }
7458
b6702015 7459 if (i > 0 && (i > 1 || inst.operands[0].present))
c19d1205
ZW
7460 po_char_or_fail (',');
7461
5be8be5d 7462 switch (op_parse_code)
c19d1205
ZW
7463 {
7464 /* Registers */
7465 case OP_oRRnpc:
5be8be5d 7466 case OP_oRRnpcsp:
c19d1205 7467 case OP_RRnpc:
5be8be5d 7468 case OP_RRnpcsp:
c19d1205 7469 case OP_oRR:
a302e574
AV
7470 case OP_RRe:
7471 case OP_RRo:
60f993ce
AV
7472 case OP_LR:
7473 case OP_oLR:
f1e1d7f3
AC
7474 case OP_SP:
7475 case OP_R12:
c19d1205
ZW
7476 case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
7477 case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
7478 case OP_RCN: po_reg_or_fail (REG_TYPE_CN); break;
7479 case OP_RF: po_reg_or_fail (REG_TYPE_FN); break;
7480 case OP_RVS: po_reg_or_fail (REG_TYPE_VFS); break;
7481 case OP_RVD: po_reg_or_fail (REG_TYPE_VFD); break;
477330fc 7482 case OP_oRND:
66d1f7cc
AV
7483 case OP_RNSDMQR:
7484 po_reg_or_goto (REG_TYPE_VFS, try_rndmqr);
7485 break;
7486 try_rndmqr:
5ee91343
AV
7487 case OP_RNDMQR:
7488 po_reg_or_goto (REG_TYPE_RN, try_rndmq);
7489 break;
7490 try_rndmq:
7491 case OP_RNDMQ:
7492 po_reg_or_goto (REG_TYPE_MQ, try_rnd);
7493 break;
7494 try_rnd:
5287ad62 7495 case OP_RND: po_reg_or_fail (REG_TYPE_VFD); break;
cd2cf30b
PB
7496 case OP_RVC:
7497 po_reg_or_goto (REG_TYPE_VFC, coproc_reg);
7498 break;
7499 /* Also accept generic coprocessor regs for unknown registers. */
7500 coproc_reg:
ba6cd17f
SD
7501 po_reg_or_goto (REG_TYPE_CN, vpr_po);
7502 break;
7503 /* Also accept P0 or p0 for VPR.P0. Since P0 is already an
7504 existing register with a value of 0, this seems like the
7505 best way to parse P0. */
7506 vpr_po:
7507 if (strncasecmp (str, "P0", 2) == 0)
7508 {
7509 str += 2;
7510 inst.operands[i].isreg = 1;
7511 inst.operands[i].reg = 13;
7512 }
7513 else
7514 goto failure;
cd2cf30b 7515 break;
c19d1205
ZW
7516 case OP_RMF: po_reg_or_fail (REG_TYPE_MVF); break;
7517 case OP_RMD: po_reg_or_fail (REG_TYPE_MVD); break;
7518 case OP_RMFX: po_reg_or_fail (REG_TYPE_MVFX); break;
7519 case OP_RMDX: po_reg_or_fail (REG_TYPE_MVDX); break;
7520 case OP_RMAX: po_reg_or_fail (REG_TYPE_MVAX); break;
7521 case OP_RMDS: po_reg_or_fail (REG_TYPE_DSPSC); break;
7522 case OP_RIWR: po_reg_or_fail (REG_TYPE_MMXWR); break;
7523 case OP_RIWC: po_reg_or_fail (REG_TYPE_MMXWC); break;
7524 case OP_RIWG: po_reg_or_fail (REG_TYPE_MMXWCG); break;
7525 case OP_RXA: po_reg_or_fail (REG_TYPE_XSCALE); break;
477330fc 7526 case OP_oRNQ:
5ee91343
AV
7527 case OP_RNQMQ:
7528 po_reg_or_goto (REG_TYPE_MQ, try_nq);
7529 break;
7530 try_nq:
5287ad62 7531 case OP_RNQ: po_reg_or_fail (REG_TYPE_NQ); break;
dec41383 7532 case OP_RNSD: po_reg_or_fail (REG_TYPE_NSD); break;
7df54120
AV
7533 case OP_RNDQMQR:
7534 po_reg_or_goto (REG_TYPE_RN, try_rndqmq);
7535 break;
7536 try_rndqmq:
5ee91343
AV
7537 case OP_oRNDQMQ:
7538 case OP_RNDQMQ:
7539 po_reg_or_goto (REG_TYPE_MQ, try_rndq);
7540 break;
7541 try_rndq:
477330fc 7542 case OP_oRNDQ:
5287ad62 7543 case OP_RNDQ: po_reg_or_fail (REG_TYPE_NDQ); break;
dd9634d9
AV
7544 case OP_RVSDMQ:
7545 po_reg_or_goto (REG_TYPE_MQ, try_rvsd);
7546 break;
7547 try_rvsd:
477330fc 7548 case OP_RVSD: po_reg_or_fail (REG_TYPE_VFSD); break;
1b883319
AV
7549 case OP_RVSD_COND:
7550 po_reg_or_goto (REG_TYPE_VFSD, try_cond);
7551 break;
66d1f7cc 7552 case OP_oRNSDMQ:
5aae9ae9
MM
7553 case OP_RNSDMQ:
7554 po_reg_or_goto (REG_TYPE_NSD, try_mq2);
7555 break;
7556 try_mq2:
7557 po_reg_or_fail (REG_TYPE_MQ);
7558 break;
477330fc
RM
7559 case OP_oRNSDQ:
7560 case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ); break;
5ee91343
AV
7561 case OP_RNSDQMQR:
7562 po_reg_or_goto (REG_TYPE_RN, try_mq);
7563 break;
7564 try_mq:
7565 case OP_oRNSDQMQ:
7566 case OP_RNSDQMQ:
7567 po_reg_or_goto (REG_TYPE_MQ, try_nsdq2);
7568 break;
7569 try_nsdq2:
7570 po_reg_or_fail (REG_TYPE_NSDQ);
7571 inst.error = 0;
7572 break;
35d1cfc2
AV
7573 case OP_RMQRR:
7574 po_reg_or_goto (REG_TYPE_RN, try_rmq);
7575 break;
7576 try_rmq:
a302e574
AV
7577 case OP_RMQ:
7578 po_reg_or_fail (REG_TYPE_MQ);
7579 break;
477330fc
RM
7580 /* Neon scalar. Using an element size of 8 means that some invalid
7581 scalars are accepted here, so deal with those in later code. */
57785aa2 7582 case OP_RNSC: po_scalar_or_goto (8, failure, REG_TYPE_VFD); break;
477330fc
RM
7583
7584 case OP_RNDQ_I0:
7585 {
7586 po_reg_or_goto (REG_TYPE_NDQ, try_imm0);
7587 break;
7588 try_imm0:
5b7c81bd 7589 po_imm_or_fail (0, 0, true);
477330fc
RM
7590 }
7591 break;
7592
7593 case OP_RVSD_I0:
7594 po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
7595 break;
7596
1b883319
AV
7597 case OP_RSVDMQ_FI0:
7598 po_reg_or_goto (REG_TYPE_MQ, try_rsvd_fi0);
7599 break;
7600 try_rsvd_fi0:
aacf0b33
KT
7601 case OP_RSVD_FI0:
7602 {
7603 po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
7604 break;
7605 try_ifimm0:
7606 if (parse_ifimm_zero (&str))
7607 inst.operands[i].imm = 0;
7608 else
7609 {
7610 inst.error
7611 = _("only floating point zero is allowed as immediate value");
7612 goto failure;
7613 }
7614 }
7615 break;
7616
477330fc
RM
7617 case OP_RR_RNSC:
7618 {
57785aa2 7619 po_scalar_or_goto (8, try_rr, REG_TYPE_VFD);
477330fc
RM
7620 break;
7621 try_rr:
7622 po_reg_or_fail (REG_TYPE_RN);
7623 }
7624 break;
7625
a8465a06
AV
7626 case OP_RNSDQ_RNSC_MQ_RR:
7627 po_reg_or_goto (REG_TYPE_RN, try_rnsdq_rnsc_mq);
7628 break;
7629 try_rnsdq_rnsc_mq:
886e1c73
AV
7630 case OP_RNSDQ_RNSC_MQ:
7631 po_reg_or_goto (REG_TYPE_MQ, try_rnsdq_rnsc);
7632 break;
7633 try_rnsdq_rnsc:
477330fc
RM
7634 case OP_RNSDQ_RNSC:
7635 {
57785aa2
AV
7636 po_scalar_or_goto (8, try_nsdq, REG_TYPE_VFD);
7637 inst.error = 0;
477330fc
RM
7638 break;
7639 try_nsdq:
7640 po_reg_or_fail (REG_TYPE_NSDQ);
57785aa2 7641 inst.error = 0;
477330fc
RM
7642 }
7643 break;
7644
dec41383
JW
7645 case OP_RNSD_RNSC:
7646 {
57785aa2 7647 po_scalar_or_goto (8, try_s_scalar, REG_TYPE_VFD);
dec41383
JW
7648 break;
7649 try_s_scalar:
57785aa2 7650 po_scalar_or_goto (4, try_nsd, REG_TYPE_VFS);
dec41383
JW
7651 break;
7652 try_nsd:
7653 po_reg_or_fail (REG_TYPE_NSD);
7654 }
7655 break;
7656
42b16635
AV
7657 case OP_RNDQMQ_RNSC_RR:
7658 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc_rr);
7659 break;
7660 try_rndq_rnsc_rr:
7661 case OP_RNDQ_RNSC_RR:
7662 po_reg_or_goto (REG_TYPE_RN, try_rndq_rnsc);
7663 break;
5d281bf0
AV
7664 case OP_RNDQMQ_RNSC:
7665 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc);
7666 break;
7667 try_rndq_rnsc:
477330fc
RM
7668 case OP_RNDQ_RNSC:
7669 {
57785aa2 7670 po_scalar_or_goto (8, try_ndq, REG_TYPE_VFD);
477330fc
RM
7671 break;
7672 try_ndq:
7673 po_reg_or_fail (REG_TYPE_NDQ);
7674 }
7675 break;
7676
7677 case OP_RND_RNSC:
7678 {
57785aa2 7679 po_scalar_or_goto (8, try_vfd, REG_TYPE_VFD);
477330fc
RM
7680 break;
7681 try_vfd:
7682 po_reg_or_fail (REG_TYPE_VFD);
7683 }
7684 break;
7685
7686 case OP_VMOV:
7687 /* WARNING: parse_neon_mov can move the operand counter, i. If we're
7688 not careful then bad things might happen. */
7689 po_misc_or_fail (parse_neon_mov (&str, &i) == FAIL);
7690 break;
7691
f601a00c
AV
7692 case OP_RNDQMQ_Ibig:
7693 po_reg_or_goto (REG_TYPE_MQ, try_rndq_ibig);
7694 break;
7695 try_rndq_ibig:
477330fc
RM
7696 case OP_RNDQ_Ibig:
7697 {
7698 po_reg_or_goto (REG_TYPE_NDQ, try_immbig);
7699 break;
7700 try_immbig:
7701 /* There's a possibility of getting a 64-bit immediate here, so
7702 we need special handling. */
5b7c81bd 7703 if (parse_big_immediate (&str, i, NULL, /*allow_symbol_p=*/false)
8335d6aa 7704 == FAIL)
477330fc
RM
7705 {
7706 inst.error = _("immediate value is out of range");
7707 goto failure;
7708 }
7709 }
7710 break;
7711
5150f0d8
AV
7712 case OP_RNDQMQ_I63b_RR:
7713 po_reg_or_goto (REG_TYPE_MQ, try_rndq_i63b_rr);
7714 break;
7715 try_rndq_i63b_rr:
7716 po_reg_or_goto (REG_TYPE_RN, try_rndq_i63b);
7717 break;
7718 try_rndq_i63b:
477330fc
RM
7719 case OP_RNDQ_I63b:
7720 {
7721 po_reg_or_goto (REG_TYPE_NDQ, try_shimm);
7722 break;
7723 try_shimm:
5b7c81bd 7724 po_imm_or_fail (0, 63, true);
477330fc
RM
7725 }
7726 break;
c19d1205
ZW
7727
7728 case OP_RRnpcb:
7729 po_char_or_fail ('[');
7730 po_reg_or_fail (REG_TYPE_RN);
7731 po_char_or_fail (']');
7732 break;
a737bd4d 7733
55881a11 7734 case OP_RRnpctw:
c19d1205 7735 case OP_RRw:
b6702015 7736 case OP_oRRw:
c19d1205
ZW
7737 po_reg_or_fail (REG_TYPE_RN);
7738 if (skip_past_char (&str, '!') == SUCCESS)
7739 inst.operands[i].writeback = 1;
7740 break;
7741
7742 /* Immediates */
5b7c81bd
AM
7743 case OP_I7: po_imm_or_fail ( 0, 7, false); break;
7744 case OP_I15: po_imm_or_fail ( 0, 15, false); break;
7745 case OP_I16: po_imm_or_fail ( 1, 16, false); break;
7746 case OP_I16z: po_imm_or_fail ( 0, 16, false); break;
7747 case OP_I31: po_imm_or_fail ( 0, 31, false); break;
7748 case OP_I32: po_imm_or_fail ( 1, 32, false); break;
7749 case OP_I32z: po_imm_or_fail ( 0, 32, false); break;
7750 case OP_I48_I64: po_imm1_or_imm2_or_fail (48, 64, false); break;
7751 case OP_I63s: po_imm_or_fail (-64, 63, false); break;
7752 case OP_I63: po_imm_or_fail ( 0, 63, false); break;
7753 case OP_I64: po_imm_or_fail ( 1, 64, false); break;
7754 case OP_I64z: po_imm_or_fail ( 0, 64, false); break;
7755 case OP_I127: po_imm_or_fail ( 0, 127, false); break;
7756 case OP_I255: po_imm_or_fail ( 0, 255, false); break;
7757 case OP_I511: po_imm_or_fail ( 0, 511, false); break;
7758 case OP_I4095: po_imm_or_fail ( 0, 4095, false); break;
7759 case OP_I8191: po_imm_or_fail ( 0, 8191, false); break;
7760 case OP_I4b: po_imm_or_fail ( 1, 4, true); break;
c19d1205 7761 case OP_oI7b:
5b7c81bd
AM
7762 case OP_I7b: po_imm_or_fail ( 0, 7, true); break;
7763 case OP_I15b: po_imm_or_fail ( 0, 15, true); break;
c19d1205 7764 case OP_oI31b:
5b7c81bd
AM
7765 case OP_I31b: po_imm_or_fail ( 0, 31, true); break;
7766 case OP_oI32b: po_imm_or_fail ( 1, 32, true); break;
7767 case OP_oI32z: po_imm_or_fail ( 0, 32, true); break;
7768 case OP_oIffffb: po_imm_or_fail ( 0, 0xffff, true); break;
c19d1205
ZW
7769
7770 /* Immediate variants */
7771 case OP_oI255c:
7772 po_char_or_fail ('{');
5b7c81bd 7773 po_imm_or_fail (0, 255, true);
c19d1205
ZW
7774 po_char_or_fail ('}');
7775 break;
7776
7777 case OP_I31w:
7778 /* The expression parser chokes on a trailing !, so we have
7779 to find it first and zap it. */
7780 {
7781 char *s = str;
7782 while (*s && *s != ',')
7783 s++;
7784 if (s[-1] == '!')
7785 {
7786 s[-1] = '\0';
7787 inst.operands[i].writeback = 1;
7788 }
5b7c81bd 7789 po_imm_or_fail (0, 31, true);
c19d1205
ZW
7790 if (str == s - 1)
7791 str = s;
7792 }
7793 break;
7794
7795 /* Expressions */
7796 case OP_EXPi: EXPi:
e2b0ab59 7797 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7798 GE_OPT_PREFIX));
7799 break;
7800
7801 case OP_EXP:
e2b0ab59 7802 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7803 GE_NO_PREFIX));
7804 break;
7805
7806 case OP_EXPr: EXPr:
e2b0ab59 7807 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205 7808 GE_NO_PREFIX));
e2b0ab59 7809 if (inst.relocs[0].exp.X_op == O_symbol)
a737bd4d 7810 {
c19d1205
ZW
7811 val = parse_reloc (&str);
7812 if (val == -1)
7813 {
7814 inst.error = _("unrecognized relocation suffix");
7815 goto failure;
7816 }
7817 else if (val != BFD_RELOC_UNUSED)
7818 {
7819 inst.operands[i].imm = val;
7820 inst.operands[i].hasreloc = 1;
7821 }
a737bd4d 7822 }
c19d1205 7823 break;
a737bd4d 7824
e2b0ab59
AV
7825 case OP_EXPs:
7826 po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
7827 GE_NO_PREFIX));
7828 if (inst.relocs[i].exp.X_op == O_symbol)
7829 {
7830 inst.operands[i].hasreloc = 1;
7831 }
7832 else if (inst.relocs[i].exp.X_op == O_constant)
7833 {
7834 inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
7835 inst.operands[i].hasreloc = 0;
7836 }
7837 break;
7838
b6895b4f
PB
7839 /* Operand for MOVW or MOVT. */
7840 case OP_HALF:
7841 po_misc_or_fail (parse_half (&str));
7842 break;
7843
e07e6e58 7844 /* Register or expression. */
c19d1205
ZW
7845 case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
7846 case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
a737bd4d 7847
e07e6e58 7848 /* Register or immediate. */
c19d1205 7849 case OP_RRnpc_I0: po_reg_or_goto (REG_TYPE_RN, I0); break;
5b7c81bd 7850 I0: po_imm_or_fail (0, 0, false); break;
a737bd4d 7851
23d00a41 7852 case OP_RRnpcsp_I32: po_reg_or_goto (REG_TYPE_RN, I32); break;
5b7c81bd 7853 I32: po_imm_or_fail (1, 32, false); break;
23d00a41 7854
c19d1205
ZW
7855 case OP_RF_IF: po_reg_or_goto (REG_TYPE_FN, IF); break;
7856 IF:
7857 if (!is_immediate_prefix (*str))
7858 goto bad_args;
7859 str++;
7860 val = parse_fpa_immediate (&str);
7861 if (val == FAIL)
7862 goto failure;
7863 /* FPA immediates are encoded as registers 8-15.
7864 parse_fpa_immediate has already applied the offset. */
7865 inst.operands[i].reg = val;
7866 inst.operands[i].isreg = 1;
7867 break;
09d92015 7868
2d447fca 7869 case OP_RIWR_I32z: po_reg_or_goto (REG_TYPE_MMXWR, I32z); break;
5b7c81bd 7870 I32z: po_imm_or_fail (0, 32, false); break;
2d447fca 7871
e07e6e58 7872 /* Two kinds of register. */
c19d1205
ZW
7873 case OP_RIWR_RIWC:
7874 {
7875 struct reg_entry *rege = arm_reg_parse_multi (&str);
97f87066
JM
7876 if (!rege
7877 || (rege->type != REG_TYPE_MMXWR
7878 && rege->type != REG_TYPE_MMXWC
7879 && rege->type != REG_TYPE_MMXWCG))
c19d1205
ZW
7880 {
7881 inst.error = _("iWMMXt data or control register expected");
7882 goto failure;
7883 }
7884 inst.operands[i].reg = rege->number;
7885 inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
7886 }
7887 break;
09d92015 7888
41adaa5c
JM
7889 case OP_RIWC_RIWG:
7890 {
7891 struct reg_entry *rege = arm_reg_parse_multi (&str);
7892 if (!rege
7893 || (rege->type != REG_TYPE_MMXWC
7894 && rege->type != REG_TYPE_MMXWCG))
7895 {
7896 inst.error = _("iWMMXt control register expected");
7897 goto failure;
7898 }
7899 inst.operands[i].reg = rege->number;
7900 inst.operands[i].isreg = 1;
7901 }
7902 break;
7903
c19d1205
ZW
7904 /* Misc */
7905 case OP_CPSF: val = parse_cps_flags (&str); break;
7906 case OP_ENDI: val = parse_endian_specifier (&str); break;
7907 case OP_oROR: val = parse_ror (&str); break;
1b883319 7908 try_cond:
c19d1205 7909 case OP_COND: val = parse_cond (&str); break;
52e7f43d
RE
7910 case OP_oBARRIER_I15:
7911 po_barrier_or_imm (str); break;
7912 immediate:
5b7c81bd 7913 if (parse_immediate (&str, &val, 0, 15, true) == FAIL)
477330fc 7914 goto failure;
52e7f43d 7915 break;
c19d1205 7916
fa94de6b 7917 case OP_wPSR:
d2cd1205 7918 case OP_rPSR:
90ec0d68
MGD
7919 po_reg_or_goto (REG_TYPE_RNB, try_psr);
7920 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_virt))
7921 {
7922 inst.error = _("Banked registers are not available with this "
7923 "architecture.");
7924 goto failure;
7925 }
7926 break;
d2cd1205
JB
7927 try_psr:
7928 val = parse_psr (&str, op_parse_code == OP_wPSR);
7929 break;
037e8744 7930
32c36c3c
AV
7931 case OP_VLDR:
7932 po_reg_or_goto (REG_TYPE_VFSD, try_sysreg);
7933 break;
7934 try_sysreg:
7935 val = parse_sys_vldr_vstr (&str);
7936 break;
7937
477330fc
RM
7938 case OP_APSR_RR:
7939 po_reg_or_goto (REG_TYPE_RN, try_apsr);
7940 break;
7941 try_apsr:
7942 /* Parse "APSR_nvzc" operand (for FMSTAT-equivalent MRS
7943 instruction). */
7944 if (strncasecmp (str, "APSR_", 5) == 0)
7945 {
7946 unsigned found = 0;
7947 str += 5;
7948 while (found < 15)
7949 switch (*str++)
7950 {
7951 case 'c': found = (found & 1) ? 16 : found | 1; break;
7952 case 'n': found = (found & 2) ? 16 : found | 2; break;
7953 case 'z': found = (found & 4) ? 16 : found | 4; break;
7954 case 'v': found = (found & 8) ? 16 : found | 8; break;
7955 default: found = 16;
7956 }
7957 if (found != 15)
7958 goto failure;
7959 inst.operands[i].isvec = 1;
f7c21dc7
NC
7960 /* APSR_nzcv is encoded in instructions as if it were the REG_PC. */
7961 inst.operands[i].reg = REG_PC;
477330fc
RM
7962 }
7963 else
7964 goto failure;
7965 break;
037e8744 7966
92e90b6e
PB
7967 case OP_TB:
7968 po_misc_or_fail (parse_tb (&str));
7969 break;
7970
e07e6e58 7971 /* Register lists. */
c19d1205 7972 case OP_REGLST:
4b5a202f 7973 val = parse_reg_list (&str, REGLIST_RN);
c19d1205
ZW
7974 if (*str == '^')
7975 {
5e0d7f77 7976 inst.operands[i].writeback = 1;
c19d1205
ZW
7977 str++;
7978 }
7979 break;
09d92015 7980
4b5a202f
AV
7981 case OP_CLRMLST:
7982 val = parse_reg_list (&str, REGLIST_CLRM);
7983 break;
7984
c19d1205 7985 case OP_VRSLST:
efd6b359
AV
7986 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_S,
7987 &partial_match);
c19d1205 7988 break;
09d92015 7989
c19d1205 7990 case OP_VRDLST:
efd6b359
AV
7991 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_D,
7992 &partial_match);
c19d1205 7993 break;
a737bd4d 7994
477330fc
RM
7995 case OP_VRSDLST:
7996 /* Allow Q registers too. */
7997 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7998 REGLIST_NEON_D, &partial_match);
477330fc
RM
7999 if (val == FAIL)
8000 {
8001 inst.error = NULL;
8002 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359
AV
8003 REGLIST_VFP_S, &partial_match);
8004 inst.operands[i].issingle = 1;
8005 }
8006 break;
8007
8008 case OP_VRSDVLST:
8009 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
8010 REGLIST_VFP_D_VPR, &partial_match);
8011 if (val == FAIL && !partial_match)
8012 {
8013 inst.error = NULL;
8014 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
8015 REGLIST_VFP_S_VPR, &partial_match);
477330fc
RM
8016 inst.operands[i].issingle = 1;
8017 }
8018 break;
8019
8020 case OP_NRDLST:
8021 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 8022 REGLIST_NEON_D, &partial_match);
477330fc 8023 break;
5287ad62 8024
35c228db
AV
8025 case OP_MSTRLST4:
8026 case OP_MSTRLST2:
8027 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
8028 1, &inst.operands[i].vectype);
8029 if (val != (((op_parse_code == OP_MSTRLST2) ? 3 : 7) << 5 | 0xe))
8030 goto failure;
8031 break;
5287ad62 8032 case OP_NSTRLST:
477330fc 8033 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
35c228db 8034 0, &inst.operands[i].vectype);
477330fc 8035 break;
5287ad62 8036
c19d1205 8037 /* Addressing modes */
35c228db
AV
8038 case OP_ADDRMVE:
8039 po_misc_or_fail (parse_address_group_reloc (&str, i, GROUP_MVE));
8040 break;
8041
c19d1205
ZW
8042 case OP_ADDR:
8043 po_misc_or_fail (parse_address (&str, i));
8044 break;
09d92015 8045
4962c51a
MS
8046 case OP_ADDRGLDR:
8047 po_misc_or_fail_no_backtrack (
477330fc 8048 parse_address_group_reloc (&str, i, GROUP_LDR));
4962c51a
MS
8049 break;
8050
8051 case OP_ADDRGLDRS:
8052 po_misc_or_fail_no_backtrack (
477330fc 8053 parse_address_group_reloc (&str, i, GROUP_LDRS));
4962c51a
MS
8054 break;
8055
8056 case OP_ADDRGLDC:
8057 po_misc_or_fail_no_backtrack (
477330fc 8058 parse_address_group_reloc (&str, i, GROUP_LDC));
4962c51a
MS
8059 break;
8060
c19d1205
ZW
8061 case OP_SH:
8062 po_misc_or_fail (parse_shifter_operand (&str, i));
8063 break;
09d92015 8064
4962c51a
MS
8065 case OP_SHG:
8066 po_misc_or_fail_no_backtrack (
477330fc 8067 parse_shifter_operand_group_reloc (&str, i));
4962c51a
MS
8068 break;
8069
c19d1205
ZW
8070 case OP_oSHll:
8071 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_IMMEDIATE));
8072 break;
09d92015 8073
c19d1205
ZW
8074 case OP_oSHar:
8075 po_misc_or_fail (parse_shift (&str, i, SHIFT_ASR_IMMEDIATE));
8076 break;
09d92015 8077
c19d1205
ZW
8078 case OP_oSHllar:
8079 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
8080 break;
09d92015 8081
1b883319
AV
8082 case OP_RMQRZ:
8083 case OP_oRMQRZ:
8084 po_reg_or_goto (REG_TYPE_MQ, try_rr_zr);
8085 break;
e39c1607
SD
8086
8087 case OP_RR_ZR:
1b883319
AV
8088 try_rr_zr:
8089 po_reg_or_goto (REG_TYPE_RN, ZR);
8090 break;
8091 ZR:
8092 po_reg_or_fail (REG_TYPE_ZR);
8093 break;
8094
c19d1205 8095 default:
5be8be5d 8096 as_fatal (_("unhandled operand code %d"), op_parse_code);
c19d1205 8097 }
09d92015 8098
c19d1205
ZW
8099 /* Various value-based sanity checks and shared operations. We
8100 do not signal immediate failures for the register constraints;
8101 this allows a syntax error to take precedence. */
5be8be5d 8102 switch (op_parse_code)
c19d1205
ZW
8103 {
8104 case OP_oRRnpc:
8105 case OP_RRnpc:
8106 case OP_RRnpcb:
8107 case OP_RRw:
b6702015 8108 case OP_oRRw:
c19d1205
ZW
8109 case OP_RRnpc_I0:
8110 if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
8111 inst.error = BAD_PC;
8112 break;
09d92015 8113
5be8be5d
DG
8114 case OP_oRRnpcsp:
8115 case OP_RRnpcsp:
23d00a41 8116 case OP_RRnpcsp_I32:
5be8be5d
DG
8117 if (inst.operands[i].isreg)
8118 {
8119 if (inst.operands[i].reg == REG_PC)
8120 inst.error = BAD_PC;
5c8ed6a4
JW
8121 else if (inst.operands[i].reg == REG_SP
8122 /* The restriction on Rd/Rt/Rt2 on Thumb mode has been
8123 relaxed since ARMv8-A. */
8124 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
8125 {
8126 gas_assert (thumb);
8127 inst.error = BAD_SP;
8128 }
5be8be5d
DG
8129 }
8130 break;
8131
55881a11 8132 case OP_RRnpctw:
fa94de6b
RM
8133 if (inst.operands[i].isreg
8134 && inst.operands[i].reg == REG_PC
55881a11
MGD
8135 && (inst.operands[i].writeback || thumb))
8136 inst.error = BAD_PC;
8137 break;
8138
1b883319 8139 case OP_RVSD_COND:
32c36c3c
AV
8140 case OP_VLDR:
8141 if (inst.operands[i].isreg)
8142 break;
8143 /* fall through. */
1b883319 8144
c19d1205
ZW
8145 case OP_CPSF:
8146 case OP_ENDI:
8147 case OP_oROR:
d2cd1205
JB
8148 case OP_wPSR:
8149 case OP_rPSR:
c19d1205 8150 case OP_COND:
52e7f43d 8151 case OP_oBARRIER_I15:
c19d1205 8152 case OP_REGLST:
4b5a202f 8153 case OP_CLRMLST:
c19d1205
ZW
8154 case OP_VRSLST:
8155 case OP_VRDLST:
477330fc 8156 case OP_VRSDLST:
efd6b359 8157 case OP_VRSDVLST:
477330fc
RM
8158 case OP_NRDLST:
8159 case OP_NSTRLST:
35c228db
AV
8160 case OP_MSTRLST2:
8161 case OP_MSTRLST4:
c19d1205
ZW
8162 if (val == FAIL)
8163 goto failure;
8164 inst.operands[i].imm = val;
8165 break;
a737bd4d 8166
60f993ce
AV
8167 case OP_LR:
8168 case OP_oLR:
8169 if (inst.operands[i].reg != REG_LR)
8170 inst.error = _("operand must be LR register");
8171 break;
8172
f1e1d7f3
AC
8173 case OP_SP:
8174 if (inst.operands[i].reg != REG_SP)
8175 inst.error = _("operand must be SP register");
8176 break;
8177
8178 case OP_R12:
8179 if (inst.operands[i].reg != REG_R12)
8180 inst.error = _("operand must be r12");
8181 break;
8182
1b883319
AV
8183 case OP_RMQRZ:
8184 case OP_oRMQRZ:
e39c1607 8185 case OP_RR_ZR:
1b883319
AV
8186 if (!inst.operands[i].iszr && inst.operands[i].reg == REG_PC)
8187 inst.error = BAD_PC;
8188 break;
8189
a302e574
AV
8190 case OP_RRe:
8191 if (inst.operands[i].isreg
8192 && (inst.operands[i].reg & 0x00000001) != 0)
8193 inst.error = BAD_ODD;
8194 break;
8195
8196 case OP_RRo:
8197 if (inst.operands[i].isreg)
8198 {
8199 if ((inst.operands[i].reg & 0x00000001) != 1)
8200 inst.error = BAD_EVEN;
8201 else if (inst.operands[i].reg == REG_SP)
8202 as_tsktsk (MVE_BAD_SP);
8203 else if (inst.operands[i].reg == REG_PC)
8204 inst.error = BAD_PC;
8205 }
8206 break;
8207
c19d1205
ZW
8208 default:
8209 break;
8210 }
09d92015 8211
c19d1205
ZW
8212 /* If we get here, this operand was successfully parsed. */
8213 inst.operands[i].present = 1;
8214 continue;
09d92015 8215
c19d1205 8216 bad_args:
09d92015 8217 inst.error = BAD_ARGS;
c19d1205
ZW
8218
8219 failure:
8220 if (!backtrack_pos)
d252fdde
PB
8221 {
8222 /* The parse routine should already have set inst.error, but set a
5f4273c7 8223 default here just in case. */
d252fdde 8224 if (!inst.error)
5ee91343 8225 inst.error = BAD_SYNTAX;
d252fdde
PB
8226 return FAIL;
8227 }
c19d1205
ZW
8228
8229 /* Do not backtrack over a trailing optional argument that
8230 absorbed some text. We will only fail again, with the
8231 'garbage following instruction' error message, which is
8232 probably less helpful than the current one. */
8233 if (backtrack_index == i && backtrack_pos != str
8234 && upat[i+1] == OP_stop)
d252fdde
PB
8235 {
8236 if (!inst.error)
5ee91343 8237 inst.error = BAD_SYNTAX;
d252fdde
PB
8238 return FAIL;
8239 }
c19d1205
ZW
8240
8241 /* Try again, skipping the optional argument at backtrack_pos. */
8242 str = backtrack_pos;
8243 inst.error = backtrack_error;
8244 inst.operands[backtrack_index].present = 0;
8245 i = backtrack_index;
8246 backtrack_pos = 0;
09d92015 8247 }
09d92015 8248
c19d1205
ZW
8249 /* Check that we have parsed all the arguments. */
8250 if (*str != '\0' && !inst.error)
8251 inst.error = _("garbage following instruction");
09d92015 8252
c19d1205 8253 return inst.error ? FAIL : SUCCESS;
09d92015
MM
8254}
8255
c19d1205
ZW
8256#undef po_char_or_fail
8257#undef po_reg_or_fail
8258#undef po_reg_or_goto
8259#undef po_imm_or_fail
5287ad62 8260#undef po_scalar_or_fail
52e7f43d 8261#undef po_barrier_or_imm
e07e6e58 8262
c19d1205 8263/* Shorthand macro for instruction encoding functions issuing errors. */
e07e6e58
NC
8264#define constraint(expr, err) \
8265 do \
c19d1205 8266 { \
e07e6e58
NC
8267 if (expr) \
8268 { \
8269 inst.error = err; \
8270 return; \
8271 } \
c19d1205 8272 } \
e07e6e58 8273 while (0)
c19d1205 8274
fdfde340
JM
8275/* Reject "bad registers" for Thumb-2 instructions. Many Thumb-2
8276 instructions are unpredictable if these registers are used. This
5c8ed6a4
JW
8277 is the BadReg predicate in ARM's Thumb-2 documentation.
8278
8279 Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few
8280 places, while the restriction on REG_SP was relaxed since ARMv8-A. */
8281#define reject_bad_reg(reg) \
8282 do \
8283 if (reg == REG_PC) \
8284 { \
8285 inst.error = BAD_PC; \
8286 return; \
8287 } \
8288 else if (reg == REG_SP \
8289 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) \
8290 { \
8291 inst.error = BAD_SP; \
8292 return; \
8293 } \
fdfde340
JM
8294 while (0)
8295
94206790
MM
8296/* If REG is R13 (the stack pointer), warn that its use is
8297 deprecated. */
8298#define warn_deprecated_sp(reg) \
8299 do \
8300 if (warn_on_deprecated && reg == REG_SP) \
5c3696f8 8301 as_tsktsk (_("use of r13 is deprecated")); \
94206790
MM
8302 while (0)
8303
c19d1205
ZW
8304/* Functions for operand encoding. ARM, then Thumb. */
8305
d840c081 8306#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31))
c19d1205 8307
9db2f6b4
RL
8308/* If the current inst is scalar ARMv8.2 fp16 instruction, do special encoding.
8309
8310 The only binary encoding difference is the Coprocessor number. Coprocessor
8311 9 is used for half-precision calculations or conversions. The format of the
2b0f3761 8312 instruction is the same as the equivalent Coprocessor 10 instruction that
9db2f6b4
RL
8313 exists for Single-Precision operation. */
8314
8315static void
8316do_scalar_fp16_v82_encode (void)
8317{
5ee91343 8318 if (inst.cond < COND_ALWAYS)
9db2f6b4
RL
8319 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
8320 " the behaviour is UNPREDICTABLE"));
8321 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
8322 _(BAD_FP16));
8323
8324 inst.instruction = (inst.instruction & 0xfffff0ff) | 0x900;
8325 mark_feature_used (&arm_ext_fp16);
8326}
8327
c19d1205
ZW
8328/* If VAL can be encoded in the immediate field of an ARM instruction,
8329 return the encoded form. Otherwise, return FAIL. */
8330
8331static unsigned int
8332encode_arm_immediate (unsigned int val)
09d92015 8333{
c19d1205
ZW
8334 unsigned int a, i;
8335
4f1d6205
L
8336 if (val <= 0xff)
8337 return val;
8338
8339 for (i = 2; i < 32; i += 2)
c19d1205
ZW
8340 if ((a = rotate_left (val, i)) <= 0xff)
8341 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
8342
8343 return FAIL;
09d92015
MM
8344}
8345
c19d1205
ZW
8346/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
8347 return the encoded form. Otherwise, return FAIL. */
8348static unsigned int
8349encode_thumb32_immediate (unsigned int val)
09d92015 8350{
c19d1205 8351 unsigned int a, i;
09d92015 8352
9c3c69f2 8353 if (val <= 0xff)
c19d1205 8354 return val;
a737bd4d 8355
9c3c69f2 8356 for (i = 1; i <= 24; i++)
09d92015 8357 {
9c3c69f2 8358 a = val >> i;
7af67752 8359 if ((val & ~(0xffU << i)) == 0)
9c3c69f2 8360 return ((val >> i) & 0x7f) | ((32 - i) << 7);
09d92015 8361 }
a737bd4d 8362
c19d1205
ZW
8363 a = val & 0xff;
8364 if (val == ((a << 16) | a))
8365 return 0x100 | a;
8366 if (val == ((a << 24) | (a << 16) | (a << 8) | a))
8367 return 0x300 | a;
09d92015 8368
c19d1205
ZW
8369 a = val & 0xff00;
8370 if (val == ((a << 16) | a))
8371 return 0x200 | (a >> 8);
a737bd4d 8372
c19d1205 8373 return FAIL;
09d92015 8374}
5287ad62 8375/* Encode a VFP SP or DP register number into inst.instruction. */
09d92015
MM
8376
8377static void
5287ad62
JB
8378encode_arm_vfp_reg (int reg, enum vfp_reg_pos pos)
8379{
8380 if ((pos == VFP_REG_Dd || pos == VFP_REG_Dn || pos == VFP_REG_Dm)
8381 && reg > 15)
8382 {
b1cc4aeb 8383 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
8384 {
8385 if (thumb_mode)
8386 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
8387 fpu_vfp_ext_d32);
8388 else
8389 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
8390 fpu_vfp_ext_d32);
8391 }
5287ad62 8392 else
477330fc
RM
8393 {
8394 first_error (_("D register out of range for selected VFP version"));
8395 return;
8396 }
5287ad62
JB
8397 }
8398
c19d1205 8399 switch (pos)
09d92015 8400 {
c19d1205
ZW
8401 case VFP_REG_Sd:
8402 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8403 break;
8404
8405 case VFP_REG_Sn:
8406 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8407 break;
8408
8409 case VFP_REG_Sm:
8410 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8411 break;
8412
5287ad62
JB
8413 case VFP_REG_Dd:
8414 inst.instruction |= ((reg & 15) << 12) | ((reg >> 4) << 22);
8415 break;
5f4273c7 8416
5287ad62
JB
8417 case VFP_REG_Dn:
8418 inst.instruction |= ((reg & 15) << 16) | ((reg >> 4) << 7);
8419 break;
5f4273c7 8420
5287ad62
JB
8421 case VFP_REG_Dm:
8422 inst.instruction |= (reg & 15) | ((reg >> 4) << 5);
8423 break;
8424
c19d1205
ZW
8425 default:
8426 abort ();
09d92015 8427 }
09d92015
MM
8428}
8429
c19d1205 8430/* Encode a <shift> in an ARM-format instruction. The immediate,
55cf6793 8431 if any, is handled by md_apply_fix. */
09d92015 8432static void
c19d1205 8433encode_arm_shift (int i)
09d92015 8434{
008a97ef
RL
8435 /* register-shifted register. */
8436 if (inst.operands[i].immisreg)
8437 {
bf355b69
MR
8438 int op_index;
8439 for (op_index = 0; op_index <= i; ++op_index)
008a97ef 8440 {
5689c942
RL
8441 /* Check the operand only when it's presented. In pre-UAL syntax,
8442 if the destination register is the same as the first operand, two
8443 register form of the instruction can be used. */
bf355b69
MR
8444 if (inst.operands[op_index].present && inst.operands[op_index].isreg
8445 && inst.operands[op_index].reg == REG_PC)
008a97ef
RL
8446 as_warn (UNPRED_REG ("r15"));
8447 }
8448
8449 if (inst.operands[i].imm == REG_PC)
8450 as_warn (UNPRED_REG ("r15"));
8451 }
8452
c19d1205
ZW
8453 if (inst.operands[i].shift_kind == SHIFT_RRX)
8454 inst.instruction |= SHIFT_ROR << 5;
8455 else
09d92015 8456 {
c19d1205
ZW
8457 inst.instruction |= inst.operands[i].shift_kind << 5;
8458 if (inst.operands[i].immisreg)
8459 {
8460 inst.instruction |= SHIFT_BY_REG;
8461 inst.instruction |= inst.operands[i].imm << 8;
8462 }
8463 else
e2b0ab59 8464 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
09d92015 8465 }
c19d1205 8466}
09d92015 8467
c19d1205
ZW
8468static void
8469encode_arm_shifter_operand (int i)
8470{
8471 if (inst.operands[i].isreg)
09d92015 8472 {
c19d1205
ZW
8473 inst.instruction |= inst.operands[i].reg;
8474 encode_arm_shift (i);
09d92015 8475 }
c19d1205 8476 else
a415b1cd
JB
8477 {
8478 inst.instruction |= INST_IMMEDIATE;
e2b0ab59 8479 if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
a415b1cd
JB
8480 inst.instruction |= inst.operands[i].imm;
8481 }
09d92015
MM
8482}
8483
c19d1205 8484/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
09d92015 8485static void
5b7c81bd 8486encode_arm_addr_mode_common (int i, bool is_t)
09d92015 8487{
2b2f5df9
NC
8488 /* PR 14260:
8489 Generate an error if the operand is not a register. */
8490 constraint (!inst.operands[i].isreg,
8491 _("Instruction does not support =N addresses"));
8492
c19d1205 8493 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 8494
c19d1205 8495 if (inst.operands[i].preind)
09d92015 8496 {
c19d1205
ZW
8497 if (is_t)
8498 {
8499 inst.error = _("instruction does not accept preindexed addressing");
8500 return;
8501 }
8502 inst.instruction |= PRE_INDEX;
8503 if (inst.operands[i].writeback)
8504 inst.instruction |= WRITE_BACK;
09d92015 8505
c19d1205
ZW
8506 }
8507 else if (inst.operands[i].postind)
8508 {
9c2799c2 8509 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
8510 if (is_t)
8511 inst.instruction |= WRITE_BACK;
8512 }
8513 else /* unindexed - only for coprocessor */
09d92015 8514 {
c19d1205 8515 inst.error = _("instruction does not accept unindexed addressing");
09d92015
MM
8516 return;
8517 }
8518
c19d1205
ZW
8519 if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
8520 && (((inst.instruction & 0x000f0000) >> 16)
8521 == ((inst.instruction & 0x0000f000) >> 12)))
8522 as_warn ((inst.instruction & LOAD_BIT)
8523 ? _("destination register same as write-back base")
8524 : _("source register same as write-back base"));
09d92015
MM
8525}
8526
c19d1205
ZW
8527/* inst.operands[i] was set up by parse_address. Encode it into an
8528 ARM-format mode 2 load or store instruction. If is_t is true,
8529 reject forms that cannot be used with a T instruction (i.e. not
8530 post-indexed). */
a737bd4d 8531static void
5b7c81bd 8532encode_arm_addr_mode_2 (int i, bool is_t)
09d92015 8533{
5b7c81bd 8534 const bool is_pc = (inst.operands[i].reg == REG_PC);
5be8be5d 8535
c19d1205 8536 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8537
c19d1205 8538 if (inst.operands[i].immisreg)
09d92015 8539 {
5be8be5d
DG
8540 constraint ((inst.operands[i].imm == REG_PC
8541 || (is_pc && inst.operands[i].writeback)),
8542 BAD_PC_ADDRESSING);
c19d1205
ZW
8543 inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
8544 inst.instruction |= inst.operands[i].imm;
8545 if (!inst.operands[i].negative)
8546 inst.instruction |= INDEX_UP;
8547 if (inst.operands[i].shifted)
8548 {
8549 if (inst.operands[i].shift_kind == SHIFT_RRX)
8550 inst.instruction |= SHIFT_ROR << 5;
8551 else
8552 {
8553 inst.instruction |= inst.operands[i].shift_kind << 5;
e2b0ab59 8554 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
c19d1205
ZW
8555 }
8556 }
09d92015 8557 }
e2b0ab59 8558 else /* immediate offset in inst.relocs[0] */
09d92015 8559 {
e2b0ab59 8560 if (is_pc && !inst.relocs[0].pc_rel)
5be8be5d 8561 {
5b7c81bd 8562 const bool is_load = ((inst.instruction & LOAD_BIT) != 0);
23a10334
JZ
8563
8564 /* If is_t is TRUE, it's called from do_ldstt. ldrt/strt
8565 cannot use PC in addressing.
8566 PC cannot be used in writeback addressing, either. */
8567 constraint ((is_t || inst.operands[i].writeback),
5be8be5d 8568 BAD_PC_ADDRESSING);
23a10334 8569
dc5ec521 8570 /* Use of PC in str is deprecated for ARMv7. */
23a10334
JZ
8571 if (warn_on_deprecated
8572 && !is_load
8573 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
5c3696f8 8574 as_tsktsk (_("use of PC in this instruction is deprecated"));
5be8be5d
DG
8575 }
8576
e2b0ab59 8577 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8578 {
8579 /* Prefer + for zero encoded value. */
8580 if (!inst.operands[i].negative)
8581 inst.instruction |= INDEX_UP;
e2b0ab59 8582 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
26d97720 8583 }
09d92015 8584 }
09d92015
MM
8585}
8586
c19d1205
ZW
8587/* inst.operands[i] was set up by parse_address. Encode it into an
8588 ARM-format mode 3 load or store instruction. Reject forms that
8589 cannot be used with such instructions. If is_t is true, reject
8590 forms that cannot be used with a T instruction (i.e. not
8591 post-indexed). */
8592static void
5b7c81bd 8593encode_arm_addr_mode_3 (int i, bool is_t)
09d92015 8594{
c19d1205 8595 if (inst.operands[i].immisreg && inst.operands[i].shifted)
09d92015 8596 {
c19d1205
ZW
8597 inst.error = _("instruction does not accept scaled register index");
8598 return;
09d92015 8599 }
a737bd4d 8600
c19d1205 8601 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8602
c19d1205
ZW
8603 if (inst.operands[i].immisreg)
8604 {
5be8be5d 8605 constraint ((inst.operands[i].imm == REG_PC
eb9f3f00 8606 || (is_t && inst.operands[i].reg == REG_PC)),
5be8be5d 8607 BAD_PC_ADDRESSING);
eb9f3f00
JB
8608 constraint (inst.operands[i].reg == REG_PC && inst.operands[i].writeback,
8609 BAD_PC_WRITEBACK);
c19d1205
ZW
8610 inst.instruction |= inst.operands[i].imm;
8611 if (!inst.operands[i].negative)
8612 inst.instruction |= INDEX_UP;
8613 }
e2b0ab59 8614 else /* immediate offset in inst.relocs[0] */
c19d1205 8615 {
e2b0ab59 8616 constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
5be8be5d
DG
8617 && inst.operands[i].writeback),
8618 BAD_PC_WRITEBACK);
c19d1205 8619 inst.instruction |= HWOFFSET_IMM;
e2b0ab59 8620 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8621 {
8622 /* Prefer + for zero encoded value. */
8623 if (!inst.operands[i].negative)
8624 inst.instruction |= INDEX_UP;
8625
e2b0ab59 8626 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
26d97720 8627 }
c19d1205 8628 }
a737bd4d
NC
8629}
8630
8335d6aa
JW
8631/* Write immediate bits [7:0] to the following locations:
8632
8633 |28/24|23 19|18 16|15 4|3 0|
8634 | 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|
8635
8636 This function is used by VMOV/VMVN/VORR/VBIC. */
8637
8638static void
8639neon_write_immbits (unsigned immbits)
8640{
8641 inst.instruction |= immbits & 0xf;
8642 inst.instruction |= ((immbits >> 4) & 0x7) << 16;
8643 inst.instruction |= ((immbits >> 7) & 0x1) << (thumb_mode ? 28 : 24);
8644}
8645
8646/* Invert low-order SIZE bits of XHI:XLO. */
8647
8648static void
8649neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
8650{
8651 unsigned immlo = xlo ? *xlo : 0;
8652 unsigned immhi = xhi ? *xhi : 0;
8653
8654 switch (size)
8655 {
8656 case 8:
8657 immlo = (~immlo) & 0xff;
8658 break;
8659
8660 case 16:
8661 immlo = (~immlo) & 0xffff;
8662 break;
8663
8664 case 64:
8665 immhi = (~immhi) & 0xffffffff;
8666 /* fall through. */
8667
8668 case 32:
8669 immlo = (~immlo) & 0xffffffff;
8670 break;
8671
8672 default:
8673 abort ();
8674 }
8675
8676 if (xlo)
8677 *xlo = immlo;
8678
8679 if (xhi)
8680 *xhi = immhi;
8681}
8682
8683/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
8684 A, B, C, D. */
09d92015 8685
c19d1205 8686static int
8335d6aa 8687neon_bits_same_in_bytes (unsigned imm)
09d92015 8688{
8335d6aa
JW
8689 return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
8690 && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
8691 && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
8692 && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
8693}
a737bd4d 8694
8335d6aa 8695/* For immediate of above form, return 0bABCD. */
09d92015 8696
8335d6aa
JW
8697static unsigned
8698neon_squash_bits (unsigned imm)
8699{
8700 return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
8701 | ((imm & 0x01000000) >> 21);
8702}
8703
8704/* Compress quarter-float representation to 0b...000 abcdefgh. */
8705
8706static unsigned
8707neon_qfloat_bits (unsigned imm)
8708{
8709 return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
8710}
8711
8712/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
8713 the instruction. *OP is passed as the initial value of the op field, and
8714 may be set to a different value depending on the constant (i.e.
8715 "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
8716 MVN). If the immediate looks like a repeated pattern then also
8717 try smaller element sizes. */
8718
8719static int
8720neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
8721 unsigned *immbits, int *op, int size,
8722 enum neon_el_type type)
8723{
8724 /* Only permit float immediates (including 0.0/-0.0) if the operand type is
8725 float. */
8726 if (type == NT_float && !float_p)
8727 return FAIL;
8728
8729 if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
09d92015 8730 {
8335d6aa
JW
8731 if (size != 32 || *op == 1)
8732 return FAIL;
8733 *immbits = neon_qfloat_bits (immlo);
8734 return 0xf;
8735 }
8736
8737 if (size == 64)
8738 {
8739 if (neon_bits_same_in_bytes (immhi)
8740 && neon_bits_same_in_bytes (immlo))
c19d1205 8741 {
8335d6aa
JW
8742 if (*op == 1)
8743 return FAIL;
8744 *immbits = (neon_squash_bits (immhi) << 4)
8745 | neon_squash_bits (immlo);
8746 *op = 1;
8747 return 0xe;
c19d1205 8748 }
a737bd4d 8749
8335d6aa
JW
8750 if (immhi != immlo)
8751 return FAIL;
8752 }
a737bd4d 8753
8335d6aa 8754 if (size >= 32)
09d92015 8755 {
8335d6aa 8756 if (immlo == (immlo & 0x000000ff))
c19d1205 8757 {
8335d6aa
JW
8758 *immbits = immlo;
8759 return 0x0;
c19d1205 8760 }
8335d6aa 8761 else if (immlo == (immlo & 0x0000ff00))
c19d1205 8762 {
8335d6aa
JW
8763 *immbits = immlo >> 8;
8764 return 0x2;
c19d1205 8765 }
8335d6aa
JW
8766 else if (immlo == (immlo & 0x00ff0000))
8767 {
8768 *immbits = immlo >> 16;
8769 return 0x4;
8770 }
8771 else if (immlo == (immlo & 0xff000000))
8772 {
8773 *immbits = immlo >> 24;
8774 return 0x6;
8775 }
8776 else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
8777 {
8778 *immbits = (immlo >> 8) & 0xff;
8779 return 0xc;
8780 }
8781 else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
8782 {
8783 *immbits = (immlo >> 16) & 0xff;
8784 return 0xd;
8785 }
8786
8787 if ((immlo & 0xffff) != (immlo >> 16))
8788 return FAIL;
8789 immlo &= 0xffff;
09d92015 8790 }
a737bd4d 8791
8335d6aa 8792 if (size >= 16)
4962c51a 8793 {
8335d6aa
JW
8794 if (immlo == (immlo & 0x000000ff))
8795 {
8796 *immbits = immlo;
8797 return 0x8;
8798 }
8799 else if (immlo == (immlo & 0x0000ff00))
8800 {
8801 *immbits = immlo >> 8;
8802 return 0xa;
8803 }
8804
8805 if ((immlo & 0xff) != (immlo >> 8))
8806 return FAIL;
8807 immlo &= 0xff;
4962c51a
MS
8808 }
8809
8335d6aa
JW
8810 if (immlo == (immlo & 0x000000ff))
8811 {
8812 /* Don't allow MVN with 8-bit immediate. */
8813 if (*op == 1)
8814 return FAIL;
8815 *immbits = immlo;
8816 return 0xe;
8817 }
26d97720 8818
8335d6aa 8819 return FAIL;
c19d1205 8820}
a737bd4d 8821
5fc177c8 8822#if defined BFD_HOST_64_BIT
ba592044
AM
8823/* Returns TRUE if double precision value V may be cast
8824 to single precision without loss of accuracy. */
8825
5b7c81bd 8826static bool
7e30b1eb 8827is_double_a_single (bfd_uint64_t v)
ba592044 8828{
7e30b1eb
AM
8829 int exp = (v >> 52) & 0x7FF;
8830 bfd_uint64_t mantissa = v & 0xFFFFFFFFFFFFFULL;
ba592044 8831
7e30b1eb
AM
8832 return ((exp == 0 || exp == 0x7FF
8833 || (exp >= 1023 - 126 && exp <= 1023 + 127))
8834 && (mantissa & 0x1FFFFFFFL) == 0);
ba592044
AM
8835}
8836
3739860c 8837/* Returns a double precision value casted to single precision
ba592044
AM
8838 (ignoring the least significant bits in exponent and mantissa). */
8839
8840static int
7e30b1eb 8841double_to_single (bfd_uint64_t v)
ba592044 8842{
7af67752
AM
8843 unsigned int sign = (v >> 63) & 1;
8844 int exp = (v >> 52) & 0x7FF;
7e30b1eb 8845 bfd_uint64_t mantissa = v & 0xFFFFFFFFFFFFFULL;
ba592044
AM
8846
8847 if (exp == 0x7FF)
8848 exp = 0xFF;
8849 else
8850 {
8851 exp = exp - 1023 + 127;
8852 if (exp >= 0xFF)
8853 {
8854 /* Infinity. */
8855 exp = 0x7F;
8856 mantissa = 0;
8857 }
8858 else if (exp < 0)
8859 {
8860 /* No denormalized numbers. */
8861 exp = 0;
8862 mantissa = 0;
8863 }
8864 }
8865 mantissa >>= 29;
8866 return (sign << 31) | (exp << 23) | mantissa;
8867}
5fc177c8 8868#endif /* BFD_HOST_64_BIT */
ba592044 8869
8335d6aa
JW
8870enum lit_type
8871{
8872 CONST_THUMB,
8873 CONST_ARM,
8874 CONST_VEC
8875};
8876
ba592044
AM
8877static void do_vfp_nsyn_opcode (const char *);
8878
e2b0ab59 8879/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
c19d1205
ZW
8880 Determine whether it can be performed with a move instruction; if
8881 it can, convert inst.instruction to that move instruction and
5b7c81bd 8882 return true; if it can't, convert inst.instruction to a literal-pool
c921be7d
NC
8883 load and return FALSE. If this is not a valid thing to do in the
8884 current context, set inst.error and return TRUE.
a737bd4d 8885
c19d1205
ZW
8886 inst.operands[i] describes the destination register. */
8887
5b7c81bd
AM
8888static bool
8889move_or_literal_pool (int i, enum lit_type t, bool mode_3)
c19d1205 8890{
53365c0d 8891 unsigned long tbit;
5b7c81bd
AM
8892 bool thumb_p = (t == CONST_THUMB);
8893 bool arm_p = (t == CONST_ARM);
53365c0d
PB
8894
8895 if (thumb_p)
8896 tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
8897 else
8898 tbit = LOAD_BIT;
8899
8900 if ((inst.instruction & tbit) == 0)
09d92015 8901 {
c19d1205 8902 inst.error = _("invalid pseudo operation");
5b7c81bd 8903 return true;
09d92015 8904 }
ba592044 8905
e2b0ab59
AV
8906 if (inst.relocs[0].exp.X_op != O_constant
8907 && inst.relocs[0].exp.X_op != O_symbol
8908 && inst.relocs[0].exp.X_op != O_big)
09d92015
MM
8909 {
8910 inst.error = _("constant expression expected");
5b7c81bd 8911 return true;
09d92015 8912 }
ba592044 8913
e2b0ab59
AV
8914 if (inst.relocs[0].exp.X_op == O_constant
8915 || inst.relocs[0].exp.X_op == O_big)
8335d6aa 8916 {
5fc177c8 8917#if defined BFD_HOST_64_BIT
7e30b1eb 8918 bfd_uint64_t v;
5fc177c8 8919#else
7e30b1eb 8920 valueT v;
5fc177c8 8921#endif
e2b0ab59 8922 if (inst.relocs[0].exp.X_op == O_big)
8335d6aa 8923 {
ba592044
AM
8924 LITTLENUM_TYPE w[X_PRECISION];
8925 LITTLENUM_TYPE * l;
8926
e2b0ab59 8927 if (inst.relocs[0].exp.X_add_number == -1)
8335d6aa 8928 {
ba592044
AM
8929 gen_to_words (w, X_PRECISION, E_PRECISION);
8930 l = w;
8931 /* FIXME: Should we check words w[2..5] ? */
8335d6aa 8932 }
ba592044
AM
8933 else
8934 l = generic_bignum;
3739860c 8935
5fc177c8 8936#if defined BFD_HOST_64_BIT
7e30b1eb
AM
8937 v = l[3] & LITTLENUM_MASK;
8938 v <<= LITTLENUM_NUMBER_OF_BITS;
8939 v |= l[2] & LITTLENUM_MASK;
8940 v <<= LITTLENUM_NUMBER_OF_BITS;
8941 v |= l[1] & LITTLENUM_MASK;
8942 v <<= LITTLENUM_NUMBER_OF_BITS;
8943 v |= l[0] & LITTLENUM_MASK;
5fc177c8 8944#else
7e30b1eb
AM
8945 v = l[1] & LITTLENUM_MASK;
8946 v <<= LITTLENUM_NUMBER_OF_BITS;
8947 v |= l[0] & LITTLENUM_MASK;
5fc177c8 8948#endif
8335d6aa 8949 }
ba592044 8950 else
e2b0ab59 8951 v = inst.relocs[0].exp.X_add_number;
ba592044
AM
8952
8953 if (!inst.operands[i].issingle)
8335d6aa 8954 {
12569877 8955 if (thumb_p)
8335d6aa 8956 {
53445554
TP
8957 /* LDR should not use lead in a flag-setting instruction being
8958 chosen so we do not check whether movs can be used. */
12569877 8959
53445554 8960 if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
ff8646ee 8961 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
53445554
TP
8962 && inst.operands[i].reg != 13
8963 && inst.operands[i].reg != 15)
12569877 8964 {
fc289b0a
TP
8965 /* Check if on thumb2 it can be done with a mov.w, mvn or
8966 movw instruction. */
12569877 8967 unsigned int newimm;
5b7c81bd 8968 bool isNegated = false;
12569877
AM
8969
8970 newimm = encode_thumb32_immediate (v);
f3da8a96 8971 if (newimm == (unsigned int) FAIL)
12569877 8972 {
582cfe03 8973 newimm = encode_thumb32_immediate (~v);
5b7c81bd 8974 isNegated = true;
12569877
AM
8975 }
8976
fc289b0a
TP
8977 /* The number can be loaded with a mov.w or mvn
8978 instruction. */
ff8646ee
TP
8979 if (newimm != (unsigned int) FAIL
8980 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
12569877 8981 {
fc289b0a 8982 inst.instruction = (0xf04f0000 /* MOV.W. */
582cfe03 8983 | (inst.operands[i].reg << 8));
fc289b0a 8984 /* Change to MOVN. */
582cfe03 8985 inst.instruction |= (isNegated ? 0x200000 : 0);
12569877
AM
8986 inst.instruction |= (newimm & 0x800) << 15;
8987 inst.instruction |= (newimm & 0x700) << 4;
8988 inst.instruction |= (newimm & 0x0ff);
5b7c81bd 8989 return true;
12569877 8990 }
fc289b0a 8991 /* The number can be loaded with a movw instruction. */
ff8646ee
TP
8992 else if ((v & ~0xFFFF) == 0
8993 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
3739860c 8994 {
582cfe03 8995 int imm = v & 0xFFFF;
12569877 8996
582cfe03 8997 inst.instruction = 0xf2400000; /* MOVW. */
12569877
AM
8998 inst.instruction |= (inst.operands[i].reg << 8);
8999 inst.instruction |= (imm & 0xf000) << 4;
9000 inst.instruction |= (imm & 0x0800) << 15;
9001 inst.instruction |= (imm & 0x0700) << 4;
9002 inst.instruction |= (imm & 0x00ff);
8fe9a076
AV
9003 /* In case this replacement is being done on Armv8-M
9004 Baseline we need to make sure to disable the
9005 instruction size check, as otherwise GAS will reject
9006 the use of this T32 instruction. */
9007 inst.size_req = 0;
5b7c81bd 9008 return true;
12569877
AM
9009 }
9010 }
8335d6aa 9011 }
12569877 9012 else if (arm_p)
ba592044
AM
9013 {
9014 int value = encode_arm_immediate (v);
12569877 9015
ba592044
AM
9016 if (value != FAIL)
9017 {
9018 /* This can be done with a mov instruction. */
9019 inst.instruction &= LITERAL_MASK;
9020 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
9021 inst.instruction |= value & 0xfff;
5b7c81bd 9022 return true;
ba592044 9023 }
8335d6aa 9024
ba592044
AM
9025 value = encode_arm_immediate (~ v);
9026 if (value != FAIL)
9027 {
9028 /* This can be done with a mvn instruction. */
9029 inst.instruction &= LITERAL_MASK;
9030 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
9031 inst.instruction |= value & 0xfff;
5b7c81bd 9032 return true;
ba592044
AM
9033 }
9034 }
934c2632 9035 else if (t == CONST_VEC && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
8335d6aa 9036 {
ba592044
AM
9037 int op = 0;
9038 unsigned immbits = 0;
9039 unsigned immlo = inst.operands[1].imm;
9040 unsigned immhi = inst.operands[1].regisimm
9041 ? inst.operands[1].reg
e2b0ab59 9042 : inst.relocs[0].exp.X_unsigned
ba592044
AM
9043 ? 0
9044 : ((bfd_int64_t)((int) immlo)) >> 32;
5b7c81bd 9045 int cmode = neon_cmode_for_move_imm (immlo, immhi, false, &immbits,
ba592044
AM
9046 &op, 64, NT_invtype);
9047
9048 if (cmode == FAIL)
9049 {
9050 neon_invert_size (&immlo, &immhi, 64);
9051 op = !op;
5b7c81bd 9052 cmode = neon_cmode_for_move_imm (immlo, immhi, false, &immbits,
ba592044
AM
9053 &op, 64, NT_invtype);
9054 }
9055
9056 if (cmode != FAIL)
9057 {
9058 inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
9059 | (1 << 23)
9060 | (cmode << 8)
9061 | (op << 5)
9062 | (1 << 4);
9063
9064 /* Fill other bits in vmov encoding for both thumb and arm. */
9065 if (thumb_mode)
eff0bc54 9066 inst.instruction |= (0x7U << 29) | (0xF << 24);
ba592044 9067 else
eff0bc54 9068 inst.instruction |= (0xFU << 28) | (0x1 << 25);
ba592044 9069 neon_write_immbits (immbits);
5b7c81bd 9070 return true;
ba592044 9071 }
8335d6aa
JW
9072 }
9073 }
8335d6aa 9074
ba592044
AM
9075 if (t == CONST_VEC)
9076 {
9077 /* Check if vldr Rx, =constant could be optimized to vmov Rx, #constant. */
9078 if (inst.operands[i].issingle
9079 && is_quarter_float (inst.operands[1].imm)
9080 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3xd))
8335d6aa 9081 {
ba592044
AM
9082 inst.operands[1].imm =
9083 neon_qfloat_bits (v);
9084 do_vfp_nsyn_opcode ("fconsts");
5b7c81bd 9085 return true;
8335d6aa 9086 }
5fc177c8
NC
9087
9088 /* If our host does not support a 64-bit type then we cannot perform
9089 the following optimization. This mean that there will be a
9090 discrepancy between the output produced by an assembler built for
9091 a 32-bit-only host and the output produced from a 64-bit host, but
9092 this cannot be helped. */
9093#if defined BFD_HOST_64_BIT
ba592044
AM
9094 else if (!inst.operands[1].issingle
9095 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
8335d6aa 9096 {
ba592044
AM
9097 if (is_double_a_single (v)
9098 && is_quarter_float (double_to_single (v)))
9099 {
9100 inst.operands[1].imm =
9101 neon_qfloat_bits (double_to_single (v));
9102 do_vfp_nsyn_opcode ("fconstd");
5b7c81bd 9103 return true;
ba592044 9104 }
8335d6aa 9105 }
5fc177c8 9106#endif
8335d6aa
JW
9107 }
9108 }
9109
9110 if (add_to_lit_pool ((!inst.operands[i].isvec
9111 || inst.operands[i].issingle) ? 4 : 8) == FAIL)
5b7c81bd 9112 return true;
8335d6aa
JW
9113
9114 inst.operands[1].reg = REG_PC;
9115 inst.operands[1].isreg = 1;
9116 inst.operands[1].preind = 1;
e2b0ab59
AV
9117 inst.relocs[0].pc_rel = 1;
9118 inst.relocs[0].type = (thumb_p
8335d6aa
JW
9119 ? BFD_RELOC_ARM_THUMB_OFFSET
9120 : (mode_3
9121 ? BFD_RELOC_ARM_HWLITERAL
9122 : BFD_RELOC_ARM_LITERAL));
5b7c81bd 9123 return false;
8335d6aa
JW
9124}
9125
9126/* inst.operands[i] was set up by parse_address. Encode it into an
9127 ARM-format instruction. Reject all forms which cannot be encoded
9128 into a coprocessor load/store instruction. If wb_ok is false,
9129 reject use of writeback; if unind_ok is false, reject use of
9130 unindexed addressing. If reloc_override is not 0, use it instead
9131 of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
9132 (in which case it is preserved). */
9133
9134static int
9135encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
9136{
9137 if (!inst.operands[i].isreg)
9138 {
99b2a2dd
NC
9139 /* PR 18256 */
9140 if (! inst.operands[0].isvec)
9141 {
9142 inst.error = _("invalid co-processor operand");
9143 return FAIL;
9144 }
5b7c81bd 9145 if (move_or_literal_pool (0, CONST_VEC, /*mode_3=*/false))
8335d6aa
JW
9146 return SUCCESS;
9147 }
9148
9149 inst.instruction |= inst.operands[i].reg << 16;
9150
9151 gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
9152
9153 if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
9154 {
9155 gas_assert (!inst.operands[i].writeback);
9156 if (!unind_ok)
9157 {
9158 inst.error = _("instruction does not support unindexed addressing");
9159 return FAIL;
9160 }
9161 inst.instruction |= inst.operands[i].imm;
9162 inst.instruction |= INDEX_UP;
9163 return SUCCESS;
9164 }
9165
9166 if (inst.operands[i].preind)
9167 inst.instruction |= PRE_INDEX;
9168
9169 if (inst.operands[i].writeback)
09d92015 9170 {
8335d6aa 9171 if (inst.operands[i].reg == REG_PC)
c19d1205 9172 {
8335d6aa
JW
9173 inst.error = _("pc may not be used with write-back");
9174 return FAIL;
c19d1205 9175 }
8335d6aa 9176 if (!wb_ok)
c19d1205 9177 {
8335d6aa
JW
9178 inst.error = _("instruction does not support writeback");
9179 return FAIL;
c19d1205 9180 }
8335d6aa 9181 inst.instruction |= WRITE_BACK;
09d92015
MM
9182 }
9183
8335d6aa 9184 if (reloc_override)
e2b0ab59
AV
9185 inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
9186 else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
9187 || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
9188 && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
c19d1205 9189 {
8335d6aa 9190 if (thumb_mode)
e2b0ab59 9191 inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
8335d6aa 9192 else
e2b0ab59 9193 inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
c19d1205 9194 }
8335d6aa
JW
9195
9196 /* Prefer + for zero encoded value. */
9197 if (!inst.operands[i].negative)
9198 inst.instruction |= INDEX_UP;
9199
9200 return SUCCESS;
09d92015
MM
9201}
9202
5f4273c7 9203/* Functions for instruction encoding, sorted by sub-architecture.
c19d1205
ZW
9204 First some generics; their names are taken from the conventional
9205 bit positions for register arguments in ARM format instructions. */
09d92015 9206
a737bd4d 9207static void
c19d1205 9208do_noargs (void)
09d92015 9209{
c19d1205 9210}
a737bd4d 9211
c19d1205
ZW
9212static void
9213do_rd (void)
9214{
9215 inst.instruction |= inst.operands[0].reg << 12;
9216}
a737bd4d 9217
16a1fa25
TP
9218static void
9219do_rn (void)
9220{
9221 inst.instruction |= inst.operands[0].reg << 16;
9222}
9223
c19d1205
ZW
9224static void
9225do_rd_rm (void)
9226{
9227 inst.instruction |= inst.operands[0].reg << 12;
9228 inst.instruction |= inst.operands[1].reg;
9229}
09d92015 9230
9eb6c0f1
MGD
9231static void
9232do_rm_rn (void)
9233{
9234 inst.instruction |= inst.operands[0].reg;
9235 inst.instruction |= inst.operands[1].reg << 16;
9236}
9237
c19d1205
ZW
9238static void
9239do_rd_rn (void)
9240{
9241 inst.instruction |= inst.operands[0].reg << 12;
9242 inst.instruction |= inst.operands[1].reg << 16;
9243}
a737bd4d 9244
c19d1205
ZW
9245static void
9246do_rn_rd (void)
9247{
9248 inst.instruction |= inst.operands[0].reg << 16;
9249 inst.instruction |= inst.operands[1].reg << 12;
9250}
09d92015 9251
4ed7ed8d
TP
9252static void
9253do_tt (void)
9254{
9255 inst.instruction |= inst.operands[0].reg << 8;
9256 inst.instruction |= inst.operands[1].reg << 16;
9257}
9258
5b7c81bd 9259static bool
59d09be6
MGD
9260check_obsolete (const arm_feature_set *feature, const char *msg)
9261{
9262 if (ARM_CPU_IS_ANY (cpu_variant))
9263 {
5c3696f8 9264 as_tsktsk ("%s", msg);
5b7c81bd 9265 return true;
59d09be6
MGD
9266 }
9267 else if (ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
9268 {
9269 as_bad ("%s", msg);
5b7c81bd 9270 return true;
59d09be6
MGD
9271 }
9272
5b7c81bd 9273 return false;
59d09be6
MGD
9274}
9275
c19d1205
ZW
9276static void
9277do_rd_rm_rn (void)
9278{
9a64e435 9279 unsigned Rn = inst.operands[2].reg;
708587a4 9280 /* Enforce restrictions on SWP instruction. */
9a64e435 9281 if ((inst.instruction & 0x0fbfffff) == 0x01000090)
56adecf4
DG
9282 {
9283 constraint (Rn == inst.operands[0].reg || Rn == inst.operands[1].reg,
9284 _("Rn must not overlap other operands"));
9285
59d09be6
MGD
9286 /* SWP{b} is obsolete for ARMv8-A, and deprecated for ARMv6* and ARMv7.
9287 */
9288 if (!check_obsolete (&arm_ext_v8,
9289 _("swp{b} use is obsoleted for ARMv8 and later"))
9290 && warn_on_deprecated
9291 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6))
5c3696f8 9292 as_tsktsk (_("swp{b} use is deprecated for ARMv6 and ARMv7"));
56adecf4 9293 }
59d09be6 9294
c19d1205
ZW
9295 inst.instruction |= inst.operands[0].reg << 12;
9296 inst.instruction |= inst.operands[1].reg;
9a64e435 9297 inst.instruction |= Rn << 16;
c19d1205 9298}
09d92015 9299
c19d1205
ZW
9300static void
9301do_rd_rn_rm (void)
9302{
9303 inst.instruction |= inst.operands[0].reg << 12;
9304 inst.instruction |= inst.operands[1].reg << 16;
9305 inst.instruction |= inst.operands[2].reg;
9306}
a737bd4d 9307
c19d1205
ZW
9308static void
9309do_rm_rd_rn (void)
9310{
5be8be5d 9311 constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
e2b0ab59
AV
9312 constraint (((inst.relocs[0].exp.X_op != O_constant
9313 && inst.relocs[0].exp.X_op != O_illegal)
9314 || inst.relocs[0].exp.X_add_number != 0),
5be8be5d 9315 BAD_ADDR_MODE);
c19d1205
ZW
9316 inst.instruction |= inst.operands[0].reg;
9317 inst.instruction |= inst.operands[1].reg << 12;
9318 inst.instruction |= inst.operands[2].reg << 16;
9319}
09d92015 9320
c19d1205
ZW
9321static void
9322do_imm0 (void)
9323{
9324 inst.instruction |= inst.operands[0].imm;
9325}
09d92015 9326
c19d1205
ZW
9327static void
9328do_rd_cpaddr (void)
9329{
9330 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 9331 encode_arm_cp_address (1, true, true, 0);
09d92015 9332}
a737bd4d 9333
c19d1205
ZW
9334/* ARM instructions, in alphabetical order by function name (except
9335 that wrapper functions appear immediately after the function they
9336 wrap). */
09d92015 9337
c19d1205
ZW
9338/* This is a pseudo-op of the form "adr rd, label" to be converted
9339 into a relative address of the form "add rd, pc, #label-.-8". */
09d92015
MM
9340
9341static void
c19d1205 9342do_adr (void)
09d92015 9343{
c19d1205 9344 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9345
c19d1205
ZW
9346 /* Frag hacking will turn this into a sub instruction if the offset turns
9347 out to be negative. */
e2b0ab59
AV
9348 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9349 inst.relocs[0].pc_rel = 1;
9350 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9351
fc6141f0 9352 if (support_interwork
e2b0ab59
AV
9353 && inst.relocs[0].exp.X_op == O_symbol
9354 && inst.relocs[0].exp.X_add_symbol != NULL
9355 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9356 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9357 inst.relocs[0].exp.X_add_number |= 1;
c19d1205 9358}
b99bd4ef 9359
c19d1205
ZW
9360/* This is a pseudo-op of the form "adrl rd, label" to be converted
9361 into a relative address of the form:
9362 add rd, pc, #low(label-.-8)"
9363 add rd, rd, #high(label-.-8)" */
b99bd4ef 9364
c19d1205
ZW
9365static void
9366do_adrl (void)
9367{
9368 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9369
c19d1205
ZW
9370 /* Frag hacking will turn this into a sub instruction if the offset turns
9371 out to be negative. */
e2b0ab59
AV
9372 inst.relocs[0].type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
9373 inst.relocs[0].pc_rel = 1;
c19d1205 9374 inst.size = INSN_SIZE * 2;
e2b0ab59 9375 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9376
fc6141f0 9377 if (support_interwork
e2b0ab59
AV
9378 && inst.relocs[0].exp.X_op == O_symbol
9379 && inst.relocs[0].exp.X_add_symbol != NULL
9380 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9381 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9382 inst.relocs[0].exp.X_add_number |= 1;
b99bd4ef
NC
9383}
9384
b99bd4ef 9385static void
c19d1205 9386do_arit (void)
b99bd4ef 9387{
e2b0ab59
AV
9388 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9389 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9390 THUMB1_RELOC_ONLY);
c19d1205
ZW
9391 if (!inst.operands[1].present)
9392 inst.operands[1].reg = inst.operands[0].reg;
9393 inst.instruction |= inst.operands[0].reg << 12;
9394 inst.instruction |= inst.operands[1].reg << 16;
9395 encode_arm_shifter_operand (2);
9396}
b99bd4ef 9397
62b3e311
PB
9398static void
9399do_barrier (void)
9400{
9401 if (inst.operands[0].present)
ccb84d65 9402 inst.instruction |= inst.operands[0].imm;
62b3e311
PB
9403 else
9404 inst.instruction |= 0xf;
9405}
9406
c19d1205
ZW
9407static void
9408do_bfc (void)
9409{
9410 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
9411 constraint (msb > 32, _("bit-field extends past end of register"));
9412 /* The instruction encoding stores the LSB and MSB,
9413 not the LSB and width. */
9414 inst.instruction |= inst.operands[0].reg << 12;
9415 inst.instruction |= inst.operands[1].imm << 7;
9416 inst.instruction |= (msb - 1) << 16;
9417}
b99bd4ef 9418
c19d1205
ZW
9419static void
9420do_bfi (void)
9421{
9422 unsigned int msb;
b99bd4ef 9423
c19d1205
ZW
9424 /* #0 in second position is alternative syntax for bfc, which is
9425 the same instruction but with REG_PC in the Rm field. */
9426 if (!inst.operands[1].isreg)
9427 inst.operands[1].reg = REG_PC;
b99bd4ef 9428
c19d1205
ZW
9429 msb = inst.operands[2].imm + inst.operands[3].imm;
9430 constraint (msb > 32, _("bit-field extends past end of register"));
9431 /* The instruction encoding stores the LSB and MSB,
9432 not the LSB and width. */
9433 inst.instruction |= inst.operands[0].reg << 12;
9434 inst.instruction |= inst.operands[1].reg;
9435 inst.instruction |= inst.operands[2].imm << 7;
9436 inst.instruction |= (msb - 1) << 16;
b99bd4ef
NC
9437}
9438
b99bd4ef 9439static void
c19d1205 9440do_bfx (void)
b99bd4ef 9441{
c19d1205
ZW
9442 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
9443 _("bit-field extends past end of register"));
9444 inst.instruction |= inst.operands[0].reg << 12;
9445 inst.instruction |= inst.operands[1].reg;
9446 inst.instruction |= inst.operands[2].imm << 7;
9447 inst.instruction |= (inst.operands[3].imm - 1) << 16;
9448}
09d92015 9449
c19d1205
ZW
9450/* ARM V5 breakpoint instruction (argument parse)
9451 BKPT <16 bit unsigned immediate>
9452 Instruction is not conditional.
9453 The bit pattern given in insns[] has the COND_ALWAYS condition,
9454 and it is an error if the caller tried to override that. */
b99bd4ef 9455
c19d1205
ZW
9456static void
9457do_bkpt (void)
9458{
9459 /* Top 12 of 16 bits to bits 19:8. */
9460 inst.instruction |= (inst.operands[0].imm & 0xfff0) << 4;
09d92015 9461
c19d1205
ZW
9462 /* Bottom 4 of 16 bits to bits 3:0. */
9463 inst.instruction |= inst.operands[0].imm & 0xf;
9464}
09d92015 9465
c19d1205
ZW
9466static void
9467encode_branch (int default_reloc)
9468{
9469 if (inst.operands[0].hasreloc)
9470 {
0855e32b
NS
9471 constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
9472 && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
9473 _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
e2b0ab59 9474 inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
0855e32b
NS
9475 ? BFD_RELOC_ARM_PLT32
9476 : thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
c19d1205 9477 }
b99bd4ef 9478 else
e2b0ab59
AV
9479 inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
9480 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
9481}
9482
b99bd4ef 9483static void
c19d1205 9484do_branch (void)
b99bd4ef 9485{
39b41c9c
PB
9486#ifdef OBJ_ELF
9487 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9488 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9489 else
9490#endif
9491 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
9492}
9493
9494static void
9495do_bl (void)
9496{
9497#ifdef OBJ_ELF
9498 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9499 {
9500 if (inst.cond == COND_ALWAYS)
9501 encode_branch (BFD_RELOC_ARM_PCREL_CALL);
9502 else
9503 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9504 }
9505 else
9506#endif
9507 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
c19d1205 9508}
b99bd4ef 9509
c19d1205
ZW
9510/* ARM V5 branch-link-exchange instruction (argument parse)
9511 BLX <target_addr> ie BLX(1)
9512 BLX{<condition>} <Rm> ie BLX(2)
9513 Unfortunately, there are two different opcodes for this mnemonic.
9514 So, the insns[].value is not used, and the code here zaps values
9515 into inst.instruction.
9516 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
b99bd4ef 9517
c19d1205
ZW
9518static void
9519do_blx (void)
9520{
9521 if (inst.operands[0].isreg)
b99bd4ef 9522 {
c19d1205
ZW
9523 /* Arg is a register; the opcode provided by insns[] is correct.
9524 It is not illegal to do "blx pc", just useless. */
9525 if (inst.operands[0].reg == REG_PC)
9526 as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
b99bd4ef 9527
c19d1205
ZW
9528 inst.instruction |= inst.operands[0].reg;
9529 }
9530 else
b99bd4ef 9531 {
c19d1205 9532 /* Arg is an address; this instruction cannot be executed
267bf995
RR
9533 conditionally, and the opcode must be adjusted.
9534 We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
9535 where we generate out a BFD_RELOC_ARM_PCREL_CALL instead. */
c19d1205 9536 constraint (inst.cond != COND_ALWAYS, BAD_COND);
2fc8bdac 9537 inst.instruction = 0xfa000000;
267bf995 9538 encode_branch (BFD_RELOC_ARM_PCREL_BLX);
b99bd4ef 9539 }
c19d1205
ZW
9540}
9541
9542static void
9543do_bx (void)
9544{
5b7c81bd 9545 bool want_reloc;
845b51d6 9546
c19d1205
ZW
9547 if (inst.operands[0].reg == REG_PC)
9548 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
b99bd4ef 9549
c19d1205 9550 inst.instruction |= inst.operands[0].reg;
845b51d6
PB
9551 /* Output R_ARM_V4BX relocations if is an EABI object that looks like
9552 it is for ARMv4t or earlier. */
9553 want_reloc = !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5);
4d354d8b
TP
9554 if (!ARM_FEATURE_ZERO (selected_object_arch)
9555 && !ARM_CPU_HAS_FEATURE (selected_object_arch, arm_ext_v5))
5b7c81bd 9556 want_reloc = true;
845b51d6 9557
5ad34203 9558#ifdef OBJ_ELF
845b51d6 9559 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
5ad34203 9560#endif
5b7c81bd 9561 want_reloc = false;
845b51d6
PB
9562
9563 if (want_reloc)
e2b0ab59 9564 inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
09d92015
MM
9565}
9566
c19d1205
ZW
9567
9568/* ARM v5TEJ. Jump to Jazelle code. */
a737bd4d
NC
9569
9570static void
c19d1205 9571do_bxj (void)
a737bd4d 9572{
c19d1205
ZW
9573 if (inst.operands[0].reg == REG_PC)
9574 as_tsktsk (_("use of r15 in bxj is not really useful"));
9575
9576 inst.instruction |= inst.operands[0].reg;
a737bd4d
NC
9577}
9578
c19d1205
ZW
9579/* Co-processor data operation:
9580 CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
9581 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>} */
9582static void
9583do_cdp (void)
9584{
9585 inst.instruction |= inst.operands[0].reg << 8;
9586 inst.instruction |= inst.operands[1].imm << 20;
9587 inst.instruction |= inst.operands[2].reg << 12;
9588 inst.instruction |= inst.operands[3].reg << 16;
9589 inst.instruction |= inst.operands[4].reg;
9590 inst.instruction |= inst.operands[5].imm << 5;
9591}
a737bd4d
NC
9592
9593static void
c19d1205 9594do_cmp (void)
a737bd4d 9595{
c19d1205
ZW
9596 inst.instruction |= inst.operands[0].reg << 16;
9597 encode_arm_shifter_operand (1);
a737bd4d
NC
9598}
9599
c19d1205
ZW
9600/* Transfer between coprocessor and ARM registers.
9601 MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
9602 MRC2
9603 MCR{cond}
9604 MCR2
9605
9606 No special properties. */
09d92015 9607
dcbd0d71
MGD
9608struct deprecated_coproc_regs_s
9609{
9610 unsigned cp;
9611 int opc1;
9612 unsigned crn;
9613 unsigned crm;
9614 int opc2;
9615 arm_feature_set deprecated;
9616 arm_feature_set obsoleted;
9617 const char *dep_msg;
9618 const char *obs_msg;
9619};
9620
9621#define DEPR_ACCESS_V8 \
9622 N_("This coprocessor register access is deprecated in ARMv8")
9623
9624/* Table of all deprecated coprocessor registers. */
9625static struct deprecated_coproc_regs_s deprecated_coproc_regs[] =
9626{
9627 {15, 0, 7, 10, 5, /* CP15DMB. */
823d2571 9628 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9629 DEPR_ACCESS_V8, NULL},
9630 {15, 0, 7, 10, 4, /* CP15DSB. */
823d2571 9631 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9632 DEPR_ACCESS_V8, NULL},
9633 {15, 0, 7, 5, 4, /* CP15ISB. */
823d2571 9634 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9635 DEPR_ACCESS_V8, NULL},
9636 {14, 6, 1, 0, 0, /* TEEHBR. */
823d2571 9637 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9638 DEPR_ACCESS_V8, NULL},
9639 {14, 6, 0, 0, 0, /* TEECR. */
823d2571 9640 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9641 DEPR_ACCESS_V8, NULL},
9642};
9643
9644#undef DEPR_ACCESS_V8
9645
9646static const size_t deprecated_coproc_reg_count =
9647 sizeof (deprecated_coproc_regs) / sizeof (deprecated_coproc_regs[0]);
9648
09d92015 9649static void
c19d1205 9650do_co_reg (void)
09d92015 9651{
fdfde340 9652 unsigned Rd;
dcbd0d71 9653 size_t i;
fdfde340
JM
9654
9655 Rd = inst.operands[2].reg;
9656 if (thumb_mode)
9657 {
9658 if (inst.instruction == 0xee000010
9659 || inst.instruction == 0xfe000010)
9660 /* MCR, MCR2 */
9661 reject_bad_reg (Rd);
5c8ed6a4 9662 else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
fdfde340
JM
9663 /* MRC, MRC2 */
9664 constraint (Rd == REG_SP, BAD_SP);
9665 }
9666 else
9667 {
9668 /* MCR */
9669 if (inst.instruction == 0xe000010)
9670 constraint (Rd == REG_PC, BAD_PC);
9671 }
9672
dcbd0d71
MGD
9673 for (i = 0; i < deprecated_coproc_reg_count; ++i)
9674 {
9675 const struct deprecated_coproc_regs_s *r =
9676 deprecated_coproc_regs + i;
9677
9678 if (inst.operands[0].reg == r->cp
9679 && inst.operands[1].imm == r->opc1
9680 && inst.operands[3].reg == r->crn
9681 && inst.operands[4].reg == r->crm
9682 && inst.operands[5].imm == r->opc2)
9683 {
b10bf8c5 9684 if (! ARM_CPU_IS_ANY (cpu_variant)
477330fc 9685 && warn_on_deprecated
dcbd0d71 9686 && ARM_CPU_HAS_FEATURE (cpu_variant, r->deprecated))
5c3696f8 9687 as_tsktsk ("%s", r->dep_msg);
dcbd0d71
MGD
9688 }
9689 }
fdfde340 9690
c19d1205
ZW
9691 inst.instruction |= inst.operands[0].reg << 8;
9692 inst.instruction |= inst.operands[1].imm << 21;
fdfde340 9693 inst.instruction |= Rd << 12;
c19d1205
ZW
9694 inst.instruction |= inst.operands[3].reg << 16;
9695 inst.instruction |= inst.operands[4].reg;
9696 inst.instruction |= inst.operands[5].imm << 5;
9697}
09d92015 9698
c19d1205
ZW
9699/* Transfer between coprocessor register and pair of ARM registers.
9700 MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
9701 MCRR2
9702 MRRC{cond}
9703 MRRC2
b99bd4ef 9704
c19d1205 9705 Two XScale instructions are special cases of these:
09d92015 9706
c19d1205
ZW
9707 MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
9708 MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
b99bd4ef 9709
5f4273c7 9710 Result unpredictable if Rd or Rn is R15. */
a737bd4d 9711
c19d1205
ZW
9712static void
9713do_co_reg2c (void)
9714{
fdfde340
JM
9715 unsigned Rd, Rn;
9716
9717 Rd = inst.operands[2].reg;
9718 Rn = inst.operands[3].reg;
9719
9720 if (thumb_mode)
9721 {
9722 reject_bad_reg (Rd);
9723 reject_bad_reg (Rn);
9724 }
9725 else
9726 {
9727 constraint (Rd == REG_PC, BAD_PC);
9728 constraint (Rn == REG_PC, BAD_PC);
9729 }
9730
873f10f0
TC
9731 /* Only check the MRRC{2} variants. */
9732 if ((inst.instruction & 0x0FF00000) == 0x0C500000)
9733 {
9734 /* If Rd == Rn, error that the operation is
9735 unpredictable (example MRRC p3,#1,r1,r1,c4). */
9736 constraint (Rd == Rn, BAD_OVERLAP);
9737 }
9738
c19d1205
ZW
9739 inst.instruction |= inst.operands[0].reg << 8;
9740 inst.instruction |= inst.operands[1].imm << 4;
fdfde340
JM
9741 inst.instruction |= Rd << 12;
9742 inst.instruction |= Rn << 16;
c19d1205 9743 inst.instruction |= inst.operands[4].reg;
b99bd4ef
NC
9744}
9745
c19d1205
ZW
9746static void
9747do_cpsi (void)
9748{
9749 inst.instruction |= inst.operands[0].imm << 6;
a028a6f5
PB
9750 if (inst.operands[1].present)
9751 {
9752 inst.instruction |= CPSI_MMOD;
9753 inst.instruction |= inst.operands[1].imm;
9754 }
c19d1205 9755}
b99bd4ef 9756
62b3e311
PB
9757static void
9758do_dbg (void)
9759{
9760 inst.instruction |= inst.operands[0].imm;
9761}
9762
eea54501
MGD
9763static void
9764do_div (void)
9765{
9766 unsigned Rd, Rn, Rm;
9767
9768 Rd = inst.operands[0].reg;
9769 Rn = (inst.operands[1].present
9770 ? inst.operands[1].reg : Rd);
9771 Rm = inst.operands[2].reg;
9772
9773 constraint ((Rd == REG_PC), BAD_PC);
9774 constraint ((Rn == REG_PC), BAD_PC);
9775 constraint ((Rm == REG_PC), BAD_PC);
9776
9777 inst.instruction |= Rd << 16;
9778 inst.instruction |= Rn << 0;
9779 inst.instruction |= Rm << 8;
9780}
9781
b99bd4ef 9782static void
c19d1205 9783do_it (void)
b99bd4ef 9784{
c19d1205 9785 /* There is no IT instruction in ARM mode. We
e07e6e58
NC
9786 process it to do the validation as if in
9787 thumb mode, just in case the code gets
9788 assembled for thumb using the unified syntax. */
9789
c19d1205 9790 inst.size = 0;
e07e6e58
NC
9791 if (unified_syntax)
9792 {
5ee91343
AV
9793 set_pred_insn_type (IT_INSN);
9794 now_pred.mask = (inst.instruction & 0xf) | 0x10;
9795 now_pred.cc = inst.operands[0].imm;
e07e6e58 9796 }
09d92015 9797}
b99bd4ef 9798
6530b175
NC
9799/* If there is only one register in the register list,
9800 then return its register number. Otherwise return -1. */
9801static int
9802only_one_reg_in_list (int range)
9803{
9804 int i = ffs (range) - 1;
9805 return (i > 15 || range != (1 << i)) ? -1 : i;
9806}
9807
09d92015 9808static void
6530b175 9809encode_ldmstm(int from_push_pop_mnem)
ea6ef066 9810{
c19d1205
ZW
9811 int base_reg = inst.operands[0].reg;
9812 int range = inst.operands[1].imm;
6530b175 9813 int one_reg;
ea6ef066 9814
c19d1205
ZW
9815 inst.instruction |= base_reg << 16;
9816 inst.instruction |= range;
ea6ef066 9817
c19d1205
ZW
9818 if (inst.operands[1].writeback)
9819 inst.instruction |= LDM_TYPE_2_OR_3;
09d92015 9820
c19d1205 9821 if (inst.operands[0].writeback)
ea6ef066 9822 {
c19d1205
ZW
9823 inst.instruction |= WRITE_BACK;
9824 /* Check for unpredictable uses of writeback. */
9825 if (inst.instruction & LOAD_BIT)
09d92015 9826 {
c19d1205
ZW
9827 /* Not allowed in LDM type 2. */
9828 if ((inst.instruction & LDM_TYPE_2_OR_3)
9829 && ((range & (1 << REG_PC)) == 0))
9830 as_warn (_("writeback of base register is UNPREDICTABLE"));
9831 /* Only allowed if base reg not in list for other types. */
9832 else if (range & (1 << base_reg))
9833 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
9834 }
9835 else /* STM. */
9836 {
9837 /* Not allowed for type 2. */
9838 if (inst.instruction & LDM_TYPE_2_OR_3)
9839 as_warn (_("writeback of base register is UNPREDICTABLE"));
9840 /* Only allowed if base reg not in list, or first in list. */
9841 else if ((range & (1 << base_reg))
9842 && (range & ((1 << base_reg) - 1)))
9843 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
09d92015 9844 }
ea6ef066 9845 }
6530b175
NC
9846
9847 /* If PUSH/POP has only one register, then use the A2 encoding. */
9848 one_reg = only_one_reg_in_list (range);
9849 if (from_push_pop_mnem && one_reg >= 0)
9850 {
9851 int is_push = (inst.instruction & A_PUSH_POP_OP_MASK) == A1_OPCODE_PUSH;
9852
4f588891
NC
9853 if (is_push && one_reg == 13 /* SP */)
9854 /* PR 22483: The A2 encoding cannot be used when
9855 pushing the stack pointer as this is UNPREDICTABLE. */
9856 return;
9857
6530b175
NC
9858 inst.instruction &= A_COND_MASK;
9859 inst.instruction |= is_push ? A2_OPCODE_PUSH : A2_OPCODE_POP;
9860 inst.instruction |= one_reg << 12;
9861 }
9862}
9863
9864static void
9865do_ldmstm (void)
9866{
5b7c81bd 9867 encode_ldmstm (/*from_push_pop_mnem=*/false);
a737bd4d
NC
9868}
9869
c19d1205
ZW
9870/* ARMv5TE load-consecutive (argument parse)
9871 Mode is like LDRH.
9872
9873 LDRccD R, mode
9874 STRccD R, mode. */
9875
a737bd4d 9876static void
c19d1205 9877do_ldrd (void)
a737bd4d 9878{
c19d1205 9879 constraint (inst.operands[0].reg % 2 != 0,
c56791bb 9880 _("first transfer register must be even"));
c19d1205
ZW
9881 constraint (inst.operands[1].present
9882 && inst.operands[1].reg != inst.operands[0].reg + 1,
c56791bb 9883 _("can only transfer two consecutive registers"));
c19d1205
ZW
9884 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
9885 constraint (!inst.operands[2].isreg, _("'[' expected"));
a737bd4d 9886
c19d1205
ZW
9887 if (!inst.operands[1].present)
9888 inst.operands[1].reg = inst.operands[0].reg + 1;
5f4273c7 9889
c56791bb
RE
9890 /* encode_arm_addr_mode_3 will diagnose overlap between the base
9891 register and the first register written; we have to diagnose
9892 overlap between the base and the second register written here. */
ea6ef066 9893
c56791bb
RE
9894 if (inst.operands[2].reg == inst.operands[1].reg
9895 && (inst.operands[2].writeback || inst.operands[2].postind))
9896 as_warn (_("base register written back, and overlaps "
9897 "second transfer register"));
b05fe5cf 9898
c56791bb
RE
9899 if (!(inst.instruction & V4_STR_BIT))
9900 {
c19d1205 9901 /* For an index-register load, the index register must not overlap the
c56791bb
RE
9902 destination (even if not write-back). */
9903 if (inst.operands[2].immisreg
9904 && ((unsigned) inst.operands[2].imm == inst.operands[0].reg
9905 || (unsigned) inst.operands[2].imm == inst.operands[1].reg))
9906 as_warn (_("index register overlaps transfer register"));
b05fe5cf 9907 }
c19d1205 9908 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 9909 encode_arm_addr_mode_3 (2, /*is_t=*/false);
b05fe5cf
ZW
9910}
9911
9912static void
c19d1205 9913do_ldrex (void)
b05fe5cf 9914{
c19d1205
ZW
9915 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
9916 || inst.operands[1].postind || inst.operands[1].writeback
9917 || inst.operands[1].immisreg || inst.operands[1].shifted
01cfc07f
NC
9918 || inst.operands[1].negative
9919 /* This can arise if the programmer has written
9920 strex rN, rM, foo
9921 or if they have mistakenly used a register name as the last
9922 operand, eg:
9923 strex rN, rM, rX
9924 It is very difficult to distinguish between these two cases
9925 because "rX" might actually be a label. ie the register
9926 name has been occluded by a symbol of the same name. So we
9927 just generate a general 'bad addressing mode' type error
9928 message and leave it up to the programmer to discover the
9929 true cause and fix their mistake. */
9930 || (inst.operands[1].reg == REG_PC),
9931 BAD_ADDR_MODE);
b05fe5cf 9932
e2b0ab59
AV
9933 constraint (inst.relocs[0].exp.X_op != O_constant
9934 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9935 _("offset must be zero in ARM encoding"));
b05fe5cf 9936
5be8be5d
DG
9937 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
9938
c19d1205
ZW
9939 inst.instruction |= inst.operands[0].reg << 12;
9940 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 9941 inst.relocs[0].type = BFD_RELOC_UNUSED;
b05fe5cf
ZW
9942}
9943
9944static void
c19d1205 9945do_ldrexd (void)
b05fe5cf 9946{
c19d1205
ZW
9947 constraint (inst.operands[0].reg % 2 != 0,
9948 _("even register required"));
9949 constraint (inst.operands[1].present
9950 && inst.operands[1].reg != inst.operands[0].reg + 1,
9951 _("can only load two consecutive registers"));
9952 /* If op 1 were present and equal to PC, this function wouldn't
9953 have been called in the first place. */
9954 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
b05fe5cf 9955
c19d1205
ZW
9956 inst.instruction |= inst.operands[0].reg << 12;
9957 inst.instruction |= inst.operands[2].reg << 16;
b05fe5cf
ZW
9958}
9959
1be5fd2e
NC
9960/* In both ARM and thumb state 'ldr pc, #imm' with an immediate
9961 which is not a multiple of four is UNPREDICTABLE. */
9962static void
9963check_ldr_r15_aligned (void)
9964{
9965 constraint (!(inst.operands[1].immisreg)
9966 && (inst.operands[0].reg == REG_PC
9967 && inst.operands[1].reg == REG_PC
e2b0ab59 9968 && (inst.relocs[0].exp.X_add_number & 0x3)),
de194d85 9969 _("ldr to register 15 must be 4-byte aligned"));
1be5fd2e
NC
9970}
9971
b05fe5cf 9972static void
c19d1205 9973do_ldst (void)
b05fe5cf 9974{
c19d1205
ZW
9975 inst.instruction |= inst.operands[0].reg << 12;
9976 if (!inst.operands[1].isreg)
5b7c81bd 9977 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/false))
b05fe5cf 9978 return;
5b7c81bd 9979 encode_arm_addr_mode_2 (1, /*is_t=*/false);
1be5fd2e 9980 check_ldr_r15_aligned ();
b05fe5cf
ZW
9981}
9982
9983static void
c19d1205 9984do_ldstt (void)
b05fe5cf 9985{
c19d1205
ZW
9986 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9987 reject [Rn,...]. */
9988 if (inst.operands[1].preind)
b05fe5cf 9989 {
e2b0ab59
AV
9990 constraint (inst.relocs[0].exp.X_op != O_constant
9991 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9992 _("this instruction requires a post-indexed address"));
b05fe5cf 9993
c19d1205
ZW
9994 inst.operands[1].preind = 0;
9995 inst.operands[1].postind = 1;
9996 inst.operands[1].writeback = 1;
b05fe5cf 9997 }
c19d1205 9998 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 9999 encode_arm_addr_mode_2 (1, /*is_t=*/true);
c19d1205 10000}
b05fe5cf 10001
c19d1205 10002/* Halfword and signed-byte load/store operations. */
b05fe5cf 10003
c19d1205
ZW
10004static void
10005do_ldstv4 (void)
10006{
ff4a8d2b 10007 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205
ZW
10008 inst.instruction |= inst.operands[0].reg << 12;
10009 if (!inst.operands[1].isreg)
5b7c81bd 10010 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/true))
b05fe5cf 10011 return;
5b7c81bd 10012 encode_arm_addr_mode_3 (1, /*is_t=*/false);
b05fe5cf
ZW
10013}
10014
10015static void
c19d1205 10016do_ldsttv4 (void)
b05fe5cf 10017{
c19d1205
ZW
10018 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
10019 reject [Rn,...]. */
10020 if (inst.operands[1].preind)
b05fe5cf 10021 {
e2b0ab59
AV
10022 constraint (inst.relocs[0].exp.X_op != O_constant
10023 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10024 _("this instruction requires a post-indexed address"));
b05fe5cf 10025
c19d1205
ZW
10026 inst.operands[1].preind = 0;
10027 inst.operands[1].postind = 1;
10028 inst.operands[1].writeback = 1;
b05fe5cf 10029 }
c19d1205 10030 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 10031 encode_arm_addr_mode_3 (1, /*is_t=*/true);
c19d1205 10032}
b05fe5cf 10033
c19d1205
ZW
10034/* Co-processor register load/store.
10035 Format: <LDC|STC>{cond}[L] CP#,CRd,<address> */
10036static void
10037do_lstc (void)
10038{
10039 inst.instruction |= inst.operands[0].reg << 8;
10040 inst.instruction |= inst.operands[1].reg << 12;
5b7c81bd 10041 encode_arm_cp_address (2, true, true, 0);
b05fe5cf
ZW
10042}
10043
b05fe5cf 10044static void
c19d1205 10045do_mlas (void)
b05fe5cf 10046{
8fb9d7b9 10047 /* This restriction does not apply to mls (nor to mla in v6 or later). */
c19d1205 10048 if (inst.operands[0].reg == inst.operands[1].reg
8fb9d7b9 10049 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6)
c19d1205 10050 && !(inst.instruction & 0x00400000))
8fb9d7b9 10051 as_tsktsk (_("Rd and Rm should be different in mla"));
b05fe5cf 10052
c19d1205
ZW
10053 inst.instruction |= inst.operands[0].reg << 16;
10054 inst.instruction |= inst.operands[1].reg;
10055 inst.instruction |= inst.operands[2].reg << 8;
10056 inst.instruction |= inst.operands[3].reg << 12;
c19d1205 10057}
b05fe5cf 10058
c19d1205
ZW
10059static void
10060do_mov (void)
10061{
e2b0ab59
AV
10062 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
10063 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 10064 THUMB1_RELOC_ONLY);
c19d1205
ZW
10065 inst.instruction |= inst.operands[0].reg << 12;
10066 encode_arm_shifter_operand (1);
10067}
b05fe5cf 10068
c19d1205
ZW
10069/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
10070static void
10071do_mov16 (void)
10072{
b6895b4f 10073 bfd_vma imm;
5b7c81bd 10074 bool top;
b6895b4f
PB
10075
10076 top = (inst.instruction & 0x00400000) != 0;
e2b0ab59 10077 constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
33eaf5de 10078 _(":lower16: not allowed in this instruction"));
e2b0ab59 10079 constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
33eaf5de 10080 _(":upper16: not allowed in this instruction"));
c19d1205 10081 inst.instruction |= inst.operands[0].reg << 12;
e2b0ab59 10082 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 10083 {
e2b0ab59 10084 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
10085 /* The value is in two pieces: 0:11, 16:19. */
10086 inst.instruction |= (imm & 0x00000fff);
10087 inst.instruction |= (imm & 0x0000f000) << 4;
10088 }
b05fe5cf 10089}
b99bd4ef 10090
037e8744
JB
10091static int
10092do_vfp_nsyn_mrs (void)
10093{
10094 if (inst.operands[0].isvec)
10095 {
10096 if (inst.operands[1].reg != 1)
477330fc 10097 first_error (_("operand 1 must be FPSCR"));
037e8744
JB
10098 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
10099 memset (&inst.operands[1], '\0', sizeof (inst.operands[1]));
10100 do_vfp_nsyn_opcode ("fmstat");
10101 }
10102 else if (inst.operands[1].isvec)
10103 do_vfp_nsyn_opcode ("fmrx");
10104 else
10105 return FAIL;
5f4273c7 10106
037e8744
JB
10107 return SUCCESS;
10108}
10109
10110static int
10111do_vfp_nsyn_msr (void)
10112{
10113 if (inst.operands[0].isvec)
10114 do_vfp_nsyn_opcode ("fmxr");
10115 else
10116 return FAIL;
10117
10118 return SUCCESS;
10119}
10120
f7c21dc7
NC
10121static void
10122do_vmrs (void)
10123{
10124 unsigned Rt = inst.operands[0].reg;
fa94de6b 10125
16d02dc9 10126 if (thumb_mode && Rt == REG_SP)
f7c21dc7
NC
10127 {
10128 inst.error = BAD_SP;
10129 return;
10130 }
10131
ba6cd17f
SD
10132 switch (inst.operands[1].reg)
10133 {
10134 /* MVFR2 is only valid for Armv8-A. */
10135 case 5:
10136 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
10137 _(BAD_FPU));
10138 break;
10139
10140 /* Check for new Armv8.1-M Mainline changes to <spec_reg>. */
10141 case 1: /* fpscr. */
10142 constraint (!(ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10143 || ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10144 _(BAD_FPU));
10145 break;
10146
ee3272d4
SP
10147 case 14: /* fpcxt_ns, fpcxtns, FPCXT_NS, FPCXTNS. */
10148 case 15: /* fpcxt_s, fpcxts, FPCXT_S, FPCXTS. */
ba6cd17f
SD
10149 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main),
10150 _("selected processor does not support instruction"));
10151 break;
10152
10153 case 2: /* fpscr_nzcvqc. */
10154 case 12: /* vpr. */
10155 case 13: /* p0. */
10156 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main)
10157 || (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10158 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10159 _("selected processor does not support instruction"));
10160 if (inst.operands[0].reg != 2
10161 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
10162 as_warn (_("accessing MVE system register without MVE is UNPREDICTABLE"));
10163 break;
10164
10165 default:
10166 break;
10167 }
40c7d507 10168
f7c21dc7 10169 /* APSR_ sets isvec. All other refs to PC are illegal. */
16d02dc9 10170 if (!inst.operands[0].isvec && Rt == REG_PC)
f7c21dc7
NC
10171 {
10172 inst.error = BAD_PC;
10173 return;
10174 }
10175
16d02dc9
JB
10176 /* If we get through parsing the register name, we just insert the number
10177 generated into the instruction without further validation. */
10178 inst.instruction |= (inst.operands[1].reg << 16);
f7c21dc7
NC
10179 inst.instruction |= (Rt << 12);
10180}
10181
10182static void
10183do_vmsr (void)
10184{
10185 unsigned Rt = inst.operands[1].reg;
fa94de6b 10186
f7c21dc7
NC
10187 if (thumb_mode)
10188 reject_bad_reg (Rt);
10189 else if (Rt == REG_PC)
10190 {
10191 inst.error = BAD_PC;
10192 return;
10193 }
10194
ba6cd17f
SD
10195 switch (inst.operands[0].reg)
10196 {
10197 /* MVFR2 is only valid for Armv8-A. */
10198 case 5:
10199 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
10200 _(BAD_FPU));
10201 break;
10202
10203 /* Check for new Armv8.1-M Mainline changes to <spec_reg>. */
10204 case 1: /* fpcr. */
10205 constraint (!(ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10206 || ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10207 _(BAD_FPU));
10208 break;
10209
10210 case 14: /* fpcxt_ns. */
10211 case 15: /* fpcxt_s. */
10212 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main),
10213 _("selected processor does not support instruction"));
10214 break;
10215
10216 case 2: /* fpscr_nzcvqc. */
10217 case 12: /* vpr. */
10218 case 13: /* p0. */
10219 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main)
10220 || (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10221 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10222 _("selected processor does not support instruction"));
10223 if (inst.operands[0].reg != 2
10224 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
10225 as_warn (_("accessing MVE system register without MVE is UNPREDICTABLE"));
10226 break;
10227
10228 default:
10229 break;
10230 }
40c7d507 10231
16d02dc9
JB
10232 /* If we get through parsing the register name, we just insert the number
10233 generated into the instruction without further validation. */
10234 inst.instruction |= (inst.operands[0].reg << 16);
f7c21dc7
NC
10235 inst.instruction |= (Rt << 12);
10236}
10237
b99bd4ef 10238static void
c19d1205 10239do_mrs (void)
b99bd4ef 10240{
90ec0d68
MGD
10241 unsigned br;
10242
037e8744
JB
10243 if (do_vfp_nsyn_mrs () == SUCCESS)
10244 return;
10245
ff4a8d2b 10246 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205 10247 inst.instruction |= inst.operands[0].reg << 12;
90ec0d68
MGD
10248
10249 if (inst.operands[1].isreg)
10250 {
10251 br = inst.operands[1].reg;
806ab1c0 10252 if (((br & 0x200) == 0) && ((br & 0xf0000) != 0xf0000))
90ec0d68
MGD
10253 as_bad (_("bad register for mrs"));
10254 }
10255 else
10256 {
10257 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
10258 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
10259 != (PSR_c|PSR_f),
d2cd1205 10260 _("'APSR', 'CPSR' or 'SPSR' expected"));
90ec0d68
MGD
10261 br = (15<<16) | (inst.operands[1].imm & SPSR_BIT);
10262 }
10263
10264 inst.instruction |= br;
c19d1205 10265}
b99bd4ef 10266
c19d1205
ZW
10267/* Two possible forms:
10268 "{C|S}PSR_<field>, Rm",
10269 "{C|S}PSR_f, #expression". */
b99bd4ef 10270
c19d1205
ZW
10271static void
10272do_msr (void)
10273{
037e8744
JB
10274 if (do_vfp_nsyn_msr () == SUCCESS)
10275 return;
10276
c19d1205
ZW
10277 inst.instruction |= inst.operands[0].imm;
10278 if (inst.operands[1].isreg)
10279 inst.instruction |= inst.operands[1].reg;
10280 else
b99bd4ef 10281 {
c19d1205 10282 inst.instruction |= INST_IMMEDIATE;
e2b0ab59
AV
10283 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
10284 inst.relocs[0].pc_rel = 0;
b99bd4ef 10285 }
b99bd4ef
NC
10286}
10287
c19d1205
ZW
10288static void
10289do_mul (void)
a737bd4d 10290{
ff4a8d2b
NC
10291 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
10292
c19d1205
ZW
10293 if (!inst.operands[2].present)
10294 inst.operands[2].reg = inst.operands[0].reg;
10295 inst.instruction |= inst.operands[0].reg << 16;
10296 inst.instruction |= inst.operands[1].reg;
10297 inst.instruction |= inst.operands[2].reg << 8;
a737bd4d 10298
8fb9d7b9
MS
10299 if (inst.operands[0].reg == inst.operands[1].reg
10300 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
10301 as_tsktsk (_("Rd and Rm should be different in mul"));
a737bd4d
NC
10302}
10303
c19d1205
ZW
10304/* Long Multiply Parser
10305 UMULL RdLo, RdHi, Rm, Rs
10306 SMULL RdLo, RdHi, Rm, Rs
10307 UMLAL RdLo, RdHi, Rm, Rs
10308 SMLAL RdLo, RdHi, Rm, Rs. */
b99bd4ef
NC
10309
10310static void
c19d1205 10311do_mull (void)
b99bd4ef 10312{
c19d1205
ZW
10313 inst.instruction |= inst.operands[0].reg << 12;
10314 inst.instruction |= inst.operands[1].reg << 16;
10315 inst.instruction |= inst.operands[2].reg;
10316 inst.instruction |= inst.operands[3].reg << 8;
b99bd4ef 10317
682b27ad
PB
10318 /* rdhi and rdlo must be different. */
10319 if (inst.operands[0].reg == inst.operands[1].reg)
10320 as_tsktsk (_("rdhi and rdlo must be different"));
10321
10322 /* rdhi, rdlo and rm must all be different before armv6. */
10323 if ((inst.operands[0].reg == inst.operands[2].reg
c19d1205 10324 || inst.operands[1].reg == inst.operands[2].reg)
682b27ad 10325 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
c19d1205
ZW
10326 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
10327}
b99bd4ef 10328
c19d1205
ZW
10329static void
10330do_nop (void)
10331{
e7495e45
NS
10332 if (inst.operands[0].present
10333 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k))
c19d1205
ZW
10334 {
10335 /* Architectural NOP hints are CPSR sets with no bits selected. */
10336 inst.instruction &= 0xf0000000;
e7495e45
NS
10337 inst.instruction |= 0x0320f000;
10338 if (inst.operands[0].present)
10339 inst.instruction |= inst.operands[0].imm;
c19d1205 10340 }
b99bd4ef
NC
10341}
10342
c19d1205
ZW
10343/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
10344 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
10345 Condition defaults to COND_ALWAYS.
10346 Error if Rd, Rn or Rm are R15. */
b99bd4ef
NC
10347
10348static void
c19d1205 10349do_pkhbt (void)
b99bd4ef 10350{
c19d1205
ZW
10351 inst.instruction |= inst.operands[0].reg << 12;
10352 inst.instruction |= inst.operands[1].reg << 16;
10353 inst.instruction |= inst.operands[2].reg;
10354 if (inst.operands[3].present)
10355 encode_arm_shift (3);
10356}
b99bd4ef 10357
c19d1205 10358/* ARM V6 PKHTB (Argument Parse). */
b99bd4ef 10359
c19d1205
ZW
10360static void
10361do_pkhtb (void)
10362{
10363 if (!inst.operands[3].present)
b99bd4ef 10364 {
c19d1205
ZW
10365 /* If the shift specifier is omitted, turn the instruction
10366 into pkhbt rd, rm, rn. */
10367 inst.instruction &= 0xfff00010;
10368 inst.instruction |= inst.operands[0].reg << 12;
10369 inst.instruction |= inst.operands[1].reg;
10370 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
10371 }
10372 else
10373 {
c19d1205
ZW
10374 inst.instruction |= inst.operands[0].reg << 12;
10375 inst.instruction |= inst.operands[1].reg << 16;
10376 inst.instruction |= inst.operands[2].reg;
10377 encode_arm_shift (3);
b99bd4ef
NC
10378 }
10379}
10380
c19d1205 10381/* ARMv5TE: Preload-Cache
60e5ef9f 10382 MP Extensions: Preload for write
c19d1205 10383
60e5ef9f 10384 PLD(W) <addr_mode>
c19d1205
ZW
10385
10386 Syntactically, like LDR with B=1, W=0, L=1. */
b99bd4ef
NC
10387
10388static void
c19d1205 10389do_pld (void)
b99bd4ef 10390{
c19d1205
ZW
10391 constraint (!inst.operands[0].isreg,
10392 _("'[' expected after PLD mnemonic"));
10393 constraint (inst.operands[0].postind,
10394 _("post-indexed expression used in preload instruction"));
10395 constraint (inst.operands[0].writeback,
10396 _("writeback used in preload instruction"));
10397 constraint (!inst.operands[0].preind,
10398 _("unindexed addressing used in preload instruction"));
5b7c81bd 10399 encode_arm_addr_mode_2 (0, /*is_t=*/false);
c19d1205 10400}
b99bd4ef 10401
62b3e311
PB
10402/* ARMv7: PLI <addr_mode> */
10403static void
10404do_pli (void)
10405{
10406 constraint (!inst.operands[0].isreg,
10407 _("'[' expected after PLI mnemonic"));
10408 constraint (inst.operands[0].postind,
10409 _("post-indexed expression used in preload instruction"));
10410 constraint (inst.operands[0].writeback,
10411 _("writeback used in preload instruction"));
10412 constraint (!inst.operands[0].preind,
10413 _("unindexed addressing used in preload instruction"));
5b7c81bd 10414 encode_arm_addr_mode_2 (0, /*is_t=*/false);
62b3e311
PB
10415 inst.instruction &= ~PRE_INDEX;
10416}
10417
c19d1205
ZW
10418static void
10419do_push_pop (void)
10420{
5e0d7f77
MP
10421 constraint (inst.operands[0].writeback,
10422 _("push/pop do not support {reglist}^"));
c19d1205
ZW
10423 inst.operands[1] = inst.operands[0];
10424 memset (&inst.operands[0], 0, sizeof inst.operands[0]);
10425 inst.operands[0].isreg = 1;
10426 inst.operands[0].writeback = 1;
10427 inst.operands[0].reg = REG_SP;
5b7c81bd 10428 encode_ldmstm (/*from_push_pop_mnem=*/true);
c19d1205 10429}
b99bd4ef 10430
c19d1205
ZW
10431/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
10432 word at the specified address and the following word
10433 respectively.
10434 Unconditionally executed.
10435 Error if Rn is R15. */
b99bd4ef 10436
c19d1205
ZW
10437static void
10438do_rfe (void)
10439{
10440 inst.instruction |= inst.operands[0].reg << 16;
10441 if (inst.operands[0].writeback)
10442 inst.instruction |= WRITE_BACK;
10443}
b99bd4ef 10444
c19d1205 10445/* ARM V6 ssat (argument parse). */
b99bd4ef 10446
c19d1205
ZW
10447static void
10448do_ssat (void)
10449{
10450 inst.instruction |= inst.operands[0].reg << 12;
10451 inst.instruction |= (inst.operands[1].imm - 1) << 16;
10452 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10453
c19d1205
ZW
10454 if (inst.operands[3].present)
10455 encode_arm_shift (3);
b99bd4ef
NC
10456}
10457
c19d1205 10458/* ARM V6 usat (argument parse). */
b99bd4ef
NC
10459
10460static void
c19d1205 10461do_usat (void)
b99bd4ef 10462{
c19d1205
ZW
10463 inst.instruction |= inst.operands[0].reg << 12;
10464 inst.instruction |= inst.operands[1].imm << 16;
10465 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10466
c19d1205
ZW
10467 if (inst.operands[3].present)
10468 encode_arm_shift (3);
b99bd4ef
NC
10469}
10470
c19d1205 10471/* ARM V6 ssat16 (argument parse). */
09d92015
MM
10472
10473static void
c19d1205 10474do_ssat16 (void)
09d92015 10475{
c19d1205
ZW
10476 inst.instruction |= inst.operands[0].reg << 12;
10477 inst.instruction |= ((inst.operands[1].imm - 1) << 16);
10478 inst.instruction |= inst.operands[2].reg;
09d92015
MM
10479}
10480
c19d1205
ZW
10481static void
10482do_usat16 (void)
a737bd4d 10483{
c19d1205
ZW
10484 inst.instruction |= inst.operands[0].reg << 12;
10485 inst.instruction |= inst.operands[1].imm << 16;
10486 inst.instruction |= inst.operands[2].reg;
10487}
a737bd4d 10488
c19d1205
ZW
10489/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
10490 preserving the other bits.
a737bd4d 10491
c19d1205
ZW
10492 setend <endian_specifier>, where <endian_specifier> is either
10493 BE or LE. */
a737bd4d 10494
c19d1205
ZW
10495static void
10496do_setend (void)
10497{
12e37cbc
MGD
10498 if (warn_on_deprecated
10499 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 10500 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 10501
c19d1205
ZW
10502 if (inst.operands[0].imm)
10503 inst.instruction |= 0x200;
a737bd4d
NC
10504}
10505
10506static void
c19d1205 10507do_shift (void)
a737bd4d 10508{
c19d1205
ZW
10509 unsigned int Rm = (inst.operands[1].present
10510 ? inst.operands[1].reg
10511 : inst.operands[0].reg);
a737bd4d 10512
c19d1205
ZW
10513 inst.instruction |= inst.operands[0].reg << 12;
10514 inst.instruction |= Rm;
10515 if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
a737bd4d 10516 {
c19d1205
ZW
10517 inst.instruction |= inst.operands[2].reg << 8;
10518 inst.instruction |= SHIFT_BY_REG;
94342ec3
NC
10519 /* PR 12854: Error on extraneous shifts. */
10520 constraint (inst.operands[2].shifted,
10521 _("extraneous shift as part of operand to shift insn"));
a737bd4d
NC
10522 }
10523 else
e2b0ab59 10524 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
a737bd4d
NC
10525}
10526
09d92015 10527static void
3eb17e6b 10528do_smc (void)
09d92015 10529{
ba85f98c
BW
10530 unsigned int value = inst.relocs[0].exp.X_add_number;
10531 constraint (value > 0xf, _("immediate too large (bigger than 0xF)"));
10532
e2b0ab59
AV
10533 inst.relocs[0].type = BFD_RELOC_ARM_SMC;
10534 inst.relocs[0].pc_rel = 0;
09d92015
MM
10535}
10536
90ec0d68
MGD
10537static void
10538do_hvc (void)
10539{
e2b0ab59
AV
10540 inst.relocs[0].type = BFD_RELOC_ARM_HVC;
10541 inst.relocs[0].pc_rel = 0;
90ec0d68
MGD
10542}
10543
09d92015 10544static void
c19d1205 10545do_swi (void)
09d92015 10546{
e2b0ab59
AV
10547 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
10548 inst.relocs[0].pc_rel = 0;
09d92015
MM
10549}
10550
ddfded2f
MW
10551static void
10552do_setpan (void)
10553{
10554 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10555 _("selected processor does not support SETPAN instruction"));
10556
10557 inst.instruction |= ((inst.operands[0].imm & 1) << 9);
10558}
10559
10560static void
10561do_t_setpan (void)
10562{
10563 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10564 _("selected processor does not support SETPAN instruction"));
10565
10566 inst.instruction |= (inst.operands[0].imm << 3);
10567}
10568
c19d1205
ZW
10569/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
10570 SMLAxy{cond} Rd,Rm,Rs,Rn
10571 SMLAWy{cond} Rd,Rm,Rs,Rn
10572 Error if any register is R15. */
e16bb312 10573
c19d1205
ZW
10574static void
10575do_smla (void)
e16bb312 10576{
c19d1205
ZW
10577 inst.instruction |= inst.operands[0].reg << 16;
10578 inst.instruction |= inst.operands[1].reg;
10579 inst.instruction |= inst.operands[2].reg << 8;
10580 inst.instruction |= inst.operands[3].reg << 12;
10581}
a737bd4d 10582
c19d1205
ZW
10583/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
10584 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
10585 Error if any register is R15.
10586 Warning if Rdlo == Rdhi. */
a737bd4d 10587
c19d1205
ZW
10588static void
10589do_smlal (void)
10590{
10591 inst.instruction |= inst.operands[0].reg << 12;
10592 inst.instruction |= inst.operands[1].reg << 16;
10593 inst.instruction |= inst.operands[2].reg;
10594 inst.instruction |= inst.operands[3].reg << 8;
a737bd4d 10595
c19d1205
ZW
10596 if (inst.operands[0].reg == inst.operands[1].reg)
10597 as_tsktsk (_("rdhi and rdlo must be different"));
10598}
a737bd4d 10599
c19d1205
ZW
10600/* ARM V5E (El Segundo) signed-multiply (argument parse)
10601 SMULxy{cond} Rd,Rm,Rs
10602 Error if any register is R15. */
a737bd4d 10603
c19d1205
ZW
10604static void
10605do_smul (void)
10606{
10607 inst.instruction |= inst.operands[0].reg << 16;
10608 inst.instruction |= inst.operands[1].reg;
10609 inst.instruction |= inst.operands[2].reg << 8;
10610}
a737bd4d 10611
b6702015
PB
10612/* ARM V6 srs (argument parse). The variable fields in the encoding are
10613 the same for both ARM and Thumb-2. */
a737bd4d 10614
c19d1205
ZW
10615static void
10616do_srs (void)
10617{
b6702015
PB
10618 int reg;
10619
10620 if (inst.operands[0].present)
10621 {
10622 reg = inst.operands[0].reg;
fdfde340 10623 constraint (reg != REG_SP, _("SRS base register must be r13"));
b6702015
PB
10624 }
10625 else
fdfde340 10626 reg = REG_SP;
b6702015
PB
10627
10628 inst.instruction |= reg << 16;
10629 inst.instruction |= inst.operands[1].imm;
10630 if (inst.operands[0].writeback || inst.operands[1].writeback)
c19d1205
ZW
10631 inst.instruction |= WRITE_BACK;
10632}
a737bd4d 10633
c19d1205 10634/* ARM V6 strex (argument parse). */
a737bd4d 10635
c19d1205
ZW
10636static void
10637do_strex (void)
10638{
10639 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10640 || inst.operands[2].postind || inst.operands[2].writeback
10641 || inst.operands[2].immisreg || inst.operands[2].shifted
01cfc07f
NC
10642 || inst.operands[2].negative
10643 /* See comment in do_ldrex(). */
10644 || (inst.operands[2].reg == REG_PC),
10645 BAD_ADDR_MODE);
a737bd4d 10646
c19d1205
ZW
10647 constraint (inst.operands[0].reg == inst.operands[1].reg
10648 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
a737bd4d 10649
e2b0ab59
AV
10650 constraint (inst.relocs[0].exp.X_op != O_constant
10651 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10652 _("offset must be zero in ARM encoding"));
a737bd4d 10653
c19d1205
ZW
10654 inst.instruction |= inst.operands[0].reg << 12;
10655 inst.instruction |= inst.operands[1].reg;
10656 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 10657 inst.relocs[0].type = BFD_RELOC_UNUSED;
e16bb312
NC
10658}
10659
877807f8
NC
10660static void
10661do_t_strexbh (void)
10662{
10663 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10664 || inst.operands[2].postind || inst.operands[2].writeback
10665 || inst.operands[2].immisreg || inst.operands[2].shifted
10666 || inst.operands[2].negative,
10667 BAD_ADDR_MODE);
10668
10669 constraint (inst.operands[0].reg == inst.operands[1].reg
10670 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10671
10672 do_rm_rd_rn ();
10673}
10674
e16bb312 10675static void
c19d1205 10676do_strexd (void)
e16bb312 10677{
c19d1205
ZW
10678 constraint (inst.operands[1].reg % 2 != 0,
10679 _("even register required"));
10680 constraint (inst.operands[2].present
10681 && inst.operands[2].reg != inst.operands[1].reg + 1,
10682 _("can only store two consecutive registers"));
10683 /* If op 2 were present and equal to PC, this function wouldn't
10684 have been called in the first place. */
10685 constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
e16bb312 10686
c19d1205
ZW
10687 constraint (inst.operands[0].reg == inst.operands[1].reg
10688 || inst.operands[0].reg == inst.operands[1].reg + 1
10689 || inst.operands[0].reg == inst.operands[3].reg,
10690 BAD_OVERLAP);
e16bb312 10691
c19d1205
ZW
10692 inst.instruction |= inst.operands[0].reg << 12;
10693 inst.instruction |= inst.operands[1].reg;
10694 inst.instruction |= inst.operands[3].reg << 16;
e16bb312
NC
10695}
10696
9eb6c0f1
MGD
10697/* ARM V8 STRL. */
10698static void
4b8c8c02 10699do_stlex (void)
9eb6c0f1
MGD
10700{
10701 constraint (inst.operands[0].reg == inst.operands[1].reg
10702 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10703
10704 do_rd_rm_rn ();
10705}
10706
10707static void
4b8c8c02 10708do_t_stlex (void)
9eb6c0f1
MGD
10709{
10710 constraint (inst.operands[0].reg == inst.operands[1].reg
10711 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10712
10713 do_rm_rd_rn ();
10714}
10715
c19d1205
ZW
10716/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
10717 extends it to 32-bits, and adds the result to a value in another
10718 register. You can specify a rotation by 0, 8, 16, or 24 bits
10719 before extracting the 16-bit value.
10720 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
10721 Condition defaults to COND_ALWAYS.
10722 Error if any register uses R15. */
10723
e16bb312 10724static void
c19d1205 10725do_sxtah (void)
e16bb312 10726{
c19d1205
ZW
10727 inst.instruction |= inst.operands[0].reg << 12;
10728 inst.instruction |= inst.operands[1].reg << 16;
10729 inst.instruction |= inst.operands[2].reg;
10730 inst.instruction |= inst.operands[3].imm << 10;
10731}
e16bb312 10732
c19d1205 10733/* ARM V6 SXTH.
e16bb312 10734
c19d1205
ZW
10735 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
10736 Condition defaults to COND_ALWAYS.
10737 Error if any register uses R15. */
e16bb312
NC
10738
10739static void
c19d1205 10740do_sxth (void)
e16bb312 10741{
c19d1205
ZW
10742 inst.instruction |= inst.operands[0].reg << 12;
10743 inst.instruction |= inst.operands[1].reg;
10744 inst.instruction |= inst.operands[2].imm << 10;
e16bb312 10745}
c19d1205
ZW
10746\f
10747/* VFP instructions. In a logical order: SP variant first, monad
10748 before dyad, arithmetic then move then load/store. */
e16bb312
NC
10749
10750static void
c19d1205 10751do_vfp_sp_monadic (void)
e16bb312 10752{
57785aa2
AV
10753 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10754 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10755 _(BAD_FPU));
10756
5287ad62
JB
10757 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10758 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10759}
10760
10761static void
c19d1205 10762do_vfp_sp_dyadic (void)
e16bb312 10763{
5287ad62
JB
10764 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10765 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
10766 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10767}
10768
10769static void
c19d1205 10770do_vfp_sp_compare_z (void)
e16bb312 10771{
5287ad62 10772 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
e16bb312
NC
10773}
10774
10775static void
c19d1205 10776do_vfp_dp_sp_cvt (void)
e16bb312 10777{
5287ad62
JB
10778 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10779 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10780}
10781
10782static void
c19d1205 10783do_vfp_sp_dp_cvt (void)
e16bb312 10784{
5287ad62
JB
10785 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10786 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
e16bb312
NC
10787}
10788
10789static void
c19d1205 10790do_vfp_reg_from_sp (void)
e16bb312 10791{
57785aa2
AV
10792 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10793 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10794 _(BAD_FPU));
10795
c19d1205 10796 inst.instruction |= inst.operands[0].reg << 12;
5287ad62 10797 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
e16bb312
NC
10798}
10799
10800static void
c19d1205 10801do_vfp_reg2_from_sp2 (void)
e16bb312 10802{
c19d1205
ZW
10803 constraint (inst.operands[2].imm != 2,
10804 _("only two consecutive VFP SP registers allowed here"));
10805 inst.instruction |= inst.operands[0].reg << 12;
10806 inst.instruction |= inst.operands[1].reg << 16;
5287ad62 10807 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10808}
10809
10810static void
c19d1205 10811do_vfp_sp_from_reg (void)
e16bb312 10812{
57785aa2
AV
10813 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10814 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10815 _(BAD_FPU));
10816
5287ad62 10817 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sn);
c19d1205 10818 inst.instruction |= inst.operands[1].reg << 12;
e16bb312
NC
10819}
10820
10821static void
c19d1205 10822do_vfp_sp2_from_reg2 (void)
e16bb312 10823{
c19d1205
ZW
10824 constraint (inst.operands[0].imm != 2,
10825 _("only two consecutive VFP SP registers allowed here"));
5287ad62 10826 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sm);
c19d1205
ZW
10827 inst.instruction |= inst.operands[1].reg << 12;
10828 inst.instruction |= inst.operands[2].reg << 16;
e16bb312
NC
10829}
10830
10831static void
c19d1205 10832do_vfp_sp_ldst (void)
e16bb312 10833{
5287ad62 10834 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
5b7c81bd 10835 encode_arm_cp_address (1, false, true, 0);
e16bb312
NC
10836}
10837
10838static void
c19d1205 10839do_vfp_dp_ldst (void)
e16bb312 10840{
5287ad62 10841 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
5b7c81bd 10842 encode_arm_cp_address (1, false, true, 0);
e16bb312
NC
10843}
10844
c19d1205 10845
e16bb312 10846static void
c19d1205 10847vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10848{
c19d1205
ZW
10849 if (inst.operands[0].writeback)
10850 inst.instruction |= WRITE_BACK;
10851 else
10852 constraint (ldstm_type != VFP_LDSTMIA,
10853 _("this addressing mode requires base-register writeback"));
10854 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10855 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sd);
c19d1205 10856 inst.instruction |= inst.operands[1].imm;
e16bb312
NC
10857}
10858
10859static void
c19d1205 10860vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10861{
c19d1205 10862 int count;
e16bb312 10863
c19d1205
ZW
10864 if (inst.operands[0].writeback)
10865 inst.instruction |= WRITE_BACK;
10866 else
10867 constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
10868 _("this addressing mode requires base-register writeback"));
e16bb312 10869
c19d1205 10870 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10871 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
e16bb312 10872
c19d1205
ZW
10873 count = inst.operands[1].imm << 1;
10874 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
10875 count += 1;
e16bb312 10876
c19d1205 10877 inst.instruction |= count;
e16bb312
NC
10878}
10879
10880static void
c19d1205 10881do_vfp_sp_ldstmia (void)
e16bb312 10882{
c19d1205 10883 vfp_sp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10884}
10885
10886static void
c19d1205 10887do_vfp_sp_ldstmdb (void)
e16bb312 10888{
c19d1205 10889 vfp_sp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10890}
10891
10892static void
c19d1205 10893do_vfp_dp_ldstmia (void)
e16bb312 10894{
c19d1205 10895 vfp_dp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10896}
10897
10898static void
c19d1205 10899do_vfp_dp_ldstmdb (void)
e16bb312 10900{
c19d1205 10901 vfp_dp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10902}
10903
10904static void
c19d1205 10905do_vfp_xp_ldstmia (void)
e16bb312 10906{
c19d1205
ZW
10907 vfp_dp_ldstm (VFP_LDSTMIAX);
10908}
e16bb312 10909
c19d1205
ZW
10910static void
10911do_vfp_xp_ldstmdb (void)
10912{
10913 vfp_dp_ldstm (VFP_LDSTMDBX);
e16bb312 10914}
5287ad62
JB
10915
10916static void
10917do_vfp_dp_rd_rm (void)
10918{
57785aa2
AV
10919 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
10920 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10921 _(BAD_FPU));
10922
5287ad62
JB
10923 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10924 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
10925}
10926
10927static void
10928do_vfp_dp_rn_rd (void)
10929{
10930 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dn);
10931 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10932}
10933
10934static void
10935do_vfp_dp_rd_rn (void)
10936{
10937 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10938 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10939}
10940
10941static void
10942do_vfp_dp_rd_rn_rm (void)
10943{
57785aa2
AV
10944 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10945 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10946 _(BAD_FPU));
10947
5287ad62
JB
10948 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10949 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10950 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dm);
10951}
10952
10953static void
10954do_vfp_dp_rd (void)
10955{
10956 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10957}
10958
10959static void
10960do_vfp_dp_rm_rd_rn (void)
10961{
57785aa2
AV
10962 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10963 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10964 _(BAD_FPU));
10965
5287ad62
JB
10966 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dm);
10967 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10968 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dn);
10969}
10970
10971/* VFPv3 instructions. */
10972static void
10973do_vfp_sp_const (void)
10974{
10975 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
00249aaa
PB
10976 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10977 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10978}
10979
10980static void
10981do_vfp_dp_const (void)
10982{
10983 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
00249aaa
PB
10984 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10985 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10986}
10987
10988static void
10989vfp_conv (int srcsize)
10990{
5f1af56b
MGD
10991 int immbits = srcsize - inst.operands[1].imm;
10992
fa94de6b
RM
10993 if (srcsize == 16 && !(immbits >= 0 && immbits <= srcsize))
10994 {
5f1af56b 10995 /* If srcsize is 16, inst.operands[1].imm must be in the range 0-16.
477330fc 10996 i.e. immbits must be in range 0 - 16. */
5f1af56b
MGD
10997 inst.error = _("immediate value out of range, expected range [0, 16]");
10998 return;
10999 }
fa94de6b 11000 else if (srcsize == 32 && !(immbits >= 0 && immbits < srcsize))
5f1af56b
MGD
11001 {
11002 /* If srcsize is 32, inst.operands[1].imm must be in the range 1-32.
477330fc 11003 i.e. immbits must be in range 0 - 31. */
5f1af56b
MGD
11004 inst.error = _("immediate value out of range, expected range [1, 32]");
11005 return;
11006 }
11007
5287ad62
JB
11008 inst.instruction |= (immbits & 1) << 5;
11009 inst.instruction |= (immbits >> 1);
11010}
11011
11012static void
11013do_vfp_sp_conv_16 (void)
11014{
11015 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
11016 vfp_conv (16);
11017}
11018
11019static void
11020do_vfp_dp_conv_16 (void)
11021{
11022 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
11023 vfp_conv (16);
11024}
11025
11026static void
11027do_vfp_sp_conv_32 (void)
11028{
11029 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
11030 vfp_conv (32);
11031}
11032
11033static void
11034do_vfp_dp_conv_32 (void)
11035{
11036 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
11037 vfp_conv (32);
11038}
c19d1205
ZW
11039\f
11040/* FPA instructions. Also in a logical order. */
e16bb312 11041
c19d1205
ZW
11042static void
11043do_fpa_cmp (void)
11044{
11045 inst.instruction |= inst.operands[0].reg << 16;
11046 inst.instruction |= inst.operands[1].reg;
11047}
b99bd4ef
NC
11048
11049static void
c19d1205 11050do_fpa_ldmstm (void)
b99bd4ef 11051{
c19d1205
ZW
11052 inst.instruction |= inst.operands[0].reg << 12;
11053 switch (inst.operands[1].imm)
11054 {
11055 case 1: inst.instruction |= CP_T_X; break;
11056 case 2: inst.instruction |= CP_T_Y; break;
11057 case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
11058 case 4: break;
11059 default: abort ();
11060 }
b99bd4ef 11061
c19d1205
ZW
11062 if (inst.instruction & (PRE_INDEX | INDEX_UP))
11063 {
11064 /* The instruction specified "ea" or "fd", so we can only accept
11065 [Rn]{!}. The instruction does not really support stacking or
11066 unstacking, so we have to emulate these by setting appropriate
11067 bits and offsets. */
e2b0ab59
AV
11068 constraint (inst.relocs[0].exp.X_op != O_constant
11069 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 11070 _("this instruction does not support indexing"));
b99bd4ef 11071
c19d1205 11072 if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
e2b0ab59 11073 inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
b99bd4ef 11074
c19d1205 11075 if (!(inst.instruction & INDEX_UP))
e2b0ab59 11076 inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
b99bd4ef 11077
c19d1205
ZW
11078 if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
11079 {
11080 inst.operands[2].preind = 0;
11081 inst.operands[2].postind = 1;
11082 }
11083 }
b99bd4ef 11084
5b7c81bd 11085 encode_arm_cp_address (2, true, true, 0);
b99bd4ef 11086}
c19d1205
ZW
11087\f
11088/* iWMMXt instructions: strictly in alphabetical order. */
b99bd4ef 11089
c19d1205
ZW
11090static void
11091do_iwmmxt_tandorc (void)
11092{
11093 constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
11094}
b99bd4ef 11095
c19d1205
ZW
11096static void
11097do_iwmmxt_textrc (void)
11098{
11099 inst.instruction |= inst.operands[0].reg << 12;
11100 inst.instruction |= inst.operands[1].imm;
11101}
b99bd4ef
NC
11102
11103static void
c19d1205 11104do_iwmmxt_textrm (void)
b99bd4ef 11105{
c19d1205
ZW
11106 inst.instruction |= inst.operands[0].reg << 12;
11107 inst.instruction |= inst.operands[1].reg << 16;
11108 inst.instruction |= inst.operands[2].imm;
11109}
b99bd4ef 11110
c19d1205
ZW
11111static void
11112do_iwmmxt_tinsr (void)
11113{
11114 inst.instruction |= inst.operands[0].reg << 16;
11115 inst.instruction |= inst.operands[1].reg << 12;
11116 inst.instruction |= inst.operands[2].imm;
11117}
b99bd4ef 11118
c19d1205
ZW
11119static void
11120do_iwmmxt_tmia (void)
11121{
11122 inst.instruction |= inst.operands[0].reg << 5;
11123 inst.instruction |= inst.operands[1].reg;
11124 inst.instruction |= inst.operands[2].reg << 12;
11125}
b99bd4ef 11126
c19d1205
ZW
11127static void
11128do_iwmmxt_waligni (void)
11129{
11130 inst.instruction |= inst.operands[0].reg << 12;
11131 inst.instruction |= inst.operands[1].reg << 16;
11132 inst.instruction |= inst.operands[2].reg;
11133 inst.instruction |= inst.operands[3].imm << 20;
11134}
b99bd4ef 11135
2d447fca
JM
11136static void
11137do_iwmmxt_wmerge (void)
11138{
11139 inst.instruction |= inst.operands[0].reg << 12;
11140 inst.instruction |= inst.operands[1].reg << 16;
11141 inst.instruction |= inst.operands[2].reg;
11142 inst.instruction |= inst.operands[3].imm << 21;
11143}
11144
c19d1205
ZW
11145static void
11146do_iwmmxt_wmov (void)
11147{
11148 /* WMOV rD, rN is an alias for WOR rD, rN, rN. */
11149 inst.instruction |= inst.operands[0].reg << 12;
11150 inst.instruction |= inst.operands[1].reg << 16;
11151 inst.instruction |= inst.operands[1].reg;
11152}
b99bd4ef 11153
c19d1205
ZW
11154static void
11155do_iwmmxt_wldstbh (void)
11156{
8f06b2d8 11157 int reloc;
c19d1205 11158 inst.instruction |= inst.operands[0].reg << 12;
8f06b2d8
PB
11159 if (thumb_mode)
11160 reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
11161 else
11162 reloc = BFD_RELOC_ARM_CP_OFF_IMM_S2;
5b7c81bd 11163 encode_arm_cp_address (1, true, false, reloc);
b99bd4ef
NC
11164}
11165
c19d1205
ZW
11166static void
11167do_iwmmxt_wldstw (void)
11168{
11169 /* RIWR_RIWC clears .isreg for a control register. */
11170 if (!inst.operands[0].isreg)
11171 {
11172 constraint (inst.cond != COND_ALWAYS, BAD_COND);
11173 inst.instruction |= 0xf0000000;
11174 }
b99bd4ef 11175
c19d1205 11176 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 11177 encode_arm_cp_address (1, true, true, 0);
c19d1205 11178}
b99bd4ef
NC
11179
11180static void
c19d1205 11181do_iwmmxt_wldstd (void)
b99bd4ef 11182{
c19d1205 11183 inst.instruction |= inst.operands[0].reg << 12;
2d447fca
JM
11184 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)
11185 && inst.operands[1].immisreg)
11186 {
11187 inst.instruction &= ~0x1a000ff;
eff0bc54 11188 inst.instruction |= (0xfU << 28);
2d447fca
JM
11189 if (inst.operands[1].preind)
11190 inst.instruction |= PRE_INDEX;
11191 if (!inst.operands[1].negative)
11192 inst.instruction |= INDEX_UP;
11193 if (inst.operands[1].writeback)
11194 inst.instruction |= WRITE_BACK;
11195 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 11196 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
2d447fca
JM
11197 inst.instruction |= inst.operands[1].imm;
11198 }
11199 else
5b7c81bd 11200 encode_arm_cp_address (1, true, false, 0);
c19d1205 11201}
b99bd4ef 11202
c19d1205
ZW
11203static void
11204do_iwmmxt_wshufh (void)
11205{
11206 inst.instruction |= inst.operands[0].reg << 12;
11207 inst.instruction |= inst.operands[1].reg << 16;
11208 inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
11209 inst.instruction |= (inst.operands[2].imm & 0x0f);
11210}
b99bd4ef 11211
c19d1205
ZW
11212static void
11213do_iwmmxt_wzero (void)
11214{
11215 /* WZERO reg is an alias for WANDN reg, reg, reg. */
11216 inst.instruction |= inst.operands[0].reg;
11217 inst.instruction |= inst.operands[0].reg << 12;
11218 inst.instruction |= inst.operands[0].reg << 16;
11219}
2d447fca
JM
11220
11221static void
11222do_iwmmxt_wrwrwr_or_imm5 (void)
11223{
11224 if (inst.operands[2].isreg)
11225 do_rd_rn_rm ();
11226 else {
11227 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2),
11228 _("immediate operand requires iWMMXt2"));
11229 do_rd_rn ();
11230 if (inst.operands[2].imm == 0)
11231 {
11232 switch ((inst.instruction >> 20) & 0xf)
11233 {
11234 case 4:
11235 case 5:
11236 case 6:
5f4273c7 11237 case 7:
2d447fca
JM
11238 /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16. */
11239 inst.operands[2].imm = 16;
11240 inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
11241 break;
11242 case 8:
11243 case 9:
11244 case 10:
11245 case 11:
11246 /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32. */
11247 inst.operands[2].imm = 32;
11248 inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
11249 break;
11250 case 12:
11251 case 13:
11252 case 14:
11253 case 15:
11254 {
11255 /* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn. */
11256 unsigned long wrn;
11257 wrn = (inst.instruction >> 16) & 0xf;
11258 inst.instruction &= 0xff0fff0f;
11259 inst.instruction |= wrn;
11260 /* Bail out here; the instruction is now assembled. */
11261 return;
11262 }
11263 }
11264 }
11265 /* Map 32 -> 0, etc. */
11266 inst.operands[2].imm &= 0x1f;
eff0bc54 11267 inst.instruction |= (0xfU << 28) | ((inst.operands[2].imm & 0x10) << 4) | (inst.operands[2].imm & 0xf);
2d447fca
JM
11268 }
11269}
c19d1205
ZW
11270\f
11271/* Cirrus Maverick instructions. Simple 2-, 3-, and 4-register
11272 operations first, then control, shift, and load/store. */
b99bd4ef 11273
c19d1205 11274/* Insns like "foo X,Y,Z". */
b99bd4ef 11275
c19d1205
ZW
11276static void
11277do_mav_triple (void)
11278{
11279 inst.instruction |= inst.operands[0].reg << 16;
11280 inst.instruction |= inst.operands[1].reg;
11281 inst.instruction |= inst.operands[2].reg << 12;
11282}
b99bd4ef 11283
c19d1205
ZW
11284/* Insns like "foo W,X,Y,Z".
11285 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
a737bd4d 11286
c19d1205
ZW
11287static void
11288do_mav_quad (void)
11289{
11290 inst.instruction |= inst.operands[0].reg << 5;
11291 inst.instruction |= inst.operands[1].reg << 12;
11292 inst.instruction |= inst.operands[2].reg << 16;
11293 inst.instruction |= inst.operands[3].reg;
a737bd4d
NC
11294}
11295
c19d1205
ZW
11296/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
11297static void
11298do_mav_dspsc (void)
a737bd4d 11299{
c19d1205
ZW
11300 inst.instruction |= inst.operands[1].reg << 12;
11301}
a737bd4d 11302
c19d1205
ZW
11303/* Maverick shift immediate instructions.
11304 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
11305 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
a737bd4d 11306
c19d1205
ZW
11307static void
11308do_mav_shift (void)
11309{
11310 int imm = inst.operands[2].imm;
a737bd4d 11311
c19d1205
ZW
11312 inst.instruction |= inst.operands[0].reg << 12;
11313 inst.instruction |= inst.operands[1].reg << 16;
a737bd4d 11314
c19d1205
ZW
11315 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
11316 Bits 5-7 of the insn should have bits 4-6 of the immediate.
11317 Bit 4 should be 0. */
11318 imm = (imm & 0xf) | ((imm & 0x70) << 1);
a737bd4d 11319
c19d1205
ZW
11320 inst.instruction |= imm;
11321}
11322\f
11323/* XScale instructions. Also sorted arithmetic before move. */
a737bd4d 11324
c19d1205
ZW
11325/* Xscale multiply-accumulate (argument parse)
11326 MIAcc acc0,Rm,Rs
11327 MIAPHcc acc0,Rm,Rs
11328 MIAxycc acc0,Rm,Rs. */
a737bd4d 11329
c19d1205
ZW
11330static void
11331do_xsc_mia (void)
11332{
11333 inst.instruction |= inst.operands[1].reg;
11334 inst.instruction |= inst.operands[2].reg << 12;
11335}
a737bd4d 11336
c19d1205 11337/* Xscale move-accumulator-register (argument parse)
a737bd4d 11338
c19d1205 11339 MARcc acc0,RdLo,RdHi. */
b99bd4ef 11340
c19d1205
ZW
11341static void
11342do_xsc_mar (void)
11343{
11344 inst.instruction |= inst.operands[1].reg << 12;
11345 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
11346}
11347
c19d1205 11348/* Xscale move-register-accumulator (argument parse)
b99bd4ef 11349
c19d1205 11350 MRAcc RdLo,RdHi,acc0. */
b99bd4ef
NC
11351
11352static void
c19d1205 11353do_xsc_mra (void)
b99bd4ef 11354{
c19d1205
ZW
11355 constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
11356 inst.instruction |= inst.operands[0].reg << 12;
11357 inst.instruction |= inst.operands[1].reg << 16;
11358}
11359\f
11360/* Encoding functions relevant only to Thumb. */
b99bd4ef 11361
c19d1205
ZW
11362/* inst.operands[i] is a shifted-register operand; encode
11363 it into inst.instruction in the format used by Thumb32. */
11364
11365static void
11366encode_thumb32_shifted_operand (int i)
11367{
e2b0ab59 11368 unsigned int value = inst.relocs[0].exp.X_add_number;
c19d1205 11369 unsigned int shift = inst.operands[i].shift_kind;
b99bd4ef 11370
9c3c69f2
PB
11371 constraint (inst.operands[i].immisreg,
11372 _("shift by register not allowed in thumb mode"));
c19d1205
ZW
11373 inst.instruction |= inst.operands[i].reg;
11374 if (shift == SHIFT_RRX)
11375 inst.instruction |= SHIFT_ROR << 4;
11376 else
b99bd4ef 11377 {
e2b0ab59 11378 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
11379 _("expression too complex"));
11380
11381 constraint (value > 32
11382 || (value == 32 && (shift == SHIFT_LSL
11383 || shift == SHIFT_ROR)),
11384 _("shift expression is too large"));
11385
11386 if (value == 0)
11387 shift = SHIFT_LSL;
11388 else if (value == 32)
11389 value = 0;
11390
11391 inst.instruction |= shift << 4;
11392 inst.instruction |= (value & 0x1c) << 10;
11393 inst.instruction |= (value & 0x03) << 6;
b99bd4ef 11394 }
c19d1205 11395}
b99bd4ef 11396
b99bd4ef 11397
c19d1205
ZW
11398/* inst.operands[i] was set up by parse_address. Encode it into a
11399 Thumb32 format load or store instruction. Reject forms that cannot
11400 be used with such instructions. If is_t is true, reject forms that
11401 cannot be used with a T instruction; if is_d is true, reject forms
5be8be5d
DG
11402 that cannot be used with a D instruction. If it is a store insn,
11403 reject PC in Rn. */
b99bd4ef 11404
c19d1205 11405static void
5b7c81bd 11406encode_thumb32_addr_mode (int i, bool is_t, bool is_d)
c19d1205 11407{
5b7c81bd 11408 const bool is_pc = (inst.operands[i].reg == REG_PC);
c19d1205
ZW
11409
11410 constraint (!inst.operands[i].isreg,
53365c0d 11411 _("Instruction does not support =N addresses"));
b99bd4ef 11412
c19d1205
ZW
11413 inst.instruction |= inst.operands[i].reg << 16;
11414 if (inst.operands[i].immisreg)
b99bd4ef 11415 {
5be8be5d 11416 constraint (is_pc, BAD_PC_ADDRESSING);
c19d1205
ZW
11417 constraint (is_t || is_d, _("cannot use register index with this instruction"));
11418 constraint (inst.operands[i].negative,
11419 _("Thumb does not support negative register indexing"));
11420 constraint (inst.operands[i].postind,
11421 _("Thumb does not support register post-indexing"));
11422 constraint (inst.operands[i].writeback,
11423 _("Thumb does not support register indexing with writeback"));
11424 constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
11425 _("Thumb supports only LSL in shifted register indexing"));
b99bd4ef 11426
f40d1643 11427 inst.instruction |= inst.operands[i].imm;
c19d1205 11428 if (inst.operands[i].shifted)
b99bd4ef 11429 {
e2b0ab59 11430 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 11431 _("expression too complex"));
e2b0ab59
AV
11432 constraint (inst.relocs[0].exp.X_add_number < 0
11433 || inst.relocs[0].exp.X_add_number > 3,
c19d1205 11434 _("shift out of range"));
e2b0ab59 11435 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
c19d1205 11436 }
e2b0ab59 11437 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
11438 }
11439 else if (inst.operands[i].preind)
11440 {
5be8be5d 11441 constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
f40d1643 11442 constraint (is_t && inst.operands[i].writeback,
c19d1205 11443 _("cannot use writeback with this instruction"));
4755303e
WN
11444 constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0),
11445 BAD_PC_ADDRESSING);
c19d1205
ZW
11446
11447 if (is_d)
11448 {
11449 inst.instruction |= 0x01000000;
11450 if (inst.operands[i].writeback)
11451 inst.instruction |= 0x00200000;
b99bd4ef 11452 }
c19d1205 11453 else
b99bd4ef 11454 {
c19d1205
ZW
11455 inst.instruction |= 0x00000c00;
11456 if (inst.operands[i].writeback)
11457 inst.instruction |= 0x00000100;
b99bd4ef 11458 }
e2b0ab59 11459 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
b99bd4ef 11460 }
c19d1205 11461 else if (inst.operands[i].postind)
b99bd4ef 11462 {
9c2799c2 11463 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
11464 constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
11465 constraint (is_t, _("cannot use post-indexing with this instruction"));
11466
11467 if (is_d)
11468 inst.instruction |= 0x00200000;
11469 else
11470 inst.instruction |= 0x00000900;
e2b0ab59 11471 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
c19d1205
ZW
11472 }
11473 else /* unindexed - only for coprocessor */
11474 inst.error = _("instruction does not accept unindexed addressing");
11475}
11476
e39c1607 11477/* Table of Thumb instructions which exist in 16- and/or 32-bit
c19d1205
ZW
11478 encodings (the latter only in post-V6T2 cores). The index is the
11479 value used in the insns table below. When there is more than one
11480 possible 16-bit encoding for the instruction, this table always
0110f2b8
PB
11481 holds variant (1).
11482 Also contains several pseudo-instructions used during relaxation. */
c19d1205 11483#define T16_32_TAB \
21d799b5
NC
11484 X(_adc, 4140, eb400000), \
11485 X(_adcs, 4140, eb500000), \
11486 X(_add, 1c00, eb000000), \
11487 X(_adds, 1c00, eb100000), \
11488 X(_addi, 0000, f1000000), \
11489 X(_addis, 0000, f1100000), \
11490 X(_add_pc,000f, f20f0000), \
11491 X(_add_sp,000d, f10d0000), \
11492 X(_adr, 000f, f20f0000), \
11493 X(_and, 4000, ea000000), \
11494 X(_ands, 4000, ea100000), \
11495 X(_asr, 1000, fa40f000), \
11496 X(_asrs, 1000, fa50f000), \
e43ca2cb 11497 X(_aut, 0000, f3af802d), \
be05908c 11498 X(_autg, 0000, fb500f00), \
21d799b5
NC
11499 X(_b, e000, f000b000), \
11500 X(_bcond, d000, f0008000), \
4389b29a 11501 X(_bf, 0000, f040e001), \
f6b2b12d 11502 X(_bfcsel,0000, f000e001), \
f1c7f421 11503 X(_bfx, 0000, f060e001), \
65d1bc05 11504 X(_bfl, 0000, f000c001), \
f1c7f421 11505 X(_bflx, 0000, f070e001), \
21d799b5
NC
11506 X(_bic, 4380, ea200000), \
11507 X(_bics, 4380, ea300000), \
e07352fa 11508 X(_bxaut, 0000, fb500f10), \
e39c1607
SD
11509 X(_cinc, 0000, ea509000), \
11510 X(_cinv, 0000, ea50a000), \
21d799b5
NC
11511 X(_cmn, 42c0, eb100f00), \
11512 X(_cmp, 2800, ebb00f00), \
e39c1607 11513 X(_cneg, 0000, ea50b000), \
21d799b5
NC
11514 X(_cpsie, b660, f3af8400), \
11515 X(_cpsid, b670, f3af8600), \
11516 X(_cpy, 4600, ea4f0000), \
e39c1607
SD
11517 X(_csel, 0000, ea508000), \
11518 X(_cset, 0000, ea5f900f), \
11519 X(_csetm, 0000, ea5fa00f), \
11520 X(_csinc, 0000, ea509000), \
11521 X(_csinv, 0000, ea50a000), \
11522 X(_csneg, 0000, ea50b000), \
21d799b5 11523 X(_dec_sp,80dd, f1ad0d00), \
60f993ce 11524 X(_dls, 0000, f040e001), \
1f6234a3 11525 X(_dlstp, 0000, f000e001), \
21d799b5
NC
11526 X(_eor, 4040, ea800000), \
11527 X(_eors, 4040, ea900000), \
11528 X(_inc_sp,00dd, f10d0d00), \
1f6234a3 11529 X(_lctp, 0000, f00fe001), \
21d799b5
NC
11530 X(_ldmia, c800, e8900000), \
11531 X(_ldr, 6800, f8500000), \
11532 X(_ldrb, 7800, f8100000), \
11533 X(_ldrh, 8800, f8300000), \
11534 X(_ldrsb, 5600, f9100000), \
11535 X(_ldrsh, 5e00, f9300000), \
11536 X(_ldr_pc,4800, f85f0000), \
11537 X(_ldr_pc2,4800, f85f0000), \
11538 X(_ldr_sp,9800, f85d0000), \
60f993ce 11539 X(_le, 0000, f00fc001), \
1f6234a3 11540 X(_letp, 0000, f01fc001), \
21d799b5
NC
11541 X(_lsl, 0000, fa00f000), \
11542 X(_lsls, 0000, fa10f000), \
11543 X(_lsr, 0800, fa20f000), \
11544 X(_lsrs, 0800, fa30f000), \
11545 X(_mov, 2000, ea4f0000), \
11546 X(_movs, 2000, ea5f0000), \
11547 X(_mul, 4340, fb00f000), \
11548 X(_muls, 4340, ffffffff), /* no 32b muls */ \
11549 X(_mvn, 43c0, ea6f0000), \
11550 X(_mvns, 43c0, ea7f0000), \
11551 X(_neg, 4240, f1c00000), /* rsb #0 */ \
11552 X(_negs, 4240, f1d00000), /* rsbs #0 */ \
11553 X(_orr, 4300, ea400000), \
11554 X(_orrs, 4300, ea500000), \
ce537a7d 11555 X(_pac, 0000, f3af801d), \
f1e1d7f3 11556 X(_pacbti, 0000, f3af800d), \
5c43020d 11557 X(_pacg, 0000, fb60f000), \
21d799b5
NC
11558 X(_pop, bc00, e8bd0000), /* ldmia sp!,... */ \
11559 X(_push, b400, e92d0000), /* stmdb sp!,... */ \
11560 X(_rev, ba00, fa90f080), \
11561 X(_rev16, ba40, fa90f090), \
11562 X(_revsh, bac0, fa90f0b0), \
11563 X(_ror, 41c0, fa60f000), \
11564 X(_rors, 41c0, fa70f000), \
11565 X(_sbc, 4180, eb600000), \
11566 X(_sbcs, 4180, eb700000), \
11567 X(_stmia, c000, e8800000), \
11568 X(_str, 6000, f8400000), \
11569 X(_strb, 7000, f8000000), \
11570 X(_strh, 8000, f8200000), \
11571 X(_str_sp,9000, f84d0000), \
11572 X(_sub, 1e00, eba00000), \
11573 X(_subs, 1e00, ebb00000), \
11574 X(_subi, 8000, f1a00000), \
11575 X(_subis, 8000, f1b00000), \
11576 X(_sxtb, b240, fa4ff080), \
11577 X(_sxth, b200, fa0ff080), \
11578 X(_tst, 4200, ea100f00), \
11579 X(_uxtb, b2c0, fa5ff080), \
11580 X(_uxth, b280, fa1ff080), \
11581 X(_nop, bf00, f3af8000), \
11582 X(_yield, bf10, f3af8001), \
11583 X(_wfe, bf20, f3af8002), \
11584 X(_wfi, bf30, f3af8003), \
60f993ce 11585 X(_wls, 0000, f040c001), \
1f6234a3 11586 X(_wlstp, 0000, f000c001), \
53c4b28b 11587 X(_sev, bf40, f3af8004), \
74db7efb
NC
11588 X(_sevl, bf50, f3af8005), \
11589 X(_udf, de00, f7f0a000)
c19d1205
ZW
11590
11591/* To catch errors in encoding functions, the codes are all offset by
11592 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
11593 as 16-bit instructions. */
21d799b5 11594#define X(a,b,c) T_MNEM##a
c19d1205
ZW
11595enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
11596#undef X
11597
11598#define X(a,b,c) 0x##b
11599static const unsigned short thumb_op16[] = { T16_32_TAB };
11600#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
11601#undef X
11602
11603#define X(a,b,c) 0x##c
11604static const unsigned int thumb_op32[] = { T16_32_TAB };
c921be7d
NC
11605#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
11606#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
c19d1205
ZW
11607#undef X
11608#undef T16_32_TAB
11609
11610/* Thumb instruction encoders, in alphabetical order. */
11611
92e90b6e 11612/* ADDW or SUBW. */
c921be7d 11613
92e90b6e
PB
11614static void
11615do_t_add_sub_w (void)
11616{
11617 int Rd, Rn;
11618
11619 Rd = inst.operands[0].reg;
11620 Rn = inst.operands[1].reg;
11621
539d4391
NC
11622 /* If Rn is REG_PC, this is ADR; if Rn is REG_SP, then this
11623 is the SP-{plus,minus}-immediate form of the instruction. */
11624 if (Rn == REG_SP)
11625 constraint (Rd == REG_PC, BAD_PC);
11626 else
11627 reject_bad_reg (Rd);
fdfde340 11628
92e90b6e 11629 inst.instruction |= (Rn << 16) | (Rd << 8);
e2b0ab59 11630 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
92e90b6e
PB
11631}
11632
c19d1205 11633/* Parse an add or subtract instruction. We get here with inst.instruction
33eaf5de 11634 equaling any of THUMB_OPCODE_add, adds, sub, or subs. */
c19d1205
ZW
11635
11636static void
11637do_t_add_sub (void)
11638{
11639 int Rd, Rs, Rn;
11640
11641 Rd = inst.operands[0].reg;
11642 Rs = (inst.operands[1].present
11643 ? inst.operands[1].reg /* Rd, Rs, foo */
11644 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11645
e07e6e58 11646 if (Rd == REG_PC)
5ee91343 11647 set_pred_insn_type_last ();
e07e6e58 11648
c19d1205
ZW
11649 if (unified_syntax)
11650 {
5b7c81bd
AM
11651 bool flags;
11652 bool narrow;
0110f2b8
PB
11653 int opcode;
11654
11655 flags = (inst.instruction == T_MNEM_adds
11656 || inst.instruction == T_MNEM_subs);
11657 if (flags)
5ee91343 11658 narrow = !in_pred_block ();
0110f2b8 11659 else
5ee91343 11660 narrow = in_pred_block ();
c19d1205 11661 if (!inst.operands[2].isreg)
b99bd4ef 11662 {
16805f35
PB
11663 int add;
11664
5c8ed6a4
JW
11665 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11666 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340 11667
16805f35
PB
11668 add = (inst.instruction == T_MNEM_add
11669 || inst.instruction == T_MNEM_adds);
0110f2b8
PB
11670 opcode = 0;
11671 if (inst.size_req != 4)
11672 {
0110f2b8 11673 /* Attempt to use a narrow opcode, with relaxation if
477330fc 11674 appropriate. */
0110f2b8
PB
11675 if (Rd == REG_SP && Rs == REG_SP && !flags)
11676 opcode = add ? T_MNEM_inc_sp : T_MNEM_dec_sp;
11677 else if (Rd <= 7 && Rs == REG_SP && add && !flags)
11678 opcode = T_MNEM_add_sp;
11679 else if (Rd <= 7 && Rs == REG_PC && add && !flags)
11680 opcode = T_MNEM_add_pc;
11681 else if (Rd <= 7 && Rs <= 7 && narrow)
11682 {
11683 if (flags)
11684 opcode = add ? T_MNEM_addis : T_MNEM_subis;
11685 else
11686 opcode = add ? T_MNEM_addi : T_MNEM_subi;
11687 }
11688 if (opcode)
11689 {
11690 inst.instruction = THUMB_OP16(opcode);
11691 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59
AV
11692 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
11693 || (inst.relocs[0].type
11694 > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
a9f02af8
MG
11695 {
11696 if (inst.size_req == 2)
e2b0ab59 11697 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
a9f02af8
MG
11698 else
11699 inst.relax = opcode;
11700 }
0110f2b8
PB
11701 }
11702 else
fe0171d2 11703 constraint (inst.size_req == 2, _("cannot honor width suffix"));
0110f2b8
PB
11704 }
11705 if (inst.size_req == 4
11706 || (inst.size_req != 2 && !opcode))
11707 {
e2b0ab59
AV
11708 constraint ((inst.relocs[0].type
11709 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
11710 && (inst.relocs[0].type
11711 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8 11712 THUMB1_RELOC_ONLY);
efd81785
PB
11713 if (Rd == REG_PC)
11714 {
fdfde340 11715 constraint (add, BAD_PC);
efd81785
PB
11716 constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
11717 _("only SUBS PC, LR, #const allowed"));
e2b0ab59 11718 constraint (inst.relocs[0].exp.X_op != O_constant,
efd81785 11719 _("expression too complex"));
e2b0ab59
AV
11720 constraint (inst.relocs[0].exp.X_add_number < 0
11721 || inst.relocs[0].exp.X_add_number > 0xff,
efd81785
PB
11722 _("immediate value out of range"));
11723 inst.instruction = T2_SUBS_PC_LR
e2b0ab59
AV
11724 | inst.relocs[0].exp.X_add_number;
11725 inst.relocs[0].type = BFD_RELOC_UNUSED;
efd81785
PB
11726 return;
11727 }
11728 else if (Rs == REG_PC)
16805f35
PB
11729 {
11730 /* Always use addw/subw. */
11731 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
e2b0ab59 11732 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
16805f35
PB
11733 }
11734 else
11735 {
11736 inst.instruction = THUMB_OP32 (inst.instruction);
11737 inst.instruction = (inst.instruction & 0xe1ffffff)
11738 | 0x10000000;
11739 if (flags)
e2b0ab59 11740 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
16805f35 11741 else
e2b0ab59 11742 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
16805f35 11743 }
dc4503c6
PB
11744 inst.instruction |= Rd << 8;
11745 inst.instruction |= Rs << 16;
0110f2b8 11746 }
b99bd4ef 11747 }
c19d1205
ZW
11748 else
11749 {
e2b0ab59 11750 unsigned int value = inst.relocs[0].exp.X_add_number;
5f4cb198
NC
11751 unsigned int shift = inst.operands[2].shift_kind;
11752
c19d1205
ZW
11753 Rn = inst.operands[2].reg;
11754 /* See if we can do this with a 16-bit instruction. */
11755 if (!inst.operands[2].shifted && inst.size_req != 4)
11756 {
e27ec89e 11757 if (Rd > 7 || Rs > 7 || Rn > 7)
5b7c81bd 11758 narrow = false;
e27ec89e
PB
11759
11760 if (narrow)
c19d1205 11761 {
e27ec89e
PB
11762 inst.instruction = ((inst.instruction == T_MNEM_adds
11763 || inst.instruction == T_MNEM_add)
c19d1205
ZW
11764 ? T_OPCODE_ADD_R3
11765 : T_OPCODE_SUB_R3);
11766 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
11767 return;
11768 }
b99bd4ef 11769
7e806470 11770 if (inst.instruction == T_MNEM_add && (Rd == Rs || Rd == Rn))
c19d1205 11771 {
7e806470
PB
11772 /* Thumb-1 cores (except v6-M) require at least one high
11773 register in a narrow non flag setting add. */
11774 if (Rd > 7 || Rn > 7
11775 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2)
11776 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_msr))
c19d1205 11777 {
7e806470
PB
11778 if (Rd == Rn)
11779 {
11780 Rn = Rs;
11781 Rs = Rd;
11782 }
c19d1205
ZW
11783 inst.instruction = T_OPCODE_ADD_HI;
11784 inst.instruction |= (Rd & 8) << 4;
11785 inst.instruction |= (Rd & 7);
11786 inst.instruction |= Rn << 3;
11787 return;
11788 }
c19d1205
ZW
11789 }
11790 }
c921be7d 11791
fdfde340 11792 constraint (Rd == REG_PC, BAD_PC);
5c8ed6a4
JW
11793 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11794 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340
JM
11795 constraint (Rs == REG_PC, BAD_PC);
11796 reject_bad_reg (Rn);
11797
c19d1205
ZW
11798 /* If we get here, it can't be done in 16 bits. */
11799 constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
11800 _("shift must be constant"));
11801 inst.instruction = THUMB_OP32 (inst.instruction);
11802 inst.instruction |= Rd << 8;
11803 inst.instruction |= Rs << 16;
5f4cb198
NC
11804 constraint (Rd == REG_SP && Rs == REG_SP && value > 3,
11805 _("shift value over 3 not allowed in thumb mode"));
11806 constraint (Rd == REG_SP && Rs == REG_SP && shift != SHIFT_LSL,
11807 _("only LSL shift allowed in thumb mode"));
c19d1205
ZW
11808 encode_thumb32_shifted_operand (2);
11809 }
11810 }
11811 else
11812 {
11813 constraint (inst.instruction == T_MNEM_adds
11814 || inst.instruction == T_MNEM_subs,
11815 BAD_THUMB32);
b99bd4ef 11816
c19d1205 11817 if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
b99bd4ef 11818 {
c19d1205
ZW
11819 constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
11820 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
11821 BAD_HIREG);
11822
11823 inst.instruction = (inst.instruction == T_MNEM_add
11824 ? 0x0000 : 0x8000);
11825 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59 11826 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
b99bd4ef
NC
11827 return;
11828 }
11829
c19d1205
ZW
11830 Rn = inst.operands[2].reg;
11831 constraint (inst.operands[2].shifted, _("unshifted register required"));
b99bd4ef 11832
c19d1205
ZW
11833 /* We now have Rd, Rs, and Rn set to registers. */
11834 if (Rd > 7 || Rs > 7 || Rn > 7)
b99bd4ef 11835 {
c19d1205
ZW
11836 /* Can't do this for SUB. */
11837 constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
11838 inst.instruction = T_OPCODE_ADD_HI;
11839 inst.instruction |= (Rd & 8) << 4;
11840 inst.instruction |= (Rd & 7);
11841 if (Rs == Rd)
11842 inst.instruction |= Rn << 3;
11843 else if (Rn == Rd)
11844 inst.instruction |= Rs << 3;
11845 else
11846 constraint (1, _("dest must overlap one source register"));
11847 }
11848 else
11849 {
11850 inst.instruction = (inst.instruction == T_MNEM_add
11851 ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
11852 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
b99bd4ef 11853 }
b99bd4ef 11854 }
b99bd4ef
NC
11855}
11856
c19d1205
ZW
11857static void
11858do_t_adr (void)
11859{
fdfde340
JM
11860 unsigned Rd;
11861
11862 Rd = inst.operands[0].reg;
11863 reject_bad_reg (Rd);
11864
11865 if (unified_syntax && inst.size_req == 0 && Rd <= 7)
0110f2b8
PB
11866 {
11867 /* Defer to section relaxation. */
11868 inst.relax = inst.instruction;
11869 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 11870 inst.instruction |= Rd << 4;
0110f2b8
PB
11871 }
11872 else if (unified_syntax && inst.size_req != 2)
e9f89963 11873 {
0110f2b8 11874 /* Generate a 32-bit opcode. */
e9f89963 11875 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 11876 inst.instruction |= Rd << 8;
e2b0ab59
AV
11877 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
11878 inst.relocs[0].pc_rel = 1;
e9f89963
PB
11879 }
11880 else
11881 {
0110f2b8 11882 /* Generate a 16-bit opcode. */
e9f89963 11883 inst.instruction = THUMB_OP16 (inst.instruction);
e2b0ab59
AV
11884 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
11885 inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust. */
11886 inst.relocs[0].pc_rel = 1;
fdfde340 11887 inst.instruction |= Rd << 4;
e9f89963 11888 }
52a86f84 11889
e2b0ab59
AV
11890 if (inst.relocs[0].exp.X_op == O_symbol
11891 && inst.relocs[0].exp.X_add_symbol != NULL
11892 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11893 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11894 inst.relocs[0].exp.X_add_number += 1;
c19d1205 11895}
b99bd4ef 11896
c19d1205
ZW
11897/* Arithmetic instructions for which there is just one 16-bit
11898 instruction encoding, and it allows only two low registers.
11899 For maximal compatibility with ARM syntax, we allow three register
11900 operands even when Thumb-32 instructions are not available, as long
11901 as the first two are identical. For instance, both "sbc r0,r1" and
11902 "sbc r0,r0,r1" are allowed. */
b99bd4ef 11903static void
c19d1205 11904do_t_arit3 (void)
b99bd4ef 11905{
c19d1205 11906 int Rd, Rs, Rn;
b99bd4ef 11907
c19d1205
ZW
11908 Rd = inst.operands[0].reg;
11909 Rs = (inst.operands[1].present
11910 ? inst.operands[1].reg /* Rd, Rs, foo */
11911 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11912 Rn = inst.operands[2].reg;
b99bd4ef 11913
fdfde340
JM
11914 reject_bad_reg (Rd);
11915 reject_bad_reg (Rs);
11916 if (inst.operands[2].isreg)
11917 reject_bad_reg (Rn);
11918
c19d1205 11919 if (unified_syntax)
b99bd4ef 11920 {
c19d1205
ZW
11921 if (!inst.operands[2].isreg)
11922 {
11923 /* For an immediate, we always generate a 32-bit opcode;
11924 section relaxation will shrink it later if possible. */
11925 inst.instruction = THUMB_OP32 (inst.instruction);
11926 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11927 inst.instruction |= Rd << 8;
11928 inst.instruction |= Rs << 16;
e2b0ab59 11929 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
c19d1205
ZW
11930 }
11931 else
11932 {
5b7c81bd 11933 bool narrow;
e27ec89e 11934
c19d1205 11935 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11936 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 11937 narrow = !in_pred_block ();
e27ec89e 11938 else
5ee91343 11939 narrow = in_pred_block ();
e27ec89e
PB
11940
11941 if (Rd > 7 || Rn > 7 || Rs > 7)
5b7c81bd 11942 narrow = false;
e27ec89e 11943 if (inst.operands[2].shifted)
5b7c81bd 11944 narrow = false;
e27ec89e 11945 if (inst.size_req == 4)
5b7c81bd 11946 narrow = false;
e27ec89e
PB
11947
11948 if (narrow
c19d1205
ZW
11949 && Rd == Rs)
11950 {
11951 inst.instruction = THUMB_OP16 (inst.instruction);
11952 inst.instruction |= Rd;
11953 inst.instruction |= Rn << 3;
11954 return;
11955 }
b99bd4ef 11956
c19d1205
ZW
11957 /* If we get here, it can't be done in 16 bits. */
11958 constraint (inst.operands[2].shifted
11959 && inst.operands[2].immisreg,
11960 _("shift must be constant"));
11961 inst.instruction = THUMB_OP32 (inst.instruction);
11962 inst.instruction |= Rd << 8;
11963 inst.instruction |= Rs << 16;
11964 encode_thumb32_shifted_operand (2);
11965 }
a737bd4d 11966 }
c19d1205 11967 else
b99bd4ef 11968 {
c19d1205
ZW
11969 /* On its face this is a lie - the instruction does set the
11970 flags. However, the only supported mnemonic in this mode
11971 says it doesn't. */
11972 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11973
c19d1205
ZW
11974 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11975 _("unshifted register required"));
11976 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11977 constraint (Rd != Rs,
11978 _("dest and source1 must be the same register"));
a737bd4d 11979
c19d1205
ZW
11980 inst.instruction = THUMB_OP16 (inst.instruction);
11981 inst.instruction |= Rd;
11982 inst.instruction |= Rn << 3;
b99bd4ef 11983 }
a737bd4d 11984}
b99bd4ef 11985
c19d1205
ZW
11986/* Similarly, but for instructions where the arithmetic operation is
11987 commutative, so we can allow either of them to be different from
11988 the destination operand in a 16-bit instruction. For instance, all
11989 three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
11990 accepted. */
11991static void
11992do_t_arit3c (void)
a737bd4d 11993{
c19d1205 11994 int Rd, Rs, Rn;
b99bd4ef 11995
c19d1205
ZW
11996 Rd = inst.operands[0].reg;
11997 Rs = (inst.operands[1].present
11998 ? inst.operands[1].reg /* Rd, Rs, foo */
11999 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
12000 Rn = inst.operands[2].reg;
c921be7d 12001
fdfde340
JM
12002 reject_bad_reg (Rd);
12003 reject_bad_reg (Rs);
12004 if (inst.operands[2].isreg)
12005 reject_bad_reg (Rn);
a737bd4d 12006
c19d1205 12007 if (unified_syntax)
a737bd4d 12008 {
c19d1205 12009 if (!inst.operands[2].isreg)
b99bd4ef 12010 {
c19d1205
ZW
12011 /* For an immediate, we always generate a 32-bit opcode;
12012 section relaxation will shrink it later if possible. */
12013 inst.instruction = THUMB_OP32 (inst.instruction);
12014 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
12015 inst.instruction |= Rd << 8;
12016 inst.instruction |= Rs << 16;
e2b0ab59 12017 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 12018 }
c19d1205 12019 else
a737bd4d 12020 {
5b7c81bd 12021 bool narrow;
e27ec89e 12022
c19d1205 12023 /* See if we can do this with a 16-bit instruction. */
e27ec89e 12024 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 12025 narrow = !in_pred_block ();
e27ec89e 12026 else
5ee91343 12027 narrow = in_pred_block ();
e27ec89e
PB
12028
12029 if (Rd > 7 || Rn > 7 || Rs > 7)
5b7c81bd 12030 narrow = false;
e27ec89e 12031 if (inst.operands[2].shifted)
5b7c81bd 12032 narrow = false;
e27ec89e 12033 if (inst.size_req == 4)
5b7c81bd 12034 narrow = false;
e27ec89e
PB
12035
12036 if (narrow)
a737bd4d 12037 {
c19d1205 12038 if (Rd == Rs)
a737bd4d 12039 {
c19d1205
ZW
12040 inst.instruction = THUMB_OP16 (inst.instruction);
12041 inst.instruction |= Rd;
12042 inst.instruction |= Rn << 3;
12043 return;
a737bd4d 12044 }
c19d1205 12045 if (Rd == Rn)
a737bd4d 12046 {
c19d1205
ZW
12047 inst.instruction = THUMB_OP16 (inst.instruction);
12048 inst.instruction |= Rd;
12049 inst.instruction |= Rs << 3;
12050 return;
a737bd4d
NC
12051 }
12052 }
c19d1205
ZW
12053
12054 /* If we get here, it can't be done in 16 bits. */
12055 constraint (inst.operands[2].shifted
12056 && inst.operands[2].immisreg,
12057 _("shift must be constant"));
12058 inst.instruction = THUMB_OP32 (inst.instruction);
12059 inst.instruction |= Rd << 8;
12060 inst.instruction |= Rs << 16;
12061 encode_thumb32_shifted_operand (2);
a737bd4d 12062 }
b99bd4ef 12063 }
c19d1205
ZW
12064 else
12065 {
12066 /* On its face this is a lie - the instruction does set the
12067 flags. However, the only supported mnemonic in this mode
12068 says it doesn't. */
12069 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 12070
c19d1205
ZW
12071 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
12072 _("unshifted register required"));
12073 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
12074
12075 inst.instruction = THUMB_OP16 (inst.instruction);
12076 inst.instruction |= Rd;
12077
12078 if (Rd == Rs)
12079 inst.instruction |= Rn << 3;
12080 else if (Rd == Rn)
12081 inst.instruction |= Rs << 3;
12082 else
12083 constraint (1, _("dest must overlap one source register"));
12084 }
a737bd4d
NC
12085}
12086
c19d1205
ZW
12087static void
12088do_t_bfc (void)
a737bd4d 12089{
fdfde340 12090 unsigned Rd;
c19d1205
ZW
12091 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
12092 constraint (msb > 32, _("bit-field extends past end of register"));
12093 /* The instruction encoding stores the LSB and MSB,
12094 not the LSB and width. */
fdfde340
JM
12095 Rd = inst.operands[0].reg;
12096 reject_bad_reg (Rd);
12097 inst.instruction |= Rd << 8;
c19d1205
ZW
12098 inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
12099 inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
12100 inst.instruction |= msb - 1;
b99bd4ef
NC
12101}
12102
c19d1205
ZW
12103static void
12104do_t_bfi (void)
b99bd4ef 12105{
fdfde340 12106 int Rd, Rn;
c19d1205 12107 unsigned int msb;
b99bd4ef 12108
fdfde340
JM
12109 Rd = inst.operands[0].reg;
12110 reject_bad_reg (Rd);
12111
c19d1205
ZW
12112 /* #0 in second position is alternative syntax for bfc, which is
12113 the same instruction but with REG_PC in the Rm field. */
12114 if (!inst.operands[1].isreg)
fdfde340
JM
12115 Rn = REG_PC;
12116 else
12117 {
12118 Rn = inst.operands[1].reg;
12119 reject_bad_reg (Rn);
12120 }
b99bd4ef 12121
c19d1205
ZW
12122 msb = inst.operands[2].imm + inst.operands[3].imm;
12123 constraint (msb > 32, _("bit-field extends past end of register"));
12124 /* The instruction encoding stores the LSB and MSB,
12125 not the LSB and width. */
fdfde340
JM
12126 inst.instruction |= Rd << 8;
12127 inst.instruction |= Rn << 16;
c19d1205
ZW
12128 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
12129 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
12130 inst.instruction |= msb - 1;
b99bd4ef
NC
12131}
12132
c19d1205
ZW
12133static void
12134do_t_bfx (void)
b99bd4ef 12135{
fdfde340
JM
12136 unsigned Rd, Rn;
12137
12138 Rd = inst.operands[0].reg;
12139 Rn = inst.operands[1].reg;
12140
12141 reject_bad_reg (Rd);
12142 reject_bad_reg (Rn);
12143
c19d1205
ZW
12144 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
12145 _("bit-field extends past end of register"));
fdfde340
JM
12146 inst.instruction |= Rd << 8;
12147 inst.instruction |= Rn << 16;
c19d1205
ZW
12148 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
12149 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
12150 inst.instruction |= inst.operands[3].imm - 1;
12151}
b99bd4ef 12152
c19d1205
ZW
12153/* ARM V5 Thumb BLX (argument parse)
12154 BLX <target_addr> which is BLX(1)
12155 BLX <Rm> which is BLX(2)
12156 Unfortunately, there are two different opcodes for this mnemonic.
12157 So, the insns[].value is not used, and the code here zaps values
12158 into inst.instruction.
b99bd4ef 12159
c19d1205
ZW
12160 ??? How to take advantage of the additional two bits of displacement
12161 available in Thumb32 mode? Need new relocation? */
b99bd4ef 12162
c19d1205
ZW
12163static void
12164do_t_blx (void)
12165{
5ee91343 12166 set_pred_insn_type_last ();
e07e6e58 12167
c19d1205 12168 if (inst.operands[0].isreg)
fdfde340
JM
12169 {
12170 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
12171 /* We have a register, so this is BLX(2). */
12172 inst.instruction |= inst.operands[0].reg << 3;
12173 }
b99bd4ef
NC
12174 else
12175 {
c19d1205 12176 /* No register. This must be BLX(1). */
2fc8bdac 12177 inst.instruction = 0xf000e800;
0855e32b 12178 encode_branch (BFD_RELOC_THUMB_PCREL_BLX);
b99bd4ef
NC
12179 }
12180}
12181
c19d1205
ZW
12182static void
12183do_t_branch (void)
b99bd4ef 12184{
0110f2b8 12185 int opcode;
dfa9f0d5 12186 int cond;
2fe88214 12187 bfd_reloc_code_real_type reloc;
dfa9f0d5 12188
e07e6e58 12189 cond = inst.cond;
5ee91343 12190 set_pred_insn_type (IF_INSIDE_IT_LAST_INSN);
e07e6e58 12191
5ee91343 12192 if (in_pred_block ())
dfa9f0d5
PB
12193 {
12194 /* Conditional branches inside IT blocks are encoded as unconditional
477330fc 12195 branches. */
dfa9f0d5 12196 cond = COND_ALWAYS;
dfa9f0d5
PB
12197 }
12198 else
12199 cond = inst.cond;
12200
12201 if (cond != COND_ALWAYS)
0110f2b8
PB
12202 opcode = T_MNEM_bcond;
12203 else
12204 opcode = inst.instruction;
12205
12d6b0b7
RS
12206 if (unified_syntax
12207 && (inst.size_req == 4
10960bfb
PB
12208 || (inst.size_req != 2
12209 && (inst.operands[0].hasreloc
e2b0ab59 12210 || inst.relocs[0].exp.X_op == O_constant))))
c19d1205 12211 {
0110f2b8 12212 inst.instruction = THUMB_OP32(opcode);
dfa9f0d5 12213 if (cond == COND_ALWAYS)
9ae92b05 12214 reloc = BFD_RELOC_THUMB_PCREL_BRANCH25;
c19d1205
ZW
12215 else
12216 {
ff8646ee
TP
12217 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2),
12218 _("selected architecture does not support "
12219 "wide conditional branch instruction"));
12220
9c2799c2 12221 gas_assert (cond != 0xF);
dfa9f0d5 12222 inst.instruction |= cond << 22;
9ae92b05 12223 reloc = BFD_RELOC_THUMB_PCREL_BRANCH20;
c19d1205
ZW
12224 }
12225 }
b99bd4ef
NC
12226 else
12227 {
0110f2b8 12228 inst.instruction = THUMB_OP16(opcode);
dfa9f0d5 12229 if (cond == COND_ALWAYS)
9ae92b05 12230 reloc = BFD_RELOC_THUMB_PCREL_BRANCH12;
c19d1205 12231 else
b99bd4ef 12232 {
dfa9f0d5 12233 inst.instruction |= cond << 8;
9ae92b05 12234 reloc = BFD_RELOC_THUMB_PCREL_BRANCH9;
b99bd4ef 12235 }
0110f2b8
PB
12236 /* Allow section relaxation. */
12237 if (unified_syntax && inst.size_req != 2)
12238 inst.relax = opcode;
b99bd4ef 12239 }
e2b0ab59
AV
12240 inst.relocs[0].type = reloc;
12241 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
12242}
12243
8884b720 12244/* Actually do the work for Thumb state bkpt and hlt. The only difference
bacebabc 12245 between the two is the maximum immediate allowed - which is passed in
8884b720 12246 RANGE. */
b99bd4ef 12247static void
8884b720 12248do_t_bkpt_hlt1 (int range)
b99bd4ef 12249{
dfa9f0d5
PB
12250 constraint (inst.cond != COND_ALWAYS,
12251 _("instruction is always unconditional"));
c19d1205 12252 if (inst.operands[0].present)
b99bd4ef 12253 {
8884b720 12254 constraint (inst.operands[0].imm > range,
c19d1205
ZW
12255 _("immediate value out of range"));
12256 inst.instruction |= inst.operands[0].imm;
b99bd4ef 12257 }
8884b720 12258
5ee91343 12259 set_pred_insn_type (NEUTRAL_IT_INSN);
8884b720
MGD
12260}
12261
12262static void
12263do_t_hlt (void)
12264{
12265 do_t_bkpt_hlt1 (63);
12266}
12267
12268static void
12269do_t_bkpt (void)
12270{
12271 do_t_bkpt_hlt1 (255);
b99bd4ef
NC
12272}
12273
12274static void
c19d1205 12275do_t_branch23 (void)
b99bd4ef 12276{
5ee91343 12277 set_pred_insn_type_last ();
0855e32b 12278 encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
fa94de6b 12279
0855e32b
NS
12280 /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
12281 this file. We used to simply ignore the PLT reloc type here --
12282 the branch encoding is now needed to deal with TLSCALL relocs.
12283 So if we see a PLT reloc now, put it back to how it used to be to
12284 keep the preexisting behaviour. */
e2b0ab59
AV
12285 if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
12286 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
90e4755a 12287
4343666d 12288#if defined(OBJ_COFF)
c19d1205
ZW
12289 /* If the destination of the branch is a defined symbol which does not have
12290 the THUMB_FUNC attribute, then we must be calling a function which has
12291 the (interfacearm) attribute. We look for the Thumb entry point to that
12292 function and change the branch to refer to that function instead. */
e2b0ab59
AV
12293 if ( inst.relocs[0].exp.X_op == O_symbol
12294 && inst.relocs[0].exp.X_add_symbol != NULL
12295 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
12296 && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
12297 inst.relocs[0].exp.X_add_symbol
12298 = find_real_start (inst.relocs[0].exp.X_add_symbol);
4343666d 12299#endif
90e4755a
RE
12300}
12301
12302static void
c19d1205 12303do_t_bx (void)
90e4755a 12304{
5ee91343 12305 set_pred_insn_type_last ();
c19d1205
ZW
12306 inst.instruction |= inst.operands[0].reg << 3;
12307 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
12308 should cause the alignment to be checked once it is known. This is
12309 because BX PC only works if the instruction is word aligned. */
12310}
90e4755a 12311
c19d1205
ZW
12312static void
12313do_t_bxj (void)
12314{
fdfde340 12315 int Rm;
90e4755a 12316
5ee91343 12317 set_pred_insn_type_last ();
fdfde340
JM
12318 Rm = inst.operands[0].reg;
12319 reject_bad_reg (Rm);
12320 inst.instruction |= Rm << 16;
90e4755a
RE
12321}
12322
12323static void
c19d1205 12324do_t_clz (void)
90e4755a 12325{
fdfde340
JM
12326 unsigned Rd;
12327 unsigned Rm;
12328
12329 Rd = inst.operands[0].reg;
12330 Rm = inst.operands[1].reg;
12331
12332 reject_bad_reg (Rd);
12333 reject_bad_reg (Rm);
12334
12335 inst.instruction |= Rd << 8;
12336 inst.instruction |= Rm << 16;
12337 inst.instruction |= Rm;
c19d1205 12338}
90e4755a 12339
e39c1607
SD
12340/* For the Armv8.1-M conditional instructions. */
12341static void
12342do_t_cond (void)
12343{
12344 unsigned Rd, Rn, Rm;
12345 signed int cond;
12346
12347 constraint (inst.cond != COND_ALWAYS, BAD_COND);
12348
12349 Rd = inst.operands[0].reg;
12350 switch (inst.instruction)
12351 {
12352 case T_MNEM_csinc:
12353 case T_MNEM_csinv:
12354 case T_MNEM_csneg:
12355 case T_MNEM_csel:
12356 Rn = inst.operands[1].reg;
12357 Rm = inst.operands[2].reg;
12358 cond = inst.operands[3].imm;
12359 constraint (Rn == REG_SP, BAD_SP);
12360 constraint (Rm == REG_SP, BAD_SP);
12361 break;
12362
12363 case T_MNEM_cinc:
12364 case T_MNEM_cinv:
12365 case T_MNEM_cneg:
12366 Rn = inst.operands[1].reg;
12367 cond = inst.operands[2].imm;
12368 /* Invert the last bit to invert the cond. */
12369 cond = TOGGLE_BIT (cond, 0);
12370 constraint (Rn == REG_SP, BAD_SP);
12371 Rm = Rn;
12372 break;
12373
12374 case T_MNEM_csetm:
12375 case T_MNEM_cset:
12376 cond = inst.operands[1].imm;
12377 /* Invert the last bit to invert the cond. */
12378 cond = TOGGLE_BIT (cond, 0);
12379 Rn = REG_PC;
12380 Rm = REG_PC;
12381 break;
12382
12383 default: abort ();
12384 }
12385
12386 set_pred_insn_type (OUTSIDE_PRED_INSN);
12387 inst.instruction = THUMB_OP32 (inst.instruction);
12388 inst.instruction |= Rd << 8;
12389 inst.instruction |= Rn << 16;
12390 inst.instruction |= Rm;
12391 inst.instruction |= cond << 4;
12392}
12393
91d8b670
JG
12394static void
12395do_t_csdb (void)
12396{
5ee91343 12397 set_pred_insn_type (OUTSIDE_PRED_INSN);
91d8b670
JG
12398}
12399
dfa9f0d5
PB
12400static void
12401do_t_cps (void)
12402{
5ee91343 12403 set_pred_insn_type (OUTSIDE_PRED_INSN);
dfa9f0d5
PB
12404 inst.instruction |= inst.operands[0].imm;
12405}
12406
c19d1205
ZW
12407static void
12408do_t_cpsi (void)
12409{
5ee91343 12410 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205 12411 if (unified_syntax
62b3e311
PB
12412 && (inst.operands[1].present || inst.size_req == 4)
12413 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
90e4755a 12414 {
c19d1205
ZW
12415 unsigned int imod = (inst.instruction & 0x0030) >> 4;
12416 inst.instruction = 0xf3af8000;
12417 inst.instruction |= imod << 9;
12418 inst.instruction |= inst.operands[0].imm << 5;
12419 if (inst.operands[1].present)
12420 inst.instruction |= 0x100 | inst.operands[1].imm;
90e4755a 12421 }
c19d1205 12422 else
90e4755a 12423 {
62b3e311
PB
12424 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)
12425 && (inst.operands[0].imm & 4),
12426 _("selected processor does not support 'A' form "
12427 "of this instruction"));
12428 constraint (inst.operands[1].present || inst.size_req == 4,
c19d1205
ZW
12429 _("Thumb does not support the 2-argument "
12430 "form of this instruction"));
12431 inst.instruction |= inst.operands[0].imm;
90e4755a 12432 }
90e4755a
RE
12433}
12434
c19d1205
ZW
12435/* THUMB CPY instruction (argument parse). */
12436
90e4755a 12437static void
c19d1205 12438do_t_cpy (void)
90e4755a 12439{
c19d1205 12440 if (inst.size_req == 4)
90e4755a 12441 {
c19d1205
ZW
12442 inst.instruction = THUMB_OP32 (T_MNEM_mov);
12443 inst.instruction |= inst.operands[0].reg << 8;
12444 inst.instruction |= inst.operands[1].reg;
90e4755a 12445 }
c19d1205 12446 else
90e4755a 12447 {
c19d1205
ZW
12448 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
12449 inst.instruction |= (inst.operands[0].reg & 0x7);
12450 inst.instruction |= inst.operands[1].reg << 3;
90e4755a 12451 }
90e4755a
RE
12452}
12453
90e4755a 12454static void
25fe350b 12455do_t_cbz (void)
90e4755a 12456{
5ee91343 12457 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
12458 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12459 inst.instruction |= inst.operands[0].reg;
e2b0ab59
AV
12460 inst.relocs[0].pc_rel = 1;
12461 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
c19d1205 12462}
90e4755a 12463
62b3e311
PB
12464static void
12465do_t_dbg (void)
12466{
12467 inst.instruction |= inst.operands[0].imm;
12468}
12469
12470static void
12471do_t_div (void)
12472{
fdfde340
JM
12473 unsigned Rd, Rn, Rm;
12474
12475 Rd = inst.operands[0].reg;
12476 Rn = (inst.operands[1].present
12477 ? inst.operands[1].reg : Rd);
12478 Rm = inst.operands[2].reg;
12479
12480 reject_bad_reg (Rd);
12481 reject_bad_reg (Rn);
12482 reject_bad_reg (Rm);
12483
12484 inst.instruction |= Rd << 8;
12485 inst.instruction |= Rn << 16;
12486 inst.instruction |= Rm;
62b3e311
PB
12487}
12488
c19d1205
ZW
12489static void
12490do_t_hint (void)
12491{
12492 if (unified_syntax && inst.size_req == 4)
12493 inst.instruction = THUMB_OP32 (inst.instruction);
12494 else
12495 inst.instruction = THUMB_OP16 (inst.instruction);
12496}
90e4755a 12497
c19d1205
ZW
12498static void
12499do_t_it (void)
12500{
12501 unsigned int cond = inst.operands[0].imm;
e27ec89e 12502
5ee91343
AV
12503 set_pred_insn_type (IT_INSN);
12504 now_pred.mask = (inst.instruction & 0xf) | 0x10;
12505 now_pred.cc = cond;
5b7c81bd 12506 now_pred.warn_deprecated = false;
5ee91343 12507 now_pred.type = SCALAR_PRED;
e27ec89e
PB
12508
12509 /* If the condition is a negative condition, invert the mask. */
c19d1205 12510 if ((cond & 0x1) == 0x0)
90e4755a 12511 {
c19d1205 12512 unsigned int mask = inst.instruction & 0x000f;
90e4755a 12513
c19d1205 12514 if ((mask & 0x7) == 0)
5a01bb1d
MGD
12515 {
12516 /* No conversion needed. */
5ee91343 12517 now_pred.block_length = 1;
5a01bb1d 12518 }
c19d1205 12519 else if ((mask & 0x3) == 0)
5a01bb1d
MGD
12520 {
12521 mask ^= 0x8;
5ee91343 12522 now_pred.block_length = 2;
5a01bb1d 12523 }
e27ec89e 12524 else if ((mask & 0x1) == 0)
5a01bb1d
MGD
12525 {
12526 mask ^= 0xC;
5ee91343 12527 now_pred.block_length = 3;
5a01bb1d 12528 }
c19d1205 12529 else
5a01bb1d
MGD
12530 {
12531 mask ^= 0xE;
5ee91343 12532 now_pred.block_length = 4;
5a01bb1d 12533 }
90e4755a 12534
e27ec89e
PB
12535 inst.instruction &= 0xfff0;
12536 inst.instruction |= mask;
c19d1205 12537 }
90e4755a 12538
c19d1205
ZW
12539 inst.instruction |= cond << 4;
12540}
90e4755a 12541
3c707909
PB
12542/* Helper function used for both push/pop and ldm/stm. */
12543static void
5b7c81bd
AM
12544encode_thumb2_multi (bool do_io, int base, unsigned mask,
12545 bool writeback)
3c707909 12546{
5b7c81bd 12547 bool load, store;
3c707909 12548
4b5a202f
AV
12549 gas_assert (base != -1 || !do_io);
12550 load = do_io && ((inst.instruction & (1 << 20)) != 0);
12551 store = do_io && !load;
3c707909
PB
12552
12553 if (mask & (1 << 13))
12554 inst.error = _("SP not allowed in register list");
1e5b0379 12555
4b5a202f 12556 if (do_io && (mask & (1 << base)) != 0
1e5b0379
NC
12557 && writeback)
12558 inst.error = _("having the base register in the register list when "
12559 "using write back is UNPREDICTABLE");
12560
3c707909
PB
12561 if (load)
12562 {
e07e6e58 12563 if (mask & (1 << 15))
477330fc
RM
12564 {
12565 if (mask & (1 << 14))
12566 inst.error = _("LR and PC should not both be in register list");
12567 else
5ee91343 12568 set_pred_insn_type_last ();
477330fc 12569 }
3c707909 12570 }
4b5a202f 12571 else if (store)
3c707909
PB
12572 {
12573 if (mask & (1 << 15))
12574 inst.error = _("PC not allowed in register list");
3c707909
PB
12575 }
12576
4b5a202f 12577 if (do_io && ((mask & (mask - 1)) == 0))
3c707909
PB
12578 {
12579 /* Single register transfers implemented as str/ldr. */
12580 if (writeback)
12581 {
12582 if (inst.instruction & (1 << 23))
12583 inst.instruction = 0x00000b04; /* ia! -> [base], #4 */
12584 else
12585 inst.instruction = 0x00000d04; /* db! -> [base, #-4]! */
12586 }
12587 else
12588 {
12589 if (inst.instruction & (1 << 23))
12590 inst.instruction = 0x00800000; /* ia -> [base] */
12591 else
12592 inst.instruction = 0x00000c04; /* db -> [base, #-4] */
12593 }
12594
12595 inst.instruction |= 0xf8400000;
12596 if (load)
12597 inst.instruction |= 0x00100000;
12598
5f4273c7 12599 mask = ffs (mask) - 1;
3c707909
PB
12600 mask <<= 12;
12601 }
12602 else if (writeback)
12603 inst.instruction |= WRITE_BACK;
12604
12605 inst.instruction |= mask;
4b5a202f
AV
12606 if (do_io)
12607 inst.instruction |= base << 16;
3c707909
PB
12608}
12609
c19d1205
ZW
12610static void
12611do_t_ldmstm (void)
12612{
12613 /* This really doesn't seem worth it. */
e2b0ab59 12614 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205
ZW
12615 _("expression too complex"));
12616 constraint (inst.operands[1].writeback,
12617 _("Thumb load/store multiple does not support {reglist}^"));
90e4755a 12618
c19d1205
ZW
12619 if (unified_syntax)
12620 {
5b7c81bd 12621 bool narrow;
3c707909
PB
12622 unsigned mask;
12623
5b7c81bd 12624 narrow = false;
c19d1205
ZW
12625 /* See if we can use a 16-bit instruction. */
12626 if (inst.instruction < 0xffff /* not ldmdb/stmdb */
12627 && inst.size_req != 4
3c707909 12628 && !(inst.operands[1].imm & ~0xff))
90e4755a 12629 {
3c707909 12630 mask = 1 << inst.operands[0].reg;
90e4755a 12631
eab4f823 12632 if (inst.operands[0].reg <= 7)
90e4755a 12633 {
3c707909 12634 if (inst.instruction == T_MNEM_stmia
eab4f823
MGD
12635 ? inst.operands[0].writeback
12636 : (inst.operands[0].writeback
12637 == !(inst.operands[1].imm & mask)))
477330fc 12638 {
eab4f823
MGD
12639 if (inst.instruction == T_MNEM_stmia
12640 && (inst.operands[1].imm & mask)
12641 && (inst.operands[1].imm & (mask - 1)))
12642 as_warn (_("value stored for r%d is UNKNOWN"),
12643 inst.operands[0].reg);
3c707909 12644
eab4f823
MGD
12645 inst.instruction = THUMB_OP16 (inst.instruction);
12646 inst.instruction |= inst.operands[0].reg << 8;
12647 inst.instruction |= inst.operands[1].imm;
5b7c81bd 12648 narrow = true;
eab4f823
MGD
12649 }
12650 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12651 {
12652 /* This means 1 register in reg list one of 3 situations:
12653 1. Instruction is stmia, but without writeback.
12654 2. lmdia without writeback, but with Rn not in
477330fc 12655 reglist.
eab4f823
MGD
12656 3. ldmia with writeback, but with Rn in reglist.
12657 Case 3 is UNPREDICTABLE behaviour, so we handle
12658 case 1 and 2 which can be converted into a 16-bit
12659 str or ldr. The SP cases are handled below. */
12660 unsigned long opcode;
12661 /* First, record an error for Case 3. */
12662 if (inst.operands[1].imm & mask
12663 && inst.operands[0].writeback)
fa94de6b 12664 inst.error =
eab4f823
MGD
12665 _("having the base register in the register list when "
12666 "using write back is UNPREDICTABLE");
fa94de6b
RM
12667
12668 opcode = (inst.instruction == T_MNEM_stmia ? T_MNEM_str
eab4f823
MGD
12669 : T_MNEM_ldr);
12670 inst.instruction = THUMB_OP16 (opcode);
12671 inst.instruction |= inst.operands[0].reg << 3;
12672 inst.instruction |= (ffs (inst.operands[1].imm)-1);
5b7c81bd 12673 narrow = true;
eab4f823 12674 }
90e4755a 12675 }
eab4f823 12676 else if (inst.operands[0] .reg == REG_SP)
90e4755a 12677 {
eab4f823
MGD
12678 if (inst.operands[0].writeback)
12679 {
fa94de6b 12680 inst.instruction =
eab4f823 12681 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12682 ? T_MNEM_push : T_MNEM_pop);
eab4f823 12683 inst.instruction |= inst.operands[1].imm;
5b7c81bd 12684 narrow = true;
eab4f823
MGD
12685 }
12686 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12687 {
fa94de6b 12688 inst.instruction =
eab4f823 12689 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12690 ? T_MNEM_str_sp : T_MNEM_ldr_sp);
eab4f823 12691 inst.instruction |= ((ffs (inst.operands[1].imm)-1) << 8);
5b7c81bd 12692 narrow = true;
eab4f823 12693 }
90e4755a 12694 }
3c707909
PB
12695 }
12696
12697 if (!narrow)
12698 {
c19d1205
ZW
12699 if (inst.instruction < 0xffff)
12700 inst.instruction = THUMB_OP32 (inst.instruction);
3c707909 12701
5b7c81bd 12702 encode_thumb2_multi (true /* do_io */, inst.operands[0].reg,
4b5a202f
AV
12703 inst.operands[1].imm,
12704 inst.operands[0].writeback);
90e4755a
RE
12705 }
12706 }
c19d1205 12707 else
90e4755a 12708 {
c19d1205
ZW
12709 constraint (inst.operands[0].reg > 7
12710 || (inst.operands[1].imm & ~0xff), BAD_HIREG);
1198ca51
PB
12711 constraint (inst.instruction != T_MNEM_ldmia
12712 && inst.instruction != T_MNEM_stmia,
12713 _("Thumb-2 instruction only valid in unified syntax"));
c19d1205 12714 if (inst.instruction == T_MNEM_stmia)
f03698e6 12715 {
c19d1205
ZW
12716 if (!inst.operands[0].writeback)
12717 as_warn (_("this instruction will write back the base register"));
12718 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
12719 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
1e5b0379 12720 as_warn (_("value stored for r%d is UNKNOWN"),
c19d1205 12721 inst.operands[0].reg);
f03698e6 12722 }
c19d1205 12723 else
90e4755a 12724 {
c19d1205
ZW
12725 if (!inst.operands[0].writeback
12726 && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
12727 as_warn (_("this instruction will write back the base register"));
12728 else if (inst.operands[0].writeback
12729 && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
12730 as_warn (_("this instruction will not write back the base register"));
90e4755a
RE
12731 }
12732
c19d1205
ZW
12733 inst.instruction = THUMB_OP16 (inst.instruction);
12734 inst.instruction |= inst.operands[0].reg << 8;
12735 inst.instruction |= inst.operands[1].imm;
12736 }
12737}
e28cd48c 12738
c19d1205
ZW
12739static void
12740do_t_ldrex (void)
12741{
12742 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
12743 || inst.operands[1].postind || inst.operands[1].writeback
12744 || inst.operands[1].immisreg || inst.operands[1].shifted
12745 || inst.operands[1].negative,
01cfc07f 12746 BAD_ADDR_MODE);
e28cd48c 12747
5be8be5d
DG
12748 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
12749
c19d1205
ZW
12750 inst.instruction |= inst.operands[0].reg << 12;
12751 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 12752 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
c19d1205 12753}
e28cd48c 12754
c19d1205
ZW
12755static void
12756do_t_ldrexd (void)
12757{
12758 if (!inst.operands[1].present)
1cac9012 12759 {
c19d1205
ZW
12760 constraint (inst.operands[0].reg == REG_LR,
12761 _("r14 not allowed as first register "
12762 "when second register is omitted"));
12763 inst.operands[1].reg = inst.operands[0].reg + 1;
b99bd4ef 12764 }
c19d1205
ZW
12765 constraint (inst.operands[0].reg == inst.operands[1].reg,
12766 BAD_OVERLAP);
b99bd4ef 12767
c19d1205
ZW
12768 inst.instruction |= inst.operands[0].reg << 12;
12769 inst.instruction |= inst.operands[1].reg << 8;
12770 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
12771}
12772
12773static void
c19d1205 12774do_t_ldst (void)
b99bd4ef 12775{
0110f2b8
PB
12776 unsigned long opcode;
12777 int Rn;
12778
e07e6e58
NC
12779 if (inst.operands[0].isreg
12780 && !inst.operands[0].preind
12781 && inst.operands[0].reg == REG_PC)
5ee91343 12782 set_pred_insn_type_last ();
e07e6e58 12783
0110f2b8 12784 opcode = inst.instruction;
c19d1205 12785 if (unified_syntax)
b99bd4ef 12786 {
53365c0d
PB
12787 if (!inst.operands[1].isreg)
12788 {
12789 if (opcode <= 0xffff)
12790 inst.instruction = THUMB_OP32 (opcode);
5b7c81bd 12791 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/false))
53365c0d
PB
12792 return;
12793 }
0110f2b8
PB
12794 if (inst.operands[1].isreg
12795 && !inst.operands[1].writeback
c19d1205
ZW
12796 && !inst.operands[1].shifted && !inst.operands[1].postind
12797 && !inst.operands[1].negative && inst.operands[0].reg <= 7
0110f2b8
PB
12798 && opcode <= 0xffff
12799 && inst.size_req != 4)
c19d1205 12800 {
0110f2b8
PB
12801 /* Insn may have a 16-bit form. */
12802 Rn = inst.operands[1].reg;
12803 if (inst.operands[1].immisreg)
12804 {
12805 inst.instruction = THUMB_OP16 (opcode);
5f4273c7 12806 /* [Rn, Rik] */
0110f2b8
PB
12807 if (Rn <= 7 && inst.operands[1].imm <= 7)
12808 goto op16;
5be8be5d
DG
12809 else if (opcode != T_MNEM_ldr && opcode != T_MNEM_str)
12810 reject_bad_reg (inst.operands[1].imm);
0110f2b8
PB
12811 }
12812 else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
12813 && opcode != T_MNEM_ldrsb)
12814 || ((Rn == REG_PC || Rn == REG_SP) && opcode == T_MNEM_ldr)
12815 || (Rn == REG_SP && opcode == T_MNEM_str))
12816 {
12817 /* [Rn, #const] */
12818 if (Rn > 7)
12819 {
12820 if (Rn == REG_PC)
12821 {
e2b0ab59 12822 if (inst.relocs[0].pc_rel)
0110f2b8
PB
12823 opcode = T_MNEM_ldr_pc2;
12824 else
12825 opcode = T_MNEM_ldr_pc;
12826 }
12827 else
12828 {
12829 if (opcode == T_MNEM_ldr)
12830 opcode = T_MNEM_ldr_sp;
12831 else
12832 opcode = T_MNEM_str_sp;
12833 }
12834 inst.instruction = inst.operands[0].reg << 8;
12835 }
12836 else
12837 {
12838 inst.instruction = inst.operands[0].reg;
12839 inst.instruction |= inst.operands[1].reg << 3;
12840 }
12841 inst.instruction |= THUMB_OP16 (opcode);
12842 if (inst.size_req == 2)
e2b0ab59 12843 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
0110f2b8
PB
12844 else
12845 inst.relax = opcode;
12846 return;
12847 }
c19d1205 12848 }
0110f2b8 12849 /* Definitely a 32-bit variant. */
5be8be5d 12850
8d67f500
NC
12851 /* Warning for Erratum 752419. */
12852 if (opcode == T_MNEM_ldr
12853 && inst.operands[0].reg == REG_SP
12854 && inst.operands[1].writeback == 1
12855 && !inst.operands[1].immisreg)
12856 {
12857 if (no_cpu_selected ()
12858 || (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7)
477330fc
RM
12859 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a)
12860 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7r)))
8d67f500
NC
12861 as_warn (_("This instruction may be unpredictable "
12862 "if executed on M-profile cores "
12863 "with interrupts enabled."));
12864 }
12865
5be8be5d 12866 /* Do some validations regarding addressing modes. */
1be5fd2e 12867 if (inst.operands[1].immisreg)
5be8be5d
DG
12868 reject_bad_reg (inst.operands[1].imm);
12869
1be5fd2e
NC
12870 constraint (inst.operands[1].writeback == 1
12871 && inst.operands[0].reg == inst.operands[1].reg,
12872 BAD_OVERLAP);
12873
0110f2b8 12874 inst.instruction = THUMB_OP32 (opcode);
c19d1205 12875 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 12876 encode_thumb32_addr_mode (1, /*is_t=*/false, /*is_d=*/false);
1be5fd2e 12877 check_ldr_r15_aligned ();
b99bd4ef
NC
12878 return;
12879 }
12880
c19d1205
ZW
12881 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12882
12883 if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
b99bd4ef 12884 {
c19d1205
ZW
12885 /* Only [Rn,Rm] is acceptable. */
12886 constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
12887 constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
12888 || inst.operands[1].postind || inst.operands[1].shifted
12889 || inst.operands[1].negative,
12890 _("Thumb does not support this addressing mode"));
12891 inst.instruction = THUMB_OP16 (inst.instruction);
12892 goto op16;
b99bd4ef 12893 }
5f4273c7 12894
c19d1205
ZW
12895 inst.instruction = THUMB_OP16 (inst.instruction);
12896 if (!inst.operands[1].isreg)
5b7c81bd 12897 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/false))
c19d1205 12898 return;
b99bd4ef 12899
c19d1205
ZW
12900 constraint (!inst.operands[1].preind
12901 || inst.operands[1].shifted
12902 || inst.operands[1].writeback,
12903 _("Thumb does not support this addressing mode"));
12904 if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
90e4755a 12905 {
c19d1205
ZW
12906 constraint (inst.instruction & 0x0600,
12907 _("byte or halfword not valid for base register"));
12908 constraint (inst.operands[1].reg == REG_PC
12909 && !(inst.instruction & THUMB_LOAD_BIT),
12910 _("r15 based store not allowed"));
12911 constraint (inst.operands[1].immisreg,
12912 _("invalid base register for register offset"));
b99bd4ef 12913
c19d1205
ZW
12914 if (inst.operands[1].reg == REG_PC)
12915 inst.instruction = T_OPCODE_LDR_PC;
12916 else if (inst.instruction & THUMB_LOAD_BIT)
12917 inst.instruction = T_OPCODE_LDR_SP;
12918 else
12919 inst.instruction = T_OPCODE_STR_SP;
b99bd4ef 12920
c19d1205 12921 inst.instruction |= inst.operands[0].reg << 8;
e2b0ab59 12922 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12923 return;
12924 }
90e4755a 12925
c19d1205
ZW
12926 constraint (inst.operands[1].reg > 7, BAD_HIREG);
12927 if (!inst.operands[1].immisreg)
12928 {
12929 /* Immediate offset. */
12930 inst.instruction |= inst.operands[0].reg;
12931 inst.instruction |= inst.operands[1].reg << 3;
e2b0ab59 12932 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12933 return;
12934 }
90e4755a 12935
c19d1205
ZW
12936 /* Register offset. */
12937 constraint (inst.operands[1].imm > 7, BAD_HIREG);
12938 constraint (inst.operands[1].negative,
12939 _("Thumb does not support this addressing mode"));
90e4755a 12940
c19d1205
ZW
12941 op16:
12942 switch (inst.instruction)
12943 {
12944 case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
12945 case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
12946 case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
12947 case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
12948 case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
12949 case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
12950 case 0x5600 /* ldrsb */:
12951 case 0x5e00 /* ldrsh */: break;
12952 default: abort ();
12953 }
90e4755a 12954
c19d1205
ZW
12955 inst.instruction |= inst.operands[0].reg;
12956 inst.instruction |= inst.operands[1].reg << 3;
12957 inst.instruction |= inst.operands[1].imm << 6;
12958}
90e4755a 12959
c19d1205
ZW
12960static void
12961do_t_ldstd (void)
12962{
12963 if (!inst.operands[1].present)
b99bd4ef 12964 {
c19d1205
ZW
12965 inst.operands[1].reg = inst.operands[0].reg + 1;
12966 constraint (inst.operands[0].reg == REG_LR,
12967 _("r14 not allowed here"));
bd340a04 12968 constraint (inst.operands[0].reg == REG_R12,
477330fc 12969 _("r12 not allowed here"));
b99bd4ef 12970 }
bd340a04
MGD
12971
12972 if (inst.operands[2].writeback
12973 && (inst.operands[0].reg == inst.operands[2].reg
12974 || inst.operands[1].reg == inst.operands[2].reg))
12975 as_warn (_("base register written back, and overlaps "
477330fc 12976 "one of transfer registers"));
bd340a04 12977
c19d1205
ZW
12978 inst.instruction |= inst.operands[0].reg << 12;
12979 inst.instruction |= inst.operands[1].reg << 8;
5b7c81bd 12980 encode_thumb32_addr_mode (2, /*is_t=*/false, /*is_d=*/true);
b99bd4ef
NC
12981}
12982
c19d1205
ZW
12983static void
12984do_t_ldstt (void)
12985{
12986 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 12987 encode_thumb32_addr_mode (1, /*is_t=*/true, /*is_d=*/false);
c19d1205 12988}
a737bd4d 12989
b99bd4ef 12990static void
c19d1205 12991do_t_mla (void)
b99bd4ef 12992{
fdfde340 12993 unsigned Rd, Rn, Rm, Ra;
c921be7d 12994
fdfde340
JM
12995 Rd = inst.operands[0].reg;
12996 Rn = inst.operands[1].reg;
12997 Rm = inst.operands[2].reg;
12998 Ra = inst.operands[3].reg;
12999
13000 reject_bad_reg (Rd);
13001 reject_bad_reg (Rn);
13002 reject_bad_reg (Rm);
13003 reject_bad_reg (Ra);
13004
13005 inst.instruction |= Rd << 8;
13006 inst.instruction |= Rn << 16;
13007 inst.instruction |= Rm;
13008 inst.instruction |= Ra << 12;
c19d1205 13009}
b99bd4ef 13010
c19d1205
ZW
13011static void
13012do_t_mlal (void)
13013{
fdfde340
JM
13014 unsigned RdLo, RdHi, Rn, Rm;
13015
13016 RdLo = inst.operands[0].reg;
13017 RdHi = inst.operands[1].reg;
13018 Rn = inst.operands[2].reg;
13019 Rm = inst.operands[3].reg;
13020
13021 reject_bad_reg (RdLo);
13022 reject_bad_reg (RdHi);
13023 reject_bad_reg (Rn);
13024 reject_bad_reg (Rm);
13025
13026 inst.instruction |= RdLo << 12;
13027 inst.instruction |= RdHi << 8;
13028 inst.instruction |= Rn << 16;
13029 inst.instruction |= Rm;
c19d1205 13030}
b99bd4ef 13031
c19d1205
ZW
13032static void
13033do_t_mov_cmp (void)
13034{
fdfde340
JM
13035 unsigned Rn, Rm;
13036
13037 Rn = inst.operands[0].reg;
13038 Rm = inst.operands[1].reg;
13039
e07e6e58 13040 if (Rn == REG_PC)
5ee91343 13041 set_pred_insn_type_last ();
e07e6e58 13042
c19d1205 13043 if (unified_syntax)
b99bd4ef 13044 {
c19d1205
ZW
13045 int r0off = (inst.instruction == T_MNEM_mov
13046 || inst.instruction == T_MNEM_movs) ? 8 : 16;
0110f2b8 13047 unsigned long opcode;
5b7c81bd
AM
13048 bool narrow;
13049 bool low_regs;
3d388997 13050
fdfde340 13051 low_regs = (Rn <= 7 && Rm <= 7);
0110f2b8 13052 opcode = inst.instruction;
5ee91343 13053 if (in_pred_block ())
0110f2b8 13054 narrow = opcode != T_MNEM_movs;
3d388997 13055 else
0110f2b8 13056 narrow = opcode != T_MNEM_movs || low_regs;
3d388997
PB
13057 if (inst.size_req == 4
13058 || inst.operands[1].shifted)
5b7c81bd 13059 narrow = false;
3d388997 13060
efd81785
PB
13061 /* MOVS PC, LR is encoded as SUBS PC, LR, #0. */
13062 if (opcode == T_MNEM_movs && inst.operands[1].isreg
13063 && !inst.operands[1].shifted
fdfde340
JM
13064 && Rn == REG_PC
13065 && Rm == REG_LR)
efd81785
PB
13066 {
13067 inst.instruction = T2_SUBS_PC_LR;
13068 return;
13069 }
13070
fdfde340
JM
13071 if (opcode == T_MNEM_cmp)
13072 {
13073 constraint (Rn == REG_PC, BAD_PC);
94206790
MM
13074 if (narrow)
13075 {
13076 /* In the Thumb-2 ISA, use of R13 as Rm is deprecated,
13077 but valid. */
13078 warn_deprecated_sp (Rm);
13079 /* R15 was documented as a valid choice for Rm in ARMv6,
13080 but as UNPREDICTABLE in ARMv7. ARM's proprietary
13081 tools reject R15, so we do too. */
13082 constraint (Rm == REG_PC, BAD_PC);
13083 }
13084 else
13085 reject_bad_reg (Rm);
fdfde340
JM
13086 }
13087 else if (opcode == T_MNEM_mov
13088 || opcode == T_MNEM_movs)
13089 {
13090 if (inst.operands[1].isreg)
13091 {
13092 if (opcode == T_MNEM_movs)
13093 {
13094 reject_bad_reg (Rn);
13095 reject_bad_reg (Rm);
13096 }
76fa04a4
MGD
13097 else if (narrow)
13098 {
13099 /* This is mov.n. */
13100 if ((Rn == REG_SP || Rn == REG_PC)
13101 && (Rm == REG_SP || Rm == REG_PC))
13102 {
5c3696f8 13103 as_tsktsk (_("Use of r%u as a source register is "
76fa04a4
MGD
13104 "deprecated when r%u is the destination "
13105 "register."), Rm, Rn);
13106 }
13107 }
13108 else
13109 {
13110 /* This is mov.w. */
13111 constraint (Rn == REG_PC, BAD_PC);
13112 constraint (Rm == REG_PC, BAD_PC);
5c8ed6a4
JW
13113 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
13114 constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
76fa04a4 13115 }
fdfde340
JM
13116 }
13117 else
13118 reject_bad_reg (Rn);
13119 }
13120
c19d1205
ZW
13121 if (!inst.operands[1].isreg)
13122 {
0110f2b8 13123 /* Immediate operand. */
5ee91343 13124 if (!in_pred_block () && opcode == T_MNEM_mov)
0110f2b8
PB
13125 narrow = 0;
13126 if (low_regs && narrow)
13127 {
13128 inst.instruction = THUMB_OP16 (opcode);
fdfde340 13129 inst.instruction |= Rn << 8;
e2b0ab59
AV
13130 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
13131 || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
72d98d16 13132 {
a9f02af8 13133 if (inst.size_req == 2)
e2b0ab59 13134 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
a9f02af8
MG
13135 else
13136 inst.relax = opcode;
72d98d16 13137 }
0110f2b8
PB
13138 }
13139 else
13140 {
e2b0ab59
AV
13141 constraint ((inst.relocs[0].type
13142 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
13143 && (inst.relocs[0].type
13144 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8
MG
13145 THUMB1_RELOC_ONLY);
13146
0110f2b8
PB
13147 inst.instruction = THUMB_OP32 (inst.instruction);
13148 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 13149 inst.instruction |= Rn << r0off;
e2b0ab59 13150 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8 13151 }
c19d1205 13152 }
728ca7c9
PB
13153 else if (inst.operands[1].shifted && inst.operands[1].immisreg
13154 && (inst.instruction == T_MNEM_mov
13155 || inst.instruction == T_MNEM_movs))
13156 {
13157 /* Register shifts are encoded as separate shift instructions. */
5b7c81bd 13158 bool flags = (inst.instruction == T_MNEM_movs);
728ca7c9 13159
5ee91343 13160 if (in_pred_block ())
728ca7c9
PB
13161 narrow = !flags;
13162 else
13163 narrow = flags;
13164
13165 if (inst.size_req == 4)
5b7c81bd 13166 narrow = false;
728ca7c9
PB
13167
13168 if (!low_regs || inst.operands[1].imm > 7)
5b7c81bd 13169 narrow = false;
728ca7c9 13170
fdfde340 13171 if (Rn != Rm)
5b7c81bd 13172 narrow = false;
728ca7c9
PB
13173
13174 switch (inst.operands[1].shift_kind)
13175 {
13176 case SHIFT_LSL:
13177 opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl);
13178 break;
13179 case SHIFT_ASR:
13180 opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr);
13181 break;
13182 case SHIFT_LSR:
13183 opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr);
13184 break;
13185 case SHIFT_ROR:
13186 opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror);
13187 break;
13188 default:
5f4273c7 13189 abort ();
728ca7c9
PB
13190 }
13191
13192 inst.instruction = opcode;
13193 if (narrow)
13194 {
fdfde340 13195 inst.instruction |= Rn;
728ca7c9
PB
13196 inst.instruction |= inst.operands[1].imm << 3;
13197 }
13198 else
13199 {
13200 if (flags)
13201 inst.instruction |= CONDS_BIT;
13202
fdfde340
JM
13203 inst.instruction |= Rn << 8;
13204 inst.instruction |= Rm << 16;
728ca7c9
PB
13205 inst.instruction |= inst.operands[1].imm;
13206 }
13207 }
3d388997 13208 else if (!narrow)
c19d1205 13209 {
728ca7c9
PB
13210 /* Some mov with immediate shift have narrow variants.
13211 Register shifts are handled above. */
13212 if (low_regs && inst.operands[1].shifted
13213 && (inst.instruction == T_MNEM_mov
13214 || inst.instruction == T_MNEM_movs))
13215 {
5ee91343 13216 if (in_pred_block ())
728ca7c9
PB
13217 narrow = (inst.instruction == T_MNEM_mov);
13218 else
13219 narrow = (inst.instruction == T_MNEM_movs);
13220 }
13221
13222 if (narrow)
13223 {
13224 switch (inst.operands[1].shift_kind)
13225 {
13226 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
13227 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
13228 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
5b7c81bd 13229 default: narrow = false; break;
728ca7c9
PB
13230 }
13231 }
13232
13233 if (narrow)
13234 {
fdfde340
JM
13235 inst.instruction |= Rn;
13236 inst.instruction |= Rm << 3;
e2b0ab59 13237 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
728ca7c9
PB
13238 }
13239 else
13240 {
13241 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 13242 inst.instruction |= Rn << r0off;
728ca7c9
PB
13243 encode_thumb32_shifted_operand (1);
13244 }
c19d1205
ZW
13245 }
13246 else
13247 switch (inst.instruction)
13248 {
13249 case T_MNEM_mov:
837b3435 13250 /* In v4t or v5t a move of two lowregs produces unpredictable
c6400f8a
MGD
13251 results. Don't allow this. */
13252 if (low_regs)
13253 {
13254 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
13255 "MOV Rd, Rs with two low registers is not "
13256 "permitted on this architecture");
fa94de6b 13257 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
c6400f8a
MGD
13258 arm_ext_v6);
13259 }
13260
c19d1205 13261 inst.instruction = T_OPCODE_MOV_HR;
fdfde340
JM
13262 inst.instruction |= (Rn & 0x8) << 4;
13263 inst.instruction |= (Rn & 0x7);
13264 inst.instruction |= Rm << 3;
c19d1205 13265 break;
b99bd4ef 13266
c19d1205
ZW
13267 case T_MNEM_movs:
13268 /* We know we have low registers at this point.
941a8a52
MGD
13269 Generate LSLS Rd, Rs, #0. */
13270 inst.instruction = T_OPCODE_LSL_I;
fdfde340
JM
13271 inst.instruction |= Rn;
13272 inst.instruction |= Rm << 3;
c19d1205
ZW
13273 break;
13274
13275 case T_MNEM_cmp:
3d388997 13276 if (low_regs)
c19d1205
ZW
13277 {
13278 inst.instruction = T_OPCODE_CMP_LR;
fdfde340
JM
13279 inst.instruction |= Rn;
13280 inst.instruction |= Rm << 3;
c19d1205
ZW
13281 }
13282 else
13283 {
13284 inst.instruction = T_OPCODE_CMP_HR;
fdfde340
JM
13285 inst.instruction |= (Rn & 0x8) << 4;
13286 inst.instruction |= (Rn & 0x7);
13287 inst.instruction |= Rm << 3;
c19d1205
ZW
13288 }
13289 break;
13290 }
b99bd4ef
NC
13291 return;
13292 }
13293
c19d1205 13294 inst.instruction = THUMB_OP16 (inst.instruction);
539d4391
NC
13295
13296 /* PR 10443: Do not silently ignore shifted operands. */
13297 constraint (inst.operands[1].shifted,
13298 _("shifts in CMP/MOV instructions are only supported in unified syntax"));
13299
c19d1205 13300 if (inst.operands[1].isreg)
b99bd4ef 13301 {
fdfde340 13302 if (Rn < 8 && Rm < 8)
b99bd4ef 13303 {
c19d1205
ZW
13304 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
13305 since a MOV instruction produces unpredictable results. */
13306 if (inst.instruction == T_OPCODE_MOV_I8)
13307 inst.instruction = T_OPCODE_ADD_I3;
b99bd4ef 13308 else
c19d1205 13309 inst.instruction = T_OPCODE_CMP_LR;
b99bd4ef 13310
fdfde340
JM
13311 inst.instruction |= Rn;
13312 inst.instruction |= Rm << 3;
b99bd4ef
NC
13313 }
13314 else
13315 {
c19d1205
ZW
13316 if (inst.instruction == T_OPCODE_MOV_I8)
13317 inst.instruction = T_OPCODE_MOV_HR;
13318 else
13319 inst.instruction = T_OPCODE_CMP_HR;
13320 do_t_cpy ();
b99bd4ef
NC
13321 }
13322 }
c19d1205 13323 else
b99bd4ef 13324 {
fdfde340 13325 constraint (Rn > 7,
c19d1205 13326 _("only lo regs allowed with immediate"));
fdfde340 13327 inst.instruction |= Rn << 8;
e2b0ab59 13328 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
c19d1205
ZW
13329 }
13330}
b99bd4ef 13331
c19d1205
ZW
13332static void
13333do_t_mov16 (void)
13334{
fdfde340 13335 unsigned Rd;
b6895b4f 13336 bfd_vma imm;
5b7c81bd 13337 bool top;
b6895b4f
PB
13338
13339 top = (inst.instruction & 0x00800000) != 0;
e2b0ab59 13340 if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
b6895b4f 13341 {
33eaf5de 13342 constraint (top, _(":lower16: not allowed in this instruction"));
e2b0ab59 13343 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
b6895b4f 13344 }
e2b0ab59 13345 else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
b6895b4f 13346 {
33eaf5de 13347 constraint (!top, _(":upper16: not allowed in this instruction"));
e2b0ab59 13348 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
b6895b4f
PB
13349 }
13350
fdfde340
JM
13351 Rd = inst.operands[0].reg;
13352 reject_bad_reg (Rd);
13353
13354 inst.instruction |= Rd << 8;
e2b0ab59 13355 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 13356 {
e2b0ab59 13357 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
13358 inst.instruction |= (imm & 0xf000) << 4;
13359 inst.instruction |= (imm & 0x0800) << 15;
13360 inst.instruction |= (imm & 0x0700) << 4;
13361 inst.instruction |= (imm & 0x00ff);
13362 }
c19d1205 13363}
b99bd4ef 13364
c19d1205
ZW
13365static void
13366do_t_mvn_tst (void)
13367{
fdfde340 13368 unsigned Rn, Rm;
c921be7d 13369
fdfde340
JM
13370 Rn = inst.operands[0].reg;
13371 Rm = inst.operands[1].reg;
13372
13373 if (inst.instruction == T_MNEM_cmp
13374 || inst.instruction == T_MNEM_cmn)
13375 constraint (Rn == REG_PC, BAD_PC);
13376 else
13377 reject_bad_reg (Rn);
13378 reject_bad_reg (Rm);
13379
c19d1205
ZW
13380 if (unified_syntax)
13381 {
13382 int r0off = (inst.instruction == T_MNEM_mvn
13383 || inst.instruction == T_MNEM_mvns) ? 8 : 16;
5b7c81bd 13384 bool narrow;
3d388997
PB
13385
13386 if (inst.size_req == 4
13387 || inst.instruction > 0xffff
13388 || inst.operands[1].shifted
fdfde340 13389 || Rn > 7 || Rm > 7)
5b7c81bd 13390 narrow = false;
fe8b4cc3
KT
13391 else if (inst.instruction == T_MNEM_cmn
13392 || inst.instruction == T_MNEM_tst)
5b7c81bd 13393 narrow = true;
3d388997 13394 else if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13395 narrow = !in_pred_block ();
3d388997 13396 else
5ee91343 13397 narrow = in_pred_block ();
3d388997 13398
c19d1205 13399 if (!inst.operands[1].isreg)
b99bd4ef 13400 {
c19d1205
ZW
13401 /* For an immediate, we always generate a 32-bit opcode;
13402 section relaxation will shrink it later if possible. */
13403 if (inst.instruction < 0xffff)
13404 inst.instruction = THUMB_OP32 (inst.instruction);
13405 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 13406 inst.instruction |= Rn << r0off;
e2b0ab59 13407 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 13408 }
c19d1205 13409 else
b99bd4ef 13410 {
c19d1205 13411 /* See if we can do this with a 16-bit instruction. */
3d388997 13412 if (narrow)
b99bd4ef 13413 {
c19d1205 13414 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13415 inst.instruction |= Rn;
13416 inst.instruction |= Rm << 3;
b99bd4ef 13417 }
c19d1205 13418 else
b99bd4ef 13419 {
c19d1205
ZW
13420 constraint (inst.operands[1].shifted
13421 && inst.operands[1].immisreg,
13422 _("shift must be constant"));
13423 if (inst.instruction < 0xffff)
13424 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 13425 inst.instruction |= Rn << r0off;
c19d1205 13426 encode_thumb32_shifted_operand (1);
b99bd4ef 13427 }
b99bd4ef
NC
13428 }
13429 }
13430 else
13431 {
c19d1205
ZW
13432 constraint (inst.instruction > 0xffff
13433 || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
13434 constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
13435 _("unshifted register required"));
fdfde340 13436 constraint (Rn > 7 || Rm > 7,
c19d1205 13437 BAD_HIREG);
b99bd4ef 13438
c19d1205 13439 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13440 inst.instruction |= Rn;
13441 inst.instruction |= Rm << 3;
b99bd4ef 13442 }
b99bd4ef
NC
13443}
13444
b05fe5cf 13445static void
c19d1205 13446do_t_mrs (void)
b05fe5cf 13447{
fdfde340 13448 unsigned Rd;
037e8744
JB
13449
13450 if (do_vfp_nsyn_mrs () == SUCCESS)
13451 return;
13452
90ec0d68
MGD
13453 Rd = inst.operands[0].reg;
13454 reject_bad_reg (Rd);
13455 inst.instruction |= Rd << 8;
13456
13457 if (inst.operands[1].isreg)
62b3e311 13458 {
90ec0d68
MGD
13459 unsigned br = inst.operands[1].reg;
13460 if (((br & 0x200) == 0) && ((br & 0xf000) != 0xf000))
13461 as_bad (_("bad register for mrs"));
13462
13463 inst.instruction |= br & (0xf << 16);
13464 inst.instruction |= (br & 0x300) >> 4;
13465 inst.instruction |= (br & SPSR_BIT) >> 2;
62b3e311
PB
13466 }
13467 else
13468 {
90ec0d68 13469 int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
5f4273c7 13470
d2cd1205 13471 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
1a43faaf
NC
13472 {
13473 /* PR gas/12698: The constraint is only applied for m_profile.
13474 If the user has specified -march=all, we want to ignore it as
13475 we are building for any CPU type, including non-m variants. */
5b7c81bd 13476 bool m_profile =
823d2571 13477 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf
NC
13478 constraint ((flags != 0) && m_profile, _("selected processor does "
13479 "not support requested special purpose register"));
13480 }
90ec0d68 13481 else
d2cd1205
JB
13482 /* mrs only accepts APSR/CPSR/SPSR/CPSR_all/SPSR_all (for non-M profile
13483 devices). */
13484 constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
13485 _("'APSR', 'CPSR' or 'SPSR' expected"));
fdfde340 13486
90ec0d68
MGD
13487 inst.instruction |= (flags & SPSR_BIT) >> 2;
13488 inst.instruction |= inst.operands[1].imm & 0xff;
13489 inst.instruction |= 0xf0000;
13490 }
c19d1205 13491}
b05fe5cf 13492
c19d1205
ZW
13493static void
13494do_t_msr (void)
13495{
62b3e311 13496 int flags;
fdfde340 13497 unsigned Rn;
62b3e311 13498
037e8744
JB
13499 if (do_vfp_nsyn_msr () == SUCCESS)
13500 return;
13501
c19d1205
ZW
13502 constraint (!inst.operands[1].isreg,
13503 _("Thumb encoding does not support an immediate here"));
90ec0d68
MGD
13504
13505 if (inst.operands[0].isreg)
13506 flags = (int)(inst.operands[0].reg);
13507 else
13508 flags = inst.operands[0].imm;
13509
d2cd1205 13510 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
62b3e311 13511 {
d2cd1205
JB
13512 int bits = inst.operands[0].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
13513
1a43faaf 13514 /* PR gas/12698: The constraint is only applied for m_profile.
477330fc
RM
13515 If the user has specified -march=all, we want to ignore it as
13516 we are building for any CPU type, including non-m variants. */
5b7c81bd 13517 bool m_profile =
823d2571 13518 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf 13519 constraint (((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
477330fc
RM
13520 && (bits & ~(PSR_s | PSR_f)) != 0)
13521 || (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
13522 && bits != PSR_f)) && m_profile,
13523 _("selected processor does not support requested special "
13524 "purpose register"));
62b3e311
PB
13525 }
13526 else
d2cd1205
JB
13527 constraint ((flags & 0xff) != 0, _("selected processor does not support "
13528 "requested special purpose register"));
c921be7d 13529
fdfde340
JM
13530 Rn = inst.operands[1].reg;
13531 reject_bad_reg (Rn);
13532
62b3e311 13533 inst.instruction |= (flags & SPSR_BIT) >> 2;
90ec0d68
MGD
13534 inst.instruction |= (flags & 0xf0000) >> 8;
13535 inst.instruction |= (flags & 0x300) >> 4;
62b3e311 13536 inst.instruction |= (flags & 0xff);
fdfde340 13537 inst.instruction |= Rn << 16;
c19d1205 13538}
b05fe5cf 13539
c19d1205
ZW
13540static void
13541do_t_mul (void)
13542{
5b7c81bd 13543 bool narrow;
fdfde340 13544 unsigned Rd, Rn, Rm;
17828f45 13545
c19d1205
ZW
13546 if (!inst.operands[2].present)
13547 inst.operands[2].reg = inst.operands[0].reg;
b05fe5cf 13548
fdfde340
JM
13549 Rd = inst.operands[0].reg;
13550 Rn = inst.operands[1].reg;
13551 Rm = inst.operands[2].reg;
13552
17828f45 13553 if (unified_syntax)
b05fe5cf 13554 {
17828f45 13555 if (inst.size_req == 4
fdfde340
JM
13556 || (Rd != Rn
13557 && Rd != Rm)
13558 || Rn > 7
13559 || Rm > 7)
5b7c81bd 13560 narrow = false;
17828f45 13561 else if (inst.instruction == T_MNEM_muls)
5ee91343 13562 narrow = !in_pred_block ();
17828f45 13563 else
5ee91343 13564 narrow = in_pred_block ();
b05fe5cf 13565 }
c19d1205 13566 else
b05fe5cf 13567 {
17828f45 13568 constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32);
fdfde340 13569 constraint (Rn > 7 || Rm > 7,
c19d1205 13570 BAD_HIREG);
5b7c81bd 13571 narrow = true;
17828f45 13572 }
b05fe5cf 13573
17828f45
JM
13574 if (narrow)
13575 {
13576 /* 16-bit MULS/Conditional MUL. */
c19d1205 13577 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 13578 inst.instruction |= Rd;
b05fe5cf 13579
fdfde340
JM
13580 if (Rd == Rn)
13581 inst.instruction |= Rm << 3;
13582 else if (Rd == Rm)
13583 inst.instruction |= Rn << 3;
c19d1205
ZW
13584 else
13585 constraint (1, _("dest must overlap one source register"));
13586 }
17828f45
JM
13587 else
13588 {
e07e6e58
NC
13589 constraint (inst.instruction != T_MNEM_mul,
13590 _("Thumb-2 MUL must not set flags"));
17828f45
JM
13591 /* 32-bit MUL. */
13592 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13593 inst.instruction |= Rd << 8;
13594 inst.instruction |= Rn << 16;
13595 inst.instruction |= Rm << 0;
13596
13597 reject_bad_reg (Rd);
13598 reject_bad_reg (Rn);
13599 reject_bad_reg (Rm);
17828f45 13600 }
c19d1205 13601}
b05fe5cf 13602
c19d1205
ZW
13603static void
13604do_t_mull (void)
13605{
fdfde340 13606 unsigned RdLo, RdHi, Rn, Rm;
b05fe5cf 13607
fdfde340
JM
13608 RdLo = inst.operands[0].reg;
13609 RdHi = inst.operands[1].reg;
13610 Rn = inst.operands[2].reg;
13611 Rm = inst.operands[3].reg;
13612
13613 reject_bad_reg (RdLo);
13614 reject_bad_reg (RdHi);
13615 reject_bad_reg (Rn);
13616 reject_bad_reg (Rm);
13617
13618 inst.instruction |= RdLo << 12;
13619 inst.instruction |= RdHi << 8;
13620 inst.instruction |= Rn << 16;
13621 inst.instruction |= Rm;
13622
13623 if (RdLo == RdHi)
c19d1205
ZW
13624 as_tsktsk (_("rdhi and rdlo must be different"));
13625}
b05fe5cf 13626
c19d1205
ZW
13627static void
13628do_t_nop (void)
13629{
5ee91343 13630 set_pred_insn_type (NEUTRAL_IT_INSN);
e07e6e58 13631
c19d1205
ZW
13632 if (unified_syntax)
13633 {
13634 if (inst.size_req == 4 || inst.operands[0].imm > 15)
b05fe5cf 13635 {
c19d1205
ZW
13636 inst.instruction = THUMB_OP32 (inst.instruction);
13637 inst.instruction |= inst.operands[0].imm;
13638 }
13639 else
13640 {
bc2d1808
NC
13641 /* PR9722: Check for Thumb2 availability before
13642 generating a thumb2 nop instruction. */
afa62d5e 13643 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
bc2d1808
NC
13644 {
13645 inst.instruction = THUMB_OP16 (inst.instruction);
13646 inst.instruction |= inst.operands[0].imm << 4;
13647 }
13648 else
13649 inst.instruction = 0x46c0;
c19d1205
ZW
13650 }
13651 }
13652 else
13653 {
13654 constraint (inst.operands[0].present,
13655 _("Thumb does not support NOP with hints"));
13656 inst.instruction = 0x46c0;
13657 }
13658}
b05fe5cf 13659
c19d1205
ZW
13660static void
13661do_t_neg (void)
13662{
13663 if (unified_syntax)
13664 {
5b7c81bd 13665 bool narrow;
3d388997
PB
13666
13667 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13668 narrow = !in_pred_block ();
3d388997 13669 else
5ee91343 13670 narrow = in_pred_block ();
3d388997 13671 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
5b7c81bd 13672 narrow = false;
3d388997 13673 if (inst.size_req == 4)
5b7c81bd 13674 narrow = false;
3d388997
PB
13675
13676 if (!narrow)
c19d1205
ZW
13677 {
13678 inst.instruction = THUMB_OP32 (inst.instruction);
13679 inst.instruction |= inst.operands[0].reg << 8;
13680 inst.instruction |= inst.operands[1].reg << 16;
b05fe5cf
ZW
13681 }
13682 else
13683 {
c19d1205
ZW
13684 inst.instruction = THUMB_OP16 (inst.instruction);
13685 inst.instruction |= inst.operands[0].reg;
13686 inst.instruction |= inst.operands[1].reg << 3;
b05fe5cf
ZW
13687 }
13688 }
13689 else
13690 {
c19d1205
ZW
13691 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
13692 BAD_HIREG);
13693 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
13694
13695 inst.instruction = THUMB_OP16 (inst.instruction);
13696 inst.instruction |= inst.operands[0].reg;
13697 inst.instruction |= inst.operands[1].reg << 3;
13698 }
13699}
13700
1c444d06
JM
13701static void
13702do_t_orn (void)
13703{
13704 unsigned Rd, Rn;
13705
13706 Rd = inst.operands[0].reg;
13707 Rn = inst.operands[1].present ? inst.operands[1].reg : Rd;
13708
fdfde340
JM
13709 reject_bad_reg (Rd);
13710 /* Rn == REG_SP is unpredictable; Rn == REG_PC is MVN. */
13711 reject_bad_reg (Rn);
13712
1c444d06
JM
13713 inst.instruction |= Rd << 8;
13714 inst.instruction |= Rn << 16;
13715
13716 if (!inst.operands[2].isreg)
13717 {
13718 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13719 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
1c444d06
JM
13720 }
13721 else
13722 {
13723 unsigned Rm;
13724
13725 Rm = inst.operands[2].reg;
fdfde340 13726 reject_bad_reg (Rm);
1c444d06
JM
13727
13728 constraint (inst.operands[2].shifted
13729 && inst.operands[2].immisreg,
13730 _("shift must be constant"));
13731 encode_thumb32_shifted_operand (2);
13732 }
13733}
13734
c19d1205
ZW
13735static void
13736do_t_pkhbt (void)
13737{
fdfde340
JM
13738 unsigned Rd, Rn, Rm;
13739
13740 Rd = inst.operands[0].reg;
13741 Rn = inst.operands[1].reg;
13742 Rm = inst.operands[2].reg;
13743
13744 reject_bad_reg (Rd);
13745 reject_bad_reg (Rn);
13746 reject_bad_reg (Rm);
13747
13748 inst.instruction |= Rd << 8;
13749 inst.instruction |= Rn << 16;
13750 inst.instruction |= Rm;
c19d1205
ZW
13751 if (inst.operands[3].present)
13752 {
e2b0ab59
AV
13753 unsigned int val = inst.relocs[0].exp.X_add_number;
13754 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
13755 _("expression too complex"));
13756 inst.instruction |= (val & 0x1c) << 10;
13757 inst.instruction |= (val & 0x03) << 6;
b05fe5cf 13758 }
c19d1205 13759}
b05fe5cf 13760
c19d1205
ZW
13761static void
13762do_t_pkhtb (void)
13763{
13764 if (!inst.operands[3].present)
1ef52f49
NC
13765 {
13766 unsigned Rtmp;
13767
13768 inst.instruction &= ~0x00000020;
13769
13770 /* PR 10168. Swap the Rm and Rn registers. */
13771 Rtmp = inst.operands[1].reg;
13772 inst.operands[1].reg = inst.operands[2].reg;
13773 inst.operands[2].reg = Rtmp;
13774 }
c19d1205 13775 do_t_pkhbt ();
b05fe5cf
ZW
13776}
13777
c19d1205
ZW
13778static void
13779do_t_pld (void)
13780{
fdfde340
JM
13781 if (inst.operands[0].immisreg)
13782 reject_bad_reg (inst.operands[0].imm);
13783
5b7c81bd 13784 encode_thumb32_addr_mode (0, /*is_t=*/false, /*is_d=*/false);
c19d1205 13785}
b05fe5cf 13786
c19d1205
ZW
13787static void
13788do_t_push_pop (void)
b99bd4ef 13789{
e9f89963 13790 unsigned mask;
5f4273c7 13791
c19d1205
ZW
13792 constraint (inst.operands[0].writeback,
13793 _("push/pop do not support {reglist}^"));
e2b0ab59 13794 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205 13795 _("expression too complex"));
b99bd4ef 13796
e9f89963 13797 mask = inst.operands[0].imm;
d3bfe16e 13798 if (inst.size_req != 4 && (mask & ~0xff) == 0)
3c707909 13799 inst.instruction = THUMB_OP16 (inst.instruction) | mask;
d3bfe16e 13800 else if (inst.size_req != 4
c6025a80 13801 && (mask & ~0xff) == (1U << (inst.instruction == T_MNEM_push
d3bfe16e 13802 ? REG_LR : REG_PC)))
b99bd4ef 13803 {
c19d1205
ZW
13804 inst.instruction = THUMB_OP16 (inst.instruction);
13805 inst.instruction |= THUMB_PP_PC_LR;
3c707909 13806 inst.instruction |= mask & 0xff;
c19d1205
ZW
13807 }
13808 else if (unified_syntax)
13809 {
3c707909 13810 inst.instruction = THUMB_OP32 (inst.instruction);
5b7c81bd 13811 encode_thumb2_multi (true /* do_io */, 13, mask, true);
4b5a202f
AV
13812 }
13813 else
13814 {
13815 inst.error = _("invalid register list to push/pop instruction");
13816 return;
c19d1205 13817 }
4b5a202f
AV
13818}
13819
13820static void
13821do_t_clrm (void)
13822{
13823 if (unified_syntax)
5b7c81bd 13824 encode_thumb2_multi (false /* do_io */, -1, inst.operands[0].imm, false);
c19d1205
ZW
13825 else
13826 {
13827 inst.error = _("invalid register list to push/pop instruction");
13828 return;
13829 }
c19d1205 13830}
b99bd4ef 13831
efd6b359
AV
13832static void
13833do_t_vscclrm (void)
13834{
13835 if (inst.operands[0].issingle)
13836 {
13837 inst.instruction |= (inst.operands[0].reg & 0x1) << 22;
13838 inst.instruction |= (inst.operands[0].reg & 0x1e) << 11;
13839 inst.instruction |= inst.operands[0].imm;
13840 }
13841 else
13842 {
13843 inst.instruction |= (inst.operands[0].reg & 0x10) << 18;
13844 inst.instruction |= (inst.operands[0].reg & 0xf) << 12;
13845 inst.instruction |= 1 << 8;
13846 inst.instruction |= inst.operands[0].imm << 1;
13847 }
13848}
13849
c19d1205
ZW
13850static void
13851do_t_rbit (void)
13852{
fdfde340
JM
13853 unsigned Rd, Rm;
13854
13855 Rd = inst.operands[0].reg;
13856 Rm = inst.operands[1].reg;
13857
13858 reject_bad_reg (Rd);
13859 reject_bad_reg (Rm);
13860
13861 inst.instruction |= Rd << 8;
13862 inst.instruction |= Rm << 16;
13863 inst.instruction |= Rm;
c19d1205 13864}
b99bd4ef 13865
c19d1205
ZW
13866static void
13867do_t_rev (void)
13868{
fdfde340
JM
13869 unsigned Rd, Rm;
13870
13871 Rd = inst.operands[0].reg;
13872 Rm = inst.operands[1].reg;
13873
13874 reject_bad_reg (Rd);
13875 reject_bad_reg (Rm);
13876
13877 if (Rd <= 7 && Rm <= 7
c19d1205
ZW
13878 && inst.size_req != 4)
13879 {
13880 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13881 inst.instruction |= Rd;
13882 inst.instruction |= Rm << 3;
c19d1205
ZW
13883 }
13884 else if (unified_syntax)
13885 {
13886 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13887 inst.instruction |= Rd << 8;
13888 inst.instruction |= Rm << 16;
13889 inst.instruction |= Rm;
c19d1205
ZW
13890 }
13891 else
13892 inst.error = BAD_HIREG;
13893}
b99bd4ef 13894
1c444d06
JM
13895static void
13896do_t_rrx (void)
13897{
13898 unsigned Rd, Rm;
13899
13900 Rd = inst.operands[0].reg;
13901 Rm = inst.operands[1].reg;
13902
fdfde340
JM
13903 reject_bad_reg (Rd);
13904 reject_bad_reg (Rm);
c921be7d 13905
1c444d06
JM
13906 inst.instruction |= Rd << 8;
13907 inst.instruction |= Rm;
13908}
13909
c19d1205
ZW
13910static void
13911do_t_rsb (void)
13912{
fdfde340 13913 unsigned Rd, Rs;
b99bd4ef 13914
c19d1205
ZW
13915 Rd = inst.operands[0].reg;
13916 Rs = (inst.operands[1].present
13917 ? inst.operands[1].reg /* Rd, Rs, foo */
13918 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
b99bd4ef 13919
fdfde340
JM
13920 reject_bad_reg (Rd);
13921 reject_bad_reg (Rs);
13922 if (inst.operands[2].isreg)
13923 reject_bad_reg (inst.operands[2].reg);
13924
c19d1205
ZW
13925 inst.instruction |= Rd << 8;
13926 inst.instruction |= Rs << 16;
13927 if (!inst.operands[2].isreg)
13928 {
5b7c81bd 13929 bool narrow;
026d3abb
PB
13930
13931 if ((inst.instruction & 0x00100000) != 0)
5ee91343 13932 narrow = !in_pred_block ();
026d3abb 13933 else
5ee91343 13934 narrow = in_pred_block ();
026d3abb
PB
13935
13936 if (Rd > 7 || Rs > 7)
5b7c81bd 13937 narrow = false;
026d3abb
PB
13938
13939 if (inst.size_req == 4 || !unified_syntax)
5b7c81bd 13940 narrow = false;
026d3abb 13941
e2b0ab59
AV
13942 if (inst.relocs[0].exp.X_op != O_constant
13943 || inst.relocs[0].exp.X_add_number != 0)
5b7c81bd 13944 narrow = false;
026d3abb
PB
13945
13946 /* Turn rsb #0 into 16-bit neg. We should probably do this via
477330fc 13947 relaxation, but it doesn't seem worth the hassle. */
026d3abb
PB
13948 if (narrow)
13949 {
e2b0ab59 13950 inst.relocs[0].type = BFD_RELOC_UNUSED;
026d3abb
PB
13951 inst.instruction = THUMB_OP16 (T_MNEM_negs);
13952 inst.instruction |= Rs << 3;
13953 inst.instruction |= Rd;
13954 }
13955 else
13956 {
13957 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13958 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
026d3abb 13959 }
c19d1205
ZW
13960 }
13961 else
13962 encode_thumb32_shifted_operand (2);
13963}
b99bd4ef 13964
c19d1205
ZW
13965static void
13966do_t_setend (void)
13967{
12e37cbc
MGD
13968 if (warn_on_deprecated
13969 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 13970 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 13971
5ee91343 13972 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
13973 if (inst.operands[0].imm)
13974 inst.instruction |= 0x8;
13975}
b99bd4ef 13976
c19d1205
ZW
13977static void
13978do_t_shift (void)
13979{
13980 if (!inst.operands[1].present)
13981 inst.operands[1].reg = inst.operands[0].reg;
13982
13983 if (unified_syntax)
13984 {
5b7c81bd 13985 bool narrow;
3d388997
PB
13986 int shift_kind;
13987
13988 switch (inst.instruction)
13989 {
13990 case T_MNEM_asr:
13991 case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
13992 case T_MNEM_lsl:
13993 case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
13994 case T_MNEM_lsr:
13995 case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
13996 case T_MNEM_ror:
13997 case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
13998 default: abort ();
13999 }
14000
14001 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 14002 narrow = !in_pred_block ();
3d388997 14003 else
5ee91343 14004 narrow = in_pred_block ();
3d388997 14005 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
5b7c81bd 14006 narrow = false;
3d388997 14007 if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
5b7c81bd 14008 narrow = false;
3d388997
PB
14009 if (inst.operands[2].isreg
14010 && (inst.operands[1].reg != inst.operands[0].reg
14011 || inst.operands[2].reg > 7))
5b7c81bd 14012 narrow = false;
3d388997 14013 if (inst.size_req == 4)
5b7c81bd 14014 narrow = false;
3d388997 14015
fdfde340
JM
14016 reject_bad_reg (inst.operands[0].reg);
14017 reject_bad_reg (inst.operands[1].reg);
c921be7d 14018
3d388997 14019 if (!narrow)
c19d1205
ZW
14020 {
14021 if (inst.operands[2].isreg)
b99bd4ef 14022 {
fdfde340 14023 reject_bad_reg (inst.operands[2].reg);
c19d1205
ZW
14024 inst.instruction = THUMB_OP32 (inst.instruction);
14025 inst.instruction |= inst.operands[0].reg << 8;
14026 inst.instruction |= inst.operands[1].reg << 16;
14027 inst.instruction |= inst.operands[2].reg;
94342ec3
NC
14028
14029 /* PR 12854: Error on extraneous shifts. */
14030 constraint (inst.operands[2].shifted,
14031 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
14032 }
14033 else
14034 {
14035 inst.operands[1].shifted = 1;
3d388997 14036 inst.operands[1].shift_kind = shift_kind;
c19d1205
ZW
14037 inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
14038 ? T_MNEM_movs : T_MNEM_mov);
14039 inst.instruction |= inst.operands[0].reg << 8;
14040 encode_thumb32_shifted_operand (1);
14041 /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
e2b0ab59 14042 inst.relocs[0].type = BFD_RELOC_UNUSED;
b99bd4ef
NC
14043 }
14044 }
14045 else
14046 {
c19d1205 14047 if (inst.operands[2].isreg)
b99bd4ef 14048 {
3d388997 14049 switch (shift_kind)
b99bd4ef 14050 {
3d388997
PB
14051 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
14052 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
14053 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
14054 case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
c19d1205 14055 default: abort ();
b99bd4ef 14056 }
5f4273c7 14057
c19d1205
ZW
14058 inst.instruction |= inst.operands[0].reg;
14059 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
14060
14061 /* PR 12854: Error on extraneous shifts. */
14062 constraint (inst.operands[2].shifted,
14063 _("extraneous shift as part of operand to shift insn"));
b99bd4ef
NC
14064 }
14065 else
14066 {
3d388997 14067 switch (shift_kind)
b99bd4ef 14068 {
3d388997
PB
14069 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
14070 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
14071 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
c19d1205 14072 default: abort ();
b99bd4ef 14073 }
e2b0ab59 14074 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
14075 inst.instruction |= inst.operands[0].reg;
14076 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
14077 }
14078 }
c19d1205
ZW
14079 }
14080 else
14081 {
14082 constraint (inst.operands[0].reg > 7
14083 || inst.operands[1].reg > 7, BAD_HIREG);
14084 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
b99bd4ef 14085
c19d1205
ZW
14086 if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
14087 {
14088 constraint (inst.operands[2].reg > 7, BAD_HIREG);
14089 constraint (inst.operands[0].reg != inst.operands[1].reg,
14090 _("source1 and dest must be same register"));
b99bd4ef 14091
c19d1205
ZW
14092 switch (inst.instruction)
14093 {
14094 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
14095 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
14096 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
14097 case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
14098 default: abort ();
14099 }
5f4273c7 14100
c19d1205
ZW
14101 inst.instruction |= inst.operands[0].reg;
14102 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
14103
14104 /* PR 12854: Error on extraneous shifts. */
14105 constraint (inst.operands[2].shifted,
14106 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
14107 }
14108 else
b99bd4ef 14109 {
c19d1205
ZW
14110 switch (inst.instruction)
14111 {
14112 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
14113 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
14114 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
14115 case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
14116 default: abort ();
14117 }
e2b0ab59 14118 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
14119 inst.instruction |= inst.operands[0].reg;
14120 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
14121 }
14122 }
b99bd4ef
NC
14123}
14124
14125static void
c19d1205 14126do_t_simd (void)
b99bd4ef 14127{
fdfde340
JM
14128 unsigned Rd, Rn, Rm;
14129
14130 Rd = inst.operands[0].reg;
14131 Rn = inst.operands[1].reg;
14132 Rm = inst.operands[2].reg;
14133
14134 reject_bad_reg (Rd);
14135 reject_bad_reg (Rn);
14136 reject_bad_reg (Rm);
14137
14138 inst.instruction |= Rd << 8;
14139 inst.instruction |= Rn << 16;
14140 inst.instruction |= Rm;
c19d1205 14141}
b99bd4ef 14142
03ee1b7f
NC
14143static void
14144do_t_simd2 (void)
14145{
14146 unsigned Rd, Rn, Rm;
14147
14148 Rd = inst.operands[0].reg;
14149 Rm = inst.operands[1].reg;
14150 Rn = inst.operands[2].reg;
14151
14152 reject_bad_reg (Rd);
14153 reject_bad_reg (Rn);
14154 reject_bad_reg (Rm);
14155
14156 inst.instruction |= Rd << 8;
14157 inst.instruction |= Rn << 16;
14158 inst.instruction |= Rm;
14159}
14160
c19d1205 14161static void
3eb17e6b 14162do_t_smc (void)
c19d1205 14163{
e2b0ab59 14164 unsigned int value = inst.relocs[0].exp.X_add_number;
f4c65163
MGD
14165 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
14166 _("SMC is not permitted on this architecture"));
e2b0ab59 14167 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 14168 _("expression too complex"));
ba85f98c
BW
14169 constraint (value > 0xf, _("immediate too large (bigger than 0xF)"));
14170
e2b0ab59 14171 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205 14172 inst.instruction |= (value & 0x000f) << 16;
ba85f98c 14173
24382199 14174 /* PR gas/15623: SMC instructions must be last in an IT block. */
5ee91343 14175 set_pred_insn_type_last ();
c19d1205 14176}
b99bd4ef 14177
90ec0d68
MGD
14178static void
14179do_t_hvc (void)
14180{
e2b0ab59 14181 unsigned int value = inst.relocs[0].exp.X_add_number;
90ec0d68 14182
e2b0ab59 14183 inst.relocs[0].type = BFD_RELOC_UNUSED;
90ec0d68
MGD
14184 inst.instruction |= (value & 0x0fff);
14185 inst.instruction |= (value & 0xf000) << 4;
14186}
14187
c19d1205 14188static void
3a21c15a 14189do_t_ssat_usat (int bias)
c19d1205 14190{
fdfde340
JM
14191 unsigned Rd, Rn;
14192
14193 Rd = inst.operands[0].reg;
14194 Rn = inst.operands[2].reg;
14195
14196 reject_bad_reg (Rd);
14197 reject_bad_reg (Rn);
14198
14199 inst.instruction |= Rd << 8;
3a21c15a 14200 inst.instruction |= inst.operands[1].imm - bias;
fdfde340 14201 inst.instruction |= Rn << 16;
b99bd4ef 14202
c19d1205 14203 if (inst.operands[3].present)
b99bd4ef 14204 {
e2b0ab59 14205 offsetT shift_amount = inst.relocs[0].exp.X_add_number;
3a21c15a 14206
e2b0ab59 14207 inst.relocs[0].type = BFD_RELOC_UNUSED;
3a21c15a 14208
e2b0ab59 14209 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 14210 _("expression too complex"));
b99bd4ef 14211
3a21c15a 14212 if (shift_amount != 0)
6189168b 14213 {
3a21c15a
NC
14214 constraint (shift_amount > 31,
14215 _("shift expression is too large"));
14216
c19d1205 14217 if (inst.operands[3].shift_kind == SHIFT_ASR)
3a21c15a
NC
14218 inst.instruction |= 0x00200000; /* sh bit. */
14219
14220 inst.instruction |= (shift_amount & 0x1c) << 10;
14221 inst.instruction |= (shift_amount & 0x03) << 6;
6189168b
NC
14222 }
14223 }
b99bd4ef 14224}
c921be7d 14225
3a21c15a
NC
14226static void
14227do_t_ssat (void)
14228{
14229 do_t_ssat_usat (1);
14230}
b99bd4ef 14231
0dd132b6 14232static void
c19d1205 14233do_t_ssat16 (void)
0dd132b6 14234{
fdfde340
JM
14235 unsigned Rd, Rn;
14236
14237 Rd = inst.operands[0].reg;
14238 Rn = inst.operands[2].reg;
14239
14240 reject_bad_reg (Rd);
14241 reject_bad_reg (Rn);
14242
14243 inst.instruction |= Rd << 8;
c19d1205 14244 inst.instruction |= inst.operands[1].imm - 1;
fdfde340 14245 inst.instruction |= Rn << 16;
c19d1205 14246}
0dd132b6 14247
c19d1205
ZW
14248static void
14249do_t_strex (void)
14250{
14251 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
14252 || inst.operands[2].postind || inst.operands[2].writeback
14253 || inst.operands[2].immisreg || inst.operands[2].shifted
14254 || inst.operands[2].negative,
01cfc07f 14255 BAD_ADDR_MODE);
0dd132b6 14256
5be8be5d
DG
14257 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
14258
c19d1205
ZW
14259 inst.instruction |= inst.operands[0].reg << 8;
14260 inst.instruction |= inst.operands[1].reg << 12;
14261 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 14262 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
0dd132b6
NC
14263}
14264
b99bd4ef 14265static void
c19d1205 14266do_t_strexd (void)
b99bd4ef 14267{
c19d1205
ZW
14268 if (!inst.operands[2].present)
14269 inst.operands[2].reg = inst.operands[1].reg + 1;
b99bd4ef 14270
c19d1205
ZW
14271 constraint (inst.operands[0].reg == inst.operands[1].reg
14272 || inst.operands[0].reg == inst.operands[2].reg
f8a8e9d6 14273 || inst.operands[0].reg == inst.operands[3].reg,
c19d1205 14274 BAD_OVERLAP);
b99bd4ef 14275
c19d1205
ZW
14276 inst.instruction |= inst.operands[0].reg;
14277 inst.instruction |= inst.operands[1].reg << 12;
14278 inst.instruction |= inst.operands[2].reg << 8;
14279 inst.instruction |= inst.operands[3].reg << 16;
b99bd4ef
NC
14280}
14281
14282static void
c19d1205 14283do_t_sxtah (void)
b99bd4ef 14284{
fdfde340
JM
14285 unsigned Rd, Rn, Rm;
14286
14287 Rd = inst.operands[0].reg;
14288 Rn = inst.operands[1].reg;
14289 Rm = inst.operands[2].reg;
14290
14291 reject_bad_reg (Rd);
14292 reject_bad_reg (Rn);
14293 reject_bad_reg (Rm);
14294
14295 inst.instruction |= Rd << 8;
14296 inst.instruction |= Rn << 16;
14297 inst.instruction |= Rm;
c19d1205
ZW
14298 inst.instruction |= inst.operands[3].imm << 4;
14299}
b99bd4ef 14300
c19d1205
ZW
14301static void
14302do_t_sxth (void)
14303{
fdfde340
JM
14304 unsigned Rd, Rm;
14305
14306 Rd = inst.operands[0].reg;
14307 Rm = inst.operands[1].reg;
14308
14309 reject_bad_reg (Rd);
14310 reject_bad_reg (Rm);
c921be7d
NC
14311
14312 if (inst.instruction <= 0xffff
14313 && inst.size_req != 4
fdfde340 14314 && Rd <= 7 && Rm <= 7
c19d1205 14315 && (!inst.operands[2].present || inst.operands[2].imm == 0))
b99bd4ef 14316 {
c19d1205 14317 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
14318 inst.instruction |= Rd;
14319 inst.instruction |= Rm << 3;
b99bd4ef 14320 }
c19d1205 14321 else if (unified_syntax)
b99bd4ef 14322 {
c19d1205
ZW
14323 if (inst.instruction <= 0xffff)
14324 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
14325 inst.instruction |= Rd << 8;
14326 inst.instruction |= Rm;
c19d1205 14327 inst.instruction |= inst.operands[2].imm << 4;
b99bd4ef 14328 }
c19d1205 14329 else
b99bd4ef 14330 {
c19d1205
ZW
14331 constraint (inst.operands[2].present && inst.operands[2].imm != 0,
14332 _("Thumb encoding does not support rotation"));
14333 constraint (1, BAD_HIREG);
b99bd4ef 14334 }
c19d1205 14335}
b99bd4ef 14336
c19d1205
ZW
14337static void
14338do_t_swi (void)
14339{
e2b0ab59 14340 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
c19d1205 14341}
b99bd4ef 14342
92e90b6e
PB
14343static void
14344do_t_tb (void)
14345{
fdfde340 14346 unsigned Rn, Rm;
92e90b6e
PB
14347 int half;
14348
14349 half = (inst.instruction & 0x10) != 0;
5ee91343 14350 set_pred_insn_type_last ();
dfa9f0d5
PB
14351 constraint (inst.operands[0].immisreg,
14352 _("instruction requires register index"));
fdfde340
JM
14353
14354 Rn = inst.operands[0].reg;
14355 Rm = inst.operands[0].imm;
c921be7d 14356
5c8ed6a4
JW
14357 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
14358 constraint (Rn == REG_SP, BAD_SP);
fdfde340
JM
14359 reject_bad_reg (Rm);
14360
92e90b6e
PB
14361 constraint (!half && inst.operands[0].shifted,
14362 _("instruction does not allow shifted index"));
fdfde340 14363 inst.instruction |= (Rn << 16) | Rm;
92e90b6e
PB
14364}
14365
74db7efb
NC
14366static void
14367do_t_udf (void)
14368{
14369 if (!inst.operands[0].present)
14370 inst.operands[0].imm = 0;
14371
14372 if ((unsigned int) inst.operands[0].imm > 255 || inst.size_req == 4)
14373 {
14374 constraint (inst.size_req == 2,
14375 _("immediate value out of range"));
14376 inst.instruction = THUMB_OP32 (inst.instruction);
14377 inst.instruction |= (inst.operands[0].imm & 0xf000u) << 4;
14378 inst.instruction |= (inst.operands[0].imm & 0x0fffu) << 0;
14379 }
14380 else
14381 {
14382 inst.instruction = THUMB_OP16 (inst.instruction);
14383 inst.instruction |= inst.operands[0].imm;
14384 }
14385
5ee91343 14386 set_pred_insn_type (NEUTRAL_IT_INSN);
74db7efb
NC
14387}
14388
14389
c19d1205
ZW
14390static void
14391do_t_usat (void)
14392{
3a21c15a 14393 do_t_ssat_usat (0);
b99bd4ef
NC
14394}
14395
14396static void
c19d1205 14397do_t_usat16 (void)
b99bd4ef 14398{
fdfde340
JM
14399 unsigned Rd, Rn;
14400
14401 Rd = inst.operands[0].reg;
14402 Rn = inst.operands[2].reg;
14403
14404 reject_bad_reg (Rd);
14405 reject_bad_reg (Rn);
14406
14407 inst.instruction |= Rd << 8;
c19d1205 14408 inst.instruction |= inst.operands[1].imm;
fdfde340 14409 inst.instruction |= Rn << 16;
b99bd4ef 14410}
c19d1205 14411
e12437dc
AV
14412/* Checking the range of the branch offset (VAL) with NBITS bits
14413 and IS_SIGNED signedness. Also checks the LSB to be 0. */
14414static int
14415v8_1_branch_value_check (int val, int nbits, int is_signed)
14416{
14417 gas_assert (nbits > 0 && nbits <= 32);
14418 if (is_signed)
14419 {
14420 int cmp = (1 << (nbits - 1));
14421 if ((val < -cmp) || (val >= cmp) || (val & 0x01))
14422 return FAIL;
14423 }
14424 else
14425 {
14426 if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
14427 return FAIL;
14428 }
14429 return SUCCESS;
14430}
14431
4389b29a
AV
14432/* For branches in Armv8.1-M Mainline. */
14433static void
14434do_t_branch_future (void)
14435{
14436 unsigned long insn = inst.instruction;
14437
14438 inst.instruction = THUMB_OP32 (inst.instruction);
14439 if (inst.operands[0].hasreloc == 0)
14440 {
5b7c81bd 14441 if (v8_1_branch_value_check (inst.operands[0].imm, 5, false) == FAIL)
4389b29a
AV
14442 as_bad (BAD_BRANCH_OFF);
14443
14444 inst.instruction |= ((inst.operands[0].imm & 0x1f) >> 1) << 23;
14445 }
14446 else
14447 {
14448 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH5;
14449 inst.relocs[0].pc_rel = 1;
14450 }
14451
14452 switch (insn)
14453 {
14454 case T_MNEM_bf:
14455 if (inst.operands[1].hasreloc == 0)
14456 {
14457 int val = inst.operands[1].imm;
5b7c81bd 14458 if (v8_1_branch_value_check (inst.operands[1].imm, 17, true) == FAIL)
4389b29a
AV
14459 as_bad (BAD_BRANCH_OFF);
14460
14461 int immA = (val & 0x0001f000) >> 12;
14462 int immB = (val & 0x00000ffc) >> 2;
14463 int immC = (val & 0x00000002) >> 1;
14464 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14465 }
14466 else
14467 {
14468 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF17;
14469 inst.relocs[1].pc_rel = 1;
14470 }
14471 break;
14472
65d1bc05
AV
14473 case T_MNEM_bfl:
14474 if (inst.operands[1].hasreloc == 0)
14475 {
14476 int val = inst.operands[1].imm;
5b7c81bd 14477 if (v8_1_branch_value_check (inst.operands[1].imm, 19, true) == FAIL)
65d1bc05
AV
14478 as_bad (BAD_BRANCH_OFF);
14479
14480 int immA = (val & 0x0007f000) >> 12;
14481 int immB = (val & 0x00000ffc) >> 2;
14482 int immC = (val & 0x00000002) >> 1;
14483 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14484 }
14485 else
14486 {
14487 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
14488 inst.relocs[1].pc_rel = 1;
14489 }
14490 break;
14491
f6b2b12d
AV
14492 case T_MNEM_bfcsel:
14493 /* Operand 1. */
14494 if (inst.operands[1].hasreloc == 0)
14495 {
14496 int val = inst.operands[1].imm;
14497 int immA = (val & 0x00001000) >> 12;
14498 int immB = (val & 0x00000ffc) >> 2;
14499 int immC = (val & 0x00000002) >> 1;
14500 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14501 }
14502 else
14503 {
14504 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF13;
14505 inst.relocs[1].pc_rel = 1;
14506 }
14507
14508 /* Operand 2. */
14509 if (inst.operands[2].hasreloc == 0)
14510 {
14511 constraint ((inst.operands[0].hasreloc != 0), BAD_ARGS);
14512 int val2 = inst.operands[2].imm;
14513 int val0 = inst.operands[0].imm & 0x1f;
14514 int diff = val2 - val0;
14515 if (diff == 4)
14516 inst.instruction |= 1 << 17; /* T bit. */
14517 else if (diff != 2)
14518 as_bad (_("out of range label-relative fixup value"));
14519 }
14520 else
14521 {
14522 constraint ((inst.operands[0].hasreloc == 0), BAD_ARGS);
14523 inst.relocs[2].type = BFD_RELOC_THUMB_PCREL_BFCSEL;
14524 inst.relocs[2].pc_rel = 1;
14525 }
14526
14527 /* Operand 3. */
14528 constraint (inst.cond != COND_ALWAYS, BAD_COND);
14529 inst.instruction |= (inst.operands[3].imm & 0xf) << 18;
14530 break;
14531
f1c7f421
AV
14532 case T_MNEM_bfx:
14533 case T_MNEM_bflx:
14534 inst.instruction |= inst.operands[1].reg << 16;
14535 break;
14536
4389b29a
AV
14537 default: abort ();
14538 }
14539}
14540
60f993ce
AV
14541/* Helper function for do_t_loloop to handle relocations. */
14542static void
14543v8_1_loop_reloc (int is_le)
14544{
14545 if (inst.relocs[0].exp.X_op == O_constant)
14546 {
14547 int value = inst.relocs[0].exp.X_add_number;
14548 value = (is_le) ? -value : value;
14549
5b7c81bd 14550 if (v8_1_branch_value_check (value, 12, false) == FAIL)
60f993ce
AV
14551 as_bad (BAD_BRANCH_OFF);
14552
14553 int imml, immh;
14554
14555 immh = (value & 0x00000ffc) >> 2;
14556 imml = (value & 0x00000002) >> 1;
14557
14558 inst.instruction |= (imml << 11) | (immh << 1);
14559 }
14560 else
14561 {
14562 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_LOOP12;
14563 inst.relocs[0].pc_rel = 1;
14564 }
14565}
14566
08132bdd
SP
14567/* For shifts with four operands in MVE. */
14568static void
14569do_mve_scalar_shift1 (void)
14570{
14571 unsigned int value = inst.operands[2].imm;
14572
14573 inst.instruction |= inst.operands[0].reg << 16;
14574 inst.instruction |= inst.operands[1].reg << 8;
14575
14576 /* Setting the bit for saturation. */
14577 inst.instruction |= ((value == 64) ? 0: 1) << 7;
14578
14579 /* Assuming Rm is already checked not to be 11x1. */
14580 constraint (inst.operands[3].reg == inst.operands[0].reg, BAD_OVERLAP);
14581 constraint (inst.operands[3].reg == inst.operands[1].reg, BAD_OVERLAP);
14582 inst.instruction |= inst.operands[3].reg << 12;
14583}
14584
23d00a41
SD
14585/* For shifts in MVE. */
14586static void
14587do_mve_scalar_shift (void)
14588{
14589 if (!inst.operands[2].present)
14590 {
14591 inst.operands[2] = inst.operands[1];
14592 inst.operands[1].reg = 0xf;
14593 }
14594
14595 inst.instruction |= inst.operands[0].reg << 16;
14596 inst.instruction |= inst.operands[1].reg << 8;
14597
14598 if (inst.operands[2].isreg)
14599 {
14600 /* Assuming Rm is already checked not to be 11x1. */
14601 constraint (inst.operands[2].reg == inst.operands[0].reg, BAD_OVERLAP);
14602 constraint (inst.operands[2].reg == inst.operands[1].reg, BAD_OVERLAP);
14603 inst.instruction |= inst.operands[2].reg << 12;
14604 }
14605 else
14606 {
14607 /* Assuming imm is already checked as [1,32]. */
14608 unsigned int value = inst.operands[2].imm;
14609 inst.instruction |= (value & 0x1c) << 10;
14610 inst.instruction |= (value & 0x03) << 6;
14611 /* Change last 4 bits from 0xd to 0xf. */
14612 inst.instruction |= 0x2;
14613 }
14614}
14615
a302e574
AV
14616/* MVE instruction encoder helpers. */
14617#define M_MNEM_vabav 0xee800f01
14618#define M_MNEM_vmladav 0xeef00e00
14619#define M_MNEM_vmladava 0xeef00e20
14620#define M_MNEM_vmladavx 0xeef01e00
14621#define M_MNEM_vmladavax 0xeef01e20
14622#define M_MNEM_vmlsdav 0xeef00e01
14623#define M_MNEM_vmlsdava 0xeef00e21
14624#define M_MNEM_vmlsdavx 0xeef01e01
14625#define M_MNEM_vmlsdavax 0xeef01e21
886e1c73
AV
14626#define M_MNEM_vmullt 0xee011e00
14627#define M_MNEM_vmullb 0xee010e00
efd0b310 14628#define M_MNEM_vctp 0xf000e801
35c228db
AV
14629#define M_MNEM_vst20 0xfc801e00
14630#define M_MNEM_vst21 0xfc801e20
14631#define M_MNEM_vst40 0xfc801e01
14632#define M_MNEM_vst41 0xfc801e21
14633#define M_MNEM_vst42 0xfc801e41
14634#define M_MNEM_vst43 0xfc801e61
14635#define M_MNEM_vld20 0xfc901e00
14636#define M_MNEM_vld21 0xfc901e20
14637#define M_MNEM_vld40 0xfc901e01
14638#define M_MNEM_vld41 0xfc901e21
14639#define M_MNEM_vld42 0xfc901e41
14640#define M_MNEM_vld43 0xfc901e61
f5f10c66
AV
14641#define M_MNEM_vstrb 0xec000e00
14642#define M_MNEM_vstrh 0xec000e10
14643#define M_MNEM_vstrw 0xec000e40
14644#define M_MNEM_vstrd 0xec000e50
14645#define M_MNEM_vldrb 0xec100e00
14646#define M_MNEM_vldrh 0xec100e10
14647#define M_MNEM_vldrw 0xec100e40
14648#define M_MNEM_vldrd 0xec100e50
57785aa2
AV
14649#define M_MNEM_vmovlt 0xeea01f40
14650#define M_MNEM_vmovlb 0xeea00f40
14651#define M_MNEM_vmovnt 0xfe311e81
14652#define M_MNEM_vmovnb 0xfe310e81
c2dafc2a
AV
14653#define M_MNEM_vadc 0xee300f00
14654#define M_MNEM_vadci 0xee301f00
14655#define M_MNEM_vbrsr 0xfe011e60
26c1e780
AV
14656#define M_MNEM_vaddlv 0xee890f00
14657#define M_MNEM_vaddlva 0xee890f20
14658#define M_MNEM_vaddv 0xeef10f00
14659#define M_MNEM_vaddva 0xeef10f20
b409bdb6
AV
14660#define M_MNEM_vddup 0xee011f6e
14661#define M_MNEM_vdwdup 0xee011f60
14662#define M_MNEM_vidup 0xee010f6e
14663#define M_MNEM_viwdup 0xee010f60
13ccd4c0
AV
14664#define M_MNEM_vmaxv 0xeee20f00
14665#define M_MNEM_vmaxav 0xeee00f00
14666#define M_MNEM_vminv 0xeee20f80
14667#define M_MNEM_vminav 0xeee00f80
93925576
AV
14668#define M_MNEM_vmlaldav 0xee800e00
14669#define M_MNEM_vmlaldava 0xee800e20
14670#define M_MNEM_vmlaldavx 0xee801e00
14671#define M_MNEM_vmlaldavax 0xee801e20
14672#define M_MNEM_vmlsldav 0xee800e01
14673#define M_MNEM_vmlsldava 0xee800e21
14674#define M_MNEM_vmlsldavx 0xee801e01
14675#define M_MNEM_vmlsldavax 0xee801e21
14676#define M_MNEM_vrmlaldavhx 0xee801f00
14677#define M_MNEM_vrmlaldavhax 0xee801f20
14678#define M_MNEM_vrmlsldavh 0xfe800e01
14679#define M_MNEM_vrmlsldavha 0xfe800e21
14680#define M_MNEM_vrmlsldavhx 0xfe801e01
14681#define M_MNEM_vrmlsldavhax 0xfe801e21
1be7aba3
AV
14682#define M_MNEM_vqmovnt 0xee331e01
14683#define M_MNEM_vqmovnb 0xee330e01
14684#define M_MNEM_vqmovunt 0xee311e81
14685#define M_MNEM_vqmovunb 0xee310e81
4aa88b50
AV
14686#define M_MNEM_vshrnt 0xee801fc1
14687#define M_MNEM_vshrnb 0xee800fc1
14688#define M_MNEM_vrshrnt 0xfe801fc1
14689#define M_MNEM_vqshrnt 0xee801f40
14690#define M_MNEM_vqshrnb 0xee800f40
14691#define M_MNEM_vqshrunt 0xee801fc0
14692#define M_MNEM_vqshrunb 0xee800fc0
14693#define M_MNEM_vrshrnb 0xfe800fc1
14694#define M_MNEM_vqrshrnt 0xee801f41
14695#define M_MNEM_vqrshrnb 0xee800f41
14696#define M_MNEM_vqrshrunt 0xfe801fc0
14697#define M_MNEM_vqrshrunb 0xfe800fc0
a302e574 14698
aab2c27d
MM
14699/* Bfloat16 instruction encoder helpers. */
14700#define B_MNEM_vfmat 0xfc300850
14701#define B_MNEM_vfmab 0xfc300810
14702
5287ad62 14703/* Neon instruction encoder helpers. */
5f4273c7 14704
5287ad62 14705/* Encodings for the different types for various Neon opcodes. */
b99bd4ef 14706
5287ad62
JB
14707/* An "invalid" code for the following tables. */
14708#define N_INV -1u
14709
14710struct neon_tab_entry
b99bd4ef 14711{
5287ad62
JB
14712 unsigned integer;
14713 unsigned float_or_poly;
14714 unsigned scalar_or_imm;
14715};
5f4273c7 14716
5287ad62
JB
14717/* Map overloaded Neon opcodes to their respective encodings. */
14718#define NEON_ENC_TAB \
14719 X(vabd, 0x0000700, 0x1200d00, N_INV), \
5ee91343 14720 X(vabdl, 0x0800700, N_INV, N_INV), \
5287ad62
JB
14721 X(vmax, 0x0000600, 0x0000f00, N_INV), \
14722 X(vmin, 0x0000610, 0x0200f00, N_INV), \
14723 X(vpadd, 0x0000b10, 0x1000d00, N_INV), \
14724 X(vpmax, 0x0000a00, 0x1000f00, N_INV), \
14725 X(vpmin, 0x0000a10, 0x1200f00, N_INV), \
14726 X(vadd, 0x0000800, 0x0000d00, N_INV), \
5ee91343 14727 X(vaddl, 0x0800000, N_INV, N_INV), \
5287ad62 14728 X(vsub, 0x1000800, 0x0200d00, N_INV), \
5ee91343 14729 X(vsubl, 0x0800200, N_INV, N_INV), \
5287ad62
JB
14730 X(vceq, 0x1000810, 0x0000e00, 0x1b10100), \
14731 X(vcge, 0x0000310, 0x1000e00, 0x1b10080), \
14732 X(vcgt, 0x0000300, 0x1200e00, 0x1b10000), \
14733 /* Register variants of the following two instructions are encoded as
e07e6e58 14734 vcge / vcgt with the operands reversed. */ \
92559b5b
PB
14735 X(vclt, 0x0000300, 0x1200e00, 0x1b10200), \
14736 X(vcle, 0x0000310, 0x1000e00, 0x1b10180), \
62f3b8c8
PB
14737 X(vfma, N_INV, 0x0000c10, N_INV), \
14738 X(vfms, N_INV, 0x0200c10, N_INV), \
5287ad62
JB
14739 X(vmla, 0x0000900, 0x0000d10, 0x0800040), \
14740 X(vmls, 0x1000900, 0x0200d10, 0x0800440), \
14741 X(vmul, 0x0000910, 0x1000d10, 0x0800840), \
14742 X(vmull, 0x0800c00, 0x0800e00, 0x0800a40), /* polynomial not float. */ \
14743 X(vmlal, 0x0800800, N_INV, 0x0800240), \
14744 X(vmlsl, 0x0800a00, N_INV, 0x0800640), \
14745 X(vqdmlal, 0x0800900, N_INV, 0x0800340), \
14746 X(vqdmlsl, 0x0800b00, N_INV, 0x0800740), \
14747 X(vqdmull, 0x0800d00, N_INV, 0x0800b40), \
14748 X(vqdmulh, 0x0000b00, N_INV, 0x0800c40), \
14749 X(vqrdmulh, 0x1000b00, N_INV, 0x0800d40), \
d6b4b13e
MW
14750 X(vqrdmlah, 0x3000b10, N_INV, 0x0800e40), \
14751 X(vqrdmlsh, 0x3000c10, N_INV, 0x0800f40), \
5287ad62
JB
14752 X(vshl, 0x0000400, N_INV, 0x0800510), \
14753 X(vqshl, 0x0000410, N_INV, 0x0800710), \
14754 X(vand, 0x0000110, N_INV, 0x0800030), \
14755 X(vbic, 0x0100110, N_INV, 0x0800030), \
14756 X(veor, 0x1000110, N_INV, N_INV), \
14757 X(vorn, 0x0300110, N_INV, 0x0800010), \
14758 X(vorr, 0x0200110, N_INV, 0x0800010), \
14759 X(vmvn, 0x1b00580, N_INV, 0x0800030), \
14760 X(vshll, 0x1b20300, N_INV, 0x0800a10), /* max shift, immediate. */ \
14761 X(vcvt, 0x1b30600, N_INV, 0x0800e10), /* integer, fixed-point. */ \
14762 X(vdup, 0xe800b10, N_INV, 0x1b00c00), /* arm, scalar. */ \
14763 X(vld1, 0x0200000, 0x0a00000, 0x0a00c00), /* interlv, lane, dup. */ \
14764 X(vst1, 0x0000000, 0x0800000, N_INV), \
14765 X(vld2, 0x0200100, 0x0a00100, 0x0a00d00), \
14766 X(vst2, 0x0000100, 0x0800100, N_INV), \
14767 X(vld3, 0x0200200, 0x0a00200, 0x0a00e00), \
14768 X(vst3, 0x0000200, 0x0800200, N_INV), \
14769 X(vld4, 0x0200300, 0x0a00300, 0x0a00f00), \
14770 X(vst4, 0x0000300, 0x0800300, N_INV), \
14771 X(vmovn, 0x1b20200, N_INV, N_INV), \
14772 X(vtrn, 0x1b20080, N_INV, N_INV), \
14773 X(vqmovn, 0x1b20200, N_INV, N_INV), \
037e8744
JB
14774 X(vqmovun, 0x1b20240, N_INV, N_INV), \
14775 X(vnmul, 0xe200a40, 0xe200b40, N_INV), \
e6655fda
PB
14776 X(vnmla, 0xe100a40, 0xe100b40, N_INV), \
14777 X(vnmls, 0xe100a00, 0xe100b00, N_INV), \
62f3b8c8
PB
14778 X(vfnma, 0xe900a40, 0xe900b40, N_INV), \
14779 X(vfnms, 0xe900a00, 0xe900b00, N_INV), \
037e8744
JB
14780 X(vcmp, 0xeb40a40, 0xeb40b40, N_INV), \
14781 X(vcmpz, 0xeb50a40, 0xeb50b40, N_INV), \
14782 X(vcmpe, 0xeb40ac0, 0xeb40bc0, N_INV), \
33399f07
MGD
14783 X(vcmpez, 0xeb50ac0, 0xeb50bc0, N_INV), \
14784 X(vseleq, 0xe000a00, N_INV, N_INV), \
14785 X(vselvs, 0xe100a00, N_INV, N_INV), \
14786 X(vselge, 0xe200a00, N_INV, N_INV), \
73924fbc
MGD
14787 X(vselgt, 0xe300a00, N_INV, N_INV), \
14788 X(vmaxnm, 0xe800a00, 0x3000f10, N_INV), \
7e8e6784 14789 X(vminnm, 0xe800a40, 0x3200f10, N_INV), \
30bdf752
MGD
14790 X(vcvta, 0xebc0a40, 0x3bb0000, N_INV), \
14791 X(vrintr, 0xeb60a40, 0x3ba0400, N_INV), \
91ff7894 14792 X(vrinta, 0xeb80a40, 0x3ba0400, N_INV), \
48adcd8e 14793 X(aes, 0x3b00300, N_INV, N_INV), \
3c9017d2
MGD
14794 X(sha3op, 0x2000c00, N_INV, N_INV), \
14795 X(sha1h, 0x3b902c0, N_INV, N_INV), \
14796 X(sha2op, 0x3ba0380, N_INV, N_INV)
5287ad62
JB
14797
14798enum neon_opc
14799{
14800#define X(OPC,I,F,S) N_MNEM_##OPC
14801NEON_ENC_TAB
14802#undef X
14803};
b99bd4ef 14804
5287ad62
JB
14805static const struct neon_tab_entry neon_enc_tab[] =
14806{
14807#define X(OPC,I,F,S) { (I), (F), (S) }
14808NEON_ENC_TAB
14809#undef X
14810};
b99bd4ef 14811
88714cb8
DG
14812/* Do not use these macros; instead, use NEON_ENCODE defined below. */
14813#define NEON_ENC_INTEGER_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14814#define NEON_ENC_ARMREG_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14815#define NEON_ENC_POLY_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14816#define NEON_ENC_FLOAT_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14817#define NEON_ENC_SCALAR_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14818#define NEON_ENC_IMMED_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14819#define NEON_ENC_INTERLV_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14820#define NEON_ENC_LANE_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14821#define NEON_ENC_DUP_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14822#define NEON_ENC_SINGLE_(X) \
037e8744 14823 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf0000000))
88714cb8 14824#define NEON_ENC_DOUBLE_(X) \
037e8744 14825 ((neon_enc_tab[(X) & 0x0fffffff].float_or_poly) | ((X) & 0xf0000000))
33399f07
MGD
14826#define NEON_ENC_FPV8_(X) \
14827 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf000000))
5287ad62 14828
88714cb8
DG
14829#define NEON_ENCODE(type, inst) \
14830 do \
14831 { \
14832 inst.instruction = NEON_ENC_##type##_ (inst.instruction); \
14833 inst.is_neon = 1; \
14834 } \
14835 while (0)
14836
14837#define check_neon_suffixes \
14838 do \
14839 { \
14840 if (!inst.error && inst.vectype.elems > 0 && !inst.is_neon) \
14841 { \
14842 as_bad (_("invalid neon suffix for non neon instruction")); \
14843 return; \
14844 } \
14845 } \
14846 while (0)
14847
037e8744
JB
14848/* Define shapes for instruction operands. The following mnemonic characters
14849 are used in this table:
5287ad62 14850
037e8744 14851 F - VFP S<n> register
5287ad62
JB
14852 D - Neon D<n> register
14853 Q - Neon Q<n> register
14854 I - Immediate
14855 S - Scalar
14856 R - ARM register
14857 L - D<n> register list
5f4273c7 14858
037e8744
JB
14859 This table is used to generate various data:
14860 - enumerations of the form NS_DDR to be used as arguments to
14861 neon_select_shape.
14862 - a table classifying shapes into single, double, quad, mixed.
5f4273c7 14863 - a table used to drive neon_select_shape. */
b99bd4ef 14864
037e8744 14865#define NEON_SHAPE_DEF \
93925576 14866 X(4, (R, R, Q, Q), QUAD), \
b409bdb6 14867 X(4, (Q, R, R, I), QUAD), \
57785aa2
AV
14868 X(4, (R, R, S, S), QUAD), \
14869 X(4, (S, S, R, R), QUAD), \
b409bdb6 14870 X(3, (Q, R, I), QUAD), \
1b883319
AV
14871 X(3, (I, Q, Q), QUAD), \
14872 X(3, (I, Q, R), QUAD), \
a302e574 14873 X(3, (R, Q, Q), QUAD), \
037e8744
JB
14874 X(3, (D, D, D), DOUBLE), \
14875 X(3, (Q, Q, Q), QUAD), \
14876 X(3, (D, D, I), DOUBLE), \
14877 X(3, (Q, Q, I), QUAD), \
14878 X(3, (D, D, S), DOUBLE), \
14879 X(3, (Q, Q, S), QUAD), \
5ee91343 14880 X(3, (Q, Q, R), QUAD), \
26c1e780
AV
14881 X(3, (R, R, Q), QUAD), \
14882 X(2, (R, Q), QUAD), \
037e8744
JB
14883 X(2, (D, D), DOUBLE), \
14884 X(2, (Q, Q), QUAD), \
14885 X(2, (D, S), DOUBLE), \
14886 X(2, (Q, S), QUAD), \
14887 X(2, (D, R), DOUBLE), \
14888 X(2, (Q, R), QUAD), \
14889 X(2, (D, I), DOUBLE), \
14890 X(2, (Q, I), QUAD), \
5aae9ae9
MM
14891 X(3, (P, F, I), SINGLE), \
14892 X(3, (P, D, I), DOUBLE), \
14893 X(3, (P, Q, I), QUAD), \
14894 X(4, (P, F, F, I), SINGLE), \
14895 X(4, (P, D, D, I), DOUBLE), \
14896 X(4, (P, Q, Q, I), QUAD), \
14897 X(5, (P, F, F, F, I), SINGLE), \
14898 X(5, (P, D, D, D, I), DOUBLE), \
14899 X(5, (P, Q, Q, Q, I), QUAD), \
037e8744
JB
14900 X(3, (D, L, D), DOUBLE), \
14901 X(2, (D, Q), MIXED), \
14902 X(2, (Q, D), MIXED), \
14903 X(3, (D, Q, I), MIXED), \
14904 X(3, (Q, D, I), MIXED), \
14905 X(3, (Q, D, D), MIXED), \
14906 X(3, (D, Q, Q), MIXED), \
14907 X(3, (Q, Q, D), MIXED), \
14908 X(3, (Q, D, S), MIXED), \
14909 X(3, (D, Q, S), MIXED), \
14910 X(4, (D, D, D, I), DOUBLE), \
14911 X(4, (Q, Q, Q, I), QUAD), \
c28eeff2
SN
14912 X(4, (D, D, S, I), DOUBLE), \
14913 X(4, (Q, Q, S, I), QUAD), \
037e8744
JB
14914 X(2, (F, F), SINGLE), \
14915 X(3, (F, F, F), SINGLE), \
14916 X(2, (F, I), SINGLE), \
14917 X(2, (F, D), MIXED), \
14918 X(2, (D, F), MIXED), \
14919 X(3, (F, F, I), MIXED), \
14920 X(4, (R, R, F, F), SINGLE), \
14921 X(4, (F, F, R, R), SINGLE), \
14922 X(3, (D, R, R), DOUBLE), \
14923 X(3, (R, R, D), DOUBLE), \
14924 X(2, (S, R), SINGLE), \
14925 X(2, (R, S), SINGLE), \
14926 X(2, (F, R), SINGLE), \
d54af2d0 14927 X(2, (R, F), SINGLE), \
1f6234a3
AV
14928/* Used for MVE tail predicated loop instructions. */\
14929 X(2, (R, R), QUAD), \
d54af2d0
RL
14930/* Half float shape supported so far. */\
14931 X (2, (H, D), MIXED), \
14932 X (2, (D, H), MIXED), \
14933 X (2, (H, F), MIXED), \
14934 X (2, (F, H), MIXED), \
14935 X (2, (H, H), HALF), \
14936 X (2, (H, R), HALF), \
14937 X (2, (R, H), HALF), \
14938 X (2, (H, I), HALF), \
14939 X (3, (H, H, H), HALF), \
14940 X (3, (H, F, I), MIXED), \
dec41383
JW
14941 X (3, (F, H, I), MIXED), \
14942 X (3, (D, H, H), MIXED), \
14943 X (3, (D, H, S), MIXED)
037e8744
JB
14944
14945#define S2(A,B) NS_##A##B
14946#define S3(A,B,C) NS_##A##B##C
14947#define S4(A,B,C,D) NS_##A##B##C##D
5aae9ae9 14948#define S5(A,B,C,D,E) NS_##A##B##C##D##E
037e8744
JB
14949
14950#define X(N, L, C) S##N L
14951
5287ad62
JB
14952enum neon_shape
14953{
037e8744
JB
14954 NEON_SHAPE_DEF,
14955 NS_NULL
5287ad62 14956};
b99bd4ef 14957
037e8744
JB
14958#undef X
14959#undef S2
14960#undef S3
14961#undef S4
5aae9ae9 14962#undef S5
037e8744
JB
14963
14964enum neon_shape_class
14965{
d54af2d0 14966 SC_HALF,
037e8744
JB
14967 SC_SINGLE,
14968 SC_DOUBLE,
14969 SC_QUAD,
14970 SC_MIXED
14971};
14972
14973#define X(N, L, C) SC_##C
14974
14975static enum neon_shape_class neon_shape_class[] =
14976{
14977 NEON_SHAPE_DEF
14978};
14979
14980#undef X
14981
14982enum neon_shape_el
14983{
d54af2d0 14984 SE_H,
037e8744
JB
14985 SE_F,
14986 SE_D,
14987 SE_Q,
14988 SE_I,
14989 SE_S,
14990 SE_R,
5aae9ae9
MM
14991 SE_L,
14992 SE_P
037e8744
JB
14993};
14994
14995/* Register widths of above. */
14996static unsigned neon_shape_el_size[] =
14997{
d54af2d0 14998 16,
037e8744
JB
14999 32,
15000 64,
15001 128,
15002 0,
15003 32,
15004 32,
5aae9ae9 15005 0,
037e8744
JB
15006 0
15007};
15008
15009struct neon_shape_info
15010{
15011 unsigned els;
15012 enum neon_shape_el el[NEON_MAX_TYPE_ELS];
15013};
15014
15015#define S2(A,B) { SE_##A, SE_##B }
15016#define S3(A,B,C) { SE_##A, SE_##B, SE_##C }
15017#define S4(A,B,C,D) { SE_##A, SE_##B, SE_##C, SE_##D }
5aae9ae9 15018#define S5(A,B,C,D,E) { SE_##A, SE_##B, SE_##C, SE_##D, SE_##E }
037e8744
JB
15019
15020#define X(N, L, C) { N, S##N L }
15021
15022static struct neon_shape_info neon_shape_tab[] =
15023{
15024 NEON_SHAPE_DEF
15025};
15026
15027#undef X
15028#undef S2
15029#undef S3
15030#undef S4
5aae9ae9 15031#undef S5
037e8744 15032
5287ad62
JB
15033/* Bit masks used in type checking given instructions.
15034 'N_EQK' means the type must be the same as (or based on in some way) the key
15035 type, which itself is marked with the 'N_KEY' bit. If the 'N_EQK' bit is
15036 set, various other bits can be set as well in order to modify the meaning of
15037 the type constraint. */
15038
15039enum neon_type_mask
15040{
8e79c3df
CM
15041 N_S8 = 0x0000001,
15042 N_S16 = 0x0000002,
15043 N_S32 = 0x0000004,
15044 N_S64 = 0x0000008,
15045 N_U8 = 0x0000010,
15046 N_U16 = 0x0000020,
15047 N_U32 = 0x0000040,
15048 N_U64 = 0x0000080,
15049 N_I8 = 0x0000100,
15050 N_I16 = 0x0000200,
15051 N_I32 = 0x0000400,
15052 N_I64 = 0x0000800,
15053 N_8 = 0x0001000,
15054 N_16 = 0x0002000,
15055 N_32 = 0x0004000,
15056 N_64 = 0x0008000,
15057 N_P8 = 0x0010000,
15058 N_P16 = 0x0020000,
15059 N_F16 = 0x0040000,
15060 N_F32 = 0x0080000,
15061 N_F64 = 0x0100000,
4f51b4bd 15062 N_P64 = 0x0200000,
aab2c27d 15063 N_BF16 = 0x0400000,
c921be7d
NC
15064 N_KEY = 0x1000000, /* Key element (main type specifier). */
15065 N_EQK = 0x2000000, /* Given operand has the same type & size as the key. */
8e79c3df 15066 N_VFP = 0x4000000, /* VFP mode: operand size must match register width. */
91ff7894 15067 N_UNT = 0x8000000, /* Must be explicitly untyped. */
c921be7d
NC
15068 N_DBL = 0x0000001, /* If N_EQK, this operand is twice the size. */
15069 N_HLF = 0x0000002, /* If N_EQK, this operand is half the size. */
15070 N_SGN = 0x0000004, /* If N_EQK, this operand is forced to be signed. */
15071 N_UNS = 0x0000008, /* If N_EQK, this operand is forced to be unsigned. */
15072 N_INT = 0x0000010, /* If N_EQK, this operand is forced to be integer. */
15073 N_FLT = 0x0000020, /* If N_EQK, this operand is forced to be float. */
15074 N_SIZ = 0x0000040, /* If N_EQK, this operand is forced to be size-only. */
5287ad62 15075 N_UTYP = 0,
4f51b4bd 15076 N_MAX_NONSPECIAL = N_P64
5287ad62
JB
15077};
15078
dcbf9037
JB
15079#define N_ALLMODS (N_DBL | N_HLF | N_SGN | N_UNS | N_INT | N_FLT | N_SIZ)
15080
5287ad62
JB
15081#define N_SU_ALL (N_S8 | N_S16 | N_S32 | N_S64 | N_U8 | N_U16 | N_U32 | N_U64)
15082#define N_SU_32 (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
15083#define N_SU_16_64 (N_S16 | N_S32 | N_S64 | N_U16 | N_U32 | N_U64)
cc933301
JW
15084#define N_S_32 (N_S8 | N_S16 | N_S32)
15085#define N_F_16_32 (N_F16 | N_F32)
15086#define N_SUF_32 (N_SU_32 | N_F_16_32)
5287ad62 15087#define N_I_ALL (N_I8 | N_I16 | N_I32 | N_I64)
cc933301 15088#define N_IF_32 (N_I8 | N_I16 | N_I32 | N_F16 | N_F32)
d54af2d0 15089#define N_F_ALL (N_F16 | N_F32 | N_F64)
5ee91343
AV
15090#define N_I_MVE (N_I8 | N_I16 | N_I32)
15091#define N_F_MVE (N_F16 | N_F32)
15092#define N_SU_MVE (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
5287ad62
JB
15093
15094/* Pass this as the first type argument to neon_check_type to ignore types
15095 altogether. */
15096#define N_IGNORE_TYPE (N_KEY | N_EQK)
15097
037e8744
JB
15098/* Select a "shape" for the current instruction (describing register types or
15099 sizes) from a list of alternatives. Return NS_NULL if the current instruction
15100 doesn't fit. For non-polymorphic shapes, checking is usually done as a
15101 function of operand parsing, so this function doesn't need to be called.
15102 Shapes should be listed in order of decreasing length. */
5287ad62
JB
15103
15104static enum neon_shape
037e8744 15105neon_select_shape (enum neon_shape shape, ...)
5287ad62 15106{
037e8744
JB
15107 va_list ap;
15108 enum neon_shape first_shape = shape;
5287ad62
JB
15109
15110 /* Fix missing optional operands. FIXME: we don't know at this point how
15111 many arguments we should have, so this makes the assumption that we have
15112 > 1. This is true of all current Neon opcodes, I think, but may not be
15113 true in the future. */
15114 if (!inst.operands[1].present)
15115 inst.operands[1] = inst.operands[0];
15116
037e8744 15117 va_start (ap, shape);
5f4273c7 15118
21d799b5 15119 for (; shape != NS_NULL; shape = (enum neon_shape) va_arg (ap, int))
037e8744
JB
15120 {
15121 unsigned j;
15122 int matches = 1;
15123
15124 for (j = 0; j < neon_shape_tab[shape].els; j++)
477330fc
RM
15125 {
15126 if (!inst.operands[j].present)
15127 {
15128 matches = 0;
15129 break;
15130 }
15131
15132 switch (neon_shape_tab[shape].el[j])
15133 {
d54af2d0
RL
15134 /* If a .f16, .16, .u16, .s16 type specifier is given over
15135 a VFP single precision register operand, it's essentially
15136 means only half of the register is used.
15137
15138 If the type specifier is given after the mnemonics, the
15139 information is stored in inst.vectype. If the type specifier
15140 is given after register operand, the information is stored
15141 in inst.operands[].vectype.
15142
15143 When there is only one type specifier, and all the register
15144 operands are the same type of hardware register, the type
15145 specifier applies to all register operands.
15146
15147 If no type specifier is given, the shape is inferred from
15148 operand information.
15149
15150 for example:
15151 vadd.f16 s0, s1, s2: NS_HHH
15152 vabs.f16 s0, s1: NS_HH
15153 vmov.f16 s0, r1: NS_HR
15154 vmov.f16 r0, s1: NS_RH
15155 vcvt.f16 r0, s1: NS_RH
15156 vcvt.f16.s32 s2, s2, #29: NS_HFI
15157 vcvt.f16.s32 s2, s2: NS_HF
15158 */
15159 case SE_H:
15160 if (!(inst.operands[j].isreg
15161 && inst.operands[j].isvec
15162 && inst.operands[j].issingle
15163 && !inst.operands[j].isquad
15164 && ((inst.vectype.elems == 1
15165 && inst.vectype.el[0].size == 16)
15166 || (inst.vectype.elems > 1
15167 && inst.vectype.el[j].size == 16)
15168 || (inst.vectype.elems == 0
15169 && inst.operands[j].vectype.type != NT_invtype
15170 && inst.operands[j].vectype.size == 16))))
15171 matches = 0;
15172 break;
15173
477330fc
RM
15174 case SE_F:
15175 if (!(inst.operands[j].isreg
15176 && inst.operands[j].isvec
15177 && inst.operands[j].issingle
d54af2d0
RL
15178 && !inst.operands[j].isquad
15179 && ((inst.vectype.elems == 1 && inst.vectype.el[0].size == 32)
15180 || (inst.vectype.elems > 1 && inst.vectype.el[j].size == 32)
15181 || (inst.vectype.elems == 0
15182 && (inst.operands[j].vectype.size == 32
15183 || inst.operands[j].vectype.type == NT_invtype)))))
477330fc
RM
15184 matches = 0;
15185 break;
15186
15187 case SE_D:
15188 if (!(inst.operands[j].isreg
15189 && inst.operands[j].isvec
15190 && !inst.operands[j].isquad
15191 && !inst.operands[j].issingle))
15192 matches = 0;
15193 break;
15194
15195 case SE_R:
15196 if (!(inst.operands[j].isreg
15197 && !inst.operands[j].isvec))
15198 matches = 0;
15199 break;
15200
15201 case SE_Q:
15202 if (!(inst.operands[j].isreg
15203 && inst.operands[j].isvec
15204 && inst.operands[j].isquad
15205 && !inst.operands[j].issingle))
15206 matches = 0;
15207 break;
15208
15209 case SE_I:
15210 if (!(!inst.operands[j].isreg
15211 && !inst.operands[j].isscalar))
15212 matches = 0;
15213 break;
15214
15215 case SE_S:
15216 if (!(!inst.operands[j].isreg
15217 && inst.operands[j].isscalar))
15218 matches = 0;
15219 break;
15220
5aae9ae9 15221 case SE_P:
477330fc
RM
15222 case SE_L:
15223 break;
15224 }
3fde54a2
JZ
15225 if (!matches)
15226 break;
477330fc 15227 }
ad6cec43
MGD
15228 if (matches && (j >= ARM_IT_MAX_OPERANDS || !inst.operands[j].present))
15229 /* We've matched all the entries in the shape table, and we don't
15230 have any left over operands which have not been matched. */
477330fc 15231 break;
037e8744 15232 }
5f4273c7 15233
037e8744 15234 va_end (ap);
5287ad62 15235
037e8744
JB
15236 if (shape == NS_NULL && first_shape != NS_NULL)
15237 first_error (_("invalid instruction shape"));
5287ad62 15238
037e8744
JB
15239 return shape;
15240}
5287ad62 15241
037e8744
JB
15242/* True if SHAPE is predominantly a quadword operation (most of the time, this
15243 means the Q bit should be set). */
15244
15245static int
15246neon_quad (enum neon_shape shape)
15247{
15248 return neon_shape_class[shape] == SC_QUAD;
5287ad62 15249}
037e8744 15250
5287ad62
JB
15251static void
15252neon_modify_type_size (unsigned typebits, enum neon_el_type *g_type,
477330fc 15253 unsigned *g_size)
5287ad62
JB
15254{
15255 /* Allow modification to be made to types which are constrained to be
15256 based on the key element, based on bits set alongside N_EQK. */
15257 if ((typebits & N_EQK) != 0)
15258 {
15259 if ((typebits & N_HLF) != 0)
15260 *g_size /= 2;
15261 else if ((typebits & N_DBL) != 0)
15262 *g_size *= 2;
15263 if ((typebits & N_SGN) != 0)
15264 *g_type = NT_signed;
15265 else if ((typebits & N_UNS) != 0)
477330fc 15266 *g_type = NT_unsigned;
5287ad62 15267 else if ((typebits & N_INT) != 0)
477330fc 15268 *g_type = NT_integer;
5287ad62 15269 else if ((typebits & N_FLT) != 0)
477330fc 15270 *g_type = NT_float;
dcbf9037 15271 else if ((typebits & N_SIZ) != 0)
477330fc 15272 *g_type = NT_untyped;
5287ad62
JB
15273 }
15274}
5f4273c7 15275
5287ad62
JB
15276/* Return operand OPNO promoted by bits set in THISARG. KEY should be the "key"
15277 operand type, i.e. the single type specified in a Neon instruction when it
15278 is the only one given. */
15279
15280static struct neon_type_el
15281neon_type_promote (struct neon_type_el *key, unsigned thisarg)
15282{
15283 struct neon_type_el dest = *key;
5f4273c7 15284
9c2799c2 15285 gas_assert ((thisarg & N_EQK) != 0);
5f4273c7 15286
5287ad62
JB
15287 neon_modify_type_size (thisarg, &dest.type, &dest.size);
15288
15289 return dest;
15290}
15291
15292/* Convert Neon type and size into compact bitmask representation. */
15293
15294static enum neon_type_mask
15295type_chk_of_el_type (enum neon_el_type type, unsigned size)
15296{
15297 switch (type)
15298 {
15299 case NT_untyped:
15300 switch (size)
477330fc
RM
15301 {
15302 case 8: return N_8;
15303 case 16: return N_16;
15304 case 32: return N_32;
15305 case 64: return N_64;
15306 default: ;
15307 }
5287ad62
JB
15308 break;
15309
15310 case NT_integer:
15311 switch (size)
477330fc
RM
15312 {
15313 case 8: return N_I8;
15314 case 16: return N_I16;
15315 case 32: return N_I32;
15316 case 64: return N_I64;
15317 default: ;
15318 }
5287ad62
JB
15319 break;
15320
15321 case NT_float:
037e8744 15322 switch (size)
477330fc 15323 {
8e79c3df 15324 case 16: return N_F16;
477330fc
RM
15325 case 32: return N_F32;
15326 case 64: return N_F64;
15327 default: ;
15328 }
5287ad62
JB
15329 break;
15330
15331 case NT_poly:
15332 switch (size)
477330fc
RM
15333 {
15334 case 8: return N_P8;
15335 case 16: return N_P16;
4f51b4bd 15336 case 64: return N_P64;
477330fc
RM
15337 default: ;
15338 }
5287ad62
JB
15339 break;
15340
15341 case NT_signed:
15342 switch (size)
477330fc
RM
15343 {
15344 case 8: return N_S8;
15345 case 16: return N_S16;
15346 case 32: return N_S32;
15347 case 64: return N_S64;
15348 default: ;
15349 }
5287ad62
JB
15350 break;
15351
15352 case NT_unsigned:
15353 switch (size)
477330fc
RM
15354 {
15355 case 8: return N_U8;
15356 case 16: return N_U16;
15357 case 32: return N_U32;
15358 case 64: return N_U64;
15359 default: ;
15360 }
5287ad62
JB
15361 break;
15362
aab2c27d
MM
15363 case NT_bfloat:
15364 if (size == 16) return N_BF16;
15365 break;
15366
5287ad62
JB
15367 default: ;
15368 }
5f4273c7 15369
5287ad62
JB
15370 return N_UTYP;
15371}
15372
15373/* Convert compact Neon bitmask type representation to a type and size. Only
15374 handles the case where a single bit is set in the mask. */
15375
dcbf9037 15376static int
5287ad62 15377el_type_of_type_chk (enum neon_el_type *type, unsigned *size,
477330fc 15378 enum neon_type_mask mask)
5287ad62 15379{
dcbf9037
JB
15380 if ((mask & N_EQK) != 0)
15381 return FAIL;
15382
5287ad62
JB
15383 if ((mask & (N_S8 | N_U8 | N_I8 | N_8 | N_P8)) != 0)
15384 *size = 8;
aab2c27d
MM
15385 else if ((mask & (N_S16 | N_U16 | N_I16 | N_16 | N_F16 | N_P16 | N_BF16))
15386 != 0)
5287ad62 15387 *size = 16;
dcbf9037 15388 else if ((mask & (N_S32 | N_U32 | N_I32 | N_32 | N_F32)) != 0)
5287ad62 15389 *size = 32;
4f51b4bd 15390 else if ((mask & (N_S64 | N_U64 | N_I64 | N_64 | N_F64 | N_P64)) != 0)
5287ad62 15391 *size = 64;
dcbf9037
JB
15392 else
15393 return FAIL;
15394
5287ad62
JB
15395 if ((mask & (N_S8 | N_S16 | N_S32 | N_S64)) != 0)
15396 *type = NT_signed;
dcbf9037 15397 else if ((mask & (N_U8 | N_U16 | N_U32 | N_U64)) != 0)
5287ad62 15398 *type = NT_unsigned;
dcbf9037 15399 else if ((mask & (N_I8 | N_I16 | N_I32 | N_I64)) != 0)
5287ad62 15400 *type = NT_integer;
dcbf9037 15401 else if ((mask & (N_8 | N_16 | N_32 | N_64)) != 0)
5287ad62 15402 *type = NT_untyped;
4f51b4bd 15403 else if ((mask & (N_P8 | N_P16 | N_P64)) != 0)
5287ad62 15404 *type = NT_poly;
d54af2d0 15405 else if ((mask & (N_F_ALL)) != 0)
5287ad62 15406 *type = NT_float;
aab2c27d
MM
15407 else if ((mask & (N_BF16)) != 0)
15408 *type = NT_bfloat;
dcbf9037
JB
15409 else
15410 return FAIL;
5f4273c7 15411
dcbf9037 15412 return SUCCESS;
5287ad62
JB
15413}
15414
15415/* Modify a bitmask of allowed types. This is only needed for type
15416 relaxation. */
15417
15418static unsigned
15419modify_types_allowed (unsigned allowed, unsigned mods)
15420{
15421 unsigned size;
15422 enum neon_el_type type;
15423 unsigned destmask;
15424 int i;
5f4273c7 15425
5287ad62 15426 destmask = 0;
5f4273c7 15427
5287ad62
JB
15428 for (i = 1; i <= N_MAX_NONSPECIAL; i <<= 1)
15429 {
21d799b5 15430 if (el_type_of_type_chk (&type, &size,
477330fc
RM
15431 (enum neon_type_mask) (allowed & i)) == SUCCESS)
15432 {
15433 neon_modify_type_size (mods, &type, &size);
15434 destmask |= type_chk_of_el_type (type, size);
15435 }
5287ad62 15436 }
5f4273c7 15437
5287ad62
JB
15438 return destmask;
15439}
15440
15441/* Check type and return type classification.
15442 The manual states (paraphrase): If one datatype is given, it indicates the
15443 type given in:
15444 - the second operand, if there is one
15445 - the operand, if there is no second operand
15446 - the result, if there are no operands.
15447 This isn't quite good enough though, so we use a concept of a "key" datatype
15448 which is set on a per-instruction basis, which is the one which matters when
15449 only one data type is written.
15450 Note: this function has side-effects (e.g. filling in missing operands). All
037e8744 15451 Neon instructions should call it before performing bit encoding. */
5287ad62
JB
15452
15453static struct neon_type_el
15454neon_check_type (unsigned els, enum neon_shape ns, ...)
15455{
15456 va_list ap;
15457 unsigned i, pass, key_el = 0;
15458 unsigned types[NEON_MAX_TYPE_ELS];
15459 enum neon_el_type k_type = NT_invtype;
15460 unsigned k_size = -1u;
15461 struct neon_type_el badtype = {NT_invtype, -1};
15462 unsigned key_allowed = 0;
15463
15464 /* Optional registers in Neon instructions are always (not) in operand 1.
15465 Fill in the missing operand here, if it was omitted. */
15466 if (els > 1 && !inst.operands[1].present)
15467 inst.operands[1] = inst.operands[0];
15468
15469 /* Suck up all the varargs. */
15470 va_start (ap, ns);
15471 for (i = 0; i < els; i++)
15472 {
15473 unsigned thisarg = va_arg (ap, unsigned);
15474 if (thisarg == N_IGNORE_TYPE)
477330fc
RM
15475 {
15476 va_end (ap);
15477 return badtype;
15478 }
5287ad62
JB
15479 types[i] = thisarg;
15480 if ((thisarg & N_KEY) != 0)
477330fc 15481 key_el = i;
5287ad62
JB
15482 }
15483 va_end (ap);
15484
dcbf9037
JB
15485 if (inst.vectype.elems > 0)
15486 for (i = 0; i < els; i++)
15487 if (inst.operands[i].vectype.type != NT_invtype)
477330fc
RM
15488 {
15489 first_error (_("types specified in both the mnemonic and operands"));
15490 return badtype;
15491 }
dcbf9037 15492
5287ad62
JB
15493 /* Duplicate inst.vectype elements here as necessary.
15494 FIXME: No idea if this is exactly the same as the ARM assembler,
15495 particularly when an insn takes one register and one non-register
15496 operand. */
15497 if (inst.vectype.elems == 1 && els > 1)
15498 {
15499 unsigned j;
15500 inst.vectype.elems = els;
15501 inst.vectype.el[key_el] = inst.vectype.el[0];
15502 for (j = 0; j < els; j++)
477330fc
RM
15503 if (j != key_el)
15504 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
15505 types[j]);
dcbf9037
JB
15506 }
15507 else if (inst.vectype.elems == 0 && els > 0)
15508 {
15509 unsigned j;
15510 /* No types were given after the mnemonic, so look for types specified
477330fc
RM
15511 after each operand. We allow some flexibility here; as long as the
15512 "key" operand has a type, we can infer the others. */
dcbf9037 15513 for (j = 0; j < els; j++)
477330fc
RM
15514 if (inst.operands[j].vectype.type != NT_invtype)
15515 inst.vectype.el[j] = inst.operands[j].vectype;
dcbf9037
JB
15516
15517 if (inst.operands[key_el].vectype.type != NT_invtype)
477330fc
RM
15518 {
15519 for (j = 0; j < els; j++)
15520 if (inst.operands[j].vectype.type == NT_invtype)
15521 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
15522 types[j]);
15523 }
dcbf9037 15524 else
477330fc
RM
15525 {
15526 first_error (_("operand types can't be inferred"));
15527 return badtype;
15528 }
5287ad62
JB
15529 }
15530 else if (inst.vectype.elems != els)
15531 {
dcbf9037 15532 first_error (_("type specifier has the wrong number of parts"));
5287ad62
JB
15533 return badtype;
15534 }
15535
15536 for (pass = 0; pass < 2; pass++)
15537 {
15538 for (i = 0; i < els; i++)
477330fc
RM
15539 {
15540 unsigned thisarg = types[i];
15541 unsigned types_allowed = ((thisarg & N_EQK) != 0 && pass != 0)
15542 ? modify_types_allowed (key_allowed, thisarg) : thisarg;
15543 enum neon_el_type g_type = inst.vectype.el[i].type;
15544 unsigned g_size = inst.vectype.el[i].size;
15545
15546 /* Decay more-specific signed & unsigned types to sign-insensitive
5287ad62 15547 integer types if sign-specific variants are unavailable. */
477330fc 15548 if ((g_type == NT_signed || g_type == NT_unsigned)
5287ad62
JB
15549 && (types_allowed & N_SU_ALL) == 0)
15550 g_type = NT_integer;
15551
477330fc 15552 /* If only untyped args are allowed, decay any more specific types to
5287ad62
JB
15553 them. Some instructions only care about signs for some element
15554 sizes, so handle that properly. */
477330fc 15555 if (((types_allowed & N_UNT) == 0)
91ff7894
MGD
15556 && ((g_size == 8 && (types_allowed & N_8) != 0)
15557 || (g_size == 16 && (types_allowed & N_16) != 0)
15558 || (g_size == 32 && (types_allowed & N_32) != 0)
15559 || (g_size == 64 && (types_allowed & N_64) != 0)))
5287ad62
JB
15560 g_type = NT_untyped;
15561
477330fc
RM
15562 if (pass == 0)
15563 {
15564 if ((thisarg & N_KEY) != 0)
15565 {
15566 k_type = g_type;
15567 k_size = g_size;
15568 key_allowed = thisarg & ~N_KEY;
cc933301
JW
15569
15570 /* Check architecture constraint on FP16 extension. */
15571 if (k_size == 16
15572 && k_type == NT_float
15573 && ! ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15574 {
15575 inst.error = _(BAD_FP16);
15576 return badtype;
15577 }
477330fc
RM
15578 }
15579 }
15580 else
15581 {
15582 if ((thisarg & N_VFP) != 0)
15583 {
15584 enum neon_shape_el regshape;
15585 unsigned regwidth, match;
99b253c5
NC
15586
15587 /* PR 11136: Catch the case where we are passed a shape of NS_NULL. */
15588 if (ns == NS_NULL)
15589 {
15590 first_error (_("invalid instruction shape"));
15591 return badtype;
15592 }
477330fc
RM
15593 regshape = neon_shape_tab[ns].el[i];
15594 regwidth = neon_shape_el_size[regshape];
15595
15596 /* In VFP mode, operands must match register widths. If we
15597 have a key operand, use its width, else use the width of
15598 the current operand. */
15599 if (k_size != -1u)
15600 match = k_size;
15601 else
15602 match = g_size;
15603
9db2f6b4
RL
15604 /* FP16 will use a single precision register. */
15605 if (regwidth == 32 && match == 16)
15606 {
15607 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15608 match = regwidth;
15609 else
15610 {
15611 inst.error = _(BAD_FP16);
15612 return badtype;
15613 }
15614 }
15615
477330fc
RM
15616 if (regwidth != match)
15617 {
15618 first_error (_("operand size must match register width"));
15619 return badtype;
15620 }
15621 }
15622
15623 if ((thisarg & N_EQK) == 0)
15624 {
15625 unsigned given_type = type_chk_of_el_type (g_type, g_size);
15626
15627 if ((given_type & types_allowed) == 0)
15628 {
a302e574 15629 first_error (BAD_SIMD_TYPE);
477330fc
RM
15630 return badtype;
15631 }
15632 }
15633 else
15634 {
15635 enum neon_el_type mod_k_type = k_type;
15636 unsigned mod_k_size = k_size;
15637 neon_modify_type_size (thisarg, &mod_k_type, &mod_k_size);
15638 if (g_type != mod_k_type || g_size != mod_k_size)
15639 {
15640 first_error (_("inconsistent types in Neon instruction"));
15641 return badtype;
15642 }
15643 }
15644 }
15645 }
5287ad62
JB
15646 }
15647
15648 return inst.vectype.el[key_el];
15649}
15650
037e8744 15651/* Neon-style VFP instruction forwarding. */
5287ad62 15652
037e8744
JB
15653/* Thumb VFP instructions have 0xE in the condition field. */
15654
15655static void
15656do_vfp_cond_or_thumb (void)
5287ad62 15657{
88714cb8
DG
15658 inst.is_neon = 1;
15659
5287ad62 15660 if (thumb_mode)
037e8744 15661 inst.instruction |= 0xe0000000;
5287ad62 15662 else
037e8744 15663 inst.instruction |= inst.cond << 28;
5287ad62
JB
15664}
15665
037e8744
JB
15666/* Look up and encode a simple mnemonic, for use as a helper function for the
15667 Neon-style VFP syntax. This avoids duplication of bits of the insns table,
15668 etc. It is assumed that operand parsing has already been done, and that the
15669 operands are in the form expected by the given opcode (this isn't necessarily
15670 the same as the form in which they were parsed, hence some massaging must
15671 take place before this function is called).
15672 Checks current arch version against that in the looked-up opcode. */
5287ad62 15673
037e8744
JB
15674static void
15675do_vfp_nsyn_opcode (const char *opname)
5287ad62 15676{
037e8744 15677 const struct asm_opcode *opcode;
5f4273c7 15678
629310ab 15679 opcode = (const struct asm_opcode *) str_hash_find (arm_ops_hsh, opname);
5287ad62 15680
037e8744
JB
15681 if (!opcode)
15682 abort ();
5287ad62 15683
037e8744 15684 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant,
477330fc
RM
15685 thumb_mode ? *opcode->tvariant : *opcode->avariant),
15686 _(BAD_FPU));
5287ad62 15687
88714cb8
DG
15688 inst.is_neon = 1;
15689
037e8744
JB
15690 if (thumb_mode)
15691 {
15692 inst.instruction = opcode->tvalue;
15693 opcode->tencode ();
15694 }
15695 else
15696 {
15697 inst.instruction = (inst.cond << 28) | opcode->avalue;
15698 opcode->aencode ();
15699 }
15700}
5287ad62
JB
15701
15702static void
037e8744 15703do_vfp_nsyn_add_sub (enum neon_shape rs)
5287ad62 15704{
037e8744
JB
15705 int is_add = (inst.instruction & 0x0fffffff) == N_MNEM_vadd;
15706
9db2f6b4 15707 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15708 {
15709 if (is_add)
477330fc 15710 do_vfp_nsyn_opcode ("fadds");
037e8744 15711 else
477330fc 15712 do_vfp_nsyn_opcode ("fsubs");
9db2f6b4
RL
15713
15714 /* ARMv8.2 fp16 instruction. */
15715 if (rs == NS_HHH)
15716 do_scalar_fp16_v82_encode ();
037e8744
JB
15717 }
15718 else
15719 {
15720 if (is_add)
477330fc 15721 do_vfp_nsyn_opcode ("faddd");
037e8744 15722 else
477330fc 15723 do_vfp_nsyn_opcode ("fsubd");
037e8744
JB
15724 }
15725}
15726
15727/* Check operand types to see if this is a VFP instruction, and if so call
15728 PFN (). */
15729
15730static int
15731try_vfp_nsyn (int args, void (*pfn) (enum neon_shape))
15732{
15733 enum neon_shape rs;
15734 struct neon_type_el et;
15735
15736 switch (args)
15737 {
15738 case 2:
9db2f6b4
RL
15739 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15740 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
037e8744 15741 break;
5f4273c7 15742
037e8744 15743 case 3:
9db2f6b4
RL
15744 rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
15745 et = neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
15746 N_F_ALL | N_KEY | N_VFP);
037e8744
JB
15747 break;
15748
15749 default:
15750 abort ();
15751 }
15752
15753 if (et.type != NT_invtype)
15754 {
15755 pfn (rs);
15756 return SUCCESS;
15757 }
037e8744 15758
99b253c5 15759 inst.error = NULL;
037e8744
JB
15760 return FAIL;
15761}
15762
15763static void
15764do_vfp_nsyn_mla_mls (enum neon_shape rs)
15765{
15766 int is_mla = (inst.instruction & 0x0fffffff) == N_MNEM_vmla;
5f4273c7 15767
9db2f6b4 15768 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15769 {
15770 if (is_mla)
477330fc 15771 do_vfp_nsyn_opcode ("fmacs");
037e8744 15772 else
477330fc 15773 do_vfp_nsyn_opcode ("fnmacs");
9db2f6b4
RL
15774
15775 /* ARMv8.2 fp16 instruction. */
15776 if (rs == NS_HHH)
15777 do_scalar_fp16_v82_encode ();
037e8744
JB
15778 }
15779 else
15780 {
15781 if (is_mla)
477330fc 15782 do_vfp_nsyn_opcode ("fmacd");
037e8744 15783 else
477330fc 15784 do_vfp_nsyn_opcode ("fnmacd");
037e8744
JB
15785 }
15786}
15787
62f3b8c8
PB
15788static void
15789do_vfp_nsyn_fma_fms (enum neon_shape rs)
15790{
15791 int is_fma = (inst.instruction & 0x0fffffff) == N_MNEM_vfma;
15792
9db2f6b4 15793 if (rs == NS_FFF || rs == NS_HHH)
62f3b8c8
PB
15794 {
15795 if (is_fma)
477330fc 15796 do_vfp_nsyn_opcode ("ffmas");
62f3b8c8 15797 else
477330fc 15798 do_vfp_nsyn_opcode ("ffnmas");
9db2f6b4
RL
15799
15800 /* ARMv8.2 fp16 instruction. */
15801 if (rs == NS_HHH)
15802 do_scalar_fp16_v82_encode ();
62f3b8c8
PB
15803 }
15804 else
15805 {
15806 if (is_fma)
477330fc 15807 do_vfp_nsyn_opcode ("ffmad");
62f3b8c8 15808 else
477330fc 15809 do_vfp_nsyn_opcode ("ffnmad");
62f3b8c8
PB
15810 }
15811}
15812
037e8744
JB
15813static void
15814do_vfp_nsyn_mul (enum neon_shape rs)
15815{
9db2f6b4
RL
15816 if (rs == NS_FFF || rs == NS_HHH)
15817 {
15818 do_vfp_nsyn_opcode ("fmuls");
15819
15820 /* ARMv8.2 fp16 instruction. */
15821 if (rs == NS_HHH)
15822 do_scalar_fp16_v82_encode ();
15823 }
037e8744
JB
15824 else
15825 do_vfp_nsyn_opcode ("fmuld");
15826}
15827
15828static void
15829do_vfp_nsyn_abs_neg (enum neon_shape rs)
15830{
15831 int is_neg = (inst.instruction & 0x80) != 0;
9db2f6b4 15832 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_VFP | N_KEY);
037e8744 15833
9db2f6b4 15834 if (rs == NS_FF || rs == NS_HH)
037e8744
JB
15835 {
15836 if (is_neg)
477330fc 15837 do_vfp_nsyn_opcode ("fnegs");
037e8744 15838 else
477330fc 15839 do_vfp_nsyn_opcode ("fabss");
9db2f6b4
RL
15840
15841 /* ARMv8.2 fp16 instruction. */
15842 if (rs == NS_HH)
15843 do_scalar_fp16_v82_encode ();
037e8744
JB
15844 }
15845 else
15846 {
15847 if (is_neg)
477330fc 15848 do_vfp_nsyn_opcode ("fnegd");
037e8744 15849 else
477330fc 15850 do_vfp_nsyn_opcode ("fabsd");
037e8744
JB
15851 }
15852}
15853
15854/* Encode single-precision (only!) VFP fldm/fstm instructions. Double precision
15855 insns belong to Neon, and are handled elsewhere. */
15856
15857static void
15858do_vfp_nsyn_ldm_stm (int is_dbmode)
15859{
15860 int is_ldm = (inst.instruction & (1 << 20)) != 0;
15861 if (is_ldm)
15862 {
15863 if (is_dbmode)
477330fc 15864 do_vfp_nsyn_opcode ("fldmdbs");
037e8744 15865 else
477330fc 15866 do_vfp_nsyn_opcode ("fldmias");
037e8744
JB
15867 }
15868 else
15869 {
15870 if (is_dbmode)
477330fc 15871 do_vfp_nsyn_opcode ("fstmdbs");
037e8744 15872 else
477330fc 15873 do_vfp_nsyn_opcode ("fstmias");
037e8744
JB
15874 }
15875}
15876
037e8744
JB
15877static void
15878do_vfp_nsyn_sqrt (void)
15879{
9db2f6b4
RL
15880 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15881 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 15882
9db2f6b4
RL
15883 if (rs == NS_FF || rs == NS_HH)
15884 {
15885 do_vfp_nsyn_opcode ("fsqrts");
15886
15887 /* ARMv8.2 fp16 instruction. */
15888 if (rs == NS_HH)
15889 do_scalar_fp16_v82_encode ();
15890 }
037e8744
JB
15891 else
15892 do_vfp_nsyn_opcode ("fsqrtd");
15893}
15894
15895static void
15896do_vfp_nsyn_div (void)
15897{
9db2f6b4 15898 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15899 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15900 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15901
9db2f6b4
RL
15902 if (rs == NS_FFF || rs == NS_HHH)
15903 {
15904 do_vfp_nsyn_opcode ("fdivs");
15905
15906 /* ARMv8.2 fp16 instruction. */
15907 if (rs == NS_HHH)
15908 do_scalar_fp16_v82_encode ();
15909 }
037e8744
JB
15910 else
15911 do_vfp_nsyn_opcode ("fdivd");
15912}
15913
15914static void
15915do_vfp_nsyn_nmul (void)
15916{
9db2f6b4 15917 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15918 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15919 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15920
9db2f6b4 15921 if (rs == NS_FFF || rs == NS_HHH)
037e8744 15922 {
88714cb8 15923 NEON_ENCODE (SINGLE, inst);
037e8744 15924 do_vfp_sp_dyadic ();
9db2f6b4
RL
15925
15926 /* ARMv8.2 fp16 instruction. */
15927 if (rs == NS_HHH)
15928 do_scalar_fp16_v82_encode ();
037e8744
JB
15929 }
15930 else
15931 {
88714cb8 15932 NEON_ENCODE (DOUBLE, inst);
037e8744
JB
15933 do_vfp_dp_rd_rn_rm ();
15934 }
15935 do_vfp_cond_or_thumb ();
9db2f6b4 15936
037e8744
JB
15937}
15938
1b883319
AV
15939/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
15940 (0, 1, 2, 3). */
15941
15942static unsigned
15943neon_logbits (unsigned x)
15944{
15945 return ffs (x) - 4;
15946}
15947
15948#define LOW4(R) ((R) & 0xf)
15949#define HI1(R) (((R) >> 4) & 1)
5aae9ae9
MM
15950#define LOW1(R) ((R) & 0x1)
15951#define HI4(R) (((R) >> 1) & 0xf)
1b883319
AV
15952
15953static unsigned
15954mve_get_vcmp_vpt_cond (struct neon_type_el et)
15955{
15956 switch (et.type)
15957 {
15958 default:
15959 first_error (BAD_EL_TYPE);
15960 return 0;
15961 case NT_float:
15962 switch (inst.operands[0].imm)
15963 {
15964 default:
15965 first_error (_("invalid condition"));
15966 return 0;
15967 case 0x0:
15968 /* eq. */
15969 return 0;
15970 case 0x1:
15971 /* ne. */
15972 return 1;
15973 case 0xa:
15974 /* ge/ */
15975 return 4;
15976 case 0xb:
15977 /* lt. */
15978 return 5;
15979 case 0xc:
15980 /* gt. */
15981 return 6;
15982 case 0xd:
15983 /* le. */
15984 return 7;
15985 }
15986 case NT_integer:
15987 /* only accept eq and ne. */
15988 if (inst.operands[0].imm > 1)
15989 {
15990 first_error (_("invalid condition"));
15991 return 0;
15992 }
15993 return inst.operands[0].imm;
15994 case NT_unsigned:
15995 if (inst.operands[0].imm == 0x2)
15996 return 2;
15997 else if (inst.operands[0].imm == 0x8)
15998 return 3;
15999 else
16000 {
16001 first_error (_("invalid condition"));
16002 return 0;
16003 }
16004 case NT_signed:
16005 switch (inst.operands[0].imm)
16006 {
16007 default:
16008 first_error (_("invalid condition"));
16009 return 0;
16010 case 0xa:
16011 /* ge. */
16012 return 4;
16013 case 0xb:
16014 /* lt. */
16015 return 5;
16016 case 0xc:
16017 /* gt. */
16018 return 6;
16019 case 0xd:
16020 /* le. */
16021 return 7;
16022 }
16023 }
16024 /* Should be unreachable. */
16025 abort ();
16026}
16027
efd0b310
SP
16028/* For VCTP (create vector tail predicate) in MVE. */
16029static void
16030do_mve_vctp (void)
16031{
16032 int dt = 0;
16033 unsigned size = 0x0;
16034
16035 if (inst.cond > COND_ALWAYS)
16036 inst.pred_insn_type = INSIDE_VPT_INSN;
16037 else
16038 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16039
16040 /* This is a typical MVE instruction which has no type but have size 8, 16,
16041 32 and 64. For instructions with no type, inst.vectype.el[j].type is set
16042 to NT_untyped and size is updated in inst.vectype.el[j].size. */
16043 if ((inst.operands[0].present) && (inst.vectype.el[0].type == NT_untyped))
16044 dt = inst.vectype.el[0].size;
16045
16046 /* Setting this does not indicate an actual NEON instruction, but only
16047 indicates that the mnemonic accepts neon-style type suffixes. */
16048 inst.is_neon = 1;
16049
16050 switch (dt)
16051 {
16052 case 8:
16053 break;
16054 case 16:
16055 size = 0x1; break;
16056 case 32:
16057 size = 0x2; break;
16058 case 64:
16059 size = 0x3; break;
16060 default:
16061 first_error (_("Type is not allowed for this instruction"));
16062 }
16063 inst.instruction |= size << 20;
16064 inst.instruction |= inst.operands[0].reg << 16;
16065}
16066
1b883319
AV
16067static void
16068do_mve_vpt (void)
16069{
16070 /* We are dealing with a vector predicated block. */
16071 if (inst.operands[0].present)
16072 {
16073 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
16074 struct neon_type_el et
16075 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
16076 N_EQK);
16077
16078 unsigned fcond = mve_get_vcmp_vpt_cond (et);
16079
16080 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
16081
16082 if (et.type == NT_invtype)
16083 return;
16084
16085 if (et.type == NT_float)
16086 {
16087 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
16088 BAD_FPU);
16089 constraint (et.size != 16 && et.size != 32, BAD_EL_TYPE);
16090 inst.instruction |= (et.size == 16) << 28;
16091 inst.instruction |= 0x3 << 20;
16092 }
16093 else
16094 {
16095 constraint (et.size != 8 && et.size != 16 && et.size != 32,
16096 BAD_EL_TYPE);
16097 inst.instruction |= 1 << 28;
16098 inst.instruction |= neon_logbits (et.size) << 20;
16099 }
16100
16101 if (inst.operands[2].isquad)
16102 {
16103 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16104 inst.instruction |= LOW4 (inst.operands[2].reg);
16105 inst.instruction |= (fcond & 0x2) >> 1;
16106 }
16107 else
16108 {
16109 if (inst.operands[2].reg == REG_SP)
16110 as_tsktsk (MVE_BAD_SP);
16111 inst.instruction |= 1 << 6;
16112 inst.instruction |= (fcond & 0x2) << 4;
16113 inst.instruction |= inst.operands[2].reg;
16114 }
16115 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16116 inst.instruction |= (fcond & 0x4) << 10;
16117 inst.instruction |= (fcond & 0x1) << 7;
16118
16119 }
16120 set_pred_insn_type (VPT_INSN);
16121 now_pred.cc = 0;
16122 now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
16123 | ((inst.instruction & 0xe000) >> 13);
5b7c81bd 16124 now_pred.warn_deprecated = false;
1b883319
AV
16125 now_pred.type = VECTOR_PRED;
16126 inst.is_neon = 1;
16127}
16128
16129static void
16130do_mve_vcmp (void)
16131{
16132 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
16133 if (!inst.operands[1].isreg || !inst.operands[1].isquad)
16134 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
16135 if (!inst.operands[2].present)
16136 first_error (_("MVE vector or ARM register expected"));
16137 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
16138
16139 /* Deal with 'else' conditional MVE's vcmp, it will be parsed as vcmpe. */
16140 if ((inst.instruction & 0xffffffff) == N_MNEM_vcmpe
16141 && inst.operands[1].isquad)
16142 {
16143 inst.instruction = N_MNEM_vcmp;
16144 inst.cond = 0x10;
16145 }
16146
16147 if (inst.cond > COND_ALWAYS)
16148 inst.pred_insn_type = INSIDE_VPT_INSN;
16149 else
16150 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16151
16152 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
16153 struct neon_type_el et
16154 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
16155 N_EQK);
16156
16157 constraint (rs == NS_IQR && inst.operands[2].reg == REG_PC
16158 && !inst.operands[2].iszr, BAD_PC);
16159
16160 unsigned fcond = mve_get_vcmp_vpt_cond (et);
16161
16162 inst.instruction = 0xee010f00;
16163 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16164 inst.instruction |= (fcond & 0x4) << 10;
16165 inst.instruction |= (fcond & 0x1) << 7;
16166 if (et.type == NT_float)
16167 {
16168 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
16169 BAD_FPU);
16170 inst.instruction |= (et.size == 16) << 28;
16171 inst.instruction |= 0x3 << 20;
16172 }
16173 else
16174 {
16175 inst.instruction |= 1 << 28;
16176 inst.instruction |= neon_logbits (et.size) << 20;
16177 }
16178 if (inst.operands[2].isquad)
16179 {
16180 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16181 inst.instruction |= (fcond & 0x2) >> 1;
16182 inst.instruction |= LOW4 (inst.operands[2].reg);
16183 }
16184 else
16185 {
16186 if (inst.operands[2].reg == REG_SP)
16187 as_tsktsk (MVE_BAD_SP);
16188 inst.instruction |= 1 << 6;
16189 inst.instruction |= (fcond & 0x2) << 4;
16190 inst.instruction |= inst.operands[2].reg;
16191 }
16192
16193 inst.is_neon = 1;
16194 return;
16195}
16196
935295b5
AV
16197static void
16198do_mve_vmaxa_vmina (void)
16199{
16200 if (inst.cond > COND_ALWAYS)
16201 inst.pred_insn_type = INSIDE_VPT_INSN;
16202 else
16203 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16204
16205 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
16206 struct neon_type_el et
16207 = neon_check_type (2, rs, N_EQK, N_KEY | N_S8 | N_S16 | N_S32);
16208
16209 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16210 inst.instruction |= neon_logbits (et.size) << 18;
16211 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16212 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16213 inst.instruction |= LOW4 (inst.operands[1].reg);
16214 inst.is_neon = 1;
16215}
16216
f30ee27c
AV
16217static void
16218do_mve_vfmas (void)
16219{
16220 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
16221 struct neon_type_el et
16222 = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK, N_EQK);
16223
16224 if (inst.cond > COND_ALWAYS)
16225 inst.pred_insn_type = INSIDE_VPT_INSN;
16226 else
16227 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16228
16229 if (inst.operands[2].reg == REG_SP)
16230 as_tsktsk (MVE_BAD_SP);
16231 else if (inst.operands[2].reg == REG_PC)
16232 as_tsktsk (MVE_BAD_PC);
16233
16234 inst.instruction |= (et.size == 16) << 28;
16235 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16236 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16237 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16238 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16239 inst.instruction |= inst.operands[2].reg;
16240 inst.is_neon = 1;
16241}
16242
b409bdb6
AV
16243static void
16244do_mve_viddup (void)
16245{
16246 if (inst.cond > COND_ALWAYS)
16247 inst.pred_insn_type = INSIDE_VPT_INSN;
16248 else
16249 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16250
16251 unsigned imm = inst.relocs[0].exp.X_add_number;
16252 constraint (imm != 1 && imm != 2 && imm != 4 && imm != 8,
16253 _("immediate must be either 1, 2, 4 or 8"));
16254
16255 enum neon_shape rs;
16256 struct neon_type_el et;
16257 unsigned Rm;
16258 if (inst.instruction == M_MNEM_vddup || inst.instruction == M_MNEM_vidup)
16259 {
16260 rs = neon_select_shape (NS_QRI, NS_NULL);
16261 et = neon_check_type (2, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK);
16262 Rm = 7;
16263 }
16264 else
16265 {
16266 constraint ((inst.operands[2].reg % 2) != 1, BAD_EVEN);
16267 if (inst.operands[2].reg == REG_SP)
16268 as_tsktsk (MVE_BAD_SP);
16269 else if (inst.operands[2].reg == REG_PC)
16270 first_error (BAD_PC);
16271
16272 rs = neon_select_shape (NS_QRRI, NS_NULL);
16273 et = neon_check_type (3, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK, N_EQK);
16274 Rm = inst.operands[2].reg >> 1;
16275 }
16276 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16277 inst.instruction |= neon_logbits (et.size) << 20;
16278 inst.instruction |= inst.operands[1].reg << 16;
16279 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16280 inst.instruction |= (imm > 2) << 7;
16281 inst.instruction |= Rm << 1;
16282 inst.instruction |= (imm == 2 || imm == 8);
16283 inst.is_neon = 1;
16284}
16285
2d78f95b
AV
16286static void
16287do_mve_vmlas (void)
16288{
16289 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
16290 struct neon_type_el et
16291 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
16292
16293 if (inst.operands[2].reg == REG_PC)
16294 as_tsktsk (MVE_BAD_PC);
16295 else if (inst.operands[2].reg == REG_SP)
16296 as_tsktsk (MVE_BAD_SP);
16297
16298 if (inst.cond > COND_ALWAYS)
16299 inst.pred_insn_type = INSIDE_VPT_INSN;
16300 else
16301 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16302
16303 inst.instruction |= (et.type == NT_unsigned) << 28;
16304 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16305 inst.instruction |= neon_logbits (et.size) << 20;
16306 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16307 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16308 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16309 inst.instruction |= inst.operands[2].reg;
16310 inst.is_neon = 1;
16311}
16312
acca5630
AV
16313static void
16314do_mve_vshll (void)
16315{
16316 struct neon_type_el et
16317 = neon_check_type (2, NS_QQI, N_EQK, N_S8 | N_U8 | N_S16 | N_U16 | N_KEY);
16318
16319 if (inst.cond > COND_ALWAYS)
16320 inst.pred_insn_type = INSIDE_VPT_INSN;
16321 else
16322 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16323
16324 int imm = inst.operands[2].imm;
16325 constraint (imm < 1 || (unsigned)imm > et.size,
16326 _("immediate value out of range"));
16327
16328 if ((unsigned)imm == et.size)
16329 {
16330 inst.instruction |= neon_logbits (et.size) << 18;
16331 inst.instruction |= 0x110001;
16332 }
16333 else
16334 {
16335 inst.instruction |= (et.size + imm) << 16;
16336 inst.instruction |= 0x800140;
16337 }
16338
16339 inst.instruction |= (et.type == NT_unsigned) << 28;
16340 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16341 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16342 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16343 inst.instruction |= LOW4 (inst.operands[1].reg);
16344 inst.is_neon = 1;
16345}
16346
16347static void
16348do_mve_vshlc (void)
16349{
16350 if (inst.cond > COND_ALWAYS)
16351 inst.pred_insn_type = INSIDE_VPT_INSN;
16352 else
16353 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16354
16355 if (inst.operands[1].reg == REG_PC)
16356 as_tsktsk (MVE_BAD_PC);
16357 else if (inst.operands[1].reg == REG_SP)
16358 as_tsktsk (MVE_BAD_SP);
16359
16360 int imm = inst.operands[2].imm;
16361 constraint (imm < 1 || imm > 32, _("immediate value out of range"));
16362
16363 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16364 inst.instruction |= (imm & 0x1f) << 16;
16365 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16366 inst.instruction |= inst.operands[1].reg;
16367 inst.is_neon = 1;
16368}
16369
4aa88b50
AV
16370static void
16371do_mve_vshrn (void)
16372{
16373 unsigned types;
16374 switch (inst.instruction)
16375 {
16376 case M_MNEM_vshrnt:
16377 case M_MNEM_vshrnb:
16378 case M_MNEM_vrshrnt:
16379 case M_MNEM_vrshrnb:
16380 types = N_I16 | N_I32;
16381 break;
16382 case M_MNEM_vqshrnt:
16383 case M_MNEM_vqshrnb:
16384 case M_MNEM_vqrshrnt:
16385 case M_MNEM_vqrshrnb:
16386 types = N_U16 | N_U32 | N_S16 | N_S32;
16387 break;
16388 case M_MNEM_vqshrunt:
16389 case M_MNEM_vqshrunb:
16390 case M_MNEM_vqrshrunt:
16391 case M_MNEM_vqrshrunb:
16392 types = N_S16 | N_S32;
16393 break;
16394 default:
16395 abort ();
16396 }
16397
16398 struct neon_type_el et = neon_check_type (2, NS_QQI, N_EQK, types | N_KEY);
16399
16400 if (inst.cond > COND_ALWAYS)
16401 inst.pred_insn_type = INSIDE_VPT_INSN;
16402 else
16403 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16404
16405 unsigned Qd = inst.operands[0].reg;
16406 unsigned Qm = inst.operands[1].reg;
16407 unsigned imm = inst.operands[2].imm;
16408 constraint (imm < 1 || ((unsigned) imm) > (et.size / 2),
16409 et.size == 16
16410 ? _("immediate operand expected in the range [1,8]")
16411 : _("immediate operand expected in the range [1,16]"));
16412
16413 inst.instruction |= (et.type == NT_unsigned) << 28;
16414 inst.instruction |= HI1 (Qd) << 22;
16415 inst.instruction |= (et.size - imm) << 16;
16416 inst.instruction |= LOW4 (Qd) << 12;
16417 inst.instruction |= HI1 (Qm) << 5;
16418 inst.instruction |= LOW4 (Qm);
16419 inst.is_neon = 1;
16420}
16421
1be7aba3
AV
16422static void
16423do_mve_vqmovn (void)
16424{
16425 struct neon_type_el et;
16426 if (inst.instruction == M_MNEM_vqmovnt
16427 || inst.instruction == M_MNEM_vqmovnb)
16428 et = neon_check_type (2, NS_QQ, N_EQK,
16429 N_U16 | N_U32 | N_S16 | N_S32 | N_KEY);
16430 else
16431 et = neon_check_type (2, NS_QQ, N_EQK, N_S16 | N_S32 | N_KEY);
16432
16433 if (inst.cond > COND_ALWAYS)
16434 inst.pred_insn_type = INSIDE_VPT_INSN;
16435 else
16436 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16437
16438 inst.instruction |= (et.type == NT_unsigned) << 28;
16439 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16440 inst.instruction |= (et.size == 32) << 18;
16441 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16442 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16443 inst.instruction |= LOW4 (inst.operands[1].reg);
16444 inst.is_neon = 1;
16445}
16446
3063888e
AV
16447static void
16448do_mve_vpsel (void)
16449{
16450 neon_select_shape (NS_QQQ, NS_NULL);
16451
16452 if (inst.cond > COND_ALWAYS)
16453 inst.pred_insn_type = INSIDE_VPT_INSN;
16454 else
16455 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16456
16457 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16458 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16459 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16460 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16461 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16462 inst.instruction |= LOW4 (inst.operands[2].reg);
16463 inst.is_neon = 1;
16464}
16465
16466static void
16467do_mve_vpnot (void)
16468{
16469 if (inst.cond > COND_ALWAYS)
16470 inst.pred_insn_type = INSIDE_VPT_INSN;
16471 else
16472 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16473}
16474
935295b5
AV
16475static void
16476do_mve_vmaxnma_vminnma (void)
16477{
16478 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
16479 struct neon_type_el et
16480 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
16481
16482 if (inst.cond > COND_ALWAYS)
16483 inst.pred_insn_type = INSIDE_VPT_INSN;
16484 else
16485 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16486
16487 inst.instruction |= (et.size == 16) << 28;
16488 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16489 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16490 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16491 inst.instruction |= LOW4 (inst.operands[1].reg);
16492 inst.is_neon = 1;
16493}
16494
5d281bf0
AV
16495static void
16496do_mve_vcmul (void)
16497{
16498 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
16499 struct neon_type_el et
16500 = neon_check_type (3, rs, N_EQK, N_EQK, N_F_MVE | N_KEY);
16501
16502 if (inst.cond > COND_ALWAYS)
16503 inst.pred_insn_type = INSIDE_VPT_INSN;
16504 else
16505 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16506
16507 unsigned rot = inst.relocs[0].exp.X_add_number;
16508 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
16509 _("immediate out of range"));
16510
16511 if (et.size == 32 && (inst.operands[0].reg == inst.operands[1].reg
16512 || inst.operands[0].reg == inst.operands[2].reg))
16513 as_tsktsk (BAD_MVE_SRCDEST);
16514
16515 inst.instruction |= (et.size == 32) << 28;
16516 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16517 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16518 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16519 inst.instruction |= (rot > 90) << 12;
16520 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16521 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16522 inst.instruction |= LOW4 (inst.operands[2].reg);
16523 inst.instruction |= (rot == 90 || rot == 270);
16524 inst.is_neon = 1;
16525}
16526
1f6234a3
AV
16527/* To handle the Low Overhead Loop instructions
16528 in Armv8.1-M Mainline and MVE. */
16529static void
16530do_t_loloop (void)
16531{
16532 unsigned long insn = inst.instruction;
16533
16534 inst.instruction = THUMB_OP32 (inst.instruction);
16535
16536 if (insn == T_MNEM_lctp)
16537 return;
16538
16539 set_pred_insn_type (MVE_OUTSIDE_PRED_INSN);
16540
16541 if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
16542 {
16543 struct neon_type_el et
16544 = neon_check_type (2, NS_RR, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
16545 inst.instruction |= neon_logbits (et.size) << 20;
16546 inst.is_neon = 1;
16547 }
16548
16549 switch (insn)
16550 {
16551 case T_MNEM_letp:
16552 constraint (!inst.operands[0].present,
16553 _("expected LR"));
16554 /* fall through. */
16555 case T_MNEM_le:
16556 /* le <label>. */
16557 if (!inst.operands[0].present)
16558 inst.instruction |= 1 << 21;
16559
5b7c81bd 16560 v8_1_loop_reloc (true);
1f6234a3
AV
16561 break;
16562
16563 case T_MNEM_wls:
16564 case T_MNEM_wlstp:
5b7c81bd 16565 v8_1_loop_reloc (false);
1f6234a3
AV
16566 /* fall through. */
16567 case T_MNEM_dlstp:
16568 case T_MNEM_dls:
16569 constraint (inst.operands[1].isreg != 1, BAD_ARGS);
16570
16571 if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
16572 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
16573 else if (inst.operands[1].reg == REG_PC)
16574 as_tsktsk (MVE_BAD_PC);
16575 if (inst.operands[1].reg == REG_SP)
16576 as_tsktsk (MVE_BAD_SP);
16577
16578 inst.instruction |= (inst.operands[1].reg << 16);
16579 break;
16580
16581 default:
16582 abort ();
16583 }
16584}
16585
16586
037e8744
JB
16587static void
16588do_vfp_nsyn_cmp (void)
16589{
9db2f6b4 16590 enum neon_shape rs;
1b883319
AV
16591 if (!inst.operands[0].isreg)
16592 {
16593 do_mve_vcmp ();
16594 return;
16595 }
16596 else
16597 {
16598 constraint (inst.operands[2].present, BAD_SYNTAX);
16599 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd),
16600 BAD_FPU);
16601 }
16602
037e8744
JB
16603 if (inst.operands[1].isreg)
16604 {
9db2f6b4
RL
16605 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
16606 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 16607
9db2f6b4 16608 if (rs == NS_FF || rs == NS_HH)
477330fc
RM
16609 {
16610 NEON_ENCODE (SINGLE, inst);
16611 do_vfp_sp_monadic ();
16612 }
037e8744 16613 else
477330fc
RM
16614 {
16615 NEON_ENCODE (DOUBLE, inst);
16616 do_vfp_dp_rd_rm ();
16617 }
037e8744
JB
16618 }
16619 else
16620 {
9db2f6b4
RL
16621 rs = neon_select_shape (NS_HI, NS_FI, NS_DI, NS_NULL);
16622 neon_check_type (2, rs, N_F_ALL | N_KEY | N_VFP, N_EQK);
037e8744
JB
16623
16624 switch (inst.instruction & 0x0fffffff)
477330fc
RM
16625 {
16626 case N_MNEM_vcmp:
16627 inst.instruction += N_MNEM_vcmpz - N_MNEM_vcmp;
16628 break;
16629 case N_MNEM_vcmpe:
16630 inst.instruction += N_MNEM_vcmpez - N_MNEM_vcmpe;
16631 break;
16632 default:
16633 abort ();
16634 }
5f4273c7 16635
9db2f6b4 16636 if (rs == NS_FI || rs == NS_HI)
477330fc
RM
16637 {
16638 NEON_ENCODE (SINGLE, inst);
16639 do_vfp_sp_compare_z ();
16640 }
037e8744 16641 else
477330fc
RM
16642 {
16643 NEON_ENCODE (DOUBLE, inst);
16644 do_vfp_dp_rd ();
16645 }
037e8744
JB
16646 }
16647 do_vfp_cond_or_thumb ();
9db2f6b4
RL
16648
16649 /* ARMv8.2 fp16 instruction. */
16650 if (rs == NS_HI || rs == NS_HH)
16651 do_scalar_fp16_v82_encode ();
037e8744
JB
16652}
16653
16654static void
16655nsyn_insert_sp (void)
16656{
16657 inst.operands[1] = inst.operands[0];
16658 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
fdfde340 16659 inst.operands[0].reg = REG_SP;
037e8744
JB
16660 inst.operands[0].isreg = 1;
16661 inst.operands[0].writeback = 1;
16662 inst.operands[0].present = 1;
16663}
16664
037e8744
JB
16665/* Fix up Neon data-processing instructions, ORing in the correct bits for
16666 ARM mode or Thumb mode and moving the encoded bit 24 to bit 28. */
16667
88714cb8
DG
16668static void
16669neon_dp_fixup (struct arm_it* insn)
037e8744 16670{
88714cb8
DG
16671 unsigned int i = insn->instruction;
16672 insn->is_neon = 1;
16673
037e8744
JB
16674 if (thumb_mode)
16675 {
16676 /* The U bit is at bit 24 by default. Move to bit 28 in Thumb mode. */
16677 if (i & (1 << 24))
477330fc 16678 i |= 1 << 28;
5f4273c7 16679
037e8744 16680 i &= ~(1 << 24);
5f4273c7 16681
037e8744
JB
16682 i |= 0xef000000;
16683 }
16684 else
16685 i |= 0xf2000000;
5f4273c7 16686
88714cb8 16687 insn->instruction = i;
037e8744
JB
16688}
16689
5ee91343 16690static void
7df54120 16691mve_encode_qqr (int size, int U, int fp)
5ee91343
AV
16692{
16693 if (inst.operands[2].reg == REG_SP)
16694 as_tsktsk (MVE_BAD_SP);
16695 else if (inst.operands[2].reg == REG_PC)
16696 as_tsktsk (MVE_BAD_PC);
16697
16698 if (fp)
16699 {
16700 /* vadd. */
16701 if (((unsigned)inst.instruction) == 0xd00)
16702 inst.instruction = 0xee300f40;
16703 /* vsub. */
16704 else if (((unsigned)inst.instruction) == 0x200d00)
16705 inst.instruction = 0xee301f40;
a8465a06
AV
16706 /* vmul. */
16707 else if (((unsigned)inst.instruction) == 0x1000d10)
16708 inst.instruction = 0xee310e60;
5ee91343
AV
16709
16710 /* Setting size which is 1 for F16 and 0 for F32. */
16711 inst.instruction |= (size == 16) << 28;
16712 }
16713 else
16714 {
16715 /* vadd. */
16716 if (((unsigned)inst.instruction) == 0x800)
16717 inst.instruction = 0xee010f40;
16718 /* vsub. */
16719 else if (((unsigned)inst.instruction) == 0x1000800)
16720 inst.instruction = 0xee011f40;
7df54120
AV
16721 /* vhadd. */
16722 else if (((unsigned)inst.instruction) == 0)
16723 inst.instruction = 0xee000f40;
16724 /* vhsub. */
16725 else if (((unsigned)inst.instruction) == 0x200)
16726 inst.instruction = 0xee001f40;
a8465a06
AV
16727 /* vmla. */
16728 else if (((unsigned)inst.instruction) == 0x900)
16729 inst.instruction = 0xee010e40;
16730 /* vmul. */
16731 else if (((unsigned)inst.instruction) == 0x910)
16732 inst.instruction = 0xee011e60;
16733 /* vqadd. */
16734 else if (((unsigned)inst.instruction) == 0x10)
16735 inst.instruction = 0xee000f60;
16736 /* vqsub. */
16737 else if (((unsigned)inst.instruction) == 0x210)
16738 inst.instruction = 0xee001f60;
42b16635
AV
16739 /* vqrdmlah. */
16740 else if (((unsigned)inst.instruction) == 0x3000b10)
16741 inst.instruction = 0xee000e40;
16742 /* vqdmulh. */
16743 else if (((unsigned)inst.instruction) == 0x0000b00)
16744 inst.instruction = 0xee010e60;
16745 /* vqrdmulh. */
16746 else if (((unsigned)inst.instruction) == 0x1000b00)
16747 inst.instruction = 0xfe010e60;
7df54120
AV
16748
16749 /* Set U-bit. */
16750 inst.instruction |= U << 28;
16751
5ee91343
AV
16752 /* Setting bits for size. */
16753 inst.instruction |= neon_logbits (size) << 20;
16754 }
16755 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16756 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16757 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16758 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16759 inst.instruction |= inst.operands[2].reg;
16760 inst.is_neon = 1;
16761}
16762
a302e574
AV
16763static void
16764mve_encode_rqq (unsigned bit28, unsigned size)
16765{
16766 inst.instruction |= bit28 << 28;
16767 inst.instruction |= neon_logbits (size) << 20;
16768 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16769 inst.instruction |= inst.operands[0].reg << 12;
16770 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16771 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16772 inst.instruction |= LOW4 (inst.operands[2].reg);
16773 inst.is_neon = 1;
16774}
16775
886e1c73
AV
16776static void
16777mve_encode_qqq (int ubit, int size)
16778{
16779
16780 inst.instruction |= (ubit != 0) << 28;
16781 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16782 inst.instruction |= neon_logbits (size) << 20;
16783 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16784 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16785 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16786 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16787 inst.instruction |= LOW4 (inst.operands[2].reg);
16788
16789 inst.is_neon = 1;
16790}
16791
26c1e780
AV
16792static void
16793mve_encode_rq (unsigned bit28, unsigned size)
16794{
16795 inst.instruction |= bit28 << 28;
16796 inst.instruction |= neon_logbits (size) << 18;
16797 inst.instruction |= inst.operands[0].reg << 12;
16798 inst.instruction |= LOW4 (inst.operands[1].reg);
16799 inst.is_neon = 1;
16800}
886e1c73 16801
93925576
AV
16802static void
16803mve_encode_rrqq (unsigned U, unsigned size)
16804{
16805 constraint (inst.operands[3].reg > 14, MVE_BAD_QREG);
16806
16807 inst.instruction |= U << 28;
16808 inst.instruction |= (inst.operands[1].reg >> 1) << 20;
16809 inst.instruction |= LOW4 (inst.operands[2].reg) << 16;
16810 inst.instruction |= (size == 32) << 16;
16811 inst.instruction |= inst.operands[0].reg << 12;
16812 inst.instruction |= HI1 (inst.operands[2].reg) << 7;
16813 inst.instruction |= inst.operands[3].reg;
16814 inst.is_neon = 1;
16815}
16816
aab2c27d
MM
16817/* Helper function for neon_three_same handling the operands. */
16818static void
16819neon_three_args (int isquad)
16820{
16821 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16822 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16823 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16824 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16825 inst.instruction |= LOW4 (inst.operands[2].reg);
16826 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16827 inst.instruction |= (isquad != 0) << 6;
16828 inst.is_neon = 1;
16829}
16830
037e8744
JB
16831/* Encode insns with bit pattern:
16832
16833 |28/24|23|22 |21 20|19 16|15 12|11 8|7|6|5|4|3 0|
16834 | U |x |D |size | Rn | Rd |x x x x|N|Q|M|x| Rm |
5f4273c7 16835
037e8744
JB
16836 SIZE is passed in bits. -1 means size field isn't changed, in case it has a
16837 different meaning for some instruction. */
16838
16839static void
16840neon_three_same (int isquad, int ubit, int size)
16841{
aab2c27d 16842 neon_three_args (isquad);
037e8744
JB
16843 inst.instruction |= (ubit != 0) << 24;
16844 if (size != -1)
16845 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 16846
88714cb8 16847 neon_dp_fixup (&inst);
037e8744
JB
16848}
16849
16850/* Encode instructions of the form:
16851
16852 |28/24|23|22|21 20|19 18|17 16|15 12|11 7|6|5|4|3 0|
16853 | U |x |D |x x |size |x x | Rd |x x x x x|Q|M|x| Rm |
5287ad62
JB
16854
16855 Don't write size if SIZE == -1. */
16856
16857static void
16858neon_two_same (int qbit, int ubit, int size)
16859{
16860 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16861 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16862 inst.instruction |= LOW4 (inst.operands[1].reg);
16863 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16864 inst.instruction |= (qbit != 0) << 6;
16865 inst.instruction |= (ubit != 0) << 24;
16866
16867 if (size != -1)
16868 inst.instruction |= neon_logbits (size) << 18;
16869
88714cb8 16870 neon_dp_fixup (&inst);
5287ad62
JB
16871}
16872
7df54120
AV
16873enum vfp_or_neon_is_neon_bits
16874{
16875NEON_CHECK_CC = 1,
16876NEON_CHECK_ARCH = 2,
16877NEON_CHECK_ARCH8 = 4
16878};
16879
16880/* Call this function if an instruction which may have belonged to the VFP or
16881 Neon instruction sets, but turned out to be a Neon instruction (due to the
16882 operand types involved, etc.). We have to check and/or fix-up a couple of
16883 things:
16884
16885 - Make sure the user hasn't attempted to make a Neon instruction
16886 conditional.
16887 - Alter the value in the condition code field if necessary.
16888 - Make sure that the arch supports Neon instructions.
16889
16890 Which of these operations take place depends on bits from enum
16891 vfp_or_neon_is_neon_bits.
16892
16893 WARNING: This function has side effects! If NEON_CHECK_CC is used and the
16894 current instruction's condition is COND_ALWAYS, the condition field is
16895 changed to inst.uncond_value. This is necessary because instructions shared
16896 between VFP and Neon may be conditional for the VFP variants only, and the
16897 unconditional Neon version must have, e.g., 0xF in the condition field. */
16898
16899static int
16900vfp_or_neon_is_neon (unsigned check)
16901{
16902/* Conditions are always legal in Thumb mode (IT blocks). */
16903if (!thumb_mode && (check & NEON_CHECK_CC))
16904 {
16905 if (inst.cond != COND_ALWAYS)
16906 {
16907 first_error (_(BAD_COND));
16908 return FAIL;
16909 }
7af67752 16910 if (inst.uncond_value != -1u)
7df54120
AV
16911 inst.instruction |= inst.uncond_value << 28;
16912 }
16913
16914
16915 if (((check & NEON_CHECK_ARCH) && !mark_feature_used (&fpu_neon_ext_v1))
16916 || ((check & NEON_CHECK_ARCH8)
16917 && !mark_feature_used (&fpu_neon_ext_armv8)))
16918 {
16919 first_error (_(BAD_FPU));
16920 return FAIL;
16921 }
16922
16923return SUCCESS;
16924}
16925
64c350f2
AV
16926
16927/* Return TRUE if the SIMD instruction is available for the current
16928 cpu_variant. FP is set to TRUE if this is a SIMD floating-point
16929 instruction. CHECK contains th. CHECK contains the set of bits to pass to
16930 vfp_or_neon_is_neon for the NEON specific checks. */
16931
5b7c81bd 16932static bool
7df54120
AV
16933check_simd_pred_availability (int fp, unsigned check)
16934{
16935if (inst.cond > COND_ALWAYS)
16936 {
16937 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16938 {
16939 inst.error = BAD_FPU;
5b7c81bd 16940 return false;
7df54120
AV
16941 }
16942 inst.pred_insn_type = INSIDE_VPT_INSN;
16943 }
16944else if (inst.cond < COND_ALWAYS)
16945 {
16946 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16947 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16948 else if (vfp_or_neon_is_neon (check) == FAIL)
5b7c81bd 16949 return false;
7df54120
AV
16950 }
16951else
16952 {
16953 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fp ? mve_fp_ext : mve_ext)
16954 && vfp_or_neon_is_neon (check) == FAIL)
5b7c81bd 16955 return false;
7df54120
AV
16956
16957 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16958 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16959 }
5b7c81bd 16960return true;
7df54120
AV
16961}
16962
5287ad62
JB
16963/* Neon instruction encoders, in approximate order of appearance. */
16964
16965static void
16966do_neon_dyadic_i_su (void)
16967{
5b7c81bd 16968 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
7df54120
AV
16969 return;
16970
16971 enum neon_shape rs;
16972 struct neon_type_el et;
16973 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16974 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
16975 else
16976 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16977
16978 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_32 | N_KEY);
16979
16980
16981 if (rs != NS_QQR)
16982 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
16983 else
16984 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
5287ad62
JB
16985}
16986
16987static void
16988do_neon_dyadic_i64_su (void)
16989{
5b7c81bd 16990 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
a8465a06
AV
16991 return;
16992 enum neon_shape rs;
16993 struct neon_type_el et;
16994 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16995 {
16996 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
16997 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
16998 }
16999 else
17000 {
17001 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17002 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
17003 }
17004 if (rs == NS_QQR)
17005 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
17006 else
17007 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
17008}
17009
17010static void
17011neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
477330fc 17012 unsigned immbits)
5287ad62
JB
17013{
17014 unsigned size = et.size >> 3;
17015 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17016 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17017 inst.instruction |= LOW4 (inst.operands[1].reg);
17018 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
17019 inst.instruction |= (isquad != 0) << 6;
17020 inst.instruction |= immbits << 16;
17021 inst.instruction |= (size >> 3) << 7;
17022 inst.instruction |= (size & 0x7) << 19;
17023 if (write_ubit)
17024 inst.instruction |= (uval != 0) << 24;
17025
88714cb8 17026 neon_dp_fixup (&inst);
5287ad62
JB
17027}
17028
17029static void
5150f0d8 17030do_neon_shl (void)
5287ad62 17031{
5b7c81bd 17032 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
17033 return;
17034
5287ad62
JB
17035 if (!inst.operands[2].isreg)
17036 {
5150f0d8
AV
17037 enum neon_shape rs;
17038 struct neon_type_el et;
17039 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17040 {
17041 rs = neon_select_shape (NS_QQI, NS_NULL);
17042 et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_MVE);
17043 }
17044 else
17045 {
17046 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
17047 et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
17048 }
cb3b1e65
JB
17049 int imm = inst.operands[2].imm;
17050
17051 constraint (imm < 0 || (unsigned)imm >= et.size,
17052 _("immediate out of range for shift"));
88714cb8 17053 NEON_ENCODE (IMMED, inst);
5b7c81bd 17054 neon_imm_shift (false, 0, neon_quad (rs), et, imm);
5287ad62
JB
17055 }
17056 else
17057 {
5150f0d8
AV
17058 enum neon_shape rs;
17059 struct neon_type_el et;
17060 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17061 {
17062 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17063 et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
17064 }
17065 else
17066 {
17067 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17068 et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
17069 }
17070
17071
17072 if (rs == NS_QQR)
17073 {
17074 constraint (inst.operands[0].reg != inst.operands[1].reg,
17075 _("invalid instruction shape"));
17076 if (inst.operands[2].reg == REG_SP)
17077 as_tsktsk (MVE_BAD_SP);
17078 else if (inst.operands[2].reg == REG_PC)
17079 as_tsktsk (MVE_BAD_PC);
17080
17081 inst.instruction = 0xee311e60;
17082 inst.instruction |= (et.type == NT_unsigned) << 28;
17083 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17084 inst.instruction |= neon_logbits (et.size) << 18;
17085 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17086 inst.instruction |= inst.operands[2].reg;
17087 inst.is_neon = 1;
17088 }
17089 else
17090 {
17091 unsigned int tmp;
17092
17093 /* VSHL/VQSHL 3-register variants have syntax such as:
17094 vshl.xx Dd, Dm, Dn
17095 whereas other 3-register operations encoded by neon_three_same have
17096 syntax like:
17097 vadd.xx Dd, Dn, Dm
17098 (i.e. with Dn & Dm reversed). Swap operands[1].reg and
17099 operands[2].reg here. */
17100 tmp = inst.operands[2].reg;
17101 inst.operands[2].reg = inst.operands[1].reg;
17102 inst.operands[1].reg = tmp;
17103 NEON_ENCODE (INTEGER, inst);
17104 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17105 }
5287ad62
JB
17106 }
17107}
17108
17109static void
5150f0d8 17110do_neon_qshl (void)
5287ad62 17111{
5b7c81bd 17112 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
17113 return;
17114
5287ad62
JB
17115 if (!inst.operands[2].isreg)
17116 {
5150f0d8
AV
17117 enum neon_shape rs;
17118 struct neon_type_el et;
17119 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17120 {
17121 rs = neon_select_shape (NS_QQI, NS_NULL);
17122 et = neon_check_type (2, rs, N_EQK, N_KEY | N_SU_MVE);
17123 }
17124 else
17125 {
17126 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
17127 et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
17128 }
cb3b1e65 17129 int imm = inst.operands[2].imm;
627907b7 17130
cb3b1e65
JB
17131 constraint (imm < 0 || (unsigned)imm >= et.size,
17132 _("immediate out of range for shift"));
88714cb8 17133 NEON_ENCODE (IMMED, inst);
5b7c81bd 17134 neon_imm_shift (true, et.type == NT_unsigned, neon_quad (rs), et, imm);
5287ad62
JB
17135 }
17136 else
17137 {
5150f0d8
AV
17138 enum neon_shape rs;
17139 struct neon_type_el et;
627907b7 17140
5150f0d8
AV
17141 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17142 {
17143 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17144 et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
17145 }
17146 else
17147 {
17148 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17149 et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
17150 }
17151
17152 if (rs == NS_QQR)
17153 {
17154 constraint (inst.operands[0].reg != inst.operands[1].reg,
17155 _("invalid instruction shape"));
17156 if (inst.operands[2].reg == REG_SP)
17157 as_tsktsk (MVE_BAD_SP);
17158 else if (inst.operands[2].reg == REG_PC)
17159 as_tsktsk (MVE_BAD_PC);
17160
17161 inst.instruction = 0xee311ee0;
17162 inst.instruction |= (et.type == NT_unsigned) << 28;
17163 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17164 inst.instruction |= neon_logbits (et.size) << 18;
17165 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17166 inst.instruction |= inst.operands[2].reg;
17167 inst.is_neon = 1;
17168 }
17169 else
17170 {
17171 unsigned int tmp;
17172
17173 /* See note in do_neon_shl. */
17174 tmp = inst.operands[2].reg;
17175 inst.operands[2].reg = inst.operands[1].reg;
17176 inst.operands[1].reg = tmp;
17177 NEON_ENCODE (INTEGER, inst);
17178 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17179 }
5287ad62
JB
17180 }
17181}
17182
627907b7
JB
17183static void
17184do_neon_rshl (void)
17185{
5b7c81bd 17186 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
1be7aba3
AV
17187 return;
17188
17189 enum neon_shape rs;
17190 struct neon_type_el et;
17191 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17192 {
17193 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
17194 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17195 }
17196 else
17197 {
17198 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17199 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
17200 }
17201
627907b7
JB
17202 unsigned int tmp;
17203
1be7aba3
AV
17204 if (rs == NS_QQR)
17205 {
17206 if (inst.operands[2].reg == REG_PC)
17207 as_tsktsk (MVE_BAD_PC);
17208 else if (inst.operands[2].reg == REG_SP)
17209 as_tsktsk (MVE_BAD_SP);
17210
17211 constraint (inst.operands[0].reg != inst.operands[1].reg,
17212 _("invalid instruction shape"));
17213
17214 if (inst.instruction == 0x0000510)
17215 /* We are dealing with vqrshl. */
17216 inst.instruction = 0xee331ee0;
17217 else
17218 /* We are dealing with vrshl. */
17219 inst.instruction = 0xee331e60;
17220
17221 inst.instruction |= (et.type == NT_unsigned) << 28;
17222 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17223 inst.instruction |= neon_logbits (et.size) << 18;
17224 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17225 inst.instruction |= inst.operands[2].reg;
17226 inst.is_neon = 1;
17227 }
17228 else
17229 {
17230 tmp = inst.operands[2].reg;
17231 inst.operands[2].reg = inst.operands[1].reg;
17232 inst.operands[1].reg = tmp;
17233 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17234 }
627907b7
JB
17235}
17236
5287ad62
JB
17237static int
17238neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
17239{
036dc3f7
PB
17240 /* Handle .I8 pseudo-instructions. */
17241 if (size == 8)
5287ad62 17242 {
5287ad62 17243 /* Unfortunately, this will make everything apart from zero out-of-range.
477330fc
RM
17244 FIXME is this the intended semantics? There doesn't seem much point in
17245 accepting .I8 if so. */
5287ad62
JB
17246 immediate |= immediate << 8;
17247 size = 16;
036dc3f7
PB
17248 }
17249
17250 if (size >= 32)
17251 {
17252 if (immediate == (immediate & 0x000000ff))
17253 {
17254 *immbits = immediate;
17255 return 0x1;
17256 }
17257 else if (immediate == (immediate & 0x0000ff00))
17258 {
17259 *immbits = immediate >> 8;
17260 return 0x3;
17261 }
17262 else if (immediate == (immediate & 0x00ff0000))
17263 {
17264 *immbits = immediate >> 16;
17265 return 0x5;
17266 }
17267 else if (immediate == (immediate & 0xff000000))
17268 {
17269 *immbits = immediate >> 24;
17270 return 0x7;
17271 }
17272 if ((immediate & 0xffff) != (immediate >> 16))
17273 goto bad_immediate;
17274 immediate &= 0xffff;
5287ad62
JB
17275 }
17276
17277 if (immediate == (immediate & 0x000000ff))
17278 {
17279 *immbits = immediate;
036dc3f7 17280 return 0x9;
5287ad62
JB
17281 }
17282 else if (immediate == (immediate & 0x0000ff00))
17283 {
17284 *immbits = immediate >> 8;
036dc3f7 17285 return 0xb;
5287ad62
JB
17286 }
17287
17288 bad_immediate:
dcbf9037 17289 first_error (_("immediate value out of range"));
5287ad62
JB
17290 return FAIL;
17291}
17292
5287ad62
JB
17293static void
17294do_neon_logic (void)
17295{
17296 if (inst.operands[2].present && inst.operands[2].isreg)
17297 {
037e8744 17298 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
f601a00c 17299 if (rs == NS_QQQ
5b7c81bd 17300 && !check_simd_pred_availability (false,
64c350f2 17301 NEON_CHECK_ARCH | NEON_CHECK_CC))
f601a00c
AV
17302 return;
17303 else if (rs != NS_QQQ
17304 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
17305 first_error (BAD_FPU);
17306
5287ad62
JB
17307 neon_check_type (3, rs, N_IGNORE_TYPE);
17308 /* U bit and size field were set as part of the bitmask. */
88714cb8 17309 NEON_ENCODE (INTEGER, inst);
037e8744 17310 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
17311 }
17312 else
17313 {
4316f0d2
DG
17314 const int three_ops_form = (inst.operands[2].present
17315 && !inst.operands[2].isreg);
17316 const int immoperand = (three_ops_form ? 2 : 1);
17317 enum neon_shape rs = (three_ops_form
17318 ? neon_select_shape (NS_DDI, NS_QQI, NS_NULL)
17319 : neon_select_shape (NS_DI, NS_QI, NS_NULL));
f601a00c
AV
17320 /* Because neon_select_shape makes the second operand a copy of the first
17321 if the second operand is not present. */
17322 if (rs == NS_QQI
5b7c81bd 17323 && !check_simd_pred_availability (false,
64c350f2 17324 NEON_CHECK_ARCH | NEON_CHECK_CC))
f601a00c
AV
17325 return;
17326 else if (rs != NS_QQI
17327 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
17328 first_error (BAD_FPU);
17329
17330 struct neon_type_el et;
17331 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17332 et = neon_check_type (2, rs, N_I32 | N_I16 | N_KEY, N_EQK);
17333 else
17334 et = neon_check_type (2, rs, N_I8 | N_I16 | N_I32 | N_I64 | N_F32
17335 | N_KEY, N_EQK);
17336
17337 if (et.type == NT_invtype)
17338 return;
21d799b5 17339 enum neon_opc opcode = (enum neon_opc) inst.instruction & 0x0fffffff;
5287ad62
JB
17340 unsigned immbits;
17341 int cmode;
5f4273c7 17342
5f4273c7 17343
4316f0d2
DG
17344 if (three_ops_form)
17345 constraint (inst.operands[0].reg != inst.operands[1].reg,
17346 _("first and second operands shall be the same register"));
17347
88714cb8 17348 NEON_ENCODE (IMMED, inst);
5287ad62 17349
4316f0d2 17350 immbits = inst.operands[immoperand].imm;
036dc3f7
PB
17351 if (et.size == 64)
17352 {
17353 /* .i64 is a pseudo-op, so the immediate must be a repeating
17354 pattern. */
4316f0d2
DG
17355 if (immbits != (inst.operands[immoperand].regisimm ?
17356 inst.operands[immoperand].reg : 0))
036dc3f7
PB
17357 {
17358 /* Set immbits to an invalid constant. */
17359 immbits = 0xdeadbeef;
17360 }
17361 }
17362
5287ad62 17363 switch (opcode)
477330fc
RM
17364 {
17365 case N_MNEM_vbic:
17366 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17367 break;
17368
17369 case N_MNEM_vorr:
17370 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17371 break;
17372
17373 case N_MNEM_vand:
17374 /* Pseudo-instruction for VBIC. */
17375 neon_invert_size (&immbits, 0, et.size);
17376 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17377 break;
17378
17379 case N_MNEM_vorn:
17380 /* Pseudo-instruction for VORR. */
17381 neon_invert_size (&immbits, 0, et.size);
17382 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17383 break;
17384
17385 default:
17386 abort ();
17387 }
5287ad62
JB
17388
17389 if (cmode == FAIL)
477330fc 17390 return;
5287ad62 17391
037e8744 17392 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
17393 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17394 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17395 inst.instruction |= cmode << 8;
17396 neon_write_immbits (immbits);
5f4273c7 17397
88714cb8 17398 neon_dp_fixup (&inst);
5287ad62
JB
17399 }
17400}
17401
17402static void
17403do_neon_bitfield (void)
17404{
037e8744 17405 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 17406 neon_check_type (3, rs, N_IGNORE_TYPE);
037e8744 17407 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
17408}
17409
17410static void
dcbf9037 17411neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types,
477330fc 17412 unsigned destbits)
5287ad62 17413{
5ee91343 17414 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
dcbf9037 17415 struct neon_type_el et = neon_check_type (3, rs, N_EQK | destbits, N_EQK,
477330fc 17416 types | N_KEY);
5287ad62
JB
17417 if (et.type == NT_float)
17418 {
88714cb8 17419 NEON_ENCODE (FLOAT, inst);
5ee91343 17420 if (rs == NS_QQR)
7df54120 17421 mve_encode_qqr (et.size, 0, 1);
5ee91343
AV
17422 else
17423 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
17424 }
17425 else
17426 {
88714cb8 17427 NEON_ENCODE (INTEGER, inst);
5ee91343 17428 if (rs == NS_QQR)
a8465a06 17429 mve_encode_qqr (et.size, et.type == ubit_meaning, 0);
5ee91343
AV
17430 else
17431 neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
5287ad62
JB
17432 }
17433}
17434
5287ad62
JB
17435
17436static void
17437do_neon_dyadic_if_su_d (void)
17438{
17439 /* This version only allow D registers, but that constraint is enforced during
17440 operand parsing so we don't need to do anything extra here. */
dcbf9037 17441 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
17442}
17443
5287ad62
JB
17444static void
17445do_neon_dyadic_if_i_d (void)
17446{
428e3f1f
PB
17447 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17448 affected if we specify unsigned args. */
17449 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
5287ad62
JB
17450}
17451
f5f10c66
AV
17452static void
17453do_mve_vstr_vldr_QI (int size, int elsize, int load)
17454{
17455 constraint (size < 32, BAD_ADDR_MODE);
17456 constraint (size != elsize, BAD_EL_TYPE);
17457 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
17458 constraint (!inst.operands[1].preind, BAD_ADDR_MODE);
17459 constraint (load && inst.operands[0].reg == inst.operands[1].reg,
17460 _("destination register and offset register may not be the"
17461 " same"));
17462
17463 int imm = inst.relocs[0].exp.X_add_number;
17464 int add = 1;
17465 if (imm < 0)
17466 {
17467 add = 0;
17468 imm = -imm;
17469 }
17470 constraint ((imm % (size / 8) != 0)
17471 || imm > (0x7f << neon_logbits (size)),
17472 (size == 32) ? _("immediate must be a multiple of 4 in the"
17473 " range of +/-[0,508]")
17474 : _("immediate must be a multiple of 8 in the"
17475 " range of +/-[0,1016]"));
17476 inst.instruction |= 0x11 << 24;
17477 inst.instruction |= add << 23;
17478 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17479 inst.instruction |= inst.operands[1].writeback << 21;
17480 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17481 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17482 inst.instruction |= 1 << 12;
17483 inst.instruction |= (size == 64) << 8;
17484 inst.instruction &= 0xffffff00;
17485 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17486 inst.instruction |= imm >> neon_logbits (size);
17487}
17488
17489static void
17490do_mve_vstr_vldr_RQ (int size, int elsize, int load)
17491{
17492 unsigned os = inst.operands[1].imm >> 5;
e449ea97 17493 unsigned type = inst.vectype.el[0].type;
f5f10c66
AV
17494 constraint (os != 0 && size == 8,
17495 _("can not shift offsets when accessing less than half-word"));
17496 constraint (os && os != neon_logbits (size),
17497 _("shift immediate must be 1, 2 or 3 for half-word, word"
17498 " or double-word accesses respectively"));
17499 if (inst.operands[1].reg == REG_PC)
17500 as_tsktsk (MVE_BAD_PC);
17501
17502 switch (size)
17503 {
17504 case 8:
17505 constraint (elsize >= 64, BAD_EL_TYPE);
17506 break;
17507 case 16:
17508 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
17509 break;
17510 case 32:
17511 case 64:
17512 constraint (elsize != size, BAD_EL_TYPE);
17513 break;
17514 default:
17515 break;
17516 }
17517 constraint (inst.operands[1].writeback || !inst.operands[1].preind,
17518 BAD_ADDR_MODE);
17519 if (load)
17520 {
17521 constraint (inst.operands[0].reg == (inst.operands[1].imm & 0x1f),
17522 _("destination register and offset register may not be"
17523 " the same"));
e449ea97
SP
17524 constraint (size == elsize && type == NT_signed, BAD_EL_TYPE);
17525 constraint (size != elsize && type != NT_unsigned && type != NT_signed,
f5f10c66 17526 BAD_EL_TYPE);
e449ea97 17527 inst.instruction |= ((size == elsize) || (type == NT_unsigned)) << 28;
f5f10c66
AV
17528 }
17529 else
17530 {
e449ea97 17531 constraint (type != NT_untyped, BAD_EL_TYPE);
f5f10c66
AV
17532 }
17533
17534 inst.instruction |= 1 << 23;
17535 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17536 inst.instruction |= inst.operands[1].reg << 16;
17537 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17538 inst.instruction |= neon_logbits (elsize) << 7;
17539 inst.instruction |= HI1 (inst.operands[1].imm) << 5;
17540 inst.instruction |= LOW4 (inst.operands[1].imm);
17541 inst.instruction |= !!os;
17542}
17543
17544static void
17545do_mve_vstr_vldr_RI (int size, int elsize, int load)
17546{
17547 enum neon_el_type type = inst.vectype.el[0].type;
17548
17549 constraint (size >= 64, BAD_ADDR_MODE);
17550 switch (size)
17551 {
17552 case 16:
17553 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
17554 break;
17555 case 32:
17556 constraint (elsize != size, BAD_EL_TYPE);
17557 break;
17558 default:
17559 break;
17560 }
17561 if (load)
17562 {
17563 constraint (elsize != size && type != NT_unsigned
17564 && type != NT_signed, BAD_EL_TYPE);
17565 }
17566 else
17567 {
17568 constraint (elsize != size && type != NT_untyped, BAD_EL_TYPE);
17569 }
17570
17571 int imm = inst.relocs[0].exp.X_add_number;
17572 int add = 1;
17573 if (imm < 0)
17574 {
17575 add = 0;
17576 imm = -imm;
17577 }
17578
17579 if ((imm % (size / 8) != 0) || imm > (0x7f << neon_logbits (size)))
17580 {
17581 switch (size)
17582 {
17583 case 8:
17584 constraint (1, _("immediate must be in the range of +/-[0,127]"));
17585 break;
17586 case 16:
17587 constraint (1, _("immediate must be a multiple of 2 in the"
17588 " range of +/-[0,254]"));
17589 break;
17590 case 32:
17591 constraint (1, _("immediate must be a multiple of 4 in the"
17592 " range of +/-[0,508]"));
17593 break;
17594 }
17595 }
17596
17597 if (size != elsize)
17598 {
17599 constraint (inst.operands[1].reg > 7, BAD_HIREG);
17600 constraint (inst.operands[0].reg > 14,
17601 _("MVE vector register in the range [Q0..Q7] expected"));
17602 inst.instruction |= (load && type == NT_unsigned) << 28;
17603 inst.instruction |= (size == 16) << 19;
17604 inst.instruction |= neon_logbits (elsize) << 7;
17605 }
17606 else
17607 {
17608 if (inst.operands[1].reg == REG_PC)
17609 as_tsktsk (MVE_BAD_PC);
17610 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
17611 as_tsktsk (MVE_BAD_SP);
17612 inst.instruction |= 1 << 12;
17613 inst.instruction |= neon_logbits (size) << 7;
17614 }
17615 inst.instruction |= inst.operands[1].preind << 24;
17616 inst.instruction |= add << 23;
17617 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17618 inst.instruction |= inst.operands[1].writeback << 21;
17619 inst.instruction |= inst.operands[1].reg << 16;
17620 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17621 inst.instruction &= 0xffffff80;
17622 inst.instruction |= imm >> neon_logbits (size);
17623
17624}
17625
17626static void
17627do_mve_vstr_vldr (void)
17628{
17629 unsigned size;
17630 int load = 0;
17631
17632 if (inst.cond > COND_ALWAYS)
17633 inst.pred_insn_type = INSIDE_VPT_INSN;
17634 else
17635 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17636
17637 switch (inst.instruction)
17638 {
17639 default:
17640 gas_assert (0);
17641 break;
17642 case M_MNEM_vldrb:
17643 load = 1;
17644 /* fall through. */
17645 case M_MNEM_vstrb:
17646 size = 8;
17647 break;
17648 case M_MNEM_vldrh:
17649 load = 1;
17650 /* fall through. */
17651 case M_MNEM_vstrh:
17652 size = 16;
17653 break;
17654 case M_MNEM_vldrw:
17655 load = 1;
17656 /* fall through. */
17657 case M_MNEM_vstrw:
17658 size = 32;
17659 break;
17660 case M_MNEM_vldrd:
17661 load = 1;
17662 /* fall through. */
17663 case M_MNEM_vstrd:
17664 size = 64;
17665 break;
17666 }
17667 unsigned elsize = inst.vectype.el[0].size;
17668
17669 if (inst.operands[1].isquad)
17670 {
17671 /* We are dealing with [Q, imm]{!} cases. */
17672 do_mve_vstr_vldr_QI (size, elsize, load);
17673 }
17674 else
17675 {
17676 if (inst.operands[1].immisreg == 2)
17677 {
17678 /* We are dealing with [R, Q, {UXTW #os}] cases. */
17679 do_mve_vstr_vldr_RQ (size, elsize, load);
17680 }
17681 else if (!inst.operands[1].immisreg)
17682 {
17683 /* We are dealing with [R, Imm]{!}/[R], Imm cases. */
17684 do_mve_vstr_vldr_RI (size, elsize, load);
17685 }
17686 else
17687 constraint (1, BAD_ADDR_MODE);
17688 }
17689
17690 inst.is_neon = 1;
17691}
17692
35c228db
AV
17693static void
17694do_mve_vst_vld (void)
17695{
17696 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17697 return;
17698
17699 constraint (!inst.operands[1].preind || inst.relocs[0].exp.X_add_symbol != 0
17700 || inst.relocs[0].exp.X_add_number != 0
17701 || inst.operands[1].immisreg != 0,
17702 BAD_ADDR_MODE);
17703 constraint (inst.vectype.el[0].size > 32, BAD_EL_TYPE);
17704 if (inst.operands[1].reg == REG_PC)
17705 as_tsktsk (MVE_BAD_PC);
17706 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
17707 as_tsktsk (MVE_BAD_SP);
17708
17709
17710 /* These instructions are one of the "exceptions" mentioned in
17711 handle_pred_state. They are MVE instructions that are not VPT compatible
17712 and do not accept a VPT code, thus appending such a code is a syntax
17713 error. */
17714 if (inst.cond > COND_ALWAYS)
17715 first_error (BAD_SYNTAX);
17716 /* If we append a scalar condition code we can set this to
17717 MVE_OUTSIDE_PRED_INSN as it will also lead to a syntax error. */
17718 else if (inst.cond < COND_ALWAYS)
17719 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17720 else
17721 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
17722
17723 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17724 inst.instruction |= inst.operands[1].writeback << 21;
17725 inst.instruction |= inst.operands[1].reg << 16;
17726 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17727 inst.instruction |= neon_logbits (inst.vectype.el[0].size) << 7;
17728 inst.is_neon = 1;
17729}
17730
26c1e780
AV
17731static void
17732do_mve_vaddlv (void)
17733{
17734 enum neon_shape rs = neon_select_shape (NS_RRQ, NS_NULL);
17735 struct neon_type_el et
17736 = neon_check_type (3, rs, N_EQK, N_EQK, N_S32 | N_U32 | N_KEY);
17737
17738 if (et.type == NT_invtype)
17739 first_error (BAD_EL_TYPE);
17740
17741 if (inst.cond > COND_ALWAYS)
17742 inst.pred_insn_type = INSIDE_VPT_INSN;
17743 else
17744 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17745
17746 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
17747
17748 inst.instruction |= (et.type == NT_unsigned) << 28;
17749 inst.instruction |= inst.operands[1].reg << 19;
17750 inst.instruction |= inst.operands[0].reg << 12;
17751 inst.instruction |= inst.operands[2].reg;
17752 inst.is_neon = 1;
17753}
17754
5287ad62 17755static void
5ee91343 17756do_neon_dyadic_if_su (void)
5287ad62 17757{
5ee91343
AV
17758 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
17759 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
17760 N_SUF_32 | N_KEY);
17761
935295b5
AV
17762 constraint ((inst.instruction == ((unsigned) N_MNEM_vmax)
17763 || inst.instruction == ((unsigned) N_MNEM_vmin))
17764 && et.type == NT_float
17765 && !ARM_CPU_HAS_FEATURE (cpu_variant,fpu_neon_ext_v1), BAD_FPU);
17766
64c350f2
AV
17767 if (!check_simd_pred_availability (et.type == NT_float,
17768 NEON_CHECK_ARCH | NEON_CHECK_CC))
037e8744
JB
17769 return;
17770
5ee91343
AV
17771 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
17772}
17773
17774static void
17775do_neon_addsub_if_i (void)
17776{
17777 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
17778 && try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
037e8744
JB
17779 return;
17780
5ee91343
AV
17781 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
17782 struct neon_type_el et = neon_check_type (3, rs, N_EQK,
17783 N_EQK, N_IF_32 | N_I64 | N_KEY);
17784
17785 constraint (rs == NS_QQR && et.size == 64, BAD_FPU);
17786 /* If we are parsing Q registers and the element types match MVE, which NEON
17787 also supports, then we must check whether this is an instruction that can
17788 be used by both MVE/NEON. This distinction can be made based on whether
17789 they are predicated or not. */
17790 if ((rs == NS_QQQ || rs == NS_QQR) && et.size != 64)
17791 {
64c350f2
AV
17792 if (!check_simd_pred_availability (et.type == NT_float,
17793 NEON_CHECK_ARCH | NEON_CHECK_CC))
5ee91343
AV
17794 return;
17795 }
17796 else
17797 {
17798 /* If they are either in a D register or are using an unsupported. */
17799 if (rs != NS_QQR
17800 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
17801 return;
17802 }
17803
5287ad62
JB
17804 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17805 affected if we specify unsigned args. */
dcbf9037 17806 neon_dyadic_misc (NT_untyped, N_IF_32 | N_I64, 0);
5287ad62
JB
17807}
17808
17809/* Swaps operands 1 and 2. If operand 1 (optional arg) was omitted, we want the
17810 result to be:
17811 V<op> A,B (A is operand 0, B is operand 2)
17812 to mean:
17813 V<op> A,B,A
17814 not:
17815 V<op> A,B,B
17816 so handle that case specially. */
17817
17818static void
17819neon_exchange_operands (void)
17820{
5287ad62
JB
17821 if (inst.operands[1].present)
17822 {
e1fa0163
NC
17823 void *scratch = xmalloc (sizeof (inst.operands[0]));
17824
5287ad62
JB
17825 /* Swap operands[1] and operands[2]. */
17826 memcpy (scratch, &inst.operands[1], sizeof (inst.operands[0]));
17827 inst.operands[1] = inst.operands[2];
17828 memcpy (&inst.operands[2], scratch, sizeof (inst.operands[0]));
e1fa0163 17829 free (scratch);
5287ad62
JB
17830 }
17831 else
17832 {
17833 inst.operands[1] = inst.operands[2];
17834 inst.operands[2] = inst.operands[0];
17835 }
17836}
17837
17838static void
17839neon_compare (unsigned regtypes, unsigned immtypes, int invert)
17840{
17841 if (inst.operands[2].isreg)
17842 {
17843 if (invert)
477330fc 17844 neon_exchange_operands ();
dcbf9037 17845 neon_dyadic_misc (NT_unsigned, regtypes, N_SIZ);
5287ad62
JB
17846 }
17847 else
17848 {
037e8744 17849 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
dcbf9037 17850 struct neon_type_el et = neon_check_type (2, rs,
477330fc 17851 N_EQK | N_SIZ, immtypes | N_KEY);
5287ad62 17852
88714cb8 17853 NEON_ENCODE (IMMED, inst);
5287ad62
JB
17854 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17855 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17856 inst.instruction |= LOW4 (inst.operands[1].reg);
17857 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 17858 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
17859 inst.instruction |= (et.type == NT_float) << 10;
17860 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 17861
88714cb8 17862 neon_dp_fixup (&inst);
5287ad62
JB
17863 }
17864}
17865
17866static void
17867do_neon_cmp (void)
17868{
5b7c81bd 17869 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, false);
5287ad62
JB
17870}
17871
17872static void
17873do_neon_cmp_inv (void)
17874{
5b7c81bd 17875 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, true);
5287ad62
JB
17876}
17877
17878static void
17879do_neon_ceq (void)
17880{
5b7c81bd 17881 neon_compare (N_IF_32, N_IF_32, false);
5287ad62
JB
17882}
17883
17884/* For multiply instructions, we have the possibility of 16-bit or 32-bit
17885 scalars, which are encoded in 5 bits, M : Rm.
17886 For 16-bit scalars, the register is encoded in Rm[2:0] and the index in
17887 M:Rm[3], and for 32-bit scalars, the register is encoded in Rm[3:0] and the
c604a79a
JW
17888 index in M.
17889
17890 Dot Product instructions are similar to multiply instructions except elsize
17891 should always be 32.
17892
17893 This function translates SCALAR, which is GAS's internal encoding of indexed
17894 scalar register, to raw encoding. There is also register and index range
17895 check based on ELSIZE. */
5287ad62
JB
17896
17897static unsigned
17898neon_scalar_for_mul (unsigned scalar, unsigned elsize)
17899{
dcbf9037
JB
17900 unsigned regno = NEON_SCALAR_REG (scalar);
17901 unsigned elno = NEON_SCALAR_INDEX (scalar);
5287ad62
JB
17902
17903 switch (elsize)
17904 {
17905 case 16:
17906 if (regno > 7 || elno > 3)
477330fc 17907 goto bad_scalar;
5287ad62 17908 return regno | (elno << 3);
5f4273c7 17909
5287ad62
JB
17910 case 32:
17911 if (regno > 15 || elno > 1)
477330fc 17912 goto bad_scalar;
5287ad62
JB
17913 return regno | (elno << 4);
17914
17915 default:
17916 bad_scalar:
dcbf9037 17917 first_error (_("scalar out of range for multiply instruction"));
5287ad62
JB
17918 }
17919
17920 return 0;
17921}
17922
17923/* Encode multiply / multiply-accumulate scalar instructions. */
17924
17925static void
17926neon_mul_mac (struct neon_type_el et, int ubit)
17927{
dcbf9037
JB
17928 unsigned scalar;
17929
17930 /* Give a more helpful error message if we have an invalid type. */
17931 if (et.type == NT_invtype)
17932 return;
5f4273c7 17933
dcbf9037 17934 scalar = neon_scalar_for_mul (inst.operands[2].reg, et.size);
5287ad62
JB
17935 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17936 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17937 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17938 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17939 inst.instruction |= LOW4 (scalar);
17940 inst.instruction |= HI1 (scalar) << 5;
17941 inst.instruction |= (et.type == NT_float) << 8;
17942 inst.instruction |= neon_logbits (et.size) << 20;
17943 inst.instruction |= (ubit != 0) << 24;
17944
88714cb8 17945 neon_dp_fixup (&inst);
5287ad62
JB
17946}
17947
17948static void
17949do_neon_mac_maybe_scalar (void)
17950{
037e8744
JB
17951 if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
17952 return;
17953
5b7c81bd 17954 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
17955 return;
17956
5287ad62
JB
17957 if (inst.operands[2].isscalar)
17958 {
a8465a06 17959 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 17960 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 17961 struct neon_type_el et = neon_check_type (3, rs,
589a7d88 17962 N_EQK, N_EQK, N_I16 | N_I32 | N_F_16_32 | N_KEY);
88714cb8 17963 NEON_ENCODE (SCALAR, inst);
037e8744 17964 neon_mul_mac (et, neon_quad (rs));
5287ad62 17965 }
a8465a06
AV
17966 else if (!inst.operands[2].isvec)
17967 {
17968 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
17969
17970 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
17971 neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17972
17973 neon_dyadic_misc (NT_unsigned, N_SU_MVE, 0);
17974 }
5287ad62 17975 else
428e3f1f 17976 {
a8465a06 17977 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
428e3f1f
PB
17978 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17979 affected if we specify unsigned args. */
17980 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
17981 }
5287ad62
JB
17982}
17983
aab2c27d
MM
17984static void
17985do_bfloat_vfma (void)
17986{
17987 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
17988 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
17989 enum neon_shape rs;
17990 int t_bit = 0;
17991
17992 if (inst.instruction != B_MNEM_vfmab)
17993 {
17994 t_bit = 1;
17995 inst.instruction = B_MNEM_vfmat;
17996 }
17997
17998 if (inst.operands[2].isscalar)
17999 {
18000 rs = neon_select_shape (NS_QQS, NS_NULL);
18001 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
18002
18003 inst.instruction |= (1 << 25);
1db66fb6
JB
18004 int idx = inst.operands[2].reg & 0xf;
18005 constraint (!(idx < 4), _("index must be in the range 0 to 3"));
aab2c27d
MM
18006 inst.operands[2].reg >>= 4;
18007 constraint (!(inst.operands[2].reg < 8),
18008 _("indexed register must be less than 8"));
18009 neon_three_args (t_bit);
1db66fb6
JB
18010 inst.instruction |= ((idx & 1) << 3);
18011 inst.instruction |= ((idx & 2) << 4);
aab2c27d
MM
18012 }
18013 else
18014 {
18015 rs = neon_select_shape (NS_QQQ, NS_NULL);
18016 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
18017 neon_three_args (t_bit);
18018 }
18019
18020}
18021
62f3b8c8
PB
18022static void
18023do_neon_fmac (void)
18024{
d58196e0
AV
18025 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_fma)
18026 && try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS)
62f3b8c8
PB
18027 return;
18028
5b7c81bd 18029 if (!check_simd_pred_availability (true, NEON_CHECK_CC | NEON_CHECK_ARCH))
62f3b8c8
PB
18030 return;
18031
d58196e0
AV
18032 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
18033 {
18034 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
18035 struct neon_type_el et = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK,
18036 N_EQK);
18037
18038 if (rs == NS_QQR)
18039 {
aab2c27d 18040
d58196e0
AV
18041 if (inst.operands[2].reg == REG_SP)
18042 as_tsktsk (MVE_BAD_SP);
18043 else if (inst.operands[2].reg == REG_PC)
18044 as_tsktsk (MVE_BAD_PC);
18045
18046 inst.instruction = 0xee310e40;
18047 inst.instruction |= (et.size == 16) << 28;
18048 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18049 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
18050 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18051 inst.instruction |= HI1 (inst.operands[1].reg) << 6;
18052 inst.instruction |= inst.operands[2].reg;
18053 inst.is_neon = 1;
18054 return;
18055 }
18056 }
18057 else
18058 {
18059 constraint (!inst.operands[2].isvec, BAD_FPU);
18060 }
18061
62f3b8c8
PB
18062 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
18063}
18064
aab2c27d
MM
18065static void
18066do_mve_vfma (void)
18067{
18068 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_bf16) &&
18069 inst.cond == COND_ALWAYS)
18070 {
18071 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
18072 inst.instruction = N_MNEM_vfma;
18073 inst.pred_insn_type = INSIDE_VPT_INSN;
18074 inst.cond = 0xf;
18075 return do_neon_fmac();
18076 }
18077 else
18078 {
18079 do_bfloat_vfma();
18080 }
18081}
18082
5287ad62
JB
18083static void
18084do_neon_tst (void)
18085{
037e8744 18086 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
18087 struct neon_type_el et = neon_check_type (3, rs,
18088 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
037e8744 18089 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
18090}
18091
18092/* VMUL with 3 registers allows the P8 type. The scalar version supports the
18093 same types as the MAC equivalents. The polynomial type for this instruction
18094 is encoded the same as the integer type. */
18095
18096static void
18097do_neon_mul (void)
18098{
037e8744
JB
18099 if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
18100 return;
18101
5b7c81bd 18102 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
18103 return;
18104
5287ad62 18105 if (inst.operands[2].isscalar)
a8465a06
AV
18106 {
18107 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
18108 do_neon_mac_maybe_scalar ();
18109 }
5287ad62 18110 else
a8465a06
AV
18111 {
18112 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18113 {
18114 enum neon_shape rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
18115 struct neon_type_el et
18116 = neon_check_type (3, rs, N_EQK, N_EQK, N_I_MVE | N_F_MVE | N_KEY);
18117 if (et.type == NT_float)
18118 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
18119 BAD_FPU);
18120
18121 neon_dyadic_misc (NT_float, N_I_MVE | N_F_MVE, 0);
18122 }
18123 else
18124 {
18125 constraint (!inst.operands[2].isvec, BAD_FPU);
18126 neon_dyadic_misc (NT_poly,
18127 N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
18128 }
18129 }
5287ad62
JB
18130}
18131
18132static void
18133do_neon_qdmulh (void)
18134{
5b7c81bd 18135 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
42b16635
AV
18136 return;
18137
5287ad62
JB
18138 if (inst.operands[2].isscalar)
18139 {
42b16635 18140 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 18141 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 18142 struct neon_type_el et = neon_check_type (3, rs,
477330fc 18143 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 18144 NEON_ENCODE (SCALAR, inst);
037e8744 18145 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
18146 }
18147 else
18148 {
42b16635
AV
18149 enum neon_shape rs;
18150 struct neon_type_el et;
18151 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18152 {
18153 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
18154 et = neon_check_type (3, rs,
18155 N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18156 }
18157 else
18158 {
18159 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
18160 et = neon_check_type (3, rs,
18161 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18162 }
18163
88714cb8 18164 NEON_ENCODE (INTEGER, inst);
42b16635
AV
18165 if (rs == NS_QQR)
18166 mve_encode_qqr (et.size, 0, 0);
18167 else
18168 /* The U bit (rounding) comes from bit mask. */
18169 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
18170 }
18171}
18172
26c1e780
AV
18173static void
18174do_mve_vaddv (void)
18175{
18176 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18177 struct neon_type_el et
18178 = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
18179
18180 if (et.type == NT_invtype)
18181 first_error (BAD_EL_TYPE);
18182
18183 if (inst.cond > COND_ALWAYS)
18184 inst.pred_insn_type = INSIDE_VPT_INSN;
18185 else
18186 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18187
18188 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
18189
18190 mve_encode_rq (et.type == NT_unsigned, et.size);
18191}
18192
7df54120
AV
18193static void
18194do_mve_vhcadd (void)
18195{
18196 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
18197 struct neon_type_el et
18198 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18199
18200 if (inst.cond > COND_ALWAYS)
18201 inst.pred_insn_type = INSIDE_VPT_INSN;
18202 else
18203 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18204
18205 unsigned rot = inst.relocs[0].exp.X_add_number;
18206 constraint (rot != 90 && rot != 270, _("immediate out of range"));
18207
18208 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
18209 as_tsktsk (_("Warning: 32-bit element size and same first and third "
18210 "operand makes instruction UNPREDICTABLE"));
18211
18212 mve_encode_qqq (0, et.size);
18213 inst.instruction |= (rot == 270) << 12;
18214 inst.is_neon = 1;
18215}
18216
35d1cfc2
AV
18217static void
18218do_mve_vqdmull (void)
18219{
18220 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
18221 struct neon_type_el et
18222 = neon_check_type (3, rs, N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18223
18224 if (et.size == 32
18225 && (inst.operands[0].reg == inst.operands[1].reg
18226 || (rs == NS_QQQ && inst.operands[0].reg == inst.operands[2].reg)))
18227 as_tsktsk (BAD_MVE_SRCDEST);
18228
18229 if (inst.cond > COND_ALWAYS)
18230 inst.pred_insn_type = INSIDE_VPT_INSN;
18231 else
18232 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18233
18234 if (rs == NS_QQQ)
18235 {
18236 mve_encode_qqq (et.size == 32, 64);
18237 inst.instruction |= 1;
18238 }
18239 else
18240 {
18241 mve_encode_qqr (64, et.size == 32, 0);
18242 inst.instruction |= 0x3 << 5;
18243 }
18244}
18245
c2dafc2a
AV
18246static void
18247do_mve_vadc (void)
18248{
18249 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
18250 struct neon_type_el et
18251 = neon_check_type (3, rs, N_KEY | N_I32, N_EQK, N_EQK);
18252
18253 if (et.type == NT_invtype)
18254 first_error (BAD_EL_TYPE);
18255
18256 if (inst.cond > COND_ALWAYS)
18257 inst.pred_insn_type = INSIDE_VPT_INSN;
18258 else
18259 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18260
18261 mve_encode_qqq (0, 64);
18262}
18263
18264static void
18265do_mve_vbrsr (void)
18266{
18267 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18268 struct neon_type_el et
18269 = neon_check_type (3, rs, N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18270
18271 if (inst.cond > COND_ALWAYS)
18272 inst.pred_insn_type = INSIDE_VPT_INSN;
18273 else
18274 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18275
7df54120 18276 mve_encode_qqr (et.size, 0, 0);
c2dafc2a
AV
18277}
18278
18279static void
18280do_mve_vsbc (void)
18281{
18282 neon_check_type (3, NS_QQQ, N_EQK, N_EQK, N_I32 | N_KEY);
18283
18284 if (inst.cond > COND_ALWAYS)
18285 inst.pred_insn_type = INSIDE_VPT_INSN;
18286 else
18287 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18288
18289 mve_encode_qqq (1, 64);
18290}
18291
2d78f95b
AV
18292static void
18293do_mve_vmulh (void)
18294{
18295 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
18296 struct neon_type_el et
18297 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
18298
18299 if (inst.cond > COND_ALWAYS)
18300 inst.pred_insn_type = INSIDE_VPT_INSN;
18301 else
18302 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18303
18304 mve_encode_qqq (et.type == NT_unsigned, et.size);
18305}
18306
42b16635
AV
18307static void
18308do_mve_vqdmlah (void)
18309{
18310 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18311 struct neon_type_el et
23d188c7 18312 = neon_check_type (3, rs, N_EQK, N_EQK, N_S_32 | N_KEY);
42b16635
AV
18313
18314 if (inst.cond > COND_ALWAYS)
18315 inst.pred_insn_type = INSIDE_VPT_INSN;
18316 else
18317 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18318
18319 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
18320}
8b8b22a4
AV
18321
18322static void
18323do_mve_vqdmladh (void)
18324{
18325 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
18326 struct neon_type_el et
18327 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18328
18329 if (inst.cond > COND_ALWAYS)
18330 inst.pred_insn_type = INSIDE_VPT_INSN;
18331 else
18332 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18333
8b8b22a4
AV
18334 mve_encode_qqq (0, et.size);
18335}
18336
18337
886e1c73
AV
18338static void
18339do_mve_vmull (void)
18340{
18341
18342 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_DDS,
18343 NS_QQS, NS_QQQ, NS_QQR, NS_NULL);
fe05f369 18344 if (inst.cond == COND_ALWAYS
886e1c73
AV
18345 && ((unsigned)inst.instruction) == M_MNEM_vmullt)
18346 {
fe05f369 18347
886e1c73
AV
18348 if (rs == NS_QQQ)
18349 {
fe05f369 18350 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
886e1c73
AV
18351 goto neon_vmul;
18352 }
18353 else
18354 goto neon_vmul;
18355 }
18356
18357 constraint (rs != NS_QQQ, BAD_FPU);
18358 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
18359 N_SU_32 | N_P8 | N_P16 | N_KEY);
18360
18361 /* We are dealing with MVE's vmullt. */
18362 if (et.size == 32
18363 && (inst.operands[0].reg == inst.operands[1].reg
18364 || inst.operands[0].reg == inst.operands[2].reg))
18365 as_tsktsk (BAD_MVE_SRCDEST);
18366
18367 if (inst.cond > COND_ALWAYS)
18368 inst.pred_insn_type = INSIDE_VPT_INSN;
18369 else
18370 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18371
18372 if (et.type == NT_poly)
18373 mve_encode_qqq (neon_logbits (et.size), 64);
18374 else
18375 mve_encode_qqq (et.type == NT_unsigned, et.size);
18376
18377 return;
18378
dc1e8a47 18379 neon_vmul:
886e1c73
AV
18380 inst.instruction = N_MNEM_vmul;
18381 inst.cond = 0xb;
18382 if (thumb_mode)
18383 inst.pred_insn_type = INSIDE_IT_INSN;
18384 do_neon_mul ();
18385}
18386
a302e574
AV
18387static void
18388do_mve_vabav (void)
18389{
18390 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
18391
18392 if (rs == NS_NULL)
18393 return;
18394
18395 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18396 return;
18397
18398 struct neon_type_el et = neon_check_type (2, NS_NULL, N_EQK, N_KEY | N_S8
18399 | N_S16 | N_S32 | N_U8 | N_U16
18400 | N_U32);
18401
18402 if (inst.cond > COND_ALWAYS)
18403 inst.pred_insn_type = INSIDE_VPT_INSN;
18404 else
18405 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18406
18407 mve_encode_rqq (et.type == NT_unsigned, et.size);
18408}
18409
18410static void
18411do_mve_vmladav (void)
18412{
18413 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
18414 struct neon_type_el et = neon_check_type (3, rs,
18415 N_EQK, N_EQK, N_SU_MVE | N_KEY);
18416
18417 if (et.type == NT_unsigned
18418 && (inst.instruction == M_MNEM_vmladavx
18419 || inst.instruction == M_MNEM_vmladavax
18420 || inst.instruction == M_MNEM_vmlsdav
18421 || inst.instruction == M_MNEM_vmlsdava
18422 || inst.instruction == M_MNEM_vmlsdavx
18423 || inst.instruction == M_MNEM_vmlsdavax))
18424 first_error (BAD_SIMD_TYPE);
18425
18426 constraint (inst.operands[2].reg > 14,
18427 _("MVE vector register in the range [Q0..Q7] expected"));
18428
18429 if (inst.cond > COND_ALWAYS)
18430 inst.pred_insn_type = INSIDE_VPT_INSN;
18431 else
18432 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18433
18434 if (inst.instruction == M_MNEM_vmlsdav
18435 || inst.instruction == M_MNEM_vmlsdava
18436 || inst.instruction == M_MNEM_vmlsdavx
18437 || inst.instruction == M_MNEM_vmlsdavax)
18438 inst.instruction |= (et.size == 8) << 28;
18439 else
18440 inst.instruction |= (et.size == 8) << 8;
18441
18442 mve_encode_rqq (et.type == NT_unsigned, 64);
18443 inst.instruction |= (et.size == 32) << 16;
18444}
18445
93925576
AV
18446static void
18447do_mve_vmlaldav (void)
18448{
18449 enum neon_shape rs = neon_select_shape (NS_RRQQ, NS_NULL);
18450 struct neon_type_el et
18451 = neon_check_type (4, rs, N_EQK, N_EQK, N_EQK,
18452 N_S16 | N_S32 | N_U16 | N_U32 | N_KEY);
18453
18454 if (et.type == NT_unsigned
18455 && (inst.instruction == M_MNEM_vmlsldav
18456 || inst.instruction == M_MNEM_vmlsldava
18457 || inst.instruction == M_MNEM_vmlsldavx
18458 || inst.instruction == M_MNEM_vmlsldavax))
18459 first_error (BAD_SIMD_TYPE);
18460
18461 if (inst.cond > COND_ALWAYS)
18462 inst.pred_insn_type = INSIDE_VPT_INSN;
18463 else
18464 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18465
18466 mve_encode_rrqq (et.type == NT_unsigned, et.size);
18467}
18468
18469static void
18470do_mve_vrmlaldavh (void)
18471{
18472 struct neon_type_el et;
18473 if (inst.instruction == M_MNEM_vrmlsldavh
18474 || inst.instruction == M_MNEM_vrmlsldavha
18475 || inst.instruction == M_MNEM_vrmlsldavhx
18476 || inst.instruction == M_MNEM_vrmlsldavhax)
18477 {
18478 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
18479 if (inst.operands[1].reg == REG_SP)
18480 as_tsktsk (MVE_BAD_SP);
18481 }
18482 else
18483 {
18484 if (inst.instruction == M_MNEM_vrmlaldavhx
18485 || inst.instruction == M_MNEM_vrmlaldavhax)
18486 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
18487 else
18488 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK,
18489 N_U32 | N_S32 | N_KEY);
18490 /* vrmlaldavh's encoding with SP as the second, odd, GPR operand may alias
18491 with vmax/min instructions, making the use of SP in assembly really
18492 nonsensical, so instead of issuing a warning like we do for other uses
18493 of SP for the odd register operand we error out. */
18494 constraint (inst.operands[1].reg == REG_SP, BAD_SP);
18495 }
18496
18497 /* Make sure we still check the second operand is an odd one and that PC is
18498 disallowed. This because we are parsing for any GPR operand, to be able
18499 to distinguish between giving a warning or an error for SP as described
18500 above. */
18501 constraint ((inst.operands[1].reg % 2) != 1, BAD_EVEN);
18502 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
18503
18504 if (inst.cond > COND_ALWAYS)
18505 inst.pred_insn_type = INSIDE_VPT_INSN;
18506 else
18507 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18508
18509 mve_encode_rrqq (et.type == NT_unsigned, 0);
18510}
18511
18512
8cd78170
AV
18513static void
18514do_mve_vmaxnmv (void)
18515{
18516 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18517 struct neon_type_el et
18518 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
18519
18520 if (inst.cond > COND_ALWAYS)
18521 inst.pred_insn_type = INSIDE_VPT_INSN;
18522 else
18523 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18524
18525 if (inst.operands[0].reg == REG_SP)
18526 as_tsktsk (MVE_BAD_SP);
18527 else if (inst.operands[0].reg == REG_PC)
18528 as_tsktsk (MVE_BAD_PC);
18529
18530 mve_encode_rq (et.size == 16, 64);
18531}
18532
13ccd4c0
AV
18533static void
18534do_mve_vmaxv (void)
18535{
18536 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18537 struct neon_type_el et;
18538
18539 if (inst.instruction == M_MNEM_vmaxv || inst.instruction == M_MNEM_vminv)
18540 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
18541 else
18542 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18543
18544 if (inst.cond > COND_ALWAYS)
18545 inst.pred_insn_type = INSIDE_VPT_INSN;
18546 else
18547 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18548
18549 if (inst.operands[0].reg == REG_SP)
18550 as_tsktsk (MVE_BAD_SP);
18551 else if (inst.operands[0].reg == REG_PC)
18552 as_tsktsk (MVE_BAD_PC);
18553
18554 mve_encode_rq (et.type == NT_unsigned, et.size);
18555}
18556
18557
643afb90
MW
18558static void
18559do_neon_qrdmlah (void)
18560{
5b7c81bd 18561 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
42b16635
AV
18562 return;
18563 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
643afb90 18564 {
42b16635
AV
18565 /* Check we're on the correct architecture. */
18566 if (!mark_feature_used (&fpu_neon_ext_armv8))
18567 inst.error
18568 = _("instruction form not available on this architecture.");
18569 else if (!mark_feature_used (&fpu_neon_ext_v8_1))
18570 {
18571 as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
18572 record_feature_use (&fpu_neon_ext_v8_1);
18573 }
18574 if (inst.operands[2].isscalar)
18575 {
18576 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
18577 struct neon_type_el et = neon_check_type (3, rs,
18578 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18579 NEON_ENCODE (SCALAR, inst);
18580 neon_mul_mac (et, neon_quad (rs));
18581 }
18582 else
18583 {
18584 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
18585 struct neon_type_el et = neon_check_type (3, rs,
18586 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18587 NEON_ENCODE (INTEGER, inst);
18588 /* The U bit (rounding) comes from bit mask. */
18589 neon_three_same (neon_quad (rs), 0, et.size);
18590 }
643afb90
MW
18591 }
18592 else
18593 {
42b16635
AV
18594 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18595 struct neon_type_el et
23d188c7 18596 = neon_check_type (3, rs, N_EQK, N_EQK, N_S_32 | N_KEY);
42b16635 18597
643afb90 18598 NEON_ENCODE (INTEGER, inst);
42b16635 18599 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
643afb90
MW
18600 }
18601}
18602
5287ad62
JB
18603static void
18604do_neon_fcmp_absolute (void)
18605{
037e8744 18606 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
18607 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
18608 N_F_16_32 | N_KEY);
5287ad62 18609 /* Size field comes from bit mask. */
cc933301 18610 neon_three_same (neon_quad (rs), 1, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
18611}
18612
18613static void
18614do_neon_fcmp_absolute_inv (void)
18615{
18616 neon_exchange_operands ();
18617 do_neon_fcmp_absolute ();
18618}
18619
18620static void
18621do_neon_step (void)
18622{
037e8744 18623 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
18624 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
18625 N_F_16_32 | N_KEY);
18626 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
18627}
18628
18629static void
18630do_neon_abs_neg (void)
18631{
037e8744
JB
18632 enum neon_shape rs;
18633 struct neon_type_el et;
5f4273c7 18634
037e8744
JB
18635 if (try_vfp_nsyn (2, do_vfp_nsyn_abs_neg) == SUCCESS)
18636 return;
18637
037e8744 18638 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
cc933301 18639 et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
5f4273c7 18640
64c350f2
AV
18641 if (!check_simd_pred_availability (et.type == NT_float,
18642 NEON_CHECK_ARCH | NEON_CHECK_CC))
485dee97
AV
18643 return;
18644
5287ad62
JB
18645 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18646 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18647 inst.instruction |= LOW4 (inst.operands[1].reg);
18648 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 18649 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18650 inst.instruction |= (et.type == NT_float) << 10;
18651 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 18652
88714cb8 18653 neon_dp_fixup (&inst);
5287ad62
JB
18654}
18655
18656static void
18657do_neon_sli (void)
18658{
5b7c81bd 18659 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
18660 return;
18661
18662 enum neon_shape rs;
18663 struct neon_type_el et;
18664 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18665 {
18666 rs = neon_select_shape (NS_QQI, NS_NULL);
18667 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18668 }
18669 else
18670 {
18671 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18672 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18673 }
18674
18675
5287ad62
JB
18676 int imm = inst.operands[2].imm;
18677 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 18678 _("immediate out of range for insert"));
5b7c81bd 18679 neon_imm_shift (false, 0, neon_quad (rs), et, imm);
5287ad62
JB
18680}
18681
18682static void
18683do_neon_sri (void)
18684{
5b7c81bd 18685 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
18686 return;
18687
18688 enum neon_shape rs;
18689 struct neon_type_el et;
18690 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18691 {
18692 rs = neon_select_shape (NS_QQI, NS_NULL);
18693 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18694 }
18695 else
18696 {
18697 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18698 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18699 }
18700
5287ad62
JB
18701 int imm = inst.operands[2].imm;
18702 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18703 _("immediate out of range for insert"));
5b7c81bd 18704 neon_imm_shift (false, 0, neon_quad (rs), et, et.size - imm);
5287ad62
JB
18705}
18706
18707static void
18708do_neon_qshlu_imm (void)
18709{
5b7c81bd 18710 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
18711 return;
18712
18713 enum neon_shape rs;
18714 struct neon_type_el et;
18715 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18716 {
18717 rs = neon_select_shape (NS_QQI, NS_NULL);
18718 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18719 }
18720 else
18721 {
18722 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18723 et = neon_check_type (2, rs, N_EQK | N_UNS,
18724 N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
18725 }
18726
5287ad62
JB
18727 int imm = inst.operands[2].imm;
18728 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 18729 _("immediate out of range for shift"));
5287ad62
JB
18730 /* Only encodes the 'U present' variant of the instruction.
18731 In this case, signed types have OP (bit 8) set to 0.
18732 Unsigned types have OP set to 1. */
18733 inst.instruction |= (et.type == NT_unsigned) << 8;
18734 /* The rest of the bits are the same as other immediate shifts. */
5b7c81bd 18735 neon_imm_shift (false, 0, neon_quad (rs), et, imm);
5287ad62
JB
18736}
18737
18738static void
18739do_neon_qmovn (void)
18740{
18741 struct neon_type_el et = neon_check_type (2, NS_DQ,
18742 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
18743 /* Saturating move where operands can be signed or unsigned, and the
18744 destination has the same signedness. */
88714cb8 18745 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18746 if (et.type == NT_unsigned)
18747 inst.instruction |= 0xc0;
18748 else
18749 inst.instruction |= 0x80;
18750 neon_two_same (0, 1, et.size / 2);
18751}
18752
18753static void
18754do_neon_qmovun (void)
18755{
18756 struct neon_type_el et = neon_check_type (2, NS_DQ,
18757 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
18758 /* Saturating move with unsigned results. Operands must be signed. */
88714cb8 18759 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18760 neon_two_same (0, 1, et.size / 2);
18761}
18762
18763static void
18764do_neon_rshift_sat_narrow (void)
18765{
18766 /* FIXME: Types for narrowing. If operands are signed, results can be signed
18767 or unsigned. If operands are unsigned, results must also be unsigned. */
18768 struct neon_type_el et = neon_check_type (2, NS_DQI,
18769 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
18770 int imm = inst.operands[2].imm;
18771 /* This gets the bounds check, size encoding and immediate bits calculation
18772 right. */
18773 et.size /= 2;
5f4273c7 18774
5287ad62
JB
18775 /* VQ{R}SHRN.I<size> <Dd>, <Qm>, #0 is a synonym for
18776 VQMOVN.I<size> <Dd>, <Qm>. */
18777 if (imm == 0)
18778 {
18779 inst.operands[2].present = 0;
18780 inst.instruction = N_MNEM_vqmovn;
18781 do_neon_qmovn ();
18782 return;
18783 }
5f4273c7 18784
5287ad62 18785 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18786 _("immediate out of range"));
5b7c81bd 18787 neon_imm_shift (true, et.type == NT_unsigned, 0, et, et.size - imm);
5287ad62
JB
18788}
18789
18790static void
18791do_neon_rshift_sat_narrow_u (void)
18792{
18793 /* FIXME: Types for narrowing. If operands are signed, results can be signed
18794 or unsigned. If operands are unsigned, results must also be unsigned. */
18795 struct neon_type_el et = neon_check_type (2, NS_DQI,
18796 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
18797 int imm = inst.operands[2].imm;
18798 /* This gets the bounds check, size encoding and immediate bits calculation
18799 right. */
18800 et.size /= 2;
18801
18802 /* VQSHRUN.I<size> <Dd>, <Qm>, #0 is a synonym for
18803 VQMOVUN.I<size> <Dd>, <Qm>. */
18804 if (imm == 0)
18805 {
18806 inst.operands[2].present = 0;
18807 inst.instruction = N_MNEM_vqmovun;
18808 do_neon_qmovun ();
18809 return;
18810 }
18811
18812 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18813 _("immediate out of range"));
5287ad62
JB
18814 /* FIXME: The manual is kind of unclear about what value U should have in
18815 VQ{R}SHRUN instructions, but U=0, op=0 definitely encodes VRSHR, so it
18816 must be 1. */
5b7c81bd 18817 neon_imm_shift (true, 1, 0, et, et.size - imm);
5287ad62
JB
18818}
18819
18820static void
18821do_neon_movn (void)
18822{
18823 struct neon_type_el et = neon_check_type (2, NS_DQ,
18824 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
88714cb8 18825 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18826 neon_two_same (0, 1, et.size / 2);
18827}
18828
18829static void
18830do_neon_rshift_narrow (void)
18831{
18832 struct neon_type_el et = neon_check_type (2, NS_DQI,
18833 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
18834 int imm = inst.operands[2].imm;
18835 /* This gets the bounds check, size encoding and immediate bits calculation
18836 right. */
18837 et.size /= 2;
5f4273c7 18838
5287ad62
JB
18839 /* If immediate is zero then we are a pseudo-instruction for
18840 VMOVN.I<size> <Dd>, <Qm> */
18841 if (imm == 0)
18842 {
18843 inst.operands[2].present = 0;
18844 inst.instruction = N_MNEM_vmovn;
18845 do_neon_movn ();
18846 return;
18847 }
5f4273c7 18848
5287ad62 18849 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18850 _("immediate out of range for narrowing operation"));
5b7c81bd 18851 neon_imm_shift (false, 0, 0, et, et.size - imm);
5287ad62
JB
18852}
18853
18854static void
18855do_neon_shll (void)
18856{
18857 /* FIXME: Type checking when lengthening. */
18858 struct neon_type_el et = neon_check_type (2, NS_QDI,
18859 N_EQK | N_DBL, N_I8 | N_I16 | N_I32 | N_KEY);
18860 unsigned imm = inst.operands[2].imm;
18861
18862 if (imm == et.size)
18863 {
18864 /* Maximum shift variant. */
88714cb8 18865 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18866 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18867 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18868 inst.instruction |= LOW4 (inst.operands[1].reg);
18869 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18870 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 18871
88714cb8 18872 neon_dp_fixup (&inst);
5287ad62
JB
18873 }
18874 else
18875 {
18876 /* A more-specific type check for non-max versions. */
18877 et = neon_check_type (2, NS_QDI,
477330fc 18878 N_EQK | N_DBL, N_SU_32 | N_KEY);
88714cb8 18879 NEON_ENCODE (IMMED, inst);
5b7c81bd 18880 neon_imm_shift (true, et.type == NT_unsigned, 0, et, imm);
5287ad62
JB
18881 }
18882}
18883
037e8744 18884/* Check the various types for the VCVT instruction, and return which version
5287ad62
JB
18885 the current instruction is. */
18886
6b9a8b67
MGD
18887#define CVT_FLAVOUR_VAR \
18888 CVT_VAR (s32_f32, N_S32, N_F32, whole_reg, "ftosls", "ftosis", "ftosizs") \
18889 CVT_VAR (u32_f32, N_U32, N_F32, whole_reg, "ftouls", "ftouis", "ftouizs") \
18890 CVT_VAR (f32_s32, N_F32, N_S32, whole_reg, "fsltos", "fsitos", NULL) \
18891 CVT_VAR (f32_u32, N_F32, N_U32, whole_reg, "fultos", "fuitos", NULL) \
18892 /* Half-precision conversions. */ \
cc933301
JW
18893 CVT_VAR (s16_f16, N_S16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
18894 CVT_VAR (u16_f16, N_U16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
18895 CVT_VAR (f16_s16, N_F16 | N_KEY, N_S16, whole_reg, NULL, NULL, NULL) \
18896 CVT_VAR (f16_u16, N_F16 | N_KEY, N_U16, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
18897 CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
18898 CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
9db2f6b4
RL
18899 /* New VCVT instructions introduced by ARMv8.2 fp16 extension. \
18900 Compared with single/double precision variants, only the co-processor \
18901 field is different, so the encoding flow is reused here. */ \
18902 CVT_VAR (f16_s32, N_F16 | N_KEY, N_S32, N_VFP, "fsltos", "fsitos", NULL) \
18903 CVT_VAR (f16_u32, N_F16 | N_KEY, N_U32, N_VFP, "fultos", "fuitos", NULL) \
18904 CVT_VAR (u32_f16, N_U32, N_F16 | N_KEY, N_VFP, "ftouls", "ftouis", "ftouizs")\
18905 CVT_VAR (s32_f16, N_S32, N_F16 | N_KEY, N_VFP, "ftosls", "ftosis", "ftosizs")\
aab2c27d 18906 CVT_VAR (bf16_f32, N_BF16, N_F32, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
18907 /* VFP instructions. */ \
18908 CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
18909 CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
18910 CVT_VAR (s32_f64, N_S32, N_F64 | key, N_VFP, "ftosld", "ftosid", "ftosizd") \
18911 CVT_VAR (u32_f64, N_U32, N_F64 | key, N_VFP, "ftould", "ftouid", "ftouizd") \
18912 CVT_VAR (f64_s32, N_F64 | key, N_S32, N_VFP, "fsltod", "fsitod", NULL) \
18913 CVT_VAR (f64_u32, N_F64 | key, N_U32, N_VFP, "fultod", "fuitod", NULL) \
18914 /* VFP instructions with bitshift. */ \
18915 CVT_VAR (f32_s16, N_F32 | key, N_S16, N_VFP, "fshtos", NULL, NULL) \
18916 CVT_VAR (f32_u16, N_F32 | key, N_U16, N_VFP, "fuhtos", NULL, NULL) \
18917 CVT_VAR (f64_s16, N_F64 | key, N_S16, N_VFP, "fshtod", NULL, NULL) \
18918 CVT_VAR (f64_u16, N_F64 | key, N_U16, N_VFP, "fuhtod", NULL, NULL) \
18919 CVT_VAR (s16_f32, N_S16, N_F32 | key, N_VFP, "ftoshs", NULL, NULL) \
18920 CVT_VAR (u16_f32, N_U16, N_F32 | key, N_VFP, "ftouhs", NULL, NULL) \
18921 CVT_VAR (s16_f64, N_S16, N_F64 | key, N_VFP, "ftoshd", NULL, NULL) \
18922 CVT_VAR (u16_f64, N_U16, N_F64 | key, N_VFP, "ftouhd", NULL, NULL)
18923
18924#define CVT_VAR(C, X, Y, R, BSN, CN, ZN) \
18925 neon_cvt_flavour_##C,
18926
18927/* The different types of conversions we can do. */
18928enum neon_cvt_flavour
18929{
18930 CVT_FLAVOUR_VAR
18931 neon_cvt_flavour_invalid,
18932 neon_cvt_flavour_first_fp = neon_cvt_flavour_f32_f64
18933};
18934
18935#undef CVT_VAR
18936
18937static enum neon_cvt_flavour
18938get_neon_cvt_flavour (enum neon_shape rs)
5287ad62 18939{
6b9a8b67
MGD
18940#define CVT_VAR(C,X,Y,R,BSN,CN,ZN) \
18941 et = neon_check_type (2, rs, (R) | (X), (R) | (Y)); \
18942 if (et.type != NT_invtype) \
18943 { \
18944 inst.error = NULL; \
18945 return (neon_cvt_flavour_##C); \
5287ad62 18946 }
6b9a8b67 18947
5287ad62 18948 struct neon_type_el et;
037e8744 18949 unsigned whole_reg = (rs == NS_FFI || rs == NS_FD || rs == NS_DF
477330fc 18950 || rs == NS_FF) ? N_VFP : 0;
037e8744
JB
18951 /* The instruction versions which take an immediate take one register
18952 argument, which is extended to the width of the full register. Thus the
18953 "source" and "destination" registers must have the same width. Hack that
18954 here by making the size equal to the key (wider, in this case) operand. */
18955 unsigned key = (rs == NS_QQI || rs == NS_DDI || rs == NS_FFI) ? N_KEY : 0;
5f4273c7 18956
6b9a8b67
MGD
18957 CVT_FLAVOUR_VAR;
18958
18959 return neon_cvt_flavour_invalid;
5287ad62
JB
18960#undef CVT_VAR
18961}
18962
7e8e6784
MGD
18963enum neon_cvt_mode
18964{
18965 neon_cvt_mode_a,
18966 neon_cvt_mode_n,
18967 neon_cvt_mode_p,
18968 neon_cvt_mode_m,
18969 neon_cvt_mode_z,
30bdf752
MGD
18970 neon_cvt_mode_x,
18971 neon_cvt_mode_r
7e8e6784
MGD
18972};
18973
037e8744
JB
18974/* Neon-syntax VFP conversions. */
18975
5287ad62 18976static void
6b9a8b67 18977do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
5287ad62 18978{
037e8744 18979 const char *opname = 0;
5f4273c7 18980
d54af2d0
RL
18981 if (rs == NS_DDI || rs == NS_QQI || rs == NS_FFI
18982 || rs == NS_FHI || rs == NS_HFI)
5287ad62 18983 {
037e8744
JB
18984 /* Conversions with immediate bitshift. */
18985 const char *enc[] =
477330fc 18986 {
6b9a8b67
MGD
18987#define CVT_VAR(C,A,B,R,BSN,CN,ZN) BSN,
18988 CVT_FLAVOUR_VAR
18989 NULL
18990#undef CVT_VAR
477330fc 18991 };
037e8744 18992
6b9a8b67 18993 if (flavour < (int) ARRAY_SIZE (enc))
477330fc
RM
18994 {
18995 opname = enc[flavour];
18996 constraint (inst.operands[0].reg != inst.operands[1].reg,
18997 _("operands 0 and 1 must be the same register"));
18998 inst.operands[1] = inst.operands[2];
18999 memset (&inst.operands[2], '\0', sizeof (inst.operands[2]));
19000 }
5287ad62
JB
19001 }
19002 else
19003 {
037e8744
JB
19004 /* Conversions without bitshift. */
19005 const char *enc[] =
477330fc 19006 {
6b9a8b67
MGD
19007#define CVT_VAR(C,A,B,R,BSN,CN,ZN) CN,
19008 CVT_FLAVOUR_VAR
19009 NULL
19010#undef CVT_VAR
477330fc 19011 };
037e8744 19012
6b9a8b67 19013 if (flavour < (int) ARRAY_SIZE (enc))
477330fc 19014 opname = enc[flavour];
037e8744
JB
19015 }
19016
19017 if (opname)
19018 do_vfp_nsyn_opcode (opname);
9db2f6b4
RL
19019
19020 /* ARMv8.2 fp16 VCVT instruction. */
19021 if (flavour == neon_cvt_flavour_s32_f16
19022 || flavour == neon_cvt_flavour_u32_f16
19023 || flavour == neon_cvt_flavour_f16_u32
19024 || flavour == neon_cvt_flavour_f16_s32)
19025 do_scalar_fp16_v82_encode ();
037e8744
JB
19026}
19027
19028static void
19029do_vfp_nsyn_cvtz (void)
19030{
d54af2d0 19031 enum neon_shape rs = neon_select_shape (NS_FH, NS_FF, NS_FD, NS_NULL);
6b9a8b67 19032 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744
JB
19033 const char *enc[] =
19034 {
6b9a8b67
MGD
19035#define CVT_VAR(C,A,B,R,BSN,CN,ZN) ZN,
19036 CVT_FLAVOUR_VAR
19037 NULL
19038#undef CVT_VAR
037e8744
JB
19039 };
19040
6b9a8b67 19041 if (flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
037e8744
JB
19042 do_vfp_nsyn_opcode (enc[flavour]);
19043}
f31fef98 19044
037e8744 19045static void
bacebabc 19046do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
7e8e6784
MGD
19047 enum neon_cvt_mode mode)
19048{
19049 int sz, op;
19050 int rm;
19051
a715796b
TG
19052 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
19053 D register operands. */
19054 if (flavour == neon_cvt_flavour_s32_f64
19055 || flavour == neon_cvt_flavour_u32_f64)
19056 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19057 _(BAD_FPU));
19058
9db2f6b4
RL
19059 if (flavour == neon_cvt_flavour_s32_f16
19060 || flavour == neon_cvt_flavour_u32_f16)
19061 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
19062 _(BAD_FP16));
19063
5ee91343 19064 set_pred_insn_type (OUTSIDE_PRED_INSN);
7e8e6784
MGD
19065
19066 switch (flavour)
19067 {
19068 case neon_cvt_flavour_s32_f64:
19069 sz = 1;
827f64ff 19070 op = 1;
7e8e6784
MGD
19071 break;
19072 case neon_cvt_flavour_s32_f32:
19073 sz = 0;
19074 op = 1;
19075 break;
9db2f6b4
RL
19076 case neon_cvt_flavour_s32_f16:
19077 sz = 0;
19078 op = 1;
19079 break;
7e8e6784
MGD
19080 case neon_cvt_flavour_u32_f64:
19081 sz = 1;
19082 op = 0;
19083 break;
19084 case neon_cvt_flavour_u32_f32:
19085 sz = 0;
19086 op = 0;
19087 break;
9db2f6b4
RL
19088 case neon_cvt_flavour_u32_f16:
19089 sz = 0;
19090 op = 0;
19091 break;
7e8e6784
MGD
19092 default:
19093 first_error (_("invalid instruction shape"));
19094 return;
19095 }
19096
19097 switch (mode)
19098 {
19099 case neon_cvt_mode_a: rm = 0; break;
19100 case neon_cvt_mode_n: rm = 1; break;
19101 case neon_cvt_mode_p: rm = 2; break;
19102 case neon_cvt_mode_m: rm = 3; break;
19103 default: first_error (_("invalid rounding mode")); return;
19104 }
19105
19106 NEON_ENCODE (FPV8, inst);
19107 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
19108 encode_arm_vfp_reg (inst.operands[1].reg, sz == 1 ? VFP_REG_Dm : VFP_REG_Sm);
19109 inst.instruction |= sz << 8;
9db2f6b4
RL
19110
19111 /* ARMv8.2 fp16 VCVT instruction. */
19112 if (flavour == neon_cvt_flavour_s32_f16
19113 ||flavour == neon_cvt_flavour_u32_f16)
19114 do_scalar_fp16_v82_encode ();
7e8e6784
MGD
19115 inst.instruction |= op << 7;
19116 inst.instruction |= rm << 16;
19117 inst.instruction |= 0xf0000000;
5b7c81bd 19118 inst.is_neon = true;
7e8e6784
MGD
19119}
19120
19121static void
19122do_neon_cvt_1 (enum neon_cvt_mode mode)
037e8744
JB
19123{
19124 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
d54af2d0
RL
19125 NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ,
19126 NS_FH, NS_HF, NS_FHI, NS_HFI,
19127 NS_NULL);
6b9a8b67 19128 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744 19129
cc933301
JW
19130 if (flavour == neon_cvt_flavour_invalid)
19131 return;
19132
e3e535bc 19133 /* PR11109: Handle round-to-zero for VCVT conversions. */
7e8e6784 19134 if (mode == neon_cvt_mode_z
e3e535bc 19135 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
cc933301
JW
19136 && (flavour == neon_cvt_flavour_s16_f16
19137 || flavour == neon_cvt_flavour_u16_f16
19138 || flavour == neon_cvt_flavour_s32_f32
bacebabc
RM
19139 || flavour == neon_cvt_flavour_u32_f32
19140 || flavour == neon_cvt_flavour_s32_f64
6b9a8b67 19141 || flavour == neon_cvt_flavour_u32_f64)
e3e535bc
NC
19142 && (rs == NS_FD || rs == NS_FF))
19143 {
19144 do_vfp_nsyn_cvtz ();
19145 return;
19146 }
19147
9db2f6b4
RL
19148 /* ARMv8.2 fp16 VCVT conversions. */
19149 if (mode == neon_cvt_mode_z
19150 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16)
19151 && (flavour == neon_cvt_flavour_s32_f16
19152 || flavour == neon_cvt_flavour_u32_f16)
19153 && (rs == NS_FH))
19154 {
19155 do_vfp_nsyn_cvtz ();
19156 do_scalar_fp16_v82_encode ();
19157 return;
19158 }
19159
225f1684
JR
19160 if ((rs == NS_FD || rs == NS_QQI) && mode == neon_cvt_mode_n
19161 && ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19162 {
19163 /* We are dealing with vcvt with the 'ne' condition. */
19164 inst.cond = 0x1;
19165 inst.instruction = N_MNEM_vcvt;
19166 do_neon_cvt_1 (neon_cvt_mode_z);
19167 return;
19168 }
19169
037e8744 19170 /* VFP rather than Neon conversions. */
6b9a8b67 19171 if (flavour >= neon_cvt_flavour_first_fp)
037e8744 19172 {
7e8e6784
MGD
19173 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
19174 do_vfp_nsyn_cvt (rs, flavour);
19175 else
19176 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
19177
037e8744
JB
19178 return;
19179 }
19180
19181 switch (rs)
19182 {
037e8744 19183 case NS_QQI:
dd9634d9
AV
19184 if (mode == neon_cvt_mode_z
19185 && (flavour == neon_cvt_flavour_f16_s16
19186 || flavour == neon_cvt_flavour_f16_u16
19187 || flavour == neon_cvt_flavour_s16_f16
19188 || flavour == neon_cvt_flavour_u16_f16
19189 || flavour == neon_cvt_flavour_f32_u32
19190 || flavour == neon_cvt_flavour_f32_s32
19191 || flavour == neon_cvt_flavour_s32_f32
19192 || flavour == neon_cvt_flavour_u32_f32))
19193 {
5b7c81bd 19194 if (!check_simd_pred_availability (true,
64c350f2 19195 NEON_CHECK_CC | NEON_CHECK_ARCH))
dd9634d9
AV
19196 return;
19197 }
dd9634d9
AV
19198 /* fall through. */
19199 case NS_DDI:
037e8744 19200 {
477330fc 19201 unsigned immbits;
cc933301
JW
19202 unsigned enctab[] = {0x0000100, 0x1000100, 0x0, 0x1000000,
19203 0x0000100, 0x1000100, 0x0, 0x1000000};
35997600 19204
dd9634d9
AV
19205 if ((rs != NS_QQI || !ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19206 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19207 return;
19208
19209 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19210 {
19211 constraint (inst.operands[2].present && inst.operands[2].imm == 0,
19212 _("immediate value out of range"));
19213 switch (flavour)
19214 {
19215 case neon_cvt_flavour_f16_s16:
19216 case neon_cvt_flavour_f16_u16:
19217 case neon_cvt_flavour_s16_f16:
19218 case neon_cvt_flavour_u16_f16:
19219 constraint (inst.operands[2].imm > 16,
19220 _("immediate value out of range"));
19221 break;
19222 case neon_cvt_flavour_f32_u32:
19223 case neon_cvt_flavour_f32_s32:
19224 case neon_cvt_flavour_s32_f32:
19225 case neon_cvt_flavour_u32_f32:
19226 constraint (inst.operands[2].imm > 32,
19227 _("immediate value out of range"));
19228 break;
19229 default:
19230 inst.error = BAD_FPU;
19231 return;
19232 }
19233 }
037e8744 19234
477330fc
RM
19235 /* Fixed-point conversion with #0 immediate is encoded as an
19236 integer conversion. */
19237 if (inst.operands[2].present && inst.operands[2].imm == 0)
19238 goto int_encode;
477330fc
RM
19239 NEON_ENCODE (IMMED, inst);
19240 if (flavour != neon_cvt_flavour_invalid)
19241 inst.instruction |= enctab[flavour];
19242 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19243 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19244 inst.instruction |= LOW4 (inst.operands[1].reg);
19245 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19246 inst.instruction |= neon_quad (rs) << 6;
19247 inst.instruction |= 1 << 21;
cc933301
JW
19248 if (flavour < neon_cvt_flavour_s16_f16)
19249 {
19250 inst.instruction |= 1 << 21;
19251 immbits = 32 - inst.operands[2].imm;
19252 inst.instruction |= immbits << 16;
19253 }
19254 else
19255 {
19256 inst.instruction |= 3 << 20;
19257 immbits = 16 - inst.operands[2].imm;
19258 inst.instruction |= immbits << 16;
19259 inst.instruction &= ~(1 << 9);
19260 }
477330fc
RM
19261
19262 neon_dp_fixup (&inst);
037e8744
JB
19263 }
19264 break;
19265
037e8744 19266 case NS_QQ:
dd9634d9
AV
19267 if ((mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
19268 || mode == neon_cvt_mode_m || mode == neon_cvt_mode_p)
19269 && (flavour == neon_cvt_flavour_s16_f16
19270 || flavour == neon_cvt_flavour_u16_f16
19271 || flavour == neon_cvt_flavour_s32_f32
19272 || flavour == neon_cvt_flavour_u32_f32))
19273 {
5b7c81bd 19274 if (!check_simd_pred_availability (true,
64c350f2 19275 NEON_CHECK_CC | NEON_CHECK_ARCH8))
dd9634d9
AV
19276 return;
19277 }
19278 else if (mode == neon_cvt_mode_z
19279 && (flavour == neon_cvt_flavour_f16_s16
19280 || flavour == neon_cvt_flavour_f16_u16
19281 || flavour == neon_cvt_flavour_s16_f16
19282 || flavour == neon_cvt_flavour_u16_f16
19283 || flavour == neon_cvt_flavour_f32_u32
19284 || flavour == neon_cvt_flavour_f32_s32
19285 || flavour == neon_cvt_flavour_s32_f32
19286 || flavour == neon_cvt_flavour_u32_f32))
19287 {
5b7c81bd 19288 if (!check_simd_pred_availability (true,
64c350f2 19289 NEON_CHECK_CC | NEON_CHECK_ARCH))
dd9634d9
AV
19290 return;
19291 }
19292 /* fall through. */
19293 case NS_DD:
7e8e6784
MGD
19294 if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
19295 {
7e8e6784 19296
dd9634d9 19297 NEON_ENCODE (FLOAT, inst);
5b7c81bd 19298 if (!check_simd_pred_availability (true,
64c350f2 19299 NEON_CHECK_CC | NEON_CHECK_ARCH8))
7e8e6784
MGD
19300 return;
19301
19302 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19303 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19304 inst.instruction |= LOW4 (inst.operands[1].reg);
19305 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19306 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
19307 inst.instruction |= (flavour == neon_cvt_flavour_u16_f16
19308 || flavour == neon_cvt_flavour_u32_f32) << 7;
7e8e6784 19309 inst.instruction |= mode << 8;
cc933301
JW
19310 if (flavour == neon_cvt_flavour_u16_f16
19311 || flavour == neon_cvt_flavour_s16_f16)
19312 /* Mask off the original size bits and reencode them. */
19313 inst.instruction = ((inst.instruction & 0xfff3ffff) | (1 << 18));
19314
7e8e6784
MGD
19315 if (thumb_mode)
19316 inst.instruction |= 0xfc000000;
19317 else
19318 inst.instruction |= 0xf0000000;
19319 }
19320 else
19321 {
037e8744 19322 int_encode:
7e8e6784 19323 {
cc933301
JW
19324 unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080,
19325 0x100, 0x180, 0x0, 0x080};
037e8744 19326
7e8e6784 19327 NEON_ENCODE (INTEGER, inst);
037e8744 19328
dd9634d9
AV
19329 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19330 {
19331 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19332 return;
19333 }
037e8744 19334
7e8e6784
MGD
19335 if (flavour != neon_cvt_flavour_invalid)
19336 inst.instruction |= enctab[flavour];
037e8744 19337
7e8e6784
MGD
19338 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19339 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19340 inst.instruction |= LOW4 (inst.operands[1].reg);
19341 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19342 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
19343 if (flavour >= neon_cvt_flavour_s16_f16
19344 && flavour <= neon_cvt_flavour_f16_u16)
19345 /* Half precision. */
19346 inst.instruction |= 1 << 18;
19347 else
19348 inst.instruction |= 2 << 18;
037e8744 19349
7e8e6784
MGD
19350 neon_dp_fixup (&inst);
19351 }
19352 }
19353 break;
037e8744 19354
8e79c3df
CM
19355 /* Half-precision conversions for Advanced SIMD -- neon. */
19356 case NS_QD:
19357 case NS_DQ:
bc52d49c
MM
19358 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19359 return;
8e79c3df
CM
19360
19361 if ((rs == NS_DQ)
19362 && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
19363 {
19364 as_bad (_("operand size must match register width"));
19365 break;
19366 }
19367
19368 if ((rs == NS_QD)
19369 && ((inst.vectype.el[0].size != 32 || inst.vectype.el[1].size != 16)))
19370 {
19371 as_bad (_("operand size must match register width"));
19372 break;
19373 }
19374
19375 if (rs == NS_DQ)
aab2c27d
MM
19376 {
19377 if (flavour == neon_cvt_flavour_bf16_f32)
19378 {
19379 if (vfp_or_neon_is_neon (NEON_CHECK_ARCH8) == FAIL)
19380 return;
19381 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
19382 /* VCVT.bf16.f32. */
19383 inst.instruction = 0x11b60640;
19384 }
19385 else
19386 /* VCVT.f16.f32. */
19387 inst.instruction = 0x3b60600;
19388 }
8e79c3df 19389 else
aab2c27d 19390 /* VCVT.f32.f16. */
8e79c3df
CM
19391 inst.instruction = 0x3b60700;
19392
19393 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19394 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19395 inst.instruction |= LOW4 (inst.operands[1].reg);
19396 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
88714cb8 19397 neon_dp_fixup (&inst);
8e79c3df
CM
19398 break;
19399
037e8744
JB
19400 default:
19401 /* Some VFP conversions go here (s32 <-> f32, u32 <-> f32). */
7e8e6784
MGD
19402 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
19403 do_vfp_nsyn_cvt (rs, flavour);
19404 else
19405 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
5287ad62 19406 }
5287ad62
JB
19407}
19408
e3e535bc
NC
19409static void
19410do_neon_cvtr (void)
19411{
7e8e6784 19412 do_neon_cvt_1 (neon_cvt_mode_x);
e3e535bc
NC
19413}
19414
19415static void
19416do_neon_cvt (void)
19417{
7e8e6784
MGD
19418 do_neon_cvt_1 (neon_cvt_mode_z);
19419}
19420
19421static void
19422do_neon_cvta (void)
19423{
19424 do_neon_cvt_1 (neon_cvt_mode_a);
19425}
19426
19427static void
19428do_neon_cvtn (void)
19429{
19430 do_neon_cvt_1 (neon_cvt_mode_n);
19431}
19432
19433static void
19434do_neon_cvtp (void)
19435{
19436 do_neon_cvt_1 (neon_cvt_mode_p);
19437}
19438
19439static void
19440do_neon_cvtm (void)
19441{
19442 do_neon_cvt_1 (neon_cvt_mode_m);
e3e535bc
NC
19443}
19444
8e79c3df 19445static void
5b7c81bd 19446do_neon_cvttb_2 (bool t, bool to, bool is_double)
8e79c3df 19447{
c70a8987
MGD
19448 if (is_double)
19449 mark_feature_used (&fpu_vfp_ext_armv8);
8e79c3df 19450
c70a8987
MGD
19451 encode_arm_vfp_reg (inst.operands[0].reg,
19452 (is_double && !to) ? VFP_REG_Dd : VFP_REG_Sd);
19453 encode_arm_vfp_reg (inst.operands[1].reg,
19454 (is_double && to) ? VFP_REG_Dm : VFP_REG_Sm);
19455 inst.instruction |= to ? 0x10000 : 0;
19456 inst.instruction |= t ? 0x80 : 0;
19457 inst.instruction |= is_double ? 0x100 : 0;
19458 do_vfp_cond_or_thumb ();
19459}
8e79c3df 19460
c70a8987 19461static void
5b7c81bd 19462do_neon_cvttb_1 (bool t)
c70a8987 19463{
d54af2d0 19464 enum neon_shape rs = neon_select_shape (NS_HF, NS_HD, NS_FH, NS_FF, NS_FD,
dd9634d9 19465 NS_DF, NS_DH, NS_QQ, NS_QQI, NS_NULL);
8e79c3df 19466
c70a8987
MGD
19467 if (rs == NS_NULL)
19468 return;
dd9634d9
AV
19469 else if (rs == NS_QQ || rs == NS_QQI)
19470 {
19471 int single_to_half = 0;
5b7c81bd 19472 if (!check_simd_pred_availability (true, NEON_CHECK_ARCH))
dd9634d9
AV
19473 return;
19474
19475 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
19476
19477 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19478 && (flavour == neon_cvt_flavour_u16_f16
19479 || flavour == neon_cvt_flavour_s16_f16
19480 || flavour == neon_cvt_flavour_f16_s16
19481 || flavour == neon_cvt_flavour_f16_u16
19482 || flavour == neon_cvt_flavour_u32_f32
19483 || flavour == neon_cvt_flavour_s32_f32
19484 || flavour == neon_cvt_flavour_f32_s32
19485 || flavour == neon_cvt_flavour_f32_u32))
19486 {
19487 inst.cond = 0xf;
19488 inst.instruction = N_MNEM_vcvt;
19489 set_pred_insn_type (INSIDE_VPT_INSN);
19490 do_neon_cvt_1 (neon_cvt_mode_z);
19491 return;
19492 }
19493 else if (rs == NS_QQ && flavour == neon_cvt_flavour_f32_f16)
19494 single_to_half = 1;
19495 else if (rs == NS_QQ && flavour != neon_cvt_flavour_f16_f32)
19496 {
19497 first_error (BAD_FPU);
19498 return;
19499 }
19500
19501 inst.instruction = 0xee3f0e01;
19502 inst.instruction |= single_to_half << 28;
19503 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19504 inst.instruction |= LOW4 (inst.operands[0].reg) << 13;
19505 inst.instruction |= t << 12;
19506 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19507 inst.instruction |= LOW4 (inst.operands[1].reg) << 1;
19508 inst.is_neon = 1;
19509 }
c70a8987
MGD
19510 else if (neon_check_type (2, rs, N_F16, N_F32 | N_VFP).type != NT_invtype)
19511 {
19512 inst.error = NULL;
5b7c81bd 19513 do_neon_cvttb_2 (t, /*to=*/true, /*is_double=*/false);
c70a8987
MGD
19514 }
19515 else if (neon_check_type (2, rs, N_F32 | N_VFP, N_F16).type != NT_invtype)
19516 {
19517 inst.error = NULL;
5b7c81bd 19518 do_neon_cvttb_2 (t, /*to=*/false, /*is_double=*/false);
c70a8987
MGD
19519 }
19520 else if (neon_check_type (2, rs, N_F16, N_F64 | N_VFP).type != NT_invtype)
19521 {
a715796b
TG
19522 /* The VCVTB and VCVTT instructions with D-register operands
19523 don't work for SP only targets. */
19524 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19525 _(BAD_FPU));
19526
c70a8987 19527 inst.error = NULL;
5b7c81bd 19528 do_neon_cvttb_2 (t, /*to=*/true, /*is_double=*/true);
c70a8987
MGD
19529 }
19530 else if (neon_check_type (2, rs, N_F64 | N_VFP, N_F16).type != NT_invtype)
19531 {
a715796b
TG
19532 /* The VCVTB and VCVTT instructions with D-register operands
19533 don't work for SP only targets. */
19534 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19535 _(BAD_FPU));
19536
c70a8987 19537 inst.error = NULL;
5b7c81bd 19538 do_neon_cvttb_2 (t, /*to=*/false, /*is_double=*/true);
c70a8987 19539 }
aab2c27d
MM
19540 else if (neon_check_type (2, rs, N_BF16 | N_VFP, N_F32).type != NT_invtype)
19541 {
19542 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
19543 inst.error = NULL;
19544 inst.instruction |= (1 << 8);
19545 inst.instruction &= ~(1 << 9);
5b7c81bd 19546 do_neon_cvttb_2 (t, /*to=*/true, /*is_double=*/false);
aab2c27d 19547 }
c70a8987
MGD
19548 else
19549 return;
19550}
19551
19552static void
19553do_neon_cvtb (void)
19554{
5b7c81bd 19555 do_neon_cvttb_1 (false);
8e79c3df
CM
19556}
19557
19558
19559static void
19560do_neon_cvtt (void)
19561{
5b7c81bd 19562 do_neon_cvttb_1 (true);
8e79c3df
CM
19563}
19564
5287ad62
JB
19565static void
19566neon_move_immediate (void)
19567{
037e8744
JB
19568 enum neon_shape rs = neon_select_shape (NS_DI, NS_QI, NS_NULL);
19569 struct neon_type_el et = neon_check_type (2, rs,
19570 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
5287ad62 19571 unsigned immlo, immhi = 0, immbits;
c96612cc 19572 int op, cmode, float_p;
5287ad62 19573
037e8744 19574 constraint (et.type == NT_invtype,
477330fc 19575 _("operand size must be specified for immediate VMOV"));
037e8744 19576
5287ad62
JB
19577 /* We start out as an MVN instruction if OP = 1, MOV otherwise. */
19578 op = (inst.instruction & (1 << 5)) != 0;
19579
19580 immlo = inst.operands[1].imm;
19581 if (inst.operands[1].regisimm)
19582 immhi = inst.operands[1].reg;
19583
19584 constraint (et.size < 32 && (immlo & ~((1 << et.size) - 1)) != 0,
477330fc 19585 _("immediate has bits set outside the operand size"));
5287ad62 19586
c96612cc
JB
19587 float_p = inst.operands[1].immisfloat;
19588
19589 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits, &op,
477330fc 19590 et.size, et.type)) == FAIL)
5287ad62
JB
19591 {
19592 /* Invert relevant bits only. */
19593 neon_invert_size (&immlo, &immhi, et.size);
19594 /* Flip from VMOV/VMVN to VMVN/VMOV. Some immediate types are unavailable
477330fc
RM
19595 with one or the other; those cases are caught by
19596 neon_cmode_for_move_imm. */
5287ad62 19597 op = !op;
c96612cc
JB
19598 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits,
19599 &op, et.size, et.type)) == FAIL)
477330fc
RM
19600 {
19601 first_error (_("immediate out of range"));
19602 return;
19603 }
5287ad62
JB
19604 }
19605
19606 inst.instruction &= ~(1 << 5);
19607 inst.instruction |= op << 5;
19608
19609 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19610 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
037e8744 19611 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
19612 inst.instruction |= cmode << 8;
19613
19614 neon_write_immbits (immbits);
19615}
19616
19617static void
19618do_neon_mvn (void)
19619{
5b7c81bd 19620 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
1a186d29
AV
19621 return;
19622
5287ad62
JB
19623 if (inst.operands[1].isreg)
19624 {
1a186d29
AV
19625 enum neon_shape rs;
19626 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19627 rs = neon_select_shape (NS_QQ, NS_NULL);
19628 else
19629 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5f4273c7 19630
250dd99f
AM
19631 if (rs == NS_NULL)
19632 return;
19633
88714cb8 19634 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
19635 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19636 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19637 inst.instruction |= LOW4 (inst.operands[1].reg);
19638 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 19639 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
19640 }
19641 else
19642 {
88714cb8 19643 NEON_ENCODE (IMMED, inst);
5287ad62
JB
19644 neon_move_immediate ();
19645 }
19646
88714cb8 19647 neon_dp_fixup (&inst);
1a186d29
AV
19648
19649 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19650 {
19651 constraint (!inst.operands[1].isreg && !inst.operands[0].isquad, BAD_FPU);
1a186d29 19652 }
5287ad62
JB
19653}
19654
19655/* Encode instructions of form:
19656
19657 |28/24|23|22|21 20|19 16|15 12|11 8|7|6|5|4|3 0|
5f4273c7 19658 | U |x |D |size | Rn | Rd |x x x x|N|x|M|x| Rm | */
5287ad62
JB
19659
19660static void
19661neon_mixed_length (struct neon_type_el et, unsigned size)
19662{
19663 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19664 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19665 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19666 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19667 inst.instruction |= LOW4 (inst.operands[2].reg);
19668 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
19669 inst.instruction |= (et.type == NT_unsigned) << 24;
19670 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 19671
88714cb8 19672 neon_dp_fixup (&inst);
5287ad62
JB
19673}
19674
19675static void
19676do_neon_dyadic_long (void)
19677{
66d1f7cc 19678 enum neon_shape rs = neon_select_shape (NS_QDD, NS_HHH, NS_FFF, NS_DDD, NS_NULL);
5ee91343
AV
19679 if (rs == NS_QDD)
19680 {
19681 if (vfp_or_neon_is_neon (NEON_CHECK_ARCH | NEON_CHECK_CC) == FAIL)
19682 return;
19683
19684 NEON_ENCODE (INTEGER, inst);
19685 /* FIXME: Type checking for lengthening op. */
19686 struct neon_type_el et = neon_check_type (3, NS_QDD,
19687 N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
19688 neon_mixed_length (et, et.size);
19689 }
19690 else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19691 && (inst.cond == 0xf || inst.cond == 0x10))
19692 {
19693 /* If parsing for MVE, vaddl/vsubl/vabdl{e,t} can only be vadd/vsub/vabd
19694 in an IT block with le/lt conditions. */
19695
19696 if (inst.cond == 0xf)
19697 inst.cond = 0xb;
19698 else if (inst.cond == 0x10)
19699 inst.cond = 0xd;
19700
19701 inst.pred_insn_type = INSIDE_IT_INSN;
19702
19703 if (inst.instruction == N_MNEM_vaddl)
19704 {
19705 inst.instruction = N_MNEM_vadd;
19706 do_neon_addsub_if_i ();
19707 }
19708 else if (inst.instruction == N_MNEM_vsubl)
19709 {
19710 inst.instruction = N_MNEM_vsub;
19711 do_neon_addsub_if_i ();
19712 }
19713 else if (inst.instruction == N_MNEM_vabdl)
19714 {
19715 inst.instruction = N_MNEM_vabd;
19716 do_neon_dyadic_if_su ();
19717 }
19718 }
19719 else
19720 first_error (BAD_FPU);
5287ad62
JB
19721}
19722
19723static void
19724do_neon_abal (void)
19725{
19726 struct neon_type_el et = neon_check_type (3, NS_QDD,
19727 N_EQK | N_INT | N_DBL, N_EQK, N_SU_32 | N_KEY);
19728 neon_mixed_length (et, et.size);
19729}
19730
19731static void
19732neon_mac_reg_scalar_long (unsigned regtypes, unsigned scalartypes)
19733{
19734 if (inst.operands[2].isscalar)
19735 {
dcbf9037 19736 struct neon_type_el et = neon_check_type (3, NS_QDS,
477330fc 19737 N_EQK | N_DBL, N_EQK, regtypes | N_KEY);
88714cb8 19738 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
19739 neon_mul_mac (et, et.type == NT_unsigned);
19740 }
19741 else
19742 {
19743 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 19744 N_EQK | N_DBL, N_EQK, scalartypes | N_KEY);
88714cb8 19745 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
19746 neon_mixed_length (et, et.size);
19747 }
19748}
19749
19750static void
19751do_neon_mac_maybe_scalar_long (void)
19752{
19753 neon_mac_reg_scalar_long (N_S16 | N_S32 | N_U16 | N_U32, N_SU_32);
19754}
19755
dec41383
JW
19756/* Like neon_scalar_for_mul, this function generate Rm encoding from GAS's
19757 internal SCALAR. QUAD_P is 1 if it's for Q format, otherwise it's 0. */
19758
19759static unsigned
19760neon_scalar_for_fmac_fp16_long (unsigned scalar, unsigned quad_p)
19761{
19762 unsigned regno = NEON_SCALAR_REG (scalar);
19763 unsigned elno = NEON_SCALAR_INDEX (scalar);
19764
19765 if (quad_p)
19766 {
19767 if (regno > 7 || elno > 3)
19768 goto bad_scalar;
19769
19770 return ((regno & 0x7)
19771 | ((elno & 0x1) << 3)
19772 | (((elno >> 1) & 0x1) << 5));
19773 }
19774 else
19775 {
19776 if (regno > 15 || elno > 1)
19777 goto bad_scalar;
19778
19779 return (((regno & 0x1) << 5)
19780 | ((regno >> 1) & 0x7)
19781 | ((elno & 0x1) << 3));
19782 }
19783
dc1e8a47 19784 bad_scalar:
dec41383
JW
19785 first_error (_("scalar out of range for multiply instruction"));
19786 return 0;
19787}
19788
19789static void
19790do_neon_fmac_maybe_scalar_long (int subtype)
19791{
19792 enum neon_shape rs;
19793 int high8;
19794 /* NOTE: vfmal/vfmsl use slightly different NEON three-same encoding. 'size"
19795 field (bits[21:20]) has different meaning. For scalar index variant, it's
19796 used to differentiate add and subtract, otherwise it's with fixed value
19797 0x2. */
19798 int size = -1;
19799
dec41383
JW
19800 /* vfmal/vfmsl are in three-same D/Q register format or the third operand can
19801 be a scalar index register. */
19802 if (inst.operands[2].isscalar)
19803 {
19804 high8 = 0xfe000000;
19805 if (subtype)
19806 size = 16;
19807 rs = neon_select_shape (NS_DHS, NS_QDS, NS_NULL);
19808 }
19809 else
19810 {
19811 high8 = 0xfc000000;
19812 size = 32;
19813 if (subtype)
19814 inst.instruction |= (0x1 << 23);
19815 rs = neon_select_shape (NS_DHH, NS_QDD, NS_NULL);
19816 }
19817
aab2c27d
MM
19818
19819 if (inst.cond != COND_ALWAYS)
19820 as_warn (_("vfmal/vfmsl with FP16 type cannot be conditional, the "
19821 "behaviour is UNPREDICTABLE"));
19822
19823 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16_fml),
19824 _(BAD_FP16));
19825
19826 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
19827 _(BAD_FPU));
dec41383
JW
19828
19829 /* "opcode" from template has included "ubit", so simply pass 0 here. Also,
19830 the "S" bit in size field has been reused to differentiate vfmal and vfmsl,
19831 so we simply pass -1 as size. */
19832 unsigned quad_p = (rs == NS_QDD || rs == NS_QDS);
19833 neon_three_same (quad_p, 0, size);
19834
19835 /* Undo neon_dp_fixup. Redo the high eight bits. */
19836 inst.instruction &= 0x00ffffff;
19837 inst.instruction |= high8;
19838
dec41383
JW
19839 /* Unlike usually NEON three-same, encoding for Vn and Vm will depend on
19840 whether the instruction is in Q form and whether Vm is a scalar indexed
19841 operand. */
19842 if (inst.operands[2].isscalar)
19843 {
19844 unsigned rm
19845 = neon_scalar_for_fmac_fp16_long (inst.operands[2].reg, quad_p);
19846 inst.instruction &= 0xffffffd0;
19847 inst.instruction |= rm;
19848
19849 if (!quad_p)
19850 {
19851 /* Redo Rn as well. */
19852 inst.instruction &= 0xfff0ff7f;
19853 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
19854 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
19855 }
19856 }
19857 else if (!quad_p)
19858 {
19859 /* Redo Rn and Rm. */
19860 inst.instruction &= 0xfff0ff50;
19861 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
19862 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
19863 inst.instruction |= HI4 (inst.operands[2].reg);
19864 inst.instruction |= LOW1 (inst.operands[2].reg) << 5;
19865 }
19866}
19867
19868static void
19869do_neon_vfmal (void)
19870{
19871 return do_neon_fmac_maybe_scalar_long (0);
19872}
19873
19874static void
19875do_neon_vfmsl (void)
19876{
19877 return do_neon_fmac_maybe_scalar_long (1);
19878}
19879
5287ad62
JB
19880static void
19881do_neon_dyadic_wide (void)
19882{
19883 struct neon_type_el et = neon_check_type (3, NS_QQD,
19884 N_EQK | N_DBL, N_EQK | N_DBL, N_SU_32 | N_KEY);
19885 neon_mixed_length (et, et.size);
19886}
19887
19888static void
19889do_neon_dyadic_narrow (void)
19890{
19891 struct neon_type_el et = neon_check_type (3, NS_QDD,
19892 N_EQK | N_DBL, N_EQK, N_I16 | N_I32 | N_I64 | N_KEY);
428e3f1f
PB
19893 /* Operand sign is unimportant, and the U bit is part of the opcode,
19894 so force the operand type to integer. */
19895 et.type = NT_integer;
5287ad62
JB
19896 neon_mixed_length (et, et.size / 2);
19897}
19898
19899static void
19900do_neon_mul_sat_scalar_long (void)
19901{
19902 neon_mac_reg_scalar_long (N_S16 | N_S32, N_S16 | N_S32);
19903}
19904
19905static void
19906do_neon_vmull (void)
19907{
19908 if (inst.operands[2].isscalar)
19909 do_neon_mac_maybe_scalar_long ();
19910 else
19911 {
19912 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 19913 N_EQK | N_DBL, N_EQK, N_SU_32 | N_P8 | N_P64 | N_KEY);
4f51b4bd 19914
5287ad62 19915 if (et.type == NT_poly)
477330fc 19916 NEON_ENCODE (POLY, inst);
5287ad62 19917 else
477330fc 19918 NEON_ENCODE (INTEGER, inst);
4f51b4bd
MGD
19919
19920 /* For polynomial encoding the U bit must be zero, and the size must
19921 be 8 (encoded as 0b00) or, on ARMv8 or later 64 (encoded, non
19922 obviously, as 0b10). */
19923 if (et.size == 64)
19924 {
19925 /* Check we're on the correct architecture. */
19926 if (!mark_feature_used (&fpu_crypto_ext_armv8))
19927 inst.error =
19928 _("Instruction form not available on this architecture.");
19929
19930 et.size = 32;
19931 }
19932
5287ad62
JB
19933 neon_mixed_length (et, et.size);
19934 }
19935}
19936
19937static void
19938do_neon_ext (void)
19939{
037e8744 19940 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
5287ad62
JB
19941 struct neon_type_el et = neon_check_type (3, rs,
19942 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
19943 unsigned imm = (inst.operands[3].imm * et.size) / 8;
35997600
NC
19944
19945 constraint (imm >= (unsigned) (neon_quad (rs) ? 16 : 8),
19946 _("shift out of range"));
5287ad62
JB
19947 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19948 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19949 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19950 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19951 inst.instruction |= LOW4 (inst.operands[2].reg);
19952 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
037e8744 19953 inst.instruction |= neon_quad (rs) << 6;
5287ad62 19954 inst.instruction |= imm << 8;
5f4273c7 19955
88714cb8 19956 neon_dp_fixup (&inst);
5287ad62
JB
19957}
19958
19959static void
19960do_neon_rev (void)
19961{
5b7c81bd 19962 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
19963 return;
19964
19965 enum neon_shape rs;
19966 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19967 rs = neon_select_shape (NS_QQ, NS_NULL);
19968 else
19969 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
19970
5287ad62
JB
19971 struct neon_type_el et = neon_check_type (2, rs,
19972 N_EQK, N_8 | N_16 | N_32 | N_KEY);
4401c241 19973
5287ad62
JB
19974 unsigned op = (inst.instruction >> 7) & 3;
19975 /* N (width of reversed regions) is encoded as part of the bitmask. We
19976 extract it here to check the elements to be reversed are smaller.
19977 Otherwise we'd get a reserved instruction. */
19978 unsigned elsize = (op == 2) ? 16 : (op == 1) ? 32 : (op == 0) ? 64 : 0;
4401c241
AV
19979
19980 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext) && elsize == 64
19981 && inst.operands[0].reg == inst.operands[1].reg)
19982 as_tsktsk (_("Warning: 64-bit element size and same destination and source"
19983 " operands makes instruction UNPREDICTABLE"));
19984
9c2799c2 19985 gas_assert (elsize != 0);
5287ad62 19986 constraint (et.size >= elsize,
477330fc 19987 _("elements must be smaller than reversal region"));
037e8744 19988 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19989}
19990
19991static void
19992do_neon_dup (void)
19993{
19994 if (inst.operands[1].isscalar)
19995 {
b409bdb6
AV
19996 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
19997 BAD_FPU);
037e8744 19998 enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
dcbf9037 19999 struct neon_type_el et = neon_check_type (2, rs,
477330fc 20000 N_EQK, N_8 | N_16 | N_32 | N_KEY);
5287ad62 20001 unsigned sizebits = et.size >> 3;
dcbf9037 20002 unsigned dm = NEON_SCALAR_REG (inst.operands[1].reg);
5287ad62 20003 int logsize = neon_logbits (et.size);
dcbf9037 20004 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg) << logsize;
037e8744
JB
20005
20006 if (vfp_or_neon_is_neon (NEON_CHECK_CC) == FAIL)
477330fc 20007 return;
037e8744 20008
88714cb8 20009 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
20010 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20011 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20012 inst.instruction |= LOW4 (dm);
20013 inst.instruction |= HI1 (dm) << 5;
037e8744 20014 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
20015 inst.instruction |= x << 17;
20016 inst.instruction |= sizebits << 16;
5f4273c7 20017
88714cb8 20018 neon_dp_fixup (&inst);
5287ad62
JB
20019 }
20020 else
20021 {
037e8744
JB
20022 enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
20023 struct neon_type_el et = neon_check_type (2, rs,
477330fc 20024 N_8 | N_16 | N_32 | N_KEY, N_EQK);
b409bdb6
AV
20025 if (rs == NS_QR)
20026 {
5b7c81bd 20027 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH))
b409bdb6
AV
20028 return;
20029 }
20030 else
20031 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
20032 BAD_FPU);
20033
20034 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20035 {
20036 if (inst.operands[1].reg == REG_SP)
20037 as_tsktsk (MVE_BAD_SP);
20038 else if (inst.operands[1].reg == REG_PC)
20039 as_tsktsk (MVE_BAD_PC);
20040 }
20041
5287ad62 20042 /* Duplicate ARM register to lanes of vector. */
88714cb8 20043 NEON_ENCODE (ARMREG, inst);
5287ad62 20044 switch (et.size)
477330fc
RM
20045 {
20046 case 8: inst.instruction |= 0x400000; break;
20047 case 16: inst.instruction |= 0x000020; break;
20048 case 32: inst.instruction |= 0x000000; break;
20049 default: break;
20050 }
5287ad62
JB
20051 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
20052 inst.instruction |= LOW4 (inst.operands[0].reg) << 16;
20053 inst.instruction |= HI1 (inst.operands[0].reg) << 7;
037e8744 20054 inst.instruction |= neon_quad (rs) << 21;
5287ad62 20055 /* The encoding for this instruction is identical for the ARM and Thumb
477330fc 20056 variants, except for the condition field. */
037e8744 20057 do_vfp_cond_or_thumb ();
5287ad62
JB
20058 }
20059}
20060
57785aa2
AV
20061static void
20062do_mve_mov (int toQ)
20063{
20064 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20065 return;
20066 if (inst.cond > COND_ALWAYS)
20067 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
20068
20069 unsigned Rt = 0, Rt2 = 1, Q0 = 2, Q1 = 3;
20070 if (toQ)
20071 {
20072 Q0 = 0;
20073 Q1 = 1;
20074 Rt = 2;
20075 Rt2 = 3;
20076 }
20077
20078 constraint (inst.operands[Q0].reg != inst.operands[Q1].reg + 2,
20079 _("Index one must be [2,3] and index two must be two less than"
20080 " index one."));
e683cb41
AC
20081 constraint (!toQ && inst.operands[Rt].reg == inst.operands[Rt2].reg,
20082 _("Destination registers may not be the same"));
57785aa2
AV
20083 constraint (inst.operands[Rt].reg == REG_SP
20084 || inst.operands[Rt2].reg == REG_SP,
20085 BAD_SP);
20086 constraint (inst.operands[Rt].reg == REG_PC
20087 || inst.operands[Rt2].reg == REG_PC,
20088 BAD_PC);
20089
20090 inst.instruction = 0xec000f00;
20091 inst.instruction |= HI1 (inst.operands[Q1].reg / 32) << 23;
20092 inst.instruction |= !!toQ << 20;
20093 inst.instruction |= inst.operands[Rt2].reg << 16;
20094 inst.instruction |= LOW4 (inst.operands[Q1].reg / 32) << 13;
20095 inst.instruction |= (inst.operands[Q1].reg % 4) << 4;
20096 inst.instruction |= inst.operands[Rt].reg;
20097}
20098
20099static void
20100do_mve_movn (void)
20101{
20102 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20103 return;
20104
20105 if (inst.cond > COND_ALWAYS)
20106 inst.pred_insn_type = INSIDE_VPT_INSN;
20107 else
20108 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
20109
20110 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_I16 | N_I32
20111 | N_KEY);
20112
20113 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20114 inst.instruction |= (neon_logbits (et.size) - 1) << 18;
20115 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20116 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20117 inst.instruction |= LOW4 (inst.operands[1].reg);
20118 inst.is_neon = 1;
20119
20120}
20121
5287ad62
JB
20122/* VMOV has particularly many variations. It can be one of:
20123 0. VMOV<c><q> <Qd>, <Qm>
20124 1. VMOV<c><q> <Dd>, <Dm>
20125 (Register operations, which are VORR with Rm = Rn.)
20126 2. VMOV<c><q>.<dt> <Qd>, #<imm>
20127 3. VMOV<c><q>.<dt> <Dd>, #<imm>
20128 (Immediate loads.)
20129 4. VMOV<c><q>.<size> <Dn[x]>, <Rd>
20130 (ARM register to scalar.)
20131 5. VMOV<c><q> <Dm>, <Rd>, <Rn>
20132 (Two ARM registers to vector.)
20133 6. VMOV<c><q>.<dt> <Rd>, <Dn[x]>
20134 (Scalar to ARM register.)
20135 7. VMOV<c><q> <Rd>, <Rn>, <Dm>
20136 (Vector to two ARM registers.)
037e8744
JB
20137 8. VMOV.F32 <Sd>, <Sm>
20138 9. VMOV.F64 <Dd>, <Dm>
20139 (VFP register moves.)
20140 10. VMOV.F32 <Sd>, #imm
20141 11. VMOV.F64 <Dd>, #imm
20142 (VFP float immediate load.)
20143 12. VMOV <Rd>, <Sm>
20144 (VFP single to ARM reg.)
20145 13. VMOV <Sd>, <Rm>
20146 (ARM reg to VFP single.)
20147 14. VMOV <Rd>, <Re>, <Sn>, <Sm>
20148 (Two ARM regs to two VFP singles.)
20149 15. VMOV <Sd>, <Se>, <Rn>, <Rm>
20150 (Two VFP singles to two ARM regs.)
57785aa2
AV
20151 16. VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]>
20152 17. VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2>
20153 18. VMOV<c>.<dt> <Rt>, <Qn[idx]>
20154 19. VMOV<c>.<dt> <Qd[idx]>, <Rt>
5f4273c7 20155
037e8744
JB
20156 These cases can be disambiguated using neon_select_shape, except cases 1/9
20157 and 3/11 which depend on the operand type too.
5f4273c7 20158
5287ad62 20159 All the encoded bits are hardcoded by this function.
5f4273c7 20160
b7fc2769
JB
20161 Cases 4, 6 may be used with VFPv1 and above (only 32-bit transfers!).
20162 Cases 5, 7 may be used with VFPv2 and above.
5f4273c7 20163
5287ad62 20164 FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
5f4273c7 20165 can specify a type where it doesn't make sense to, and is ignored). */
5287ad62
JB
20166
20167static void
20168do_neon_mov (void)
20169{
57785aa2
AV
20170 enum neon_shape rs = neon_select_shape (NS_RRSS, NS_SSRR, NS_RRFF, NS_FFRR,
20171 NS_DRR, NS_RRD, NS_QQ, NS_DD, NS_QI,
20172 NS_DI, NS_SR, NS_RS, NS_FF, NS_FI,
20173 NS_RF, NS_FR, NS_HR, NS_RH, NS_HI,
20174 NS_NULL);
037e8744
JB
20175 struct neon_type_el et;
20176 const char *ldconst = 0;
5287ad62 20177
037e8744 20178 switch (rs)
5287ad62 20179 {
037e8744
JB
20180 case NS_DD: /* case 1/9. */
20181 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
20182 /* It is not an error here if no type is given. */
20183 inst.error = NULL;
1c1e0fe5
SP
20184
20185 /* In MVE we interpret the following instructions as same, so ignoring
20186 the following type (float) and size (64) checks.
20187 a: VMOV<c><q> <Dd>, <Dm>
20188 b: VMOV<c><q>.F64 <Dd>, <Dm>. */
20189 if ((et.type == NT_float && et.size == 64)
20190 || (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)))
477330fc
RM
20191 {
20192 do_vfp_nsyn_opcode ("fcpyd");
20193 break;
20194 }
037e8744 20195 /* fall through. */
5287ad62 20196
037e8744
JB
20197 case NS_QQ: /* case 0/1. */
20198 {
5b7c81bd 20199 if (!check_simd_pred_availability (false,
64c350f2 20200 NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc
RM
20201 return;
20202 /* The architecture manual I have doesn't explicitly state which
20203 value the U bit should have for register->register moves, but
20204 the equivalent VORR instruction has U = 0, so do that. */
20205 inst.instruction = 0x0200110;
20206 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20207 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20208 inst.instruction |= LOW4 (inst.operands[1].reg);
20209 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20210 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20211 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20212 inst.instruction |= neon_quad (rs) << 6;
20213
20214 neon_dp_fixup (&inst);
037e8744
JB
20215 }
20216 break;
5f4273c7 20217
037e8744
JB
20218 case NS_DI: /* case 3/11. */
20219 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
20220 inst.error = NULL;
20221 if (et.type == NT_float && et.size == 64)
477330fc
RM
20222 {
20223 /* case 11 (fconstd). */
20224 ldconst = "fconstd";
20225 goto encode_fconstd;
20226 }
037e8744
JB
20227 /* fall through. */
20228
20229 case NS_QI: /* case 2/3. */
5b7c81bd 20230 if (!check_simd_pred_availability (false,
64c350f2 20231 NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc 20232 return;
037e8744
JB
20233 inst.instruction = 0x0800010;
20234 neon_move_immediate ();
88714cb8 20235 neon_dp_fixup (&inst);
5287ad62 20236 break;
5f4273c7 20237
037e8744
JB
20238 case NS_SR: /* case 4. */
20239 {
477330fc
RM
20240 unsigned bcdebits = 0;
20241 int logsize;
20242 unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
20243 unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
037e8744 20244
05ac0ffb
JB
20245 /* .<size> is optional here, defaulting to .32. */
20246 if (inst.vectype.elems == 0
20247 && inst.operands[0].vectype.type == NT_invtype
20248 && inst.operands[1].vectype.type == NT_invtype)
20249 {
20250 inst.vectype.el[0].type = NT_untyped;
20251 inst.vectype.el[0].size = 32;
20252 inst.vectype.elems = 1;
20253 }
20254
477330fc
RM
20255 et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
20256 logsize = neon_logbits (et.size);
20257
57785aa2
AV
20258 if (et.size != 32)
20259 {
20260 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
20261 && vfp_or_neon_is_neon (NEON_CHECK_ARCH) == FAIL)
20262 return;
20263 }
20264 else
20265 {
20266 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
20267 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20268 _(BAD_FPU));
20269 }
20270
20271 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20272 {
20273 if (inst.operands[1].reg == REG_SP)
20274 as_tsktsk (MVE_BAD_SP);
20275 else if (inst.operands[1].reg == REG_PC)
20276 as_tsktsk (MVE_BAD_PC);
20277 }
20278 unsigned size = inst.operands[0].isscalar == 1 ? 64 : 128;
20279
477330fc 20280 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2
AV
20281 constraint (x >= size / et.size, _("scalar index out of range"));
20282
477330fc
RM
20283
20284 switch (et.size)
20285 {
20286 case 8: bcdebits = 0x8; break;
20287 case 16: bcdebits = 0x1; break;
20288 case 32: bcdebits = 0x0; break;
20289 default: ;
20290 }
20291
57785aa2 20292 bcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
20293
20294 inst.instruction = 0xe000b10;
20295 do_vfp_cond_or_thumb ();
20296 inst.instruction |= LOW4 (dn) << 16;
20297 inst.instruction |= HI1 (dn) << 7;
20298 inst.instruction |= inst.operands[1].reg << 12;
20299 inst.instruction |= (bcdebits & 3) << 5;
57785aa2
AV
20300 inst.instruction |= ((bcdebits >> 2) & 3) << 21;
20301 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
20302 }
20303 break;
5f4273c7 20304
037e8744 20305 case NS_DRR: /* case 5 (fmdrr). */
57785aa2
AV
20306 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20307 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 20308 _(BAD_FPU));
b7fc2769 20309
037e8744
JB
20310 inst.instruction = 0xc400b10;
20311 do_vfp_cond_or_thumb ();
20312 inst.instruction |= LOW4 (inst.operands[0].reg);
20313 inst.instruction |= HI1 (inst.operands[0].reg) << 5;
20314 inst.instruction |= inst.operands[1].reg << 12;
20315 inst.instruction |= inst.operands[2].reg << 16;
20316 break;
5f4273c7 20317
037e8744
JB
20318 case NS_RS: /* case 6. */
20319 {
477330fc
RM
20320 unsigned logsize;
20321 unsigned dn = NEON_SCALAR_REG (inst.operands[1].reg);
20322 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
20323 unsigned abcdebits = 0;
037e8744 20324
05ac0ffb
JB
20325 /* .<dt> is optional here, defaulting to .32. */
20326 if (inst.vectype.elems == 0
20327 && inst.operands[0].vectype.type == NT_invtype
20328 && inst.operands[1].vectype.type == NT_invtype)
20329 {
20330 inst.vectype.el[0].type = NT_untyped;
20331 inst.vectype.el[0].size = 32;
20332 inst.vectype.elems = 1;
20333 }
20334
91d6fa6a
NC
20335 et = neon_check_type (2, NS_NULL,
20336 N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
477330fc
RM
20337 logsize = neon_logbits (et.size);
20338
57785aa2
AV
20339 if (et.size != 32)
20340 {
20341 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
20342 && vfp_or_neon_is_neon (NEON_CHECK_CC
20343 | NEON_CHECK_ARCH) == FAIL)
20344 return;
20345 }
20346 else
20347 {
20348 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
20349 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20350 _(BAD_FPU));
20351 }
20352
20353 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20354 {
20355 if (inst.operands[0].reg == REG_SP)
20356 as_tsktsk (MVE_BAD_SP);
20357 else if (inst.operands[0].reg == REG_PC)
20358 as_tsktsk (MVE_BAD_PC);
20359 }
20360
20361 unsigned size = inst.operands[1].isscalar == 1 ? 64 : 128;
20362
477330fc 20363 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2 20364 constraint (x >= size / et.size, _("scalar index out of range"));
477330fc
RM
20365
20366 switch (et.size)
20367 {
20368 case 8: abcdebits = (et.type == NT_signed) ? 0x08 : 0x18; break;
20369 case 16: abcdebits = (et.type == NT_signed) ? 0x01 : 0x11; break;
20370 case 32: abcdebits = 0x00; break;
20371 default: ;
20372 }
20373
57785aa2 20374 abcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
20375 inst.instruction = 0xe100b10;
20376 do_vfp_cond_or_thumb ();
20377 inst.instruction |= LOW4 (dn) << 16;
20378 inst.instruction |= HI1 (dn) << 7;
20379 inst.instruction |= inst.operands[0].reg << 12;
20380 inst.instruction |= (abcdebits & 3) << 5;
20381 inst.instruction |= (abcdebits >> 2) << 21;
57785aa2 20382 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
20383 }
20384 break;
5f4273c7 20385
037e8744 20386 case NS_RRD: /* case 7 (fmrrd). */
57785aa2
AV
20387 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20388 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 20389 _(BAD_FPU));
037e8744
JB
20390
20391 inst.instruction = 0xc500b10;
20392 do_vfp_cond_or_thumb ();
20393 inst.instruction |= inst.operands[0].reg << 12;
20394 inst.instruction |= inst.operands[1].reg << 16;
20395 inst.instruction |= LOW4 (inst.operands[2].reg);
20396 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20397 break;
5f4273c7 20398
037e8744
JB
20399 case NS_FF: /* case 8 (fcpys). */
20400 do_vfp_nsyn_opcode ("fcpys");
20401 break;
5f4273c7 20402
9db2f6b4 20403 case NS_HI:
037e8744
JB
20404 case NS_FI: /* case 10 (fconsts). */
20405 ldconst = "fconsts";
4ef4710f 20406 encode_fconstd:
58ed5c38
TC
20407 if (!inst.operands[1].immisfloat)
20408 {
4ef4710f 20409 unsigned new_imm;
58ed5c38 20410 /* Immediate has to fit in 8 bits so float is enough. */
4ef4710f
NC
20411 float imm = (float) inst.operands[1].imm;
20412 memcpy (&new_imm, &imm, sizeof (float));
20413 /* But the assembly may have been written to provide an integer
20414 bit pattern that equates to a float, so check that the
20415 conversion has worked. */
20416 if (is_quarter_float (new_imm))
20417 {
20418 if (is_quarter_float (inst.operands[1].imm))
20419 as_warn (_("immediate constant is valid both as a bit-pattern and a floating point value (using the fp value)"));
20420
20421 inst.operands[1].imm = new_imm;
20422 inst.operands[1].immisfloat = 1;
20423 }
58ed5c38
TC
20424 }
20425
037e8744 20426 if (is_quarter_float (inst.operands[1].imm))
477330fc
RM
20427 {
20428 inst.operands[1].imm = neon_qfloat_bits (inst.operands[1].imm);
20429 do_vfp_nsyn_opcode (ldconst);
9db2f6b4
RL
20430
20431 /* ARMv8.2 fp16 vmov.f16 instruction. */
20432 if (rs == NS_HI)
20433 do_scalar_fp16_v82_encode ();
477330fc 20434 }
5287ad62 20435 else
477330fc 20436 first_error (_("immediate out of range"));
037e8744 20437 break;
5f4273c7 20438
9db2f6b4 20439 case NS_RH:
037e8744
JB
20440 case NS_RF: /* case 12 (fmrs). */
20441 do_vfp_nsyn_opcode ("fmrs");
9db2f6b4
RL
20442 /* ARMv8.2 fp16 vmov.f16 instruction. */
20443 if (rs == NS_RH)
20444 do_scalar_fp16_v82_encode ();
037e8744 20445 break;
5f4273c7 20446
9db2f6b4 20447 case NS_HR:
037e8744
JB
20448 case NS_FR: /* case 13 (fmsr). */
20449 do_vfp_nsyn_opcode ("fmsr");
9db2f6b4
RL
20450 /* ARMv8.2 fp16 vmov.f16 instruction. */
20451 if (rs == NS_HR)
20452 do_scalar_fp16_v82_encode ();
037e8744 20453 break;
5f4273c7 20454
57785aa2
AV
20455 case NS_RRSS:
20456 do_mve_mov (0);
20457 break;
20458 case NS_SSRR:
20459 do_mve_mov (1);
20460 break;
20461
037e8744
JB
20462 /* The encoders for the fmrrs and fmsrr instructions expect three operands
20463 (one of which is a list), but we have parsed four. Do some fiddling to
20464 make the operands what do_vfp_reg2_from_sp2 and do_vfp_sp2_from_reg2
20465 expect. */
20466 case NS_RRFF: /* case 14 (fmrrs). */
57785aa2
AV
20467 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20468 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20469 _(BAD_FPU));
037e8744 20470 constraint (inst.operands[3].reg != inst.operands[2].reg + 1,
477330fc 20471 _("VFP registers must be adjacent"));
037e8744
JB
20472 inst.operands[2].imm = 2;
20473 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
20474 do_vfp_nsyn_opcode ("fmrrs");
20475 break;
5f4273c7 20476
037e8744 20477 case NS_FFRR: /* case 15 (fmsrr). */
57785aa2
AV
20478 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20479 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20480 _(BAD_FPU));
037e8744 20481 constraint (inst.operands[1].reg != inst.operands[0].reg + 1,
477330fc 20482 _("VFP registers must be adjacent"));
037e8744
JB
20483 inst.operands[1] = inst.operands[2];
20484 inst.operands[2] = inst.operands[3];
20485 inst.operands[0].imm = 2;
20486 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
20487 do_vfp_nsyn_opcode ("fmsrr");
5287ad62 20488 break;
5f4273c7 20489
4c261dff
NC
20490 case NS_NULL:
20491 /* neon_select_shape has determined that the instruction
20492 shape is wrong and has already set the error message. */
20493 break;
20494
5287ad62
JB
20495 default:
20496 abort ();
20497 }
20498}
20499
57785aa2
AV
20500static void
20501do_mve_movl (void)
20502{
20503 if (!(inst.operands[0].present && inst.operands[0].isquad
20504 && inst.operands[1].present && inst.operands[1].isquad
20505 && !inst.operands[2].present))
20506 {
20507 inst.instruction = 0;
20508 inst.cond = 0xb;
20509 if (thumb_mode)
20510 set_pred_insn_type (INSIDE_IT_INSN);
20511 do_neon_mov ();
20512 return;
20513 }
20514
20515 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20516 return;
20517
20518 if (inst.cond != COND_ALWAYS)
20519 inst.pred_insn_type = INSIDE_VPT_INSN;
20520
20521 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_S8 | N_U8
20522 | N_S16 | N_U16 | N_KEY);
20523
20524 inst.instruction |= (et.type == NT_unsigned) << 28;
20525 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20526 inst.instruction |= (neon_logbits (et.size) + 1) << 19;
20527 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20528 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20529 inst.instruction |= LOW4 (inst.operands[1].reg);
20530 inst.is_neon = 1;
20531}
20532
5287ad62
JB
20533static void
20534do_neon_rshift_round_imm (void)
20535{
5b7c81bd 20536 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
20537 return;
20538
20539 enum neon_shape rs;
20540 struct neon_type_el et;
20541
20542 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20543 {
20544 rs = neon_select_shape (NS_QQI, NS_NULL);
20545 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
20546 }
20547 else
20548 {
20549 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
20550 et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
20551 }
5287ad62
JB
20552 int imm = inst.operands[2].imm;
20553
20554 /* imm == 0 case is encoded as VMOV for V{R}SHR. */
20555 if (imm == 0)
20556 {
20557 inst.operands[2].present = 0;
20558 do_neon_mov ();
20559 return;
20560 }
20561
20562 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 20563 _("immediate out of range for shift"));
5b7c81bd 20564 neon_imm_shift (true, et.type == NT_unsigned, neon_quad (rs), et,
477330fc 20565 et.size - imm);
5287ad62
JB
20566}
20567
9db2f6b4
RL
20568static void
20569do_neon_movhf (void)
20570{
20571 enum neon_shape rs = neon_select_shape (NS_HH, NS_NULL);
20572 constraint (rs != NS_HH, _("invalid suffix"));
20573
7bdf778b
ASDV
20574 if (inst.cond != COND_ALWAYS)
20575 {
20576 if (thumb_mode)
20577 {
20578 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
20579 " the behaviour is UNPREDICTABLE"));
20580 }
20581 else
20582 {
20583 inst.error = BAD_COND;
20584 return;
20585 }
20586 }
20587
9db2f6b4
RL
20588 do_vfp_sp_monadic ();
20589
20590 inst.is_neon = 1;
20591 inst.instruction |= 0xf0000000;
20592}
20593
5287ad62
JB
20594static void
20595do_neon_movl (void)
20596{
20597 struct neon_type_el et = neon_check_type (2, NS_QD,
20598 N_EQK | N_DBL, N_SU_32 | N_KEY);
20599 unsigned sizebits = et.size >> 3;
20600 inst.instruction |= sizebits << 19;
20601 neon_two_same (0, et.type == NT_unsigned, -1);
20602}
20603
20604static void
20605do_neon_trn (void)
20606{
037e8744 20607 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20608 struct neon_type_el et = neon_check_type (2, rs,
20609 N_EQK, N_8 | N_16 | N_32 | N_KEY);
88714cb8 20610 NEON_ENCODE (INTEGER, inst);
037e8744 20611 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20612}
20613
20614static void
20615do_neon_zip_uzp (void)
20616{
037e8744 20617 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20618 struct neon_type_el et = neon_check_type (2, rs,
20619 N_EQK, N_8 | N_16 | N_32 | N_KEY);
20620 if (rs == NS_DD && et.size == 32)
20621 {
20622 /* Special case: encode as VTRN.32 <Dd>, <Dm>. */
20623 inst.instruction = N_MNEM_vtrn;
20624 do_neon_trn ();
20625 return;
20626 }
037e8744 20627 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20628}
20629
20630static void
20631do_neon_sat_abs_neg (void)
20632{
5b7c81bd 20633 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
1a186d29
AV
20634 return;
20635
20636 enum neon_shape rs;
20637 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20638 rs = neon_select_shape (NS_QQ, NS_NULL);
20639 else
20640 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20641 struct neon_type_el et = neon_check_type (2, rs,
20642 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 20643 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20644}
20645
20646static void
20647do_neon_pair_long (void)
20648{
037e8744 20649 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20650 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
20651 /* Unsigned is encoded in OP field (bit 7) for these instruction. */
20652 inst.instruction |= (et.type == NT_unsigned) << 7;
037e8744 20653 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20654}
20655
20656static void
20657do_neon_recip_est (void)
20658{
037e8744 20659 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62 20660 struct neon_type_el et = neon_check_type (2, rs,
cc933301 20661 N_EQK | N_FLT, N_F_16_32 | N_U32 | N_KEY);
5287ad62 20662 inst.instruction |= (et.type == NT_float) << 8;
037e8744 20663 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20664}
20665
20666static void
20667do_neon_cls (void)
20668{
5b7c81bd 20669 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
f30ee27c
AV
20670 return;
20671
20672 enum neon_shape rs;
20673 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20674 rs = neon_select_shape (NS_QQ, NS_NULL);
20675 else
20676 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20677
5287ad62
JB
20678 struct neon_type_el et = neon_check_type (2, rs,
20679 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 20680 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20681}
20682
20683static void
20684do_neon_clz (void)
20685{
5b7c81bd 20686 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
f30ee27c
AV
20687 return;
20688
20689 enum neon_shape rs;
20690 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20691 rs = neon_select_shape (NS_QQ, NS_NULL);
20692 else
20693 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20694
5287ad62
JB
20695 struct neon_type_el et = neon_check_type (2, rs,
20696 N_EQK, N_I8 | N_I16 | N_I32 | N_KEY);
037e8744 20697 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20698}
20699
20700static void
20701do_neon_cnt (void)
20702{
037e8744 20703 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20704 struct neon_type_el et = neon_check_type (2, rs,
20705 N_EQK | N_INT, N_8 | N_KEY);
037e8744 20706 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20707}
20708
20709static void
20710do_neon_swp (void)
20711{
037e8744 20712 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
250dd99f
AM
20713 if (rs == NS_NULL)
20714 return;
037e8744 20715 neon_two_same (neon_quad (rs), 1, -1);
5287ad62
JB
20716}
20717
20718static void
20719do_neon_tbl_tbx (void)
20720{
20721 unsigned listlenbits;
dcbf9037 20722 neon_check_type (3, NS_DLD, N_EQK, N_EQK, N_8 | N_KEY);
5f4273c7 20723
5287ad62
JB
20724 if (inst.operands[1].imm < 1 || inst.operands[1].imm > 4)
20725 {
dcbf9037 20726 first_error (_("bad list length for table lookup"));
5287ad62
JB
20727 return;
20728 }
5f4273c7 20729
5287ad62
JB
20730 listlenbits = inst.operands[1].imm - 1;
20731 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20732 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20733 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20734 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20735 inst.instruction |= LOW4 (inst.operands[2].reg);
20736 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20737 inst.instruction |= listlenbits << 8;
5f4273c7 20738
88714cb8 20739 neon_dp_fixup (&inst);
5287ad62
JB
20740}
20741
20742static void
20743do_neon_ldm_stm (void)
20744{
ef8f595f
MI
20745 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
20746 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20747 _(BAD_FPU));
5287ad62
JB
20748 /* P, U and L bits are part of bitmask. */
20749 int is_dbmode = (inst.instruction & (1 << 24)) != 0;
20750 unsigned offsetbits = inst.operands[1].imm * 2;
20751
037e8744
JB
20752 if (inst.operands[1].issingle)
20753 {
20754 do_vfp_nsyn_ldm_stm (is_dbmode);
20755 return;
20756 }
20757
5287ad62 20758 constraint (is_dbmode && !inst.operands[0].writeback,
477330fc 20759 _("writeback (!) must be used for VLDMDB and VSTMDB"));
5287ad62
JB
20760
20761 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
477330fc
RM
20762 _("register list must contain at least 1 and at most 16 "
20763 "registers"));
5287ad62
JB
20764
20765 inst.instruction |= inst.operands[0].reg << 16;
20766 inst.instruction |= inst.operands[0].writeback << 21;
20767 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
20768 inst.instruction |= HI1 (inst.operands[1].reg) << 22;
20769
20770 inst.instruction |= offsetbits;
5f4273c7 20771
037e8744 20772 do_vfp_cond_or_thumb ();
5287ad62
JB
20773}
20774
d6dc01ba
MK
20775static void
20776do_vfp_nsyn_push_pop_check (void)
20777{
20778 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd), _(BAD_FPU));
20779
20780 if (inst.operands[1].issingle)
20781 {
20782 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 32,
20783 _("register list must contain at least 1 and at most 32 registers"));
20784 }
20785 else
20786 {
20787 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
20788 _("register list must contain at least 1 and at most 16 registers"));
20789 }
20790}
20791
ef8f595f
MI
20792static void
20793do_vfp_nsyn_pop (void)
20794{
20795 nsyn_insert_sp ();
ef8f595f 20796
d6dc01ba
MK
20797 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20798 return do_vfp_nsyn_opcode ("vldm");
ef8f595f 20799
d6dc01ba 20800 do_vfp_nsyn_push_pop_check ();
ef8f595f
MI
20801
20802 if (inst.operands[1].issingle)
20803 do_vfp_nsyn_opcode ("fldmias");
20804 else
20805 do_vfp_nsyn_opcode ("fldmiad");
20806}
20807
20808static void
20809do_vfp_nsyn_push (void)
20810{
20811 nsyn_insert_sp ();
ef8f595f 20812
d6dc01ba
MK
20813 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20814 return do_vfp_nsyn_opcode ("vstmdb");
ef8f595f 20815
d6dc01ba 20816 do_vfp_nsyn_push_pop_check ();
ef8f595f
MI
20817
20818 if (inst.operands[1].issingle)
20819 do_vfp_nsyn_opcode ("fstmdbs");
20820 else
20821 do_vfp_nsyn_opcode ("fstmdbd");
20822}
20823
5287ad62
JB
20824static void
20825do_neon_ldr_str (void)
20826{
5287ad62 20827 int is_ldr = (inst.instruction & (1 << 20)) != 0;
5f4273c7 20828
6844b2c2
MGD
20829 /* Use of PC in vstr in ARM mode is deprecated in ARMv7.
20830 And is UNPREDICTABLE in thumb mode. */
fa94de6b 20831 if (!is_ldr
6844b2c2 20832 && inst.operands[1].reg == REG_PC
ba86b375 20833 && (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7) || thumb_mode))
6844b2c2 20834 {
94dcf8bf 20835 if (thumb_mode)
6844b2c2 20836 inst.error = _("Use of PC here is UNPREDICTABLE");
94dcf8bf 20837 else if (warn_on_deprecated)
5c3696f8 20838 as_tsktsk (_("Use of PC here is deprecated"));
6844b2c2
MGD
20839 }
20840
037e8744
JB
20841 if (inst.operands[0].issingle)
20842 {
cd2f129f 20843 if (is_ldr)
477330fc 20844 do_vfp_nsyn_opcode ("flds");
cd2f129f 20845 else
477330fc 20846 do_vfp_nsyn_opcode ("fsts");
9db2f6b4
RL
20847
20848 /* ARMv8.2 vldr.16/vstr.16 instruction. */
20849 if (inst.vectype.el[0].size == 16)
20850 do_scalar_fp16_v82_encode ();
5287ad62
JB
20851 }
20852 else
5287ad62 20853 {
cd2f129f 20854 if (is_ldr)
477330fc 20855 do_vfp_nsyn_opcode ("fldd");
5287ad62 20856 else
477330fc 20857 do_vfp_nsyn_opcode ("fstd");
5287ad62 20858 }
5287ad62
JB
20859}
20860
32c36c3c
AV
20861static void
20862do_t_vldr_vstr_sysreg (void)
20863{
20864 int fp_vldr_bitno = 20, sysreg_vldr_bitno = 20;
5b7c81bd 20865 bool is_vldr = ((inst.instruction & (1 << fp_vldr_bitno)) != 0);
32c36c3c
AV
20866
20867 /* Use of PC is UNPREDICTABLE. */
20868 if (inst.operands[1].reg == REG_PC)
20869 inst.error = _("Use of PC here is UNPREDICTABLE");
20870
20871 if (inst.operands[1].immisreg)
20872 inst.error = _("instruction does not accept register index");
20873
20874 if (!inst.operands[1].isreg)
20875 inst.error = _("instruction does not accept PC-relative addressing");
20876
20877 if (abs (inst.operands[1].imm) >= (1 << 7))
20878 inst.error = _("immediate value out of range");
20879
20880 inst.instruction = 0xec000f80;
20881 if (is_vldr)
20882 inst.instruction |= 1 << sysreg_vldr_bitno;
5b7c81bd 20883 encode_arm_cp_address (1, true, false, BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM);
32c36c3c
AV
20884 inst.instruction |= (inst.operands[0].imm & 0x7) << 13;
20885 inst.instruction |= (inst.operands[0].imm & 0x8) << 19;
20886}
20887
20888static void
20889do_vldr_vstr (void)
20890{
5b7c81bd 20891 bool sysreg_op = !inst.operands[0].isreg;
32c36c3c
AV
20892
20893 /* VLDR/VSTR (System Register). */
20894 if (sysreg_op)
20895 {
20896 if (!mark_feature_used (&arm_ext_v8_1m_main))
20897 as_bad (_("Instruction not permitted on this architecture"));
20898
20899 do_t_vldr_vstr_sysreg ();
20900 }
20901 /* VLDR/VSTR. */
20902 else
20903 {
ef8f595f
MI
20904 if (!mark_feature_used (&fpu_vfp_ext_v1xd)
20905 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
32c36c3c
AV
20906 as_bad (_("Instruction not permitted on this architecture"));
20907 do_neon_ldr_str ();
20908 }
20909}
20910
5287ad62
JB
20911/* "interleave" version also handles non-interleaving register VLD1/VST1
20912 instructions. */
20913
20914static void
20915do_neon_ld_st_interleave (void)
20916{
037e8744 20917 struct neon_type_el et = neon_check_type (1, NS_NULL,
477330fc 20918 N_8 | N_16 | N_32 | N_64);
5287ad62
JB
20919 unsigned alignbits = 0;
20920 unsigned idx;
20921 /* The bits in this table go:
20922 0: register stride of one (0) or two (1)
20923 1,2: register list length, minus one (1, 2, 3, 4).
20924 3,4: <n> in instruction type, minus one (VLD<n> / VST<n>).
20925 We use -1 for invalid entries. */
20926 const int typetable[] =
20927 {
20928 0x7, -1, 0xa, -1, 0x6, -1, 0x2, -1, /* VLD1 / VST1. */
20929 -1, -1, 0x8, 0x9, -1, -1, 0x3, -1, /* VLD2 / VST2. */
20930 -1, -1, -1, -1, 0x4, 0x5, -1, -1, /* VLD3 / VST3. */
20931 -1, -1, -1, -1, -1, -1, 0x0, 0x1 /* VLD4 / VST4. */
20932 };
20933 int typebits;
20934
dcbf9037
JB
20935 if (et.type == NT_invtype)
20936 return;
20937
5287ad62
JB
20938 if (inst.operands[1].immisalign)
20939 switch (inst.operands[1].imm >> 8)
20940 {
20941 case 64: alignbits = 1; break;
20942 case 128:
477330fc 20943 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2
e23c0ad8 20944 && NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
477330fc
RM
20945 goto bad_alignment;
20946 alignbits = 2;
20947 break;
5287ad62 20948 case 256:
477330fc
RM
20949 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
20950 goto bad_alignment;
20951 alignbits = 3;
20952 break;
5287ad62
JB
20953 default:
20954 bad_alignment:
477330fc
RM
20955 first_error (_("bad alignment"));
20956 return;
5287ad62
JB
20957 }
20958
20959 inst.instruction |= alignbits << 4;
20960 inst.instruction |= neon_logbits (et.size) << 6;
20961
20962 /* Bits [4:6] of the immediate in a list specifier encode register stride
20963 (minus 1) in bit 4, and list length in bits [5:6]. We put the <n> of
20964 VLD<n>/VST<n> in bits [9:8] of the initial bitmask. Suck it out here, look
20965 up the right value for "type" in a table based on this value and the given
20966 list style, then stick it back. */
20967 idx = ((inst.operands[0].imm >> 4) & 7)
477330fc 20968 | (((inst.instruction >> 8) & 3) << 3);
5287ad62
JB
20969
20970 typebits = typetable[idx];
5f4273c7 20971
5287ad62 20972 constraint (typebits == -1, _("bad list type for instruction"));
1d50d57c 20973 constraint (((inst.instruction >> 8) & 3) && et.size == 64,
35c228db 20974 BAD_EL_TYPE);
5287ad62
JB
20975
20976 inst.instruction &= ~0xf00;
20977 inst.instruction |= typebits << 8;
20978}
20979
20980/* Check alignment is valid for do_neon_ld_st_lane and do_neon_ld_dup.
20981 *DO_ALIGN is set to 1 if the relevant alignment bit should be set, 0
20982 otherwise. The variable arguments are a list of pairs of legal (size, align)
20983 values, terminated with -1. */
20984
20985static int
aa8a0863 20986neon_alignment_bit (int size, int align, int *do_alignment, ...)
5287ad62
JB
20987{
20988 va_list ap;
20989 int result = FAIL, thissize, thisalign;
5f4273c7 20990
5287ad62
JB
20991 if (!inst.operands[1].immisalign)
20992 {
aa8a0863 20993 *do_alignment = 0;
5287ad62
JB
20994 return SUCCESS;
20995 }
5f4273c7 20996
aa8a0863 20997 va_start (ap, do_alignment);
5287ad62
JB
20998
20999 do
21000 {
21001 thissize = va_arg (ap, int);
21002 if (thissize == -1)
477330fc 21003 break;
5287ad62
JB
21004 thisalign = va_arg (ap, int);
21005
21006 if (size == thissize && align == thisalign)
477330fc 21007 result = SUCCESS;
5287ad62
JB
21008 }
21009 while (result != SUCCESS);
21010
21011 va_end (ap);
21012
21013 if (result == SUCCESS)
aa8a0863 21014 *do_alignment = 1;
5287ad62 21015 else
dcbf9037 21016 first_error (_("unsupported alignment for instruction"));
5f4273c7 21017
5287ad62
JB
21018 return result;
21019}
21020
21021static void
21022do_neon_ld_st_lane (void)
21023{
037e8744 21024 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 21025 int align_good, do_alignment = 0;
5287ad62
JB
21026 int logsize = neon_logbits (et.size);
21027 int align = inst.operands[1].imm >> 8;
21028 int n = (inst.instruction >> 8) & 3;
21029 int max_el = 64 / et.size;
5f4273c7 21030
dcbf9037
JB
21031 if (et.type == NT_invtype)
21032 return;
5f4273c7 21033
5287ad62 21034 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != n + 1,
477330fc 21035 _("bad list length"));
5287ad62 21036 constraint (NEON_LANE (inst.operands[0].imm) >= max_el,
477330fc 21037 _("scalar index out of range"));
5287ad62 21038 constraint (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2
477330fc
RM
21039 && et.size == 8,
21040 _("stride of 2 unavailable when element size is 8"));
5f4273c7 21041
5287ad62
JB
21042 switch (n)
21043 {
21044 case 0: /* VLD1 / VST1. */
aa8a0863 21045 align_good = neon_alignment_bit (et.size, align, &do_alignment, 16, 16,
477330fc 21046 32, 32, -1);
5287ad62 21047 if (align_good == FAIL)
477330fc 21048 return;
aa8a0863 21049 if (do_alignment)
477330fc
RM
21050 {
21051 unsigned alignbits = 0;
21052 switch (et.size)
21053 {
21054 case 16: alignbits = 0x1; break;
21055 case 32: alignbits = 0x3; break;
21056 default: ;
21057 }
21058 inst.instruction |= alignbits << 4;
21059 }
5287ad62
JB
21060 break;
21061
21062 case 1: /* VLD2 / VST2. */
aa8a0863
TS
21063 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 16,
21064 16, 32, 32, 64, -1);
5287ad62 21065 if (align_good == FAIL)
477330fc 21066 return;
aa8a0863 21067 if (do_alignment)
477330fc 21068 inst.instruction |= 1 << 4;
5287ad62
JB
21069 break;
21070
21071 case 2: /* VLD3 / VST3. */
21072 constraint (inst.operands[1].immisalign,
477330fc 21073 _("can't use alignment with this instruction"));
5287ad62
JB
21074 break;
21075
21076 case 3: /* VLD4 / VST4. */
aa8a0863 21077 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc 21078 16, 64, 32, 64, 32, 128, -1);
5287ad62 21079 if (align_good == FAIL)
477330fc 21080 return;
aa8a0863 21081 if (do_alignment)
477330fc
RM
21082 {
21083 unsigned alignbits = 0;
21084 switch (et.size)
21085 {
21086 case 8: alignbits = 0x1; break;
21087 case 16: alignbits = 0x1; break;
21088 case 32: alignbits = (align == 64) ? 0x1 : 0x2; break;
21089 default: ;
21090 }
21091 inst.instruction |= alignbits << 4;
21092 }
5287ad62
JB
21093 break;
21094
21095 default: ;
21096 }
21097
21098 /* Reg stride of 2 is encoded in bit 5 when size==16, bit 6 when size==32. */
21099 if (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2)
21100 inst.instruction |= 1 << (4 + logsize);
5f4273c7 21101
5287ad62
JB
21102 inst.instruction |= NEON_LANE (inst.operands[0].imm) << (logsize + 5);
21103 inst.instruction |= logsize << 10;
21104}
21105
21106/* Encode single n-element structure to all lanes VLD<n> instructions. */
21107
21108static void
21109do_neon_ld_dup (void)
21110{
037e8744 21111 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 21112 int align_good, do_alignment = 0;
5287ad62 21113
dcbf9037
JB
21114 if (et.type == NT_invtype)
21115 return;
21116
5287ad62
JB
21117 switch ((inst.instruction >> 8) & 3)
21118 {
21119 case 0: /* VLD1. */
9c2799c2 21120 gas_assert (NEON_REG_STRIDE (inst.operands[0].imm) != 2);
5287ad62 21121 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863 21122 &do_alignment, 16, 16, 32, 32, -1);
5287ad62 21123 if (align_good == FAIL)
477330fc 21124 return;
5287ad62 21125 switch (NEON_REGLIST_LENGTH (inst.operands[0].imm))
477330fc
RM
21126 {
21127 case 1: break;
21128 case 2: inst.instruction |= 1 << 5; break;
21129 default: first_error (_("bad list length")); return;
21130 }
5287ad62
JB
21131 inst.instruction |= neon_logbits (et.size) << 6;
21132 break;
21133
21134 case 1: /* VLD2. */
21135 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863
TS
21136 &do_alignment, 8, 16, 16, 32, 32, 64,
21137 -1);
5287ad62 21138 if (align_good == FAIL)
477330fc 21139 return;
5287ad62 21140 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2,
477330fc 21141 _("bad list length"));
5287ad62 21142 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 21143 inst.instruction |= 1 << 5;
5287ad62
JB
21144 inst.instruction |= neon_logbits (et.size) << 6;
21145 break;
21146
21147 case 2: /* VLD3. */
21148 constraint (inst.operands[1].immisalign,
477330fc 21149 _("can't use alignment with this instruction"));
5287ad62 21150 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 3,
477330fc 21151 _("bad list length"));
5287ad62 21152 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 21153 inst.instruction |= 1 << 5;
5287ad62
JB
21154 inst.instruction |= neon_logbits (et.size) << 6;
21155 break;
21156
21157 case 3: /* VLD4. */
21158 {
477330fc 21159 int align = inst.operands[1].imm >> 8;
aa8a0863 21160 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc
RM
21161 16, 64, 32, 64, 32, 128, -1);
21162 if (align_good == FAIL)
21163 return;
21164 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4,
21165 _("bad list length"));
21166 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
21167 inst.instruction |= 1 << 5;
21168 if (et.size == 32 && align == 128)
21169 inst.instruction |= 0x3 << 6;
21170 else
21171 inst.instruction |= neon_logbits (et.size) << 6;
5287ad62
JB
21172 }
21173 break;
21174
21175 default: ;
21176 }
21177
aa8a0863 21178 inst.instruction |= do_alignment << 4;
5287ad62
JB
21179}
21180
21181/* Disambiguate VLD<n> and VST<n> instructions, and fill in common bits (those
21182 apart from bits [11:4]. */
21183
21184static void
21185do_neon_ldx_stx (void)
21186{
b1a769ed
DG
21187 if (inst.operands[1].isreg)
21188 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
21189
5287ad62
JB
21190 switch (NEON_LANE (inst.operands[0].imm))
21191 {
21192 case NEON_INTERLEAVE_LANES:
88714cb8 21193 NEON_ENCODE (INTERLV, inst);
5287ad62
JB
21194 do_neon_ld_st_interleave ();
21195 break;
5f4273c7 21196
5287ad62 21197 case NEON_ALL_LANES:
88714cb8 21198 NEON_ENCODE (DUP, inst);
2d51fb74
JB
21199 if (inst.instruction == N_INV)
21200 {
21201 first_error ("only loads support such operands");
21202 break;
21203 }
5287ad62
JB
21204 do_neon_ld_dup ();
21205 break;
5f4273c7 21206
5287ad62 21207 default:
88714cb8 21208 NEON_ENCODE (LANE, inst);
5287ad62
JB
21209 do_neon_ld_st_lane ();
21210 }
21211
21212 /* L bit comes from bit mask. */
21213 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21214 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21215 inst.instruction |= inst.operands[1].reg << 16;
5f4273c7 21216
5287ad62
JB
21217 if (inst.operands[1].postind)
21218 {
21219 int postreg = inst.operands[1].imm & 0xf;
21220 constraint (!inst.operands[1].immisreg,
477330fc 21221 _("post-index must be a register"));
5287ad62 21222 constraint (postreg == 0xd || postreg == 0xf,
477330fc 21223 _("bad register for post-index"));
5287ad62
JB
21224 inst.instruction |= postreg;
21225 }
4f2374c7 21226 else
5287ad62 21227 {
4f2374c7 21228 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
e2b0ab59
AV
21229 constraint (inst.relocs[0].exp.X_op != O_constant
21230 || inst.relocs[0].exp.X_add_number != 0,
4f2374c7
WN
21231 BAD_ADDR_MODE);
21232
21233 if (inst.operands[1].writeback)
21234 {
21235 inst.instruction |= 0xd;
21236 }
21237 else
21238 inst.instruction |= 0xf;
5287ad62 21239 }
5f4273c7 21240
5287ad62
JB
21241 if (thumb_mode)
21242 inst.instruction |= 0xf9000000;
21243 else
21244 inst.instruction |= 0xf4000000;
21245}
33399f07
MGD
21246
21247/* FP v8. */
21248static void
21249do_vfp_nsyn_fpv8 (enum neon_shape rs)
21250{
a715796b
TG
21251 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
21252 D register operands. */
21253 if (neon_shape_class[rs] == SC_DOUBLE)
21254 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
21255 _(BAD_FPU));
21256
33399f07
MGD
21257 NEON_ENCODE (FPV8, inst);
21258
9db2f6b4
RL
21259 if (rs == NS_FFF || rs == NS_HHH)
21260 {
21261 do_vfp_sp_dyadic ();
21262
21263 /* ARMv8.2 fp16 instruction. */
21264 if (rs == NS_HHH)
21265 do_scalar_fp16_v82_encode ();
21266 }
33399f07
MGD
21267 else
21268 do_vfp_dp_rd_rn_rm ();
21269
21270 if (rs == NS_DDD)
21271 inst.instruction |= 0x100;
21272
21273 inst.instruction |= 0xf0000000;
21274}
21275
21276static void
21277do_vsel (void)
21278{
5ee91343 21279 set_pred_insn_type (OUTSIDE_PRED_INSN);
33399f07
MGD
21280
21281 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
21282 first_error (_("invalid instruction shape"));
21283}
21284
73924fbc
MGD
21285static void
21286do_vmaxnm (void)
21287{
935295b5
AV
21288 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
21289 set_pred_insn_type (OUTSIDE_PRED_INSN);
73924fbc
MGD
21290
21291 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
21292 return;
21293
5b7c81bd 21294 if (!check_simd_pred_availability (true, NEON_CHECK_CC | NEON_CHECK_ARCH8))
73924fbc
MGD
21295 return;
21296
cc933301 21297 neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
73924fbc
MGD
21298}
21299
30bdf752
MGD
21300static void
21301do_vrint_1 (enum neon_cvt_mode mode)
21302{
9db2f6b4 21303 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_QQ, NS_NULL);
30bdf752
MGD
21304 struct neon_type_el et;
21305
21306 if (rs == NS_NULL)
21307 return;
21308
a715796b
TG
21309 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
21310 D register operands. */
21311 if (neon_shape_class[rs] == SC_DOUBLE)
21312 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
21313 _(BAD_FPU));
21314
9db2f6b4
RL
21315 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY
21316 | N_VFP);
30bdf752
MGD
21317 if (et.type != NT_invtype)
21318 {
21319 /* VFP encodings. */
21320 if (mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
21321 || mode == neon_cvt_mode_p || mode == neon_cvt_mode_m)
5ee91343 21322 set_pred_insn_type (OUTSIDE_PRED_INSN);
30bdf752
MGD
21323
21324 NEON_ENCODE (FPV8, inst);
9db2f6b4 21325 if (rs == NS_FF || rs == NS_HH)
30bdf752
MGD
21326 do_vfp_sp_monadic ();
21327 else
21328 do_vfp_dp_rd_rm ();
21329
21330 switch (mode)
21331 {
21332 case neon_cvt_mode_r: inst.instruction |= 0x00000000; break;
21333 case neon_cvt_mode_z: inst.instruction |= 0x00000080; break;
21334 case neon_cvt_mode_x: inst.instruction |= 0x00010000; break;
21335 case neon_cvt_mode_a: inst.instruction |= 0xf0000000; break;
21336 case neon_cvt_mode_n: inst.instruction |= 0xf0010000; break;
21337 case neon_cvt_mode_p: inst.instruction |= 0xf0020000; break;
21338 case neon_cvt_mode_m: inst.instruction |= 0xf0030000; break;
21339 default: abort ();
21340 }
21341
21342 inst.instruction |= (rs == NS_DD) << 8;
21343 do_vfp_cond_or_thumb ();
9db2f6b4
RL
21344
21345 /* ARMv8.2 fp16 vrint instruction. */
21346 if (rs == NS_HH)
21347 do_scalar_fp16_v82_encode ();
30bdf752
MGD
21348 }
21349 else
21350 {
21351 /* Neon encodings (or something broken...). */
21352 inst.error = NULL;
cc933301 21353 et = neon_check_type (2, rs, N_EQK, N_F_16_32 | N_KEY);
30bdf752
MGD
21354
21355 if (et.type == NT_invtype)
21356 return;
21357
5b7c81bd 21358 if (!check_simd_pred_availability (true,
64c350f2 21359 NEON_CHECK_CC | NEON_CHECK_ARCH8))
30bdf752
MGD
21360 return;
21361
a710b305
AV
21362 NEON_ENCODE (FLOAT, inst);
21363
30bdf752
MGD
21364 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21365 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21366 inst.instruction |= LOW4 (inst.operands[1].reg);
21367 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
21368 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
21369 /* Mask off the original size bits and reencode them. */
21370 inst.instruction = ((inst.instruction & 0xfff3ffff)
21371 | neon_logbits (et.size) << 18);
21372
30bdf752
MGD
21373 switch (mode)
21374 {
21375 case neon_cvt_mode_z: inst.instruction |= 3 << 7; break;
21376 case neon_cvt_mode_x: inst.instruction |= 1 << 7; break;
21377 case neon_cvt_mode_a: inst.instruction |= 2 << 7; break;
21378 case neon_cvt_mode_n: inst.instruction |= 0 << 7; break;
21379 case neon_cvt_mode_p: inst.instruction |= 7 << 7; break;
21380 case neon_cvt_mode_m: inst.instruction |= 5 << 7; break;
21381 case neon_cvt_mode_r: inst.error = _("invalid rounding mode"); break;
21382 default: abort ();
21383 }
21384
21385 if (thumb_mode)
21386 inst.instruction |= 0xfc000000;
21387 else
21388 inst.instruction |= 0xf0000000;
21389 }
21390}
21391
21392static void
21393do_vrintx (void)
21394{
21395 do_vrint_1 (neon_cvt_mode_x);
21396}
21397
21398static void
21399do_vrintz (void)
21400{
21401 do_vrint_1 (neon_cvt_mode_z);
21402}
21403
21404static void
21405do_vrintr (void)
21406{
21407 do_vrint_1 (neon_cvt_mode_r);
21408}
21409
21410static void
21411do_vrinta (void)
21412{
21413 do_vrint_1 (neon_cvt_mode_a);
21414}
21415
21416static void
21417do_vrintn (void)
21418{
21419 do_vrint_1 (neon_cvt_mode_n);
21420}
21421
21422static void
21423do_vrintp (void)
21424{
21425 do_vrint_1 (neon_cvt_mode_p);
21426}
21427
21428static void
21429do_vrintm (void)
21430{
21431 do_vrint_1 (neon_cvt_mode_m);
21432}
21433
c28eeff2
SN
21434static unsigned
21435neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
21436{
21437 unsigned regno = NEON_SCALAR_REG (opnd);
21438 unsigned elno = NEON_SCALAR_INDEX (opnd);
21439
21440 if (elsize == 16 && elno < 2 && regno < 16)
21441 return regno | (elno << 4);
21442 else if (elsize == 32 && elno == 0)
21443 return regno;
21444
21445 first_error (_("scalar out of range"));
21446 return 0;
21447}
21448
21449static void
21450do_vcmla (void)
21451{
5d281bf0
AV
21452 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext)
21453 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
21454 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
21455 constraint (inst.relocs[0].exp.X_op != O_constant,
21456 _("expression too complex"));
21457 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
21458 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
21459 _("immediate out of range"));
21460 rot /= 90;
5d281bf0 21461
5b7c81bd 21462 if (!check_simd_pred_availability (true,
64c350f2 21463 NEON_CHECK_ARCH8 | NEON_CHECK_CC))
5d281bf0
AV
21464 return;
21465
c28eeff2
SN
21466 if (inst.operands[2].isscalar)
21467 {
5d281bf0
AV
21468 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
21469 first_error (_("invalid instruction shape"));
c28eeff2
SN
21470 enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
21471 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
21472 N_KEY | N_F16 | N_F32).size;
21473 unsigned m = neon_scalar_for_vcmla (inst.operands[2].reg, size);
21474 inst.is_neon = 1;
21475 inst.instruction = 0xfe000800;
21476 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21477 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21478 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
21479 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
21480 inst.instruction |= LOW4 (m);
21481 inst.instruction |= HI1 (m) << 5;
21482 inst.instruction |= neon_quad (rs) << 6;
21483 inst.instruction |= rot << 20;
21484 inst.instruction |= (size == 32) << 23;
21485 }
21486 else
21487 {
5d281bf0
AV
21488 enum neon_shape rs;
21489 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
21490 rs = neon_select_shape (NS_QQQI, NS_NULL);
21491 else
21492 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
21493
c28eeff2
SN
21494 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
21495 N_KEY | N_F16 | N_F32).size;
5d281bf0
AV
21496 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext) && size == 32
21497 && (inst.operands[0].reg == inst.operands[1].reg
21498 || inst.operands[0].reg == inst.operands[2].reg))
21499 as_tsktsk (BAD_MVE_SRCDEST);
21500
c28eeff2
SN
21501 neon_three_same (neon_quad (rs), 0, -1);
21502 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
21503 inst.instruction |= 0xfc200800;
21504 inst.instruction |= rot << 23;
21505 inst.instruction |= (size == 32) << 20;
21506 }
21507}
21508
21509static void
21510do_vcadd (void)
21511{
5d281bf0
AV
21512 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
21513 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
21514 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
21515 constraint (inst.relocs[0].exp.X_op != O_constant,
21516 _("expression too complex"));
5d281bf0 21517
e2b0ab59 21518 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2 21519 constraint (rot != 90 && rot != 270, _("immediate out of range"));
5d281bf0
AV
21520 enum neon_shape rs;
21521 struct neon_type_el et;
21522 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
21523 {
21524 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
21525 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32);
21526 }
21527 else
21528 {
21529 rs = neon_select_shape (NS_QQQI, NS_NULL);
21530 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32 | N_I8
21531 | N_I16 | N_I32);
21532 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
21533 as_tsktsk (_("Warning: 32-bit element size and same first and third "
21534 "operand makes instruction UNPREDICTABLE"));
21535 }
21536
21537 if (et.type == NT_invtype)
21538 return;
21539
64c350f2
AV
21540 if (!check_simd_pred_availability (et.type == NT_float,
21541 NEON_CHECK_ARCH8 | NEON_CHECK_CC))
5d281bf0
AV
21542 return;
21543
21544 if (et.type == NT_float)
21545 {
21546 neon_three_same (neon_quad (rs), 0, -1);
21547 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
21548 inst.instruction |= 0xfc800800;
21549 inst.instruction |= (rot == 270) << 24;
21550 inst.instruction |= (et.size == 32) << 20;
21551 }
21552 else
21553 {
21554 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
21555 inst.instruction = 0xfe000f00;
21556 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21557 inst.instruction |= neon_logbits (et.size) << 20;
21558 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
21559 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21560 inst.instruction |= (rot == 270) << 12;
21561 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
21562 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
21563 inst.instruction |= LOW4 (inst.operands[2].reg);
21564 inst.is_neon = 1;
21565 }
c28eeff2
SN
21566}
21567
c604a79a
JW
21568/* Dot Product instructions encoding support. */
21569
21570static void
21571do_neon_dotproduct (int unsigned_p)
21572{
21573 enum neon_shape rs;
21574 unsigned scalar_oprd2 = 0;
21575 int high8;
21576
21577 if (inst.cond != COND_ALWAYS)
21578 as_warn (_("Dot Product instructions cannot be conditional, the behaviour "
21579 "is UNPREDICTABLE"));
21580
21581 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
21582 _(BAD_FPU));
21583
21584 /* Dot Product instructions are in three-same D/Q register format or the third
21585 operand can be a scalar index register. */
21586 if (inst.operands[2].isscalar)
21587 {
21588 scalar_oprd2 = neon_scalar_for_mul (inst.operands[2].reg, 32);
21589 high8 = 0xfe000000;
21590 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21591 }
21592 else
21593 {
21594 high8 = 0xfc000000;
21595 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
21596 }
21597
21598 if (unsigned_p)
21599 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_U8);
21600 else
21601 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_S8);
21602
21603 /* The "U" bit in traditional Three Same encoding is fixed to 0 for Dot
21604 Product instruction, so we pass 0 as the "ubit" parameter. And the
21605 "Size" field are fixed to 0x2, so we pass 32 as the "size" parameter. */
21606 neon_three_same (neon_quad (rs), 0, 32);
21607
21608 /* Undo neon_dp_fixup. Dot Product instructions are using a slightly
21609 different NEON three-same encoding. */
21610 inst.instruction &= 0x00ffffff;
21611 inst.instruction |= high8;
21612 /* Encode 'U' bit which indicates signedness. */
21613 inst.instruction |= (unsigned_p ? 1 : 0) << 4;
21614 /* Re-encode operand2 if it's indexed scalar operand. What has been encoded
21615 from inst.operand[2].reg in neon_three_same is GAS's internal encoding, not
21616 the instruction encoding. */
21617 if (inst.operands[2].isscalar)
21618 {
21619 inst.instruction &= 0xffffffd0;
21620 inst.instruction |= LOW4 (scalar_oprd2);
21621 inst.instruction |= HI1 (scalar_oprd2) << 5;
21622 }
21623}
21624
21625/* Dot Product instructions for signed integer. */
21626
21627static void
21628do_neon_dotproduct_s (void)
21629{
21630 return do_neon_dotproduct (0);
21631}
21632
21633/* Dot Product instructions for unsigned integer. */
21634
21635static void
21636do_neon_dotproduct_u (void)
21637{
21638 return do_neon_dotproduct (1);
21639}
21640
616ce08e
MM
21641static void
21642do_vusdot (void)
21643{
21644 enum neon_shape rs;
21645 set_pred_insn_type (OUTSIDE_PRED_INSN);
21646 if (inst.operands[2].isscalar)
21647 {
21648 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21649 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21650
21651 inst.instruction |= (1 << 25);
1db66fb6
JB
21652 int idx = inst.operands[2].reg & 0xf;
21653 constraint ((idx != 1 && idx != 0), _("index must be 0 or 1"));
616ce08e
MM
21654 inst.operands[2].reg >>= 4;
21655 constraint (!(inst.operands[2].reg < 16),
21656 _("indexed register must be less than 16"));
21657 neon_three_args (rs == NS_QQS);
1db66fb6 21658 inst.instruction |= (idx << 5);
616ce08e
MM
21659 }
21660 else
21661 {
21662 inst.instruction |= (1 << 21);
21663 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
21664 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21665 neon_three_args (rs == NS_QQQ);
21666 }
21667}
21668
21669static void
21670do_vsudot (void)
21671{
21672 enum neon_shape rs;
21673 set_pred_insn_type (OUTSIDE_PRED_INSN);
21674 if (inst.operands[2].isscalar)
21675 {
21676 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21677 neon_check_type (3, rs, N_EQK, N_EQK, N_U8 | N_KEY);
21678
21679 inst.instruction |= (1 << 25);
1db66fb6
JB
21680 int idx = inst.operands[2].reg & 0xf;
21681 constraint ((idx != 1 && idx != 0), _("index must be 0 or 1"));
616ce08e
MM
21682 inst.operands[2].reg >>= 4;
21683 constraint (!(inst.operands[2].reg < 16),
21684 _("indexed register must be less than 16"));
21685 neon_three_args (rs == NS_QQS);
1db66fb6 21686 inst.instruction |= (idx << 5);
616ce08e
MM
21687 }
21688}
21689
21690static void
21691do_vsmmla (void)
21692{
21693 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
21694 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21695
21696 set_pred_insn_type (OUTSIDE_PRED_INSN);
21697
21698 neon_three_args (1);
21699
21700}
21701
21702static void
21703do_vummla (void)
21704{
21705 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
21706 neon_check_type (3, rs, N_EQK, N_EQK, N_U8 | N_KEY);
21707
21708 set_pred_insn_type (OUTSIDE_PRED_INSN);
21709
21710 neon_three_args (1);
21711
21712}
21713
4934a27c 21714static void
1db66fb6 21715check_cde_operand (size_t idx, int is_dual)
4934a27c 21716{
1db66fb6
JB
21717 unsigned Rx = inst.operands[idx].reg;
21718 bool isvec = inst.operands[idx].isvec;
4934a27c
MM
21719 if (is_dual == 0 && thumb_mode)
21720 constraint (
21721 !((Rx <= 14 && Rx != 13) || (Rx == REG_PC && isvec)),
21722 _("Register must be r0-r14 except r13, or APSR_nzcv."));
21723 else
21724 constraint ( !((Rx <= 10 && Rx % 2 == 0 )),
21725 _("Register must be an even register between r0-r10."));
21726}
21727
5b7c81bd 21728static bool
4934a27c
MM
21729cde_coproc_enabled (unsigned coproc)
21730{
21731 switch (coproc)
21732 {
21733 case 0: return mark_feature_used (&arm_ext_cde0);
21734 case 1: return mark_feature_used (&arm_ext_cde1);
21735 case 2: return mark_feature_used (&arm_ext_cde2);
21736 case 3: return mark_feature_used (&arm_ext_cde3);
21737 case 4: return mark_feature_used (&arm_ext_cde4);
21738 case 5: return mark_feature_used (&arm_ext_cde5);
21739 case 6: return mark_feature_used (&arm_ext_cde6);
21740 case 7: return mark_feature_used (&arm_ext_cde7);
5b7c81bd 21741 default: return false;
4934a27c
MM
21742 }
21743}
21744
21745#define cde_coproc_pos 8
21746static void
21747cde_handle_coproc (void)
21748{
21749 unsigned coproc = inst.operands[0].reg;
21750 constraint (coproc > 7, _("CDE Coprocessor must be in range 0-7"));
21751 constraint (!(cde_coproc_enabled (coproc)), BAD_CDE_COPROC);
21752 inst.instruction |= coproc << cde_coproc_pos;
21753}
21754#undef cde_coproc_pos
21755
21756static void
5b7c81bd 21757cxn_handle_predication (bool is_accum)
4934a27c 21758{
cceb53b8
MM
21759 if (is_accum && conditional_insn ())
21760 set_pred_insn_type (INSIDE_IT_INSN);
21761 else if (conditional_insn ())
21762 /* conditional_insn essentially checks for a suffix, not whether the
21763 instruction is inside an IT block or not.
21764 The non-accumulator versions should not have suffixes. */
4934a27c 21765 inst.error = BAD_SYNTAX;
4934a27c
MM
21766 else
21767 set_pred_insn_type (OUTSIDE_PRED_INSN);
21768}
21769
21770static void
5b7c81bd 21771do_custom_instruction_1 (int is_dual, bool is_accum)
4934a27c
MM
21772{
21773
21774 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21775
21776 unsigned imm, Rd;
21777
21778 Rd = inst.operands[1].reg;
21779 check_cde_operand (1, is_dual);
21780
21781 if (is_dual == 1)
21782 {
21783 constraint (inst.operands[2].reg != Rd + 1,
21784 _("cx1d requires consecutive destination registers."));
21785 imm = inst.operands[3].imm;
21786 }
21787 else if (is_dual == 0)
21788 imm = inst.operands[2].imm;
21789 else
21790 abort ();
21791
21792 inst.instruction |= Rd << 12;
21793 inst.instruction |= (imm & 0x1F80) << 9;
21794 inst.instruction |= (imm & 0x0040) << 1;
21795 inst.instruction |= (imm & 0x003f);
21796
21797 cde_handle_coproc ();
21798 cxn_handle_predication (is_accum);
21799}
21800
21801static void
5b7c81bd 21802do_custom_instruction_2 (int is_dual, bool is_accum)
4934a27c
MM
21803{
21804
21805 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21806
21807 unsigned imm, Rd, Rn;
21808
21809 Rd = inst.operands[1].reg;
21810
21811 if (is_dual == 1)
21812 {
21813 constraint (inst.operands[2].reg != Rd + 1,
21814 _("cx2d requires consecutive destination registers."));
21815 imm = inst.operands[4].imm;
21816 Rn = inst.operands[3].reg;
21817 }
21818 else if (is_dual == 0)
21819 {
21820 imm = inst.operands[3].imm;
21821 Rn = inst.operands[2].reg;
21822 }
21823 else
21824 abort ();
21825
21826 check_cde_operand (2 + is_dual, /* is_dual = */0);
21827 check_cde_operand (1, is_dual);
21828
21829 inst.instruction |= Rd << 12;
21830 inst.instruction |= Rn << 16;
21831
21832 inst.instruction |= (imm & 0x0380) << 13;
21833 inst.instruction |= (imm & 0x0040) << 1;
21834 inst.instruction |= (imm & 0x003f);
21835
21836 cde_handle_coproc ();
21837 cxn_handle_predication (is_accum);
21838}
21839
21840static void
5b7c81bd 21841do_custom_instruction_3 (int is_dual, bool is_accum)
4934a27c
MM
21842{
21843
21844 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21845
21846 unsigned imm, Rd, Rn, Rm;
21847
21848 Rd = inst.operands[1].reg;
21849
21850 if (is_dual == 1)
21851 {
21852 constraint (inst.operands[2].reg != Rd + 1,
21853 _("cx3d requires consecutive destination registers."));
21854 imm = inst.operands[5].imm;
21855 Rn = inst.operands[3].reg;
21856 Rm = inst.operands[4].reg;
21857 }
21858 else if (is_dual == 0)
21859 {
21860 imm = inst.operands[4].imm;
21861 Rn = inst.operands[2].reg;
21862 Rm = inst.operands[3].reg;
21863 }
21864 else
21865 abort ();
21866
21867 check_cde_operand (1, is_dual);
21868 check_cde_operand (2 + is_dual, /* is_dual = */0);
21869 check_cde_operand (3 + is_dual, /* is_dual = */0);
21870
21871 inst.instruction |= Rd;
21872 inst.instruction |= Rn << 16;
21873 inst.instruction |= Rm << 12;
21874
21875 inst.instruction |= (imm & 0x0038) << 17;
21876 inst.instruction |= (imm & 0x0004) << 5;
21877 inst.instruction |= (imm & 0x0003) << 4;
21878
21879 cde_handle_coproc ();
21880 cxn_handle_predication (is_accum);
21881}
21882
21883static void
21884do_cx1 (void)
21885{
21886 return do_custom_instruction_1 (0, 0);
21887}
21888
21889static void
21890do_cx1a (void)
21891{
21892 return do_custom_instruction_1 (0, 1);
21893}
21894
21895static void
21896do_cx1d (void)
21897{
21898 return do_custom_instruction_1 (1, 0);
21899}
21900
21901static void
21902do_cx1da (void)
21903{
21904 return do_custom_instruction_1 (1, 1);
21905}
21906
21907static void
21908do_cx2 (void)
21909{
21910 return do_custom_instruction_2 (0, 0);
21911}
21912
21913static void
21914do_cx2a (void)
21915{
21916 return do_custom_instruction_2 (0, 1);
21917}
21918
21919static void
21920do_cx2d (void)
21921{
21922 return do_custom_instruction_2 (1, 0);
21923}
21924
21925static void
21926do_cx2da (void)
21927{
21928 return do_custom_instruction_2 (1, 1);
21929}
21930
21931static void
21932do_cx3 (void)
21933{
21934 return do_custom_instruction_3 (0, 0);
21935}
21936
21937static void
21938do_cx3a (void)
21939{
21940 return do_custom_instruction_3 (0, 1);
21941}
21942
21943static void
21944do_cx3d (void)
21945{
21946 return do_custom_instruction_3 (1, 0);
21947}
21948
21949static void
21950do_cx3da (void)
21951{
21952 return do_custom_instruction_3 (1, 1);
21953}
21954
5aae9ae9
MM
21955static void
21956vcx_assign_vec_d (unsigned regnum)
21957{
21958 inst.instruction |= HI4 (regnum) << 12;
21959 inst.instruction |= LOW1 (regnum) << 22;
21960}
21961
21962static void
21963vcx_assign_vec_m (unsigned regnum)
21964{
21965 inst.instruction |= HI4 (regnum);
21966 inst.instruction |= LOW1 (regnum) << 5;
21967}
21968
21969static void
21970vcx_assign_vec_n (unsigned regnum)
21971{
21972 inst.instruction |= HI4 (regnum) << 16;
21973 inst.instruction |= LOW1 (regnum) << 7;
21974}
21975
21976enum vcx_reg_type {
21977 q_reg,
21978 d_reg,
21979 s_reg
21980};
21981
21982static enum vcx_reg_type
21983vcx_get_reg_type (enum neon_shape ns)
21984{
21985 gas_assert (ns == NS_PQI
21986 || ns == NS_PDI
21987 || ns == NS_PFI
21988 || ns == NS_PQQI
21989 || ns == NS_PDDI
21990 || ns == NS_PFFI
21991 || ns == NS_PQQQI
21992 || ns == NS_PDDDI
21993 || ns == NS_PFFFI);
21994 if (ns == NS_PQI || ns == NS_PQQI || ns == NS_PQQQI)
21995 return q_reg;
21996 if (ns == NS_PDI || ns == NS_PDDI || ns == NS_PDDDI)
21997 return d_reg;
21998 return s_reg;
21999}
22000
22001#define vcx_size_pos 24
22002#define vcx_vec_pos 6
22003static unsigned
22004vcx_handle_shape (enum vcx_reg_type reg_type)
22005{
22006 unsigned mult = 2;
22007 if (reg_type == q_reg)
22008 inst.instruction |= 1 << vcx_vec_pos;
22009 else if (reg_type == d_reg)
22010 inst.instruction |= 1 << vcx_size_pos;
22011 else
22012 mult = 1;
22013 /* NOTE:
22014 The documentation says that the Q registers are encoded as 2*N in the D:Vd
22015 bits (or equivalent for N and M registers).
22016 Similarly the D registers are encoded as N in D:Vd bits.
22017 While the S registers are encoded as N in the Vd:D bits.
22018
22019 Taking into account the maximum values of these registers we can see a
22020 nicer pattern for calculation:
22021 Q -> 7, D -> 15, S -> 31
22022
22023 If we say that everything is encoded in the Vd:D bits, then we can say
22024 that Q is encoded as 4*N, and D is encoded as 2*N.
22025 This way the bits will end up the same, and calculation is simpler.
22026 (calculation is now:
22027 1. Multiply by a number determined by the register letter.
22028 2. Encode resulting number in Vd:D bits.)
22029
22030 This is made a little more complicated by automatic handling of 'Q'
22031 registers elsewhere, which means the register number is already 2*N where
22032 N is the number the user wrote after the register letter.
22033 */
22034 return mult;
22035}
22036#undef vcx_vec_pos
22037#undef vcx_size_pos
22038
22039static void
22040vcx_ensure_register_in_range (unsigned R, enum vcx_reg_type reg_type)
22041{
22042 if (reg_type == q_reg)
22043 {
22044 gas_assert (R % 2 == 0);
22045 constraint (R >= 16, _("'q' register must be in range 0-7"));
22046 }
22047 else if (reg_type == d_reg)
22048 constraint (R >= 16, _("'d' register must be in range 0-15"));
22049 else
22050 constraint (R >= 32, _("'s' register must be in range 0-31"));
22051}
22052
22053static void (*vcx_assign_vec[3]) (unsigned) = {
22054 vcx_assign_vec_d,
22055 vcx_assign_vec_m,
22056 vcx_assign_vec_n
22057};
22058
22059static void
22060vcx_handle_register_arguments (unsigned num_registers,
22061 enum vcx_reg_type reg_type)
22062{
1ed818b4 22063 unsigned R, i;
5aae9ae9 22064 unsigned reg_mult = vcx_handle_shape (reg_type);
1ed818b4 22065 for (i = 0; i < num_registers; i++)
5aae9ae9
MM
22066 {
22067 R = inst.operands[i+1].reg;
22068 vcx_ensure_register_in_range (R, reg_type);
22069 if (num_registers == 3 && i > 0)
22070 {
22071 if (i == 2)
22072 vcx_assign_vec[1] (R * reg_mult);
22073 else
22074 vcx_assign_vec[2] (R * reg_mult);
22075 continue;
22076 }
22077 vcx_assign_vec[i](R * reg_mult);
22078 }
22079}
22080
22081static void
22082vcx_handle_insn_block (enum vcx_reg_type reg_type)
22083{
22084 if (reg_type == q_reg)
22085 if (inst.cond > COND_ALWAYS)
22086 inst.pred_insn_type = INSIDE_VPT_INSN;
22087 else
22088 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
22089 else if (inst.cond == COND_ALWAYS)
22090 inst.pred_insn_type = OUTSIDE_PRED_INSN;
22091 else
22092 inst.error = BAD_NOT_IT;
22093}
22094
22095static void
22096vcx_handle_common_checks (unsigned num_args, enum neon_shape rs)
22097{
22098 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
22099 cde_handle_coproc ();
22100 enum vcx_reg_type reg_type = vcx_get_reg_type (rs);
22101 vcx_handle_register_arguments (num_args, reg_type);
22102 vcx_handle_insn_block (reg_type);
22103 if (reg_type == q_reg)
22104 constraint (!mark_feature_used (&mve_ext),
22105 _("vcx instructions with Q registers require MVE"));
22106 else
22107 constraint (!(ARM_FSET_CPU_SUBSET (armv8m_fp, cpu_variant)
22108 && mark_feature_used (&armv8m_fp))
22109 && !mark_feature_used (&mve_ext),
22110 _("vcx instructions with S or D registers require either MVE"
ddc73fa9 22111 " or Armv8-M floating point extension."));
5aae9ae9
MM
22112}
22113
22114static void
22115do_vcx1 (void)
22116{
22117 enum neon_shape rs = neon_select_shape (NS_PQI, NS_PDI, NS_PFI, NS_NULL);
22118 vcx_handle_common_checks (1, rs);
22119
22120 unsigned imm = inst.operands[2].imm;
22121 inst.instruction |= (imm & 0x03f);
22122 inst.instruction |= (imm & 0x040) << 1;
22123 inst.instruction |= (imm & 0x780) << 9;
22124 if (rs != NS_PQI)
22125 constraint (imm >= 2048,
22126 _("vcx1 with S or D registers takes immediate within 0-2047"));
22127 inst.instruction |= (imm & 0x800) << 13;
22128}
22129
22130static void
22131do_vcx2 (void)
22132{
22133 enum neon_shape rs = neon_select_shape (NS_PQQI, NS_PDDI, NS_PFFI, NS_NULL);
22134 vcx_handle_common_checks (2, rs);
22135
22136 unsigned imm = inst.operands[3].imm;
22137 inst.instruction |= (imm & 0x01) << 4;
22138 inst.instruction |= (imm & 0x02) << 6;
22139 inst.instruction |= (imm & 0x3c) << 14;
22140 if (rs != NS_PQQI)
22141 constraint (imm >= 64,
22142 _("vcx2 with S or D registers takes immediate within 0-63"));
22143 inst.instruction |= (imm & 0x40) << 18;
22144}
22145
22146static void
22147do_vcx3 (void)
22148{
22149 enum neon_shape rs = neon_select_shape (NS_PQQQI, NS_PDDDI, NS_PFFFI, NS_NULL);
22150 vcx_handle_common_checks (3, rs);
22151
22152 unsigned imm = inst.operands[4].imm;
22153 inst.instruction |= (imm & 0x1) << 4;
22154 inst.instruction |= (imm & 0x6) << 19;
22155 if (rs != NS_PQQQI)
22156 constraint (imm >= 8,
22157 _("vcx2 with S or D registers takes immediate within 0-7"));
22158 inst.instruction |= (imm & 0x8) << 21;
22159}
22160
91ff7894
MGD
22161/* Crypto v1 instructions. */
22162static void
22163do_crypto_2op_1 (unsigned elttype, int op)
22164{
5ee91343 22165 set_pred_insn_type (OUTSIDE_PRED_INSN);
91ff7894
MGD
22166
22167 if (neon_check_type (2, NS_QQ, N_EQK | N_UNT, elttype | N_UNT | N_KEY).type
22168 == NT_invtype)
22169 return;
22170
22171 inst.error = NULL;
22172
22173 NEON_ENCODE (INTEGER, inst);
22174 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
22175 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
22176 inst.instruction |= LOW4 (inst.operands[1].reg);
22177 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
22178 if (op != -1)
22179 inst.instruction |= op << 6;
22180
22181 if (thumb_mode)
22182 inst.instruction |= 0xfc000000;
22183 else
22184 inst.instruction |= 0xf0000000;
22185}
22186
48adcd8e
MGD
22187static void
22188do_crypto_3op_1 (int u, int op)
22189{
5ee91343 22190 set_pred_insn_type (OUTSIDE_PRED_INSN);
48adcd8e
MGD
22191
22192 if (neon_check_type (3, NS_QQQ, N_EQK | N_UNT, N_EQK | N_UNT,
22193 N_32 | N_UNT | N_KEY).type == NT_invtype)
22194 return;
22195
22196 inst.error = NULL;
22197
22198 NEON_ENCODE (INTEGER, inst);
22199 neon_three_same (1, u, 8 << op);
22200}
22201
91ff7894
MGD
22202static void
22203do_aese (void)
22204{
22205 do_crypto_2op_1 (N_8, 0);
22206}
22207
22208static void
22209do_aesd (void)
22210{
22211 do_crypto_2op_1 (N_8, 1);
22212}
22213
22214static void
22215do_aesmc (void)
22216{
22217 do_crypto_2op_1 (N_8, 2);
22218}
22219
22220static void
22221do_aesimc (void)
22222{
22223 do_crypto_2op_1 (N_8, 3);
22224}
22225
48adcd8e
MGD
22226static void
22227do_sha1c (void)
22228{
22229 do_crypto_3op_1 (0, 0);
22230}
22231
22232static void
22233do_sha1p (void)
22234{
22235 do_crypto_3op_1 (0, 1);
22236}
22237
22238static void
22239do_sha1m (void)
22240{
22241 do_crypto_3op_1 (0, 2);
22242}
22243
22244static void
22245do_sha1su0 (void)
22246{
22247 do_crypto_3op_1 (0, 3);
22248}
91ff7894 22249
48adcd8e
MGD
22250static void
22251do_sha256h (void)
22252{
22253 do_crypto_3op_1 (1, 0);
22254}
22255
22256static void
22257do_sha256h2 (void)
22258{
22259 do_crypto_3op_1 (1, 1);
22260}
22261
22262static void
22263do_sha256su1 (void)
22264{
22265 do_crypto_3op_1 (1, 2);
22266}
3c9017d2
MGD
22267
22268static void
22269do_sha1h (void)
22270{
22271 do_crypto_2op_1 (N_32, -1);
22272}
22273
22274static void
22275do_sha1su1 (void)
22276{
22277 do_crypto_2op_1 (N_32, 0);
22278}
22279
22280static void
22281do_sha256su0 (void)
22282{
22283 do_crypto_2op_1 (N_32, 1);
22284}
dd5181d5
KT
22285
22286static void
22287do_crc32_1 (unsigned int poly, unsigned int sz)
22288{
22289 unsigned int Rd = inst.operands[0].reg;
22290 unsigned int Rn = inst.operands[1].reg;
22291 unsigned int Rm = inst.operands[2].reg;
22292
5ee91343 22293 set_pred_insn_type (OUTSIDE_PRED_INSN);
dd5181d5
KT
22294 inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
22295 inst.instruction |= LOW4 (Rn) << 16;
22296 inst.instruction |= LOW4 (Rm);
22297 inst.instruction |= sz << (thumb_mode ? 4 : 21);
22298 inst.instruction |= poly << (thumb_mode ? 20 : 9);
22299
22300 if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
22301 as_warn (UNPRED_REG ("r15"));
dd5181d5
KT
22302}
22303
22304static void
22305do_crc32b (void)
22306{
22307 do_crc32_1 (0, 0);
22308}
22309
22310static void
22311do_crc32h (void)
22312{
22313 do_crc32_1 (0, 1);
22314}
22315
22316static void
22317do_crc32w (void)
22318{
22319 do_crc32_1 (0, 2);
22320}
22321
22322static void
22323do_crc32cb (void)
22324{
22325 do_crc32_1 (1, 0);
22326}
22327
22328static void
22329do_crc32ch (void)
22330{
22331 do_crc32_1 (1, 1);
22332}
22333
22334static void
22335do_crc32cw (void)
22336{
22337 do_crc32_1 (1, 2);
22338}
22339
49e8a725
SN
22340static void
22341do_vjcvt (void)
22342{
22343 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
22344 _(BAD_FPU));
22345 neon_check_type (2, NS_FD, N_S32, N_F64);
22346 do_vfp_sp_dp_cvt ();
22347 do_vfp_cond_or_thumb ();
22348}
22349
aab2c27d
MM
22350static void
22351do_vdot (void)
22352{
22353 enum neon_shape rs;
22354 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
22355 set_pred_insn_type (OUTSIDE_PRED_INSN);
22356 if (inst.operands[2].isscalar)
22357 {
22358 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
22359 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22360
22361 inst.instruction |= (1 << 25);
1db66fb6
JB
22362 int idx = inst.operands[2].reg & 0xf;
22363 constraint ((idx != 1 && idx != 0), _("index must be 0 or 1"));
aab2c27d
MM
22364 inst.operands[2].reg >>= 4;
22365 constraint (!(inst.operands[2].reg < 16),
22366 _("indexed register must be less than 16"));
22367 neon_three_args (rs == NS_QQS);
1db66fb6 22368 inst.instruction |= (idx << 5);
aab2c27d
MM
22369 }
22370 else
22371 {
22372 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
22373 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22374 neon_three_args (rs == NS_QQQ);
22375 }
22376}
22377
22378static void
22379do_vmmla (void)
22380{
22381 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
22382 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22383
22384 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
22385 set_pred_insn_type (OUTSIDE_PRED_INSN);
22386
22387 neon_three_args (1);
22388}
22389
f1e1d7f3
AC
22390static void
22391do_t_pacbti (void)
22392{
22393 inst.instruction = THUMB_OP32 (inst.instruction);
22394}
22395
e07352fa
AC
22396static void
22397do_t_pacbti_nonop (void)
22398{
22399 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, pacbti_ext),
22400 _(BAD_PACBTI));
22401
22402 inst.instruction = THUMB_OP32 (inst.instruction);
22403 inst.instruction |= inst.operands[0].reg << 12;
22404 inst.instruction |= inst.operands[1].reg << 16;
22405 inst.instruction |= inst.operands[2].reg;
22406}
22407
5c43020d
AC
22408static void
22409do_t_pacbti_pacg (void)
22410{
22411 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, pacbti_ext),
22412 _(BAD_PACBTI));
22413
22414 inst.instruction = THUMB_OP32 (inst.instruction);
22415 inst.instruction |= inst.operands[0].reg << 8;
22416 inst.instruction |= inst.operands[1].reg << 16;
22417 inst.instruction |= inst.operands[2].reg;
22418}
22419
5287ad62
JB
22420\f
22421/* Overall per-instruction processing. */
22422
22423/* We need to be able to fix up arbitrary expressions in some statements.
22424 This is so that we can handle symbols that are an arbitrary distance from
22425 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
22426 which returns part of an address in a form which will be valid for
22427 a data instruction. We do this by pushing the expression into a symbol
22428 in the expr_section, and creating a fix for that. */
22429
22430static void
22431fix_new_arm (fragS * frag,
22432 int where,
22433 short int size,
22434 expressionS * exp,
22435 int pc_rel,
22436 int reloc)
22437{
22438 fixS * new_fix;
22439
22440 switch (exp->X_op)
22441 {
22442 case O_constant:
6e7ce2cd
PB
22443 if (pc_rel)
22444 {
22445 /* Create an absolute valued symbol, so we have something to
477330fc
RM
22446 refer to in the object file. Unfortunately for us, gas's
22447 generic expression parsing will already have folded out
22448 any use of .set foo/.type foo %function that may have
22449 been used to set type information of the target location,
22450 that's being specified symbolically. We have to presume
22451 the user knows what they are doing. */
6e7ce2cd
PB
22452 char name[16 + 8];
22453 symbolS *symbol;
22454
22455 sprintf (name, "*ABS*0x%lx", (unsigned long)exp->X_add_number);
22456
22457 symbol = symbol_find_or_make (name);
22458 S_SET_SEGMENT (symbol, absolute_section);
22459 symbol_set_frag (symbol, &zero_address_frag);
22460 S_SET_VALUE (symbol, exp->X_add_number);
22461 exp->X_op = O_symbol;
22462 exp->X_add_symbol = symbol;
22463 exp->X_add_number = 0;
22464 }
22465 /* FALLTHROUGH */
5287ad62
JB
22466 case O_symbol:
22467 case O_add:
22468 case O_subtract:
21d799b5 22469 new_fix = fix_new_exp (frag, where, size, exp, pc_rel,
477330fc 22470 (enum bfd_reloc_code_real) reloc);
5287ad62
JB
22471 break;
22472
22473 default:
21d799b5 22474 new_fix = (fixS *) fix_new (frag, where, size, make_expr_symbol (exp), 0,
477330fc 22475 pc_rel, (enum bfd_reloc_code_real) reloc);
5287ad62
JB
22476 break;
22477 }
22478
22479 /* Mark whether the fix is to a THUMB instruction, or an ARM
22480 instruction. */
22481 new_fix->tc_fix_data = thumb_mode;
22482}
22483
22484/* Create a frg for an instruction requiring relaxation. */
22485static void
22486output_relax_insn (void)
22487{
22488 char * to;
22489 symbolS *sym;
0110f2b8
PB
22490 int offset;
22491
6e1cb1a6
PB
22492 /* The size of the instruction is unknown, so tie the debug info to the
22493 start of the instruction. */
22494 dwarf2_emit_insn (0);
6e1cb1a6 22495
e2b0ab59 22496 switch (inst.relocs[0].exp.X_op)
0110f2b8
PB
22497 {
22498 case O_symbol:
e2b0ab59
AV
22499 sym = inst.relocs[0].exp.X_add_symbol;
22500 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
22501 break;
22502 case O_constant:
22503 sym = NULL;
e2b0ab59 22504 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
22505 break;
22506 default:
e2b0ab59 22507 sym = make_expr_symbol (&inst.relocs[0].exp);
0110f2b8
PB
22508 offset = 0;
22509 break;
22510 }
22511 to = frag_var (rs_machine_dependent, INSN_SIZE, THUMB_SIZE,
22512 inst.relax, sym, offset, NULL/*offset, opcode*/);
22513 md_number_to_chars (to, inst.instruction, THUMB_SIZE);
0110f2b8
PB
22514}
22515
22516/* Write a 32-bit thumb instruction to buf. */
22517static void
22518put_thumb32_insn (char * buf, unsigned long insn)
22519{
22520 md_number_to_chars (buf, insn >> 16, THUMB_SIZE);
22521 md_number_to_chars (buf + THUMB_SIZE, insn, THUMB_SIZE);
22522}
22523
b99bd4ef 22524static void
c19d1205 22525output_inst (const char * str)
b99bd4ef 22526{
c19d1205 22527 char * to = NULL;
b99bd4ef 22528
c19d1205 22529 if (inst.error)
b99bd4ef 22530 {
c19d1205 22531 as_bad ("%s -- `%s'", inst.error, str);
b99bd4ef
NC
22532 return;
22533 }
5f4273c7
NC
22534 if (inst.relax)
22535 {
22536 output_relax_insn ();
0110f2b8 22537 return;
5f4273c7 22538 }
c19d1205
ZW
22539 if (inst.size == 0)
22540 return;
b99bd4ef 22541
c19d1205 22542 to = frag_more (inst.size);
8dc2430f
NC
22543 /* PR 9814: Record the thumb mode into the current frag so that we know
22544 what type of NOP padding to use, if necessary. We override any previous
22545 setting so that if the mode has changed then the NOPS that we use will
22546 match the encoding of the last instruction in the frag. */
cd000bff 22547 frag_now->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
c19d1205
ZW
22548
22549 if (thumb_mode && (inst.size > THUMB_SIZE))
b99bd4ef 22550 {
9c2799c2 22551 gas_assert (inst.size == (2 * THUMB_SIZE));
0110f2b8 22552 put_thumb32_insn (to, inst.instruction);
b99bd4ef 22553 }
c19d1205 22554 else if (inst.size > INSN_SIZE)
b99bd4ef 22555 {
9c2799c2 22556 gas_assert (inst.size == (2 * INSN_SIZE));
c19d1205
ZW
22557 md_number_to_chars (to, inst.instruction, INSN_SIZE);
22558 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
b99bd4ef 22559 }
c19d1205
ZW
22560 else
22561 md_number_to_chars (to, inst.instruction, inst.size);
b99bd4ef 22562
e2b0ab59
AV
22563 int r;
22564 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
22565 {
22566 if (inst.relocs[r].type != BFD_RELOC_UNUSED)
22567 fix_new_arm (frag_now, to - frag_now->fr_literal,
22568 inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
22569 inst.relocs[r].type);
22570 }
b99bd4ef 22571
c19d1205 22572 dwarf2_emit_insn (inst.size);
c19d1205 22573}
b99bd4ef 22574
e07e6e58
NC
22575static char *
22576output_it_inst (int cond, int mask, char * to)
22577{
22578 unsigned long instruction = 0xbf00;
22579
22580 mask &= 0xf;
22581 instruction |= mask;
22582 instruction |= cond << 4;
22583
22584 if (to == NULL)
22585 {
22586 to = frag_more (2);
22587#ifdef OBJ_ELF
22588 dwarf2_emit_insn (2);
22589#endif
22590 }
22591
22592 md_number_to_chars (to, instruction, 2);
22593
22594 return to;
22595}
22596
c19d1205
ZW
22597/* Tag values used in struct asm_opcode's tag field. */
22598enum opcode_tag
22599{
22600 OT_unconditional, /* Instruction cannot be conditionalized.
22601 The ARM condition field is still 0xE. */
22602 OT_unconditionalF, /* Instruction cannot be conditionalized
22603 and carries 0xF in its ARM condition field. */
22604 OT_csuffix, /* Instruction takes a conditional suffix. */
5ee91343
AV
22605 OT_csuffixF, /* Some forms of the instruction take a scalar
22606 conditional suffix, others place 0xF where the
22607 condition field would be, others take a vector
22608 conditional suffix. */
c19d1205
ZW
22609 OT_cinfix3, /* Instruction takes a conditional infix,
22610 beginning at character index 3. (In
22611 unified mode, it becomes a suffix.) */
088fa78e
KH
22612 OT_cinfix3_deprecated, /* The same as OT_cinfix3. This is used for
22613 tsts, cmps, cmns, and teqs. */
e3cb604e
PB
22614 OT_cinfix3_legacy, /* Legacy instruction takes a conditional infix at
22615 character index 3, even in unified mode. Used for
22616 legacy instructions where suffix and infix forms
22617 may be ambiguous. */
c19d1205 22618 OT_csuf_or_in3, /* Instruction takes either a conditional
e3cb604e 22619 suffix or an infix at character index 3. */
c19d1205
ZW
22620 OT_odd_infix_unc, /* This is the unconditional variant of an
22621 instruction that takes a conditional infix
22622 at an unusual position. In unified mode,
22623 this variant will accept a suffix. */
22624 OT_odd_infix_0 /* Values greater than or equal to OT_odd_infix_0
22625 are the conditional variants of instructions that
22626 take conditional infixes in unusual positions.
22627 The infix appears at character index
22628 (tag - OT_odd_infix_0). These are not accepted
22629 in unified mode. */
22630};
b99bd4ef 22631
c19d1205
ZW
22632/* Subroutine of md_assemble, responsible for looking up the primary
22633 opcode from the mnemonic the user wrote. STR points to the
22634 beginning of the mnemonic.
22635
22636 This is not simply a hash table lookup, because of conditional
22637 variants. Most instructions have conditional variants, which are
22638 expressed with a _conditional affix_ to the mnemonic. If we were
22639 to encode each conditional variant as a literal string in the opcode
22640 table, it would have approximately 20,000 entries.
22641
22642 Most mnemonics take this affix as a suffix, and in unified syntax,
22643 'most' is upgraded to 'all'. However, in the divided syntax, some
22644 instructions take the affix as an infix, notably the s-variants of
22645 the arithmetic instructions. Of those instructions, all but six
22646 have the infix appear after the third character of the mnemonic.
22647
22648 Accordingly, the algorithm for looking up primary opcodes given
22649 an identifier is:
22650
22651 1. Look up the identifier in the opcode table.
22652 If we find a match, go to step U.
22653
22654 2. Look up the last two characters of the identifier in the
22655 conditions table. If we find a match, look up the first N-2
22656 characters of the identifier in the opcode table. If we
22657 find a match, go to step CE.
22658
22659 3. Look up the fourth and fifth characters of the identifier in
22660 the conditions table. If we find a match, extract those
22661 characters from the identifier, and look up the remaining
22662 characters in the opcode table. If we find a match, go
22663 to step CM.
22664
22665 4. Fail.
22666
22667 U. Examine the tag field of the opcode structure, in case this is
22668 one of the six instructions with its conditional infix in an
22669 unusual place. If it is, the tag tells us where to find the
22670 infix; look it up in the conditions table and set inst.cond
22671 accordingly. Otherwise, this is an unconditional instruction.
22672 Again set inst.cond accordingly. Return the opcode structure.
22673
22674 CE. Examine the tag field to make sure this is an instruction that
22675 should receive a conditional suffix. If it is not, fail.
22676 Otherwise, set inst.cond from the suffix we already looked up,
22677 and return the opcode structure.
22678
22679 CM. Examine the tag field to make sure this is an instruction that
22680 should receive a conditional infix after the third character.
22681 If it is not, fail. Otherwise, undo the edits to the current
22682 line of input and proceed as for case CE. */
22683
22684static const struct asm_opcode *
22685opcode_lookup (char **str)
22686{
22687 char *end, *base;
22688 char *affix;
22689 const struct asm_opcode *opcode;
22690 const struct asm_cond *cond;
e3cb604e 22691 char save[2];
c19d1205
ZW
22692
22693 /* Scan up to the end of the mnemonic, which must end in white space,
721a8186 22694 '.' (in unified mode, or for Neon/VFP instructions), or end of string. */
c19d1205 22695 for (base = end = *str; *end != '\0'; end++)
721a8186 22696 if (*end == ' ' || *end == '.')
c19d1205 22697 break;
b99bd4ef 22698
c19d1205 22699 if (end == base)
c921be7d 22700 return NULL;
b99bd4ef 22701
5287ad62 22702 /* Handle a possible width suffix and/or Neon type suffix. */
c19d1205 22703 if (end[0] == '.')
b99bd4ef 22704 {
5287ad62 22705 int offset = 2;
5f4273c7 22706
267d2029 22707 /* The .w and .n suffixes are only valid if the unified syntax is in
477330fc 22708 use. */
267d2029 22709 if (unified_syntax && end[1] == 'w')
c19d1205 22710 inst.size_req = 4;
267d2029 22711 else if (unified_syntax && end[1] == 'n')
c19d1205
ZW
22712 inst.size_req = 2;
22713 else
477330fc 22714 offset = 0;
5287ad62
JB
22715
22716 inst.vectype.elems = 0;
22717
22718 *str = end + offset;
b99bd4ef 22719
5f4273c7 22720 if (end[offset] == '.')
5287ad62 22721 {
267d2029 22722 /* See if we have a Neon type suffix (possible in either unified or
477330fc
RM
22723 non-unified ARM syntax mode). */
22724 if (parse_neon_type (&inst.vectype, str) == FAIL)
c921be7d 22725 return NULL;
477330fc 22726 }
5287ad62 22727 else if (end[offset] != '\0' && end[offset] != ' ')
477330fc 22728 return NULL;
b99bd4ef 22729 }
c19d1205
ZW
22730 else
22731 *str = end;
b99bd4ef 22732
c19d1205 22733 /* Look for unaffixed or special-case affixed mnemonic. */
629310ab 22734 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22735 end - base);
f3da8a96 22736 cond = NULL;
c19d1205 22737 if (opcode)
b99bd4ef 22738 {
c19d1205
ZW
22739 /* step U */
22740 if (opcode->tag < OT_odd_infix_0)
b99bd4ef 22741 {
c19d1205
ZW
22742 inst.cond = COND_ALWAYS;
22743 return opcode;
b99bd4ef 22744 }
b99bd4ef 22745
278df34e 22746 if (warn_on_deprecated && unified_syntax)
5c3696f8 22747 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205 22748 affix = base + (opcode->tag - OT_odd_infix_0);
629310ab 22749 cond = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, affix, 2);
9c2799c2 22750 gas_assert (cond);
b99bd4ef 22751
c19d1205
ZW
22752 inst.cond = cond->value;
22753 return opcode;
22754 }
5ee91343
AV
22755 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
22756 {
22757 /* Cannot have a conditional suffix on a mnemonic of less than a character.
22758 */
22759 if (end - base < 2)
22760 return NULL;
22761 affix = end - 1;
629310ab
ML
22762 cond = (const struct asm_cond *) str_hash_find_n (arm_vcond_hsh, affix, 1);
22763 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22764 affix - base);
5ee91343
AV
22765 /* If this opcode can not be vector predicated then don't accept it with a
22766 vector predication code. */
22767 if (opcode && !opcode->mayBeVecPred)
22768 opcode = NULL;
22769 }
22770 if (!opcode || !cond)
22771 {
22772 /* Cannot have a conditional suffix on a mnemonic of less than two
22773 characters. */
22774 if (end - base < 3)
22775 return NULL;
b99bd4ef 22776
5ee91343
AV
22777 /* Look for suffixed mnemonic. */
22778 affix = end - 2;
629310ab
ML
22779 cond = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, affix, 2);
22780 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22781 affix - base);
5ee91343 22782 }
b99bd4ef 22783
c19d1205
ZW
22784 if (opcode && cond)
22785 {
22786 /* step CE */
22787 switch (opcode->tag)
22788 {
e3cb604e
PB
22789 case OT_cinfix3_legacy:
22790 /* Ignore conditional suffixes matched on infix only mnemonics. */
22791 break;
22792
c19d1205 22793 case OT_cinfix3:
088fa78e 22794 case OT_cinfix3_deprecated:
c19d1205
ZW
22795 case OT_odd_infix_unc:
22796 if (!unified_syntax)
0198d5e6 22797 return NULL;
1a0670f3 22798 /* Fall through. */
c19d1205
ZW
22799
22800 case OT_csuffix:
477330fc 22801 case OT_csuffixF:
c19d1205
ZW
22802 case OT_csuf_or_in3:
22803 inst.cond = cond->value;
22804 return opcode;
22805
22806 case OT_unconditional:
22807 case OT_unconditionalF:
dfa9f0d5 22808 if (thumb_mode)
c921be7d 22809 inst.cond = cond->value;
dfa9f0d5
PB
22810 else
22811 {
c921be7d 22812 /* Delayed diagnostic. */
dfa9f0d5
PB
22813 inst.error = BAD_COND;
22814 inst.cond = COND_ALWAYS;
22815 }
c19d1205 22816 return opcode;
b99bd4ef 22817
c19d1205 22818 default:
c921be7d 22819 return NULL;
c19d1205
ZW
22820 }
22821 }
b99bd4ef 22822
c19d1205
ZW
22823 /* Cannot have a usual-position infix on a mnemonic of less than
22824 six characters (five would be a suffix). */
22825 if (end - base < 6)
c921be7d 22826 return NULL;
b99bd4ef 22827
c19d1205
ZW
22828 /* Look for infixed mnemonic in the usual position. */
22829 affix = base + 3;
629310ab 22830 cond = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, affix, 2);
e3cb604e 22831 if (!cond)
c921be7d 22832 return NULL;
e3cb604e
PB
22833
22834 memcpy (save, affix, 2);
22835 memmove (affix, affix + 2, (end - affix) - 2);
629310ab 22836 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22837 (end - base) - 2);
e3cb604e
PB
22838 memmove (affix + 2, affix, (end - affix) - 2);
22839 memcpy (affix, save, 2);
22840
088fa78e
KH
22841 if (opcode
22842 && (opcode->tag == OT_cinfix3
22843 || opcode->tag == OT_cinfix3_deprecated
22844 || opcode->tag == OT_csuf_or_in3
22845 || opcode->tag == OT_cinfix3_legacy))
b99bd4ef 22846 {
c921be7d 22847 /* Step CM. */
278df34e 22848 if (warn_on_deprecated && unified_syntax
088fa78e
KH
22849 && (opcode->tag == OT_cinfix3
22850 || opcode->tag == OT_cinfix3_deprecated))
5c3696f8 22851 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205
ZW
22852
22853 inst.cond = cond->value;
22854 return opcode;
b99bd4ef
NC
22855 }
22856
c921be7d 22857 return NULL;
b99bd4ef
NC
22858}
22859
e07e6e58
NC
22860/* This function generates an initial IT instruction, leaving its block
22861 virtually open for the new instructions. Eventually,
5ee91343 22862 the mask will be updated by now_pred_add_mask () each time
e07e6e58
NC
22863 a new instruction needs to be included in the IT block.
22864 Finally, the block is closed with close_automatic_it_block ().
22865 The block closure can be requested either from md_assemble (),
22866 a tencode (), or due to a label hook. */
22867
22868static void
22869new_automatic_it_block (int cond)
22870{
5ee91343
AV
22871 now_pred.state = AUTOMATIC_PRED_BLOCK;
22872 now_pred.mask = 0x18;
22873 now_pred.cc = cond;
22874 now_pred.block_length = 1;
cd000bff 22875 mapping_state (MAP_THUMB);
5ee91343 22876 now_pred.insn = output_it_inst (cond, now_pred.mask, NULL);
5b7c81bd
AM
22877 now_pred.warn_deprecated = false;
22878 now_pred.insn_cond = true;
e07e6e58
NC
22879}
22880
22881/* Close an automatic IT block.
22882 See comments in new_automatic_it_block (). */
22883
22884static void
22885close_automatic_it_block (void)
22886{
5ee91343
AV
22887 now_pred.mask = 0x10;
22888 now_pred.block_length = 0;
e07e6e58
NC
22889}
22890
22891/* Update the mask of the current automatically-generated IT
22892 instruction. See comments in new_automatic_it_block (). */
22893
22894static void
5ee91343 22895now_pred_add_mask (int cond)
e07e6e58
NC
22896{
22897#define CLEAR_BIT(value, nbit) ((value) & ~(1 << (nbit)))
22898#define SET_BIT_VALUE(value, bitvalue, nbit) (CLEAR_BIT (value, nbit) \
477330fc 22899 | ((bitvalue) << (nbit)))
e07e6e58 22900 const int resulting_bit = (cond & 1);
c921be7d 22901
5ee91343
AV
22902 now_pred.mask &= 0xf;
22903 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 22904 resulting_bit,
5ee91343
AV
22905 (5 - now_pred.block_length));
22906 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 22907 1,
5ee91343
AV
22908 ((5 - now_pred.block_length) - 1));
22909 output_it_inst (now_pred.cc, now_pred.mask, now_pred.insn);
e07e6e58
NC
22910
22911#undef CLEAR_BIT
22912#undef SET_BIT_VALUE
e07e6e58
NC
22913}
22914
22915/* The IT blocks handling machinery is accessed through the these functions:
22916 it_fsm_pre_encode () from md_assemble ()
5ee91343
AV
22917 set_pred_insn_type () optional, from the tencode functions
22918 set_pred_insn_type_last () ditto
22919 in_pred_block () ditto
e07e6e58 22920 it_fsm_post_encode () from md_assemble ()
33eaf5de 22921 force_automatic_it_block_close () from label handling functions
e07e6e58
NC
22922
22923 Rationale:
22924 1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
477330fc
RM
22925 initializing the IT insn type with a generic initial value depending
22926 on the inst.condition.
e07e6e58 22927 2) During the tencode function, two things may happen:
477330fc 22928 a) The tencode function overrides the IT insn type by
5ee91343
AV
22929 calling either set_pred_insn_type (type) or
22930 set_pred_insn_type_last ().
477330fc 22931 b) The tencode function queries the IT block state by
5ee91343 22932 calling in_pred_block () (i.e. to determine narrow/not narrow mode).
477330fc 22933
5ee91343
AV
22934 Both set_pred_insn_type and in_pred_block run the internal FSM state
22935 handling function (handle_pred_state), because: a) setting the IT insn
477330fc
RM
22936 type may incur in an invalid state (exiting the function),
22937 and b) querying the state requires the FSM to be updated.
22938 Specifically we want to avoid creating an IT block for conditional
22939 branches, so it_fsm_pre_encode is actually a guess and we can't
22940 determine whether an IT block is required until the tencode () routine
22941 has decided what type of instruction this actually it.
5ee91343
AV
22942 Because of this, if set_pred_insn_type and in_pred_block have to be
22943 used, set_pred_insn_type has to be called first.
477330fc 22944
5ee91343
AV
22945 set_pred_insn_type_last () is a wrapper of set_pred_insn_type (type),
22946 that determines the insn IT type depending on the inst.cond code.
477330fc
RM
22947 When a tencode () routine encodes an instruction that can be
22948 either outside an IT block, or, in the case of being inside, has to be
5ee91343 22949 the last one, set_pred_insn_type_last () will determine the proper
477330fc 22950 IT instruction type based on the inst.cond code. Otherwise,
5ee91343 22951 set_pred_insn_type can be called for overriding that logic or
477330fc
RM
22952 for covering other cases.
22953
5ee91343
AV
22954 Calling handle_pred_state () may not transition the IT block state to
22955 OUTSIDE_PRED_BLOCK immediately, since the (current) state could be
477330fc 22956 still queried. Instead, if the FSM determines that the state should
5ee91343 22957 be transitioned to OUTSIDE_PRED_BLOCK, a flag is marked to be closed
477330fc
RM
22958 after the tencode () function: that's what it_fsm_post_encode () does.
22959
5ee91343 22960 Since in_pred_block () calls the state handling function to get an
477330fc
RM
22961 updated state, an error may occur (due to invalid insns combination).
22962 In that case, inst.error is set.
22963 Therefore, inst.error has to be checked after the execution of
22964 the tencode () routine.
e07e6e58
NC
22965
22966 3) Back in md_assemble(), it_fsm_post_encode () is called to commit
477330fc 22967 any pending state change (if any) that didn't take place in
5ee91343 22968 handle_pred_state () as explained above. */
e07e6e58
NC
22969
22970static void
22971it_fsm_pre_encode (void)
22972{
22973 if (inst.cond != COND_ALWAYS)
5ee91343 22974 inst.pred_insn_type = INSIDE_IT_INSN;
e07e6e58 22975 else
5ee91343 22976 inst.pred_insn_type = OUTSIDE_PRED_INSN;
e07e6e58 22977
5ee91343 22978 now_pred.state_handled = 0;
e07e6e58
NC
22979}
22980
22981/* IT state FSM handling function. */
5ee91343
AV
22982/* MVE instructions and non-MVE instructions are handled differently because of
22983 the introduction of VPT blocks.
22984 Specifications say that any non-MVE instruction inside a VPT block is
22985 UNPREDICTABLE, with the exception of the BKPT instruction. Whereas most MVE
22986 instructions are deemed to be UNPREDICTABLE if inside an IT block. For the
35c228db 22987 few exceptions we have MVE_UNPREDICABLE_INSN.
5ee91343
AV
22988 The error messages provided depending on the different combinations possible
22989 are described in the cases below:
22990 For 'most' MVE instructions:
22991 1) In an IT block, with an IT code: syntax error
22992 2) In an IT block, with a VPT code: error: must be in a VPT block
22993 3) In an IT block, with no code: warning: UNPREDICTABLE
22994 4) In a VPT block, with an IT code: syntax error
22995 5) In a VPT block, with a VPT code: OK!
22996 6) In a VPT block, with no code: error: missing code
22997 7) Outside a pred block, with an IT code: error: syntax error
22998 8) Outside a pred block, with a VPT code: error: should be in a VPT block
22999 9) Outside a pred block, with no code: OK!
23000 For non-MVE instructions:
23001 10) In an IT block, with an IT code: OK!
23002 11) In an IT block, with a VPT code: syntax error
23003 12) In an IT block, with no code: error: missing code
23004 13) In a VPT block, with an IT code: error: should be in an IT block
23005 14) In a VPT block, with a VPT code: syntax error
23006 15) In a VPT block, with no code: UNPREDICTABLE
23007 16) Outside a pred block, with an IT code: error: should be in an IT block
23008 17) Outside a pred block, with a VPT code: syntax error
23009 18) Outside a pred block, with no code: OK!
23010 */
23011
e07e6e58
NC
23012
23013static int
5ee91343 23014handle_pred_state (void)
e07e6e58 23015{
5ee91343 23016 now_pred.state_handled = 1;
5b7c81bd 23017 now_pred.insn_cond = false;
e07e6e58 23018
5ee91343 23019 switch (now_pred.state)
e07e6e58 23020 {
5ee91343
AV
23021 case OUTSIDE_PRED_BLOCK:
23022 switch (inst.pred_insn_type)
e07e6e58 23023 {
35c228db 23024 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
23025 case MVE_OUTSIDE_PRED_INSN:
23026 if (inst.cond < COND_ALWAYS)
23027 {
23028 /* Case 7: Outside a pred block, with an IT code: error: syntax
23029 error. */
23030 inst.error = BAD_SYNTAX;
23031 return FAIL;
23032 }
23033 /* Case 9: Outside a pred block, with no code: OK! */
23034 break;
23035 case OUTSIDE_PRED_INSN:
23036 if (inst.cond > COND_ALWAYS)
23037 {
23038 /* Case 17: Outside a pred block, with a VPT code: syntax error.
23039 */
23040 inst.error = BAD_SYNTAX;
23041 return FAIL;
23042 }
23043 /* Case 18: Outside a pred block, with no code: OK! */
e07e6e58
NC
23044 break;
23045
5ee91343
AV
23046 case INSIDE_VPT_INSN:
23047 /* Case 8: Outside a pred block, with a VPT code: error: should be in
23048 a VPT block. */
23049 inst.error = BAD_OUT_VPT;
23050 return FAIL;
23051
e07e6e58
NC
23052 case INSIDE_IT_INSN:
23053 case INSIDE_IT_LAST_INSN:
5ee91343 23054 if (inst.cond < COND_ALWAYS)
e07e6e58 23055 {
5ee91343
AV
23056 /* Case 16: Outside a pred block, with an IT code: error: should
23057 be in an IT block. */
23058 if (thumb_mode == 0)
e07e6e58 23059 {
5ee91343
AV
23060 if (unified_syntax
23061 && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
23062 as_tsktsk (_("Warning: conditional outside an IT block"\
23063 " for Thumb."));
e07e6e58
NC
23064 }
23065 else
23066 {
5ee91343
AV
23067 if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
23068 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
23069 {
23070 /* Automatically generate the IT instruction. */
23071 new_automatic_it_block (inst.cond);
23072 if (inst.pred_insn_type == INSIDE_IT_LAST_INSN)
23073 close_automatic_it_block ();
23074 }
23075 else
23076 {
23077 inst.error = BAD_OUT_IT;
23078 return FAIL;
23079 }
e07e6e58 23080 }
5ee91343 23081 break;
e07e6e58 23082 }
5ee91343
AV
23083 else if (inst.cond > COND_ALWAYS)
23084 {
23085 /* Case 17: Outside a pred block, with a VPT code: syntax error.
23086 */
23087 inst.error = BAD_SYNTAX;
23088 return FAIL;
23089 }
23090 else
23091 gas_assert (0);
e07e6e58
NC
23092 case IF_INSIDE_IT_LAST_INSN:
23093 case NEUTRAL_IT_INSN:
23094 break;
23095
5ee91343
AV
23096 case VPT_INSN:
23097 if (inst.cond != COND_ALWAYS)
23098 first_error (BAD_SYNTAX);
23099 now_pred.state = MANUAL_PRED_BLOCK;
23100 now_pred.block_length = 0;
23101 now_pred.type = VECTOR_PRED;
23102 now_pred.cc = 0;
23103 break;
e07e6e58 23104 case IT_INSN:
5ee91343
AV
23105 now_pred.state = MANUAL_PRED_BLOCK;
23106 now_pred.block_length = 0;
23107 now_pred.type = SCALAR_PRED;
e07e6e58
NC
23108 break;
23109 }
23110 break;
23111
5ee91343 23112 case AUTOMATIC_PRED_BLOCK:
e07e6e58
NC
23113 /* Three things may happen now:
23114 a) We should increment current it block size;
23115 b) We should close current it block (closing insn or 4 insns);
23116 c) We should close current it block and start a new one (due
23117 to incompatible conditions or
23118 4 insns-length block reached). */
23119
5ee91343 23120 switch (inst.pred_insn_type)
e07e6e58 23121 {
5ee91343
AV
23122 case INSIDE_VPT_INSN:
23123 case VPT_INSN:
35c228db 23124 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
23125 case MVE_OUTSIDE_PRED_INSN:
23126 gas_assert (0);
23127 case OUTSIDE_PRED_INSN:
2b0f3761 23128 /* The closure of the block shall happen immediately,
5ee91343 23129 so any in_pred_block () call reports the block as closed. */
e07e6e58
NC
23130 force_automatic_it_block_close ();
23131 break;
23132
23133 case INSIDE_IT_INSN:
23134 case INSIDE_IT_LAST_INSN:
23135 case IF_INSIDE_IT_LAST_INSN:
5ee91343 23136 now_pred.block_length++;
e07e6e58 23137
5ee91343
AV
23138 if (now_pred.block_length > 4
23139 || !now_pred_compatible (inst.cond))
e07e6e58
NC
23140 {
23141 force_automatic_it_block_close ();
5ee91343 23142 if (inst.pred_insn_type != IF_INSIDE_IT_LAST_INSN)
e07e6e58
NC
23143 new_automatic_it_block (inst.cond);
23144 }
23145 else
23146 {
5b7c81bd 23147 now_pred.insn_cond = true;
5ee91343 23148 now_pred_add_mask (inst.cond);
e07e6e58
NC
23149 }
23150
5ee91343
AV
23151 if (now_pred.state == AUTOMATIC_PRED_BLOCK
23152 && (inst.pred_insn_type == INSIDE_IT_LAST_INSN
23153 || inst.pred_insn_type == IF_INSIDE_IT_LAST_INSN))
e07e6e58
NC
23154 close_automatic_it_block ();
23155 break;
23156
4934a27c 23157 /* Fallthrough. */
e07e6e58 23158 case NEUTRAL_IT_INSN:
5ee91343 23159 now_pred.block_length++;
5b7c81bd 23160 now_pred.insn_cond = true;
e07e6e58 23161
5ee91343 23162 if (now_pred.block_length > 4)
e07e6e58
NC
23163 force_automatic_it_block_close ();
23164 else
5ee91343 23165 now_pred_add_mask (now_pred.cc & 1);
e07e6e58
NC
23166 break;
23167
23168 case IT_INSN:
23169 close_automatic_it_block ();
5ee91343 23170 now_pred.state = MANUAL_PRED_BLOCK;
e07e6e58
NC
23171 break;
23172 }
23173 break;
23174
5ee91343 23175 case MANUAL_PRED_BLOCK:
e07e6e58 23176 {
7af67752
AM
23177 unsigned int cond;
23178 int is_last;
5ee91343 23179 if (now_pred.type == SCALAR_PRED)
e07e6e58 23180 {
5ee91343
AV
23181 /* Check conditional suffixes. */
23182 cond = now_pred.cc ^ ((now_pred.mask >> 4) & 1) ^ 1;
23183 now_pred.mask <<= 1;
23184 now_pred.mask &= 0x1f;
23185 is_last = (now_pred.mask == 0x10);
23186 }
23187 else
23188 {
23189 now_pred.cc ^= (now_pred.mask >> 4);
23190 cond = now_pred.cc + 0xf;
23191 now_pred.mask <<= 1;
23192 now_pred.mask &= 0x1f;
23193 is_last = now_pred.mask == 0x10;
23194 }
5b7c81bd 23195 now_pred.insn_cond = true;
e07e6e58 23196
5ee91343
AV
23197 switch (inst.pred_insn_type)
23198 {
23199 case OUTSIDE_PRED_INSN:
23200 if (now_pred.type == SCALAR_PRED)
23201 {
23202 if (inst.cond == COND_ALWAYS)
23203 {
23204 /* Case 12: In an IT block, with no code: error: missing
23205 code. */
23206 inst.error = BAD_NOT_IT;
23207 return FAIL;
23208 }
23209 else if (inst.cond > COND_ALWAYS)
23210 {
23211 /* Case 11: In an IT block, with a VPT code: syntax error.
23212 */
23213 inst.error = BAD_SYNTAX;
23214 return FAIL;
23215 }
23216 else if (thumb_mode)
23217 {
23218 /* This is for some special cases where a non-MVE
23219 instruction is not allowed in an IT block, such as cbz,
23220 but are put into one with a condition code.
23221 You could argue this should be a syntax error, but we
23222 gave the 'not allowed in IT block' diagnostic in the
23223 past so we will keep doing so. */
23224 inst.error = BAD_NOT_IT;
23225 return FAIL;
23226 }
23227 break;
23228 }
23229 else
23230 {
23231 /* Case 15: In a VPT block, with no code: UNPREDICTABLE. */
23232 as_tsktsk (MVE_NOT_VPT);
23233 return SUCCESS;
23234 }
23235 case MVE_OUTSIDE_PRED_INSN:
23236 if (now_pred.type == SCALAR_PRED)
23237 {
23238 if (inst.cond == COND_ALWAYS)
23239 {
23240 /* Case 3: In an IT block, with no code: warning:
23241 UNPREDICTABLE. */
23242 as_tsktsk (MVE_NOT_IT);
23243 return SUCCESS;
23244 }
23245 else if (inst.cond < COND_ALWAYS)
23246 {
23247 /* Case 1: In an IT block, with an IT code: syntax error.
23248 */
23249 inst.error = BAD_SYNTAX;
23250 return FAIL;
23251 }
23252 else
23253 gas_assert (0);
23254 }
23255 else
23256 {
23257 if (inst.cond < COND_ALWAYS)
23258 {
23259 /* Case 4: In a VPT block, with an IT code: syntax error.
23260 */
23261 inst.error = BAD_SYNTAX;
23262 return FAIL;
23263 }
23264 else if (inst.cond == COND_ALWAYS)
23265 {
23266 /* Case 6: In a VPT block, with no code: error: missing
23267 code. */
23268 inst.error = BAD_NOT_VPT;
23269 return FAIL;
23270 }
23271 else
23272 {
23273 gas_assert (0);
23274 }
23275 }
35c228db
AV
23276 case MVE_UNPREDICABLE_INSN:
23277 as_tsktsk (now_pred.type == SCALAR_PRED ? MVE_NOT_IT : MVE_NOT_VPT);
23278 return SUCCESS;
e07e6e58 23279 case INSIDE_IT_INSN:
5ee91343 23280 if (inst.cond > COND_ALWAYS)
e07e6e58 23281 {
5ee91343
AV
23282 /* Case 11: In an IT block, with a VPT code: syntax error. */
23283 /* Case 14: In a VPT block, with a VPT code: syntax error. */
23284 inst.error = BAD_SYNTAX;
23285 return FAIL;
23286 }
23287 else if (now_pred.type == SCALAR_PRED)
23288 {
23289 /* Case 10: In an IT block, with an IT code: OK! */
23290 if (cond != inst.cond)
23291 {
23292 inst.error = now_pred.type == SCALAR_PRED ? BAD_IT_COND :
23293 BAD_VPT_COND;
23294 return FAIL;
23295 }
23296 }
23297 else
23298 {
23299 /* Case 13: In a VPT block, with an IT code: error: should be
23300 in an IT block. */
23301 inst.error = BAD_OUT_IT;
e07e6e58
NC
23302 return FAIL;
23303 }
23304 break;
23305
5ee91343
AV
23306 case INSIDE_VPT_INSN:
23307 if (now_pred.type == SCALAR_PRED)
23308 {
23309 /* Case 2: In an IT block, with a VPT code: error: must be in a
23310 VPT block. */
23311 inst.error = BAD_OUT_VPT;
23312 return FAIL;
23313 }
23314 /* Case 5: In a VPT block, with a VPT code: OK! */
23315 else if (cond != inst.cond)
23316 {
23317 inst.error = BAD_VPT_COND;
23318 return FAIL;
23319 }
23320 break;
e07e6e58
NC
23321 case INSIDE_IT_LAST_INSN:
23322 case IF_INSIDE_IT_LAST_INSN:
5ee91343
AV
23323 if (now_pred.type == VECTOR_PRED || inst.cond > COND_ALWAYS)
23324 {
23325 /* Case 4: In a VPT block, with an IT code: syntax error. */
23326 /* Case 11: In an IT block, with a VPT code: syntax error. */
23327 inst.error = BAD_SYNTAX;
23328 return FAIL;
23329 }
23330 else if (cond != inst.cond)
e07e6e58
NC
23331 {
23332 inst.error = BAD_IT_COND;
23333 return FAIL;
23334 }
23335 if (!is_last)
23336 {
23337 inst.error = BAD_BRANCH;
23338 return FAIL;
23339 }
23340 break;
23341
23342 case NEUTRAL_IT_INSN:
5ee91343
AV
23343 /* The BKPT instruction is unconditional even in a IT or VPT
23344 block. */
e07e6e58
NC
23345 break;
23346
23347 case IT_INSN:
5ee91343
AV
23348 if (now_pred.type == SCALAR_PRED)
23349 {
23350 inst.error = BAD_IT_IT;
23351 return FAIL;
23352 }
23353 /* fall through. */
23354 case VPT_INSN:
23355 if (inst.cond == COND_ALWAYS)
23356 {
23357 /* Executing a VPT/VPST instruction inside an IT block or a
23358 VPT/VPST/IT instruction inside a VPT block is UNPREDICTABLE.
23359 */
23360 if (now_pred.type == SCALAR_PRED)
23361 as_tsktsk (MVE_NOT_IT);
23362 else
23363 as_tsktsk (MVE_NOT_VPT);
23364 return SUCCESS;
23365 }
23366 else
23367 {
23368 /* VPT/VPST do not accept condition codes. */
23369 inst.error = BAD_SYNTAX;
23370 return FAIL;
23371 }
e07e6e58 23372 }
5ee91343 23373 }
e07e6e58
NC
23374 break;
23375 }
23376
23377 return SUCCESS;
23378}
23379
5a01bb1d
MGD
23380struct depr_insn_mask
23381{
23382 unsigned long pattern;
23383 unsigned long mask;
23384 const char* description;
23385};
23386
23387/* List of 16-bit instruction patterns deprecated in an IT block in
23388 ARMv8. */
23389static const struct depr_insn_mask depr_it_insns[] = {
23390 { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
23391 { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
23392 { 0xa000, 0xb800, N_("ADR") },
23393 { 0x4800, 0xf800, N_("Literal loads") },
23394 { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
23395 { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
c8de034b
JW
23396 /* NOTE: 0x00dd is not the real encoding, instead, it is the 'tvalue'
23397 field in asm_opcode. 'tvalue' is used at the stage this check happen. */
23398 { 0x00dd, 0x7fff, N_("ADD/SUB sp, sp #imm") },
5a01bb1d
MGD
23399 { 0, 0, NULL }
23400};
23401
e07e6e58
NC
23402static void
23403it_fsm_post_encode (void)
23404{
23405 int is_last;
23406
5ee91343
AV
23407 if (!now_pred.state_handled)
23408 handle_pred_state ();
e07e6e58 23409
5ee91343 23410 if (now_pred.insn_cond
24f19ccb 23411 && warn_on_restrict_it
5ee91343 23412 && !now_pred.warn_deprecated
5a01bb1d 23413 && warn_on_deprecated
164446e0
AF
23414 && (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)
23415 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8r))
df9909b8 23416 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m))
5a01bb1d
MGD
23417 {
23418 if (inst.instruction >= 0x10000)
23419 {
5c3696f8 23420 as_tsktsk (_("IT blocks containing 32-bit Thumb instructions are "
df9909b8 23421 "performance deprecated in ARMv8-A and ARMv8-R"));
5b7c81bd 23422 now_pred.warn_deprecated = true;
5a01bb1d
MGD
23423 }
23424 else
23425 {
23426 const struct depr_insn_mask *p = depr_it_insns;
23427
23428 while (p->mask != 0)
23429 {
23430 if ((inst.instruction & p->mask) == p->pattern)
23431 {
df9909b8
TP
23432 as_tsktsk (_("IT blocks containing 16-bit Thumb "
23433 "instructions of the following class are "
23434 "performance deprecated in ARMv8-A and "
23435 "ARMv8-R: %s"), p->description);
5b7c81bd 23436 now_pred.warn_deprecated = true;
5a01bb1d
MGD
23437 break;
23438 }
23439
23440 ++p;
23441 }
23442 }
23443
5ee91343 23444 if (now_pred.block_length > 1)
5a01bb1d 23445 {
5c3696f8 23446 as_tsktsk (_("IT blocks containing more than one conditional "
df9909b8
TP
23447 "instruction are performance deprecated in ARMv8-A and "
23448 "ARMv8-R"));
5b7c81bd 23449 now_pred.warn_deprecated = true;
5a01bb1d
MGD
23450 }
23451 }
23452
5ee91343
AV
23453 is_last = (now_pred.mask == 0x10);
23454 if (is_last)
23455 {
23456 now_pred.state = OUTSIDE_PRED_BLOCK;
23457 now_pred.mask = 0;
23458 }
e07e6e58
NC
23459}
23460
23461static void
23462force_automatic_it_block_close (void)
23463{
5ee91343 23464 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
e07e6e58
NC
23465 {
23466 close_automatic_it_block ();
5ee91343
AV
23467 now_pred.state = OUTSIDE_PRED_BLOCK;
23468 now_pred.mask = 0;
e07e6e58
NC
23469 }
23470}
23471
23472static int
5ee91343 23473in_pred_block (void)
e07e6e58 23474{
5ee91343
AV
23475 if (!now_pred.state_handled)
23476 handle_pred_state ();
e07e6e58 23477
5ee91343 23478 return now_pred.state != OUTSIDE_PRED_BLOCK;
e07e6e58
NC
23479}
23480
ff8646ee
TP
23481/* Whether OPCODE only has T32 encoding. Since this function is only used by
23482 t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed
23483 here, hence the "known" in the function name. */
fc289b0a 23484
5b7c81bd 23485static bool
ff8646ee 23486known_t32_only_insn (const struct asm_opcode *opcode)
fc289b0a
TP
23487{
23488 /* Original Thumb-1 wide instruction. */
23489 if (opcode->tencode == do_t_blx
23490 || opcode->tencode == do_t_branch23
23491 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
23492 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
5b7c81bd 23493 return true;
fc289b0a 23494
16a1fa25
TP
23495 /* Wide-only instruction added to ARMv8-M Baseline. */
23496 if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m_m_only)
ff8646ee
TP
23497 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics)
23498 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m)
23499 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div))
5b7c81bd 23500 return true;
ff8646ee 23501
5b7c81bd 23502 return false;
ff8646ee
TP
23503}
23504
23505/* Whether wide instruction variant can be used if available for a valid OPCODE
23506 in ARCH. */
23507
5b7c81bd 23508static bool
ff8646ee
TP
23509t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode)
23510{
23511 if (known_t32_only_insn (opcode))
5b7c81bd 23512 return true;
ff8646ee
TP
23513
23514 /* Instruction with narrow and wide encoding added to ARMv8-M. Availability
23515 of variant T3 of B.W is checked in do_t_branch. */
23516 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
23517 && opcode->tencode == do_t_branch)
5b7c81bd 23518 return true;
ff8646ee 23519
bada4342
JW
23520 /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */
23521 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
23522 && opcode->tencode == do_t_mov_cmp
23523 /* Make sure CMP instruction is not affected. */
23524 && opcode->aencode == do_mov)
5b7c81bd 23525 return true;
bada4342 23526
ff8646ee
TP
23527 /* Wide instruction variants of all instructions with narrow *and* wide
23528 variants become available with ARMv6t2. Other opcodes are either
23529 narrow-only or wide-only and are thus available if OPCODE is valid. */
23530 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2))
5b7c81bd 23531 return true;
ff8646ee
TP
23532
23533 /* OPCODE with narrow only instruction variant or wide variant not
23534 available. */
5b7c81bd 23535 return false;
fc289b0a
TP
23536}
23537
c19d1205
ZW
23538void
23539md_assemble (char *str)
b99bd4ef 23540{
c19d1205
ZW
23541 char *p = str;
23542 const struct asm_opcode * opcode;
b99bd4ef 23543
c19d1205
ZW
23544 /* Align the previous label if needed. */
23545 if (last_label_seen != NULL)
b99bd4ef 23546 {
c19d1205
ZW
23547 symbol_set_frag (last_label_seen, frag_now);
23548 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
23549 S_SET_SEGMENT (last_label_seen, now_seg);
b99bd4ef
NC
23550 }
23551
c19d1205 23552 memset (&inst, '\0', sizeof (inst));
e2b0ab59
AV
23553 int r;
23554 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
23555 inst.relocs[r].type = BFD_RELOC_UNUSED;
b99bd4ef 23556
c19d1205
ZW
23557 opcode = opcode_lookup (&p);
23558 if (!opcode)
b99bd4ef 23559 {
c19d1205 23560 /* It wasn't an instruction, but it might be a register alias of
dcbf9037 23561 the form alias .req reg, or a Neon .dn/.qn directive. */
c921be7d 23562 if (! create_register_alias (str, p)
477330fc 23563 && ! create_neon_reg_alias (str, p))
c19d1205 23564 as_bad (_("bad instruction `%s'"), str);
b99bd4ef 23565
b99bd4ef
NC
23566 return;
23567 }
23568
278df34e 23569 if (warn_on_deprecated && opcode->tag == OT_cinfix3_deprecated)
5c3696f8 23570 as_tsktsk (_("s suffix on comparison instruction is deprecated"));
088fa78e 23571
037e8744
JB
23572 /* The value which unconditional instructions should have in place of the
23573 condition field. */
7af67752 23574 inst.uncond_value = (opcode->tag == OT_csuffixF) ? 0xf : -1u;
037e8744 23575
c19d1205 23576 if (thumb_mode)
b99bd4ef 23577 {
e74cfd16 23578 arm_feature_set variant;
8f06b2d8
PB
23579
23580 variant = cpu_variant;
23581 /* Only allow coprocessor instructions on Thumb-2 capable devices. */
e74cfd16
PB
23582 if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2))
23583 ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard);
c19d1205 23584 /* Check that this instruction is supported for this CPU. */
62b3e311
PB
23585 if (!opcode->tvariant
23586 || (thumb_mode == 1
23587 && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
b99bd4ef 23588 {
173205ca
TP
23589 if (opcode->tencode == do_t_swi)
23590 as_bad (_("SVC is not permitted on this architecture"));
23591 else
23592 as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
b99bd4ef
NC
23593 return;
23594 }
c19d1205
ZW
23595 if (inst.cond != COND_ALWAYS && !unified_syntax
23596 && opcode->tencode != do_t_branch)
b99bd4ef 23597 {
c19d1205 23598 as_bad (_("Thumb does not support conditional execution"));
b99bd4ef
NC
23599 return;
23600 }
23601
fc289b0a
TP
23602 /* Two things are addressed here:
23603 1) Implicit require narrow instructions on Thumb-1.
23604 This avoids relaxation accidentally introducing Thumb-2
23605 instructions.
23606 2) Reject wide instructions in non Thumb-2 cores.
23607
23608 Only instructions with narrow and wide variants need to be handled
23609 but selecting all non wide-only instructions is easier. */
23610 if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)
ff8646ee 23611 && !t32_insn_ok (variant, opcode))
076d447c 23612 {
fc289b0a
TP
23613 if (inst.size_req == 0)
23614 inst.size_req = 2;
23615 else if (inst.size_req == 4)
752d5da4 23616 {
ff8646ee
TP
23617 if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m))
23618 as_bad (_("selected processor does not support 32bit wide "
23619 "variant of instruction `%s'"), str);
23620 else
23621 as_bad (_("selected processor does not support `%s' in "
23622 "Thumb-2 mode"), str);
fc289b0a 23623 return;
752d5da4 23624 }
076d447c
PB
23625 }
23626
c19d1205
ZW
23627 inst.instruction = opcode->tvalue;
23628
5b7c81bd 23629 if (!parse_operands (p, opcode->operands, /*thumb=*/true))
477330fc 23630 {
5ee91343 23631 /* Prepare the pred_insn_type for those encodings that don't set
477330fc
RM
23632 it. */
23633 it_fsm_pre_encode ();
c19d1205 23634
477330fc 23635 opcode->tencode ();
e07e6e58 23636
477330fc
RM
23637 it_fsm_post_encode ();
23638 }
e27ec89e 23639
0110f2b8 23640 if (!(inst.error || inst.relax))
b99bd4ef 23641 {
9c2799c2 23642 gas_assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
c19d1205
ZW
23643 inst.size = (inst.instruction > 0xffff ? 4 : 2);
23644 if (inst.size_req && inst.size_req != inst.size)
b99bd4ef 23645 {
c19d1205 23646 as_bad (_("cannot honor width suffix -- `%s'"), str);
b99bd4ef
NC
23647 return;
23648 }
23649 }
076d447c
PB
23650
23651 /* Something has gone badly wrong if we try to relax a fixed size
477330fc 23652 instruction. */
9c2799c2 23653 gas_assert (inst.size_req == 0 || !inst.relax);
076d447c 23654
e74cfd16
PB
23655 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
23656 *opcode->tvariant);
ee065d83 23657 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
fc289b0a
TP
23658 set those bits when Thumb-2 32-bit instructions are seen. The impact
23659 of relaxable instructions will be considered later after we finish all
23660 relaxation. */
ff8646ee
TP
23661 if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any))
23662 variant = arm_arch_none;
23663 else
23664 variant = cpu_variant;
23665 if (inst.size == 4 && !t32_insn_ok (variant, opcode))
e74cfd16
PB
23666 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
23667 arm_ext_v6t2);
cd000bff 23668
88714cb8
DG
23669 check_neon_suffixes;
23670
cd000bff 23671 if (!inst.error)
c877a2f2
NC
23672 {
23673 mapping_state (MAP_THUMB);
23674 }
c19d1205 23675 }
3e9e4fcf 23676 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205 23677 {
5b7c81bd 23678 bool is_bx;
845b51d6
PB
23679
23680 /* bx is allowed on v5 cores, and sometimes on v4 cores. */
23681 is_bx = (opcode->aencode == do_bx);
23682
c19d1205 23683 /* Check that this instruction is supported for this CPU. */
845b51d6
PB
23684 if (!(is_bx && fix_v4bx)
23685 && !(opcode->avariant &&
23686 ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)))
b99bd4ef 23687 {
84b52b66 23688 as_bad (_("selected processor does not support `%s' in ARM mode"), str);
c19d1205 23689 return;
b99bd4ef 23690 }
c19d1205 23691 if (inst.size_req)
b99bd4ef 23692 {
c19d1205
ZW
23693 as_bad (_("width suffixes are invalid in ARM mode -- `%s'"), str);
23694 return;
b99bd4ef
NC
23695 }
23696
c19d1205
ZW
23697 inst.instruction = opcode->avalue;
23698 if (opcode->tag == OT_unconditionalF)
eff0bc54 23699 inst.instruction |= 0xFU << 28;
c19d1205
ZW
23700 else
23701 inst.instruction |= inst.cond << 28;
23702 inst.size = INSN_SIZE;
5b7c81bd 23703 if (!parse_operands (p, opcode->operands, /*thumb=*/false))
477330fc
RM
23704 {
23705 it_fsm_pre_encode ();
23706 opcode->aencode ();
23707 it_fsm_post_encode ();
23708 }
ee065d83 23709 /* Arm mode bx is marked as both v4T and v5 because it's still required
477330fc 23710 on a hypothetical non-thumb v5 core. */
845b51d6 23711 if (is_bx)
e74cfd16 23712 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t);
ee065d83 23713 else
e74cfd16
PB
23714 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
23715 *opcode->avariant);
88714cb8
DG
23716
23717 check_neon_suffixes;
23718
cd000bff 23719 if (!inst.error)
c877a2f2
NC
23720 {
23721 mapping_state (MAP_ARM);
23722 }
b99bd4ef 23723 }
3e9e4fcf
JB
23724 else
23725 {
23726 as_bad (_("attempt to use an ARM instruction on a Thumb-only processor "
23727 "-- `%s'"), str);
23728 return;
23729 }
c19d1205
ZW
23730 output_inst (str);
23731}
b99bd4ef 23732
e07e6e58 23733static void
5ee91343 23734check_pred_blocks_finished (void)
e07e6e58
NC
23735{
23736#ifdef OBJ_ELF
23737 asection *sect;
23738
23739 for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
5ee91343
AV
23740 if (seg_info (sect)->tc_segment_info_data.current_pred.state
23741 == MANUAL_PRED_BLOCK)
e07e6e58 23742 {
5ee91343
AV
23743 if (now_pred.type == SCALAR_PRED)
23744 as_warn (_("section '%s' finished with an open IT block."),
23745 sect->name);
23746 else
23747 as_warn (_("section '%s' finished with an open VPT/VPST block."),
23748 sect->name);
e07e6e58
NC
23749 }
23750#else
5ee91343
AV
23751 if (now_pred.state == MANUAL_PRED_BLOCK)
23752 {
23753 if (now_pred.type == SCALAR_PRED)
23754 as_warn (_("file finished with an open IT block."));
23755 else
23756 as_warn (_("file finished with an open VPT/VPST block."));
23757 }
e07e6e58
NC
23758#endif
23759}
23760
c19d1205
ZW
23761/* Various frobbings of labels and their addresses. */
23762
23763void
23764arm_start_line_hook (void)
23765{
23766 last_label_seen = NULL;
b99bd4ef
NC
23767}
23768
c19d1205
ZW
23769void
23770arm_frob_label (symbolS * sym)
b99bd4ef 23771{
c19d1205 23772 last_label_seen = sym;
b99bd4ef 23773
c19d1205 23774 ARM_SET_THUMB (sym, thumb_mode);
b99bd4ef 23775
c19d1205
ZW
23776#if defined OBJ_COFF || defined OBJ_ELF
23777 ARM_SET_INTERWORK (sym, support_interwork);
23778#endif
b99bd4ef 23779
e07e6e58
NC
23780 force_automatic_it_block_close ();
23781
5f4273c7 23782 /* Note - do not allow local symbols (.Lxxx) to be labelled
c19d1205
ZW
23783 as Thumb functions. This is because these labels, whilst
23784 they exist inside Thumb code, are not the entry points for
23785 possible ARM->Thumb calls. Also, these labels can be used
23786 as part of a computed goto or switch statement. eg gcc
23787 can generate code that looks like this:
b99bd4ef 23788
c19d1205
ZW
23789 ldr r2, [pc, .Laaa]
23790 lsl r3, r3, #2
23791 ldr r2, [r3, r2]
23792 mov pc, r2
b99bd4ef 23793
c19d1205
ZW
23794 .Lbbb: .word .Lxxx
23795 .Lccc: .word .Lyyy
23796 ..etc...
23797 .Laaa: .word Lbbb
b99bd4ef 23798
c19d1205
ZW
23799 The first instruction loads the address of the jump table.
23800 The second instruction converts a table index into a byte offset.
23801 The third instruction gets the jump address out of the table.
23802 The fourth instruction performs the jump.
b99bd4ef 23803
c19d1205
ZW
23804 If the address stored at .Laaa is that of a symbol which has the
23805 Thumb_Func bit set, then the linker will arrange for this address
23806 to have the bottom bit set, which in turn would mean that the
23807 address computation performed by the third instruction would end
23808 up with the bottom bit set. Since the ARM is capable of unaligned
23809 word loads, the instruction would then load the incorrect address
23810 out of the jump table, and chaos would ensue. */
23811 if (label_is_thumb_function_name
23812 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
fd361982 23813 && (bfd_section_flags (now_seg) & SEC_CODE) != 0)
b99bd4ef 23814 {
c19d1205
ZW
23815 /* When the address of a Thumb function is taken the bottom
23816 bit of that address should be set. This will allow
23817 interworking between Arm and Thumb functions to work
23818 correctly. */
b99bd4ef 23819
c19d1205 23820 THUMB_SET_FUNC (sym, 1);
b99bd4ef 23821
5b7c81bd 23822 label_is_thumb_function_name = false;
b99bd4ef 23823 }
07a53e5c 23824
07a53e5c 23825 dwarf2_emit_label (sym);
b99bd4ef
NC
23826}
23827
5b7c81bd 23828bool
c19d1205 23829arm_data_in_code (void)
b99bd4ef 23830{
d34049e8 23831 if (thumb_mode && startswith (input_line_pointer + 1, "data:"))
b99bd4ef 23832 {
c19d1205
ZW
23833 *input_line_pointer = '/';
23834 input_line_pointer += 5;
23835 *input_line_pointer = 0;
5b7c81bd 23836 return true;
b99bd4ef
NC
23837 }
23838
5b7c81bd 23839 return false;
b99bd4ef
NC
23840}
23841
c19d1205
ZW
23842char *
23843arm_canonicalize_symbol_name (char * name)
b99bd4ef 23844{
c19d1205 23845 int len;
b99bd4ef 23846
c19d1205
ZW
23847 if (thumb_mode && (len = strlen (name)) > 5
23848 && streq (name + len - 5, "/data"))
23849 *(name + len - 5) = 0;
b99bd4ef 23850
c19d1205 23851 return name;
b99bd4ef 23852}
c19d1205
ZW
23853\f
23854/* Table of all register names defined by default. The user can
23855 define additional names with .req. Note that all register names
23856 should appear in both upper and lowercase variants. Some registers
23857 also have mixed-case names. */
b99bd4ef 23858
5b7c81bd 23859#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, true, 0 }
c19d1205 23860#define REGNUM(p,n,t) REGDEF(p##n, n, t)
5287ad62 23861#define REGNUM2(p,n,t) REGDEF(p##n, 2 * n, t)
c19d1205
ZW
23862#define REGSET(p,t) \
23863 REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
23864 REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
23865 REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
23866 REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
5287ad62
JB
23867#define REGSETH(p,t) \
23868 REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
23869 REGNUM(p,20,t), REGNUM(p,21,t), REGNUM(p,22,t), REGNUM(p,23,t), \
23870 REGNUM(p,24,t), REGNUM(p,25,t), REGNUM(p,26,t), REGNUM(p,27,t), \
23871 REGNUM(p,28,t), REGNUM(p,29,t), REGNUM(p,30,t), REGNUM(p,31,t)
23872#define REGSET2(p,t) \
23873 REGNUM2(p, 0,t), REGNUM2(p, 1,t), REGNUM2(p, 2,t), REGNUM2(p, 3,t), \
23874 REGNUM2(p, 4,t), REGNUM2(p, 5,t), REGNUM2(p, 6,t), REGNUM2(p, 7,t), \
23875 REGNUM2(p, 8,t), REGNUM2(p, 9,t), REGNUM2(p,10,t), REGNUM2(p,11,t), \
23876 REGNUM2(p,12,t), REGNUM2(p,13,t), REGNUM2(p,14,t), REGNUM2(p,15,t)
90ec0d68
MGD
23877#define SPLRBANK(base,bank,t) \
23878 REGDEF(lr_##bank, 768|((base+0)<<16), t), \
23879 REGDEF(sp_##bank, 768|((base+1)<<16), t), \
23880 REGDEF(spsr_##bank, 768|(base<<16)|SPSR_BIT, t), \
23881 REGDEF(LR_##bank, 768|((base+0)<<16), t), \
23882 REGDEF(SP_##bank, 768|((base+1)<<16), t), \
23883 REGDEF(SPSR_##bank, 768|(base<<16)|SPSR_BIT, t)
7ed4c4c5 23884
c19d1205 23885static const struct reg_entry reg_names[] =
7ed4c4c5 23886{
c19d1205
ZW
23887 /* ARM integer registers. */
23888 REGSET(r, RN), REGSET(R, RN),
7ed4c4c5 23889
c19d1205
ZW
23890 /* ATPCS synonyms. */
23891 REGDEF(a1,0,RN), REGDEF(a2,1,RN), REGDEF(a3, 2,RN), REGDEF(a4, 3,RN),
23892 REGDEF(v1,4,RN), REGDEF(v2,5,RN), REGDEF(v3, 6,RN), REGDEF(v4, 7,RN),
23893 REGDEF(v5,8,RN), REGDEF(v6,9,RN), REGDEF(v7,10,RN), REGDEF(v8,11,RN),
7ed4c4c5 23894
c19d1205
ZW
23895 REGDEF(A1,0,RN), REGDEF(A2,1,RN), REGDEF(A3, 2,RN), REGDEF(A4, 3,RN),
23896 REGDEF(V1,4,RN), REGDEF(V2,5,RN), REGDEF(V3, 6,RN), REGDEF(V4, 7,RN),
23897 REGDEF(V5,8,RN), REGDEF(V6,9,RN), REGDEF(V7,10,RN), REGDEF(V8,11,RN),
7ed4c4c5 23898
c19d1205
ZW
23899 /* Well-known aliases. */
23900 REGDEF(wr, 7,RN), REGDEF(sb, 9,RN), REGDEF(sl,10,RN), REGDEF(fp,11,RN),
23901 REGDEF(ip,12,RN), REGDEF(sp,13,RN), REGDEF(lr,14,RN), REGDEF(pc,15,RN),
23902
23903 REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
23904 REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
23905
1b883319
AV
23906 /* Defining the new Zero register from ARMv8.1-M. */
23907 REGDEF(zr,15,ZR),
23908 REGDEF(ZR,15,ZR),
23909
c19d1205
ZW
23910 /* Coprocessor numbers. */
23911 REGSET(p, CP), REGSET(P, CP),
23912
23913 /* Coprocessor register numbers. The "cr" variants are for backward
23914 compatibility. */
23915 REGSET(c, CN), REGSET(C, CN),
23916 REGSET(cr, CN), REGSET(CR, CN),
23917
90ec0d68
MGD
23918 /* ARM banked registers. */
23919 REGDEF(R8_usr,512|(0<<16),RNB), REGDEF(r8_usr,512|(0<<16),RNB),
23920 REGDEF(R9_usr,512|(1<<16),RNB), REGDEF(r9_usr,512|(1<<16),RNB),
23921 REGDEF(R10_usr,512|(2<<16),RNB), REGDEF(r10_usr,512|(2<<16),RNB),
23922 REGDEF(R11_usr,512|(3<<16),RNB), REGDEF(r11_usr,512|(3<<16),RNB),
23923 REGDEF(R12_usr,512|(4<<16),RNB), REGDEF(r12_usr,512|(4<<16),RNB),
23924 REGDEF(SP_usr,512|(5<<16),RNB), REGDEF(sp_usr,512|(5<<16),RNB),
23925 REGDEF(LR_usr,512|(6<<16),RNB), REGDEF(lr_usr,512|(6<<16),RNB),
23926
23927 REGDEF(R8_fiq,512|(8<<16),RNB), REGDEF(r8_fiq,512|(8<<16),RNB),
23928 REGDEF(R9_fiq,512|(9<<16),RNB), REGDEF(r9_fiq,512|(9<<16),RNB),
23929 REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
23930 REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
23931 REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
1472d06f 23932 REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(sp_fiq,512|(13<<16),RNB),
90ec0d68
MGD
23933 REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
23934 REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
23935
23936 SPLRBANK(0,IRQ,RNB), SPLRBANK(0,irq,RNB),
23937 SPLRBANK(2,SVC,RNB), SPLRBANK(2,svc,RNB),
23938 SPLRBANK(4,ABT,RNB), SPLRBANK(4,abt,RNB),
23939 SPLRBANK(6,UND,RNB), SPLRBANK(6,und,RNB),
23940 SPLRBANK(12,MON,RNB), SPLRBANK(12,mon,RNB),
23941 REGDEF(elr_hyp,768|(14<<16),RNB), REGDEF(ELR_hyp,768|(14<<16),RNB),
23942 REGDEF(sp_hyp,768|(15<<16),RNB), REGDEF(SP_hyp,768|(15<<16),RNB),
fa94de6b 23943 REGDEF(spsr_hyp,768|(14<<16)|SPSR_BIT,RNB),
90ec0d68
MGD
23944 REGDEF(SPSR_hyp,768|(14<<16)|SPSR_BIT,RNB),
23945
c19d1205
ZW
23946 /* FPA registers. */
23947 REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
23948 REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
23949
23950 REGNUM(F,0,FN), REGNUM(F,1,FN), REGNUM(F,2,FN), REGNUM(F,3,FN),
23951 REGNUM(F,4,FN), REGNUM(F,5,FN), REGNUM(F,6,FN), REGNUM(F,7, FN),
23952
23953 /* VFP SP registers. */
5287ad62
JB
23954 REGSET(s,VFS), REGSET(S,VFS),
23955 REGSETH(s,VFS), REGSETH(S,VFS),
c19d1205
ZW
23956
23957 /* VFP DP Registers. */
5287ad62
JB
23958 REGSET(d,VFD), REGSET(D,VFD),
23959 /* Extra Neon DP registers. */
23960 REGSETH(d,VFD), REGSETH(D,VFD),
23961
23962 /* Neon QP registers. */
23963 REGSET2(q,NQ), REGSET2(Q,NQ),
c19d1205
ZW
23964
23965 /* VFP control registers. */
23966 REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
23967 REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
cd2cf30b
PB
23968 REGDEF(fpinst,9,VFC), REGDEF(fpinst2,10,VFC),
23969 REGDEF(FPINST,9,VFC), REGDEF(FPINST2,10,VFC),
23970 REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
23971 REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
40c7d507 23972 REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
ba6cd17f
SD
23973 REGDEF(fpscr_nzcvqc,2,VFC), REGDEF(FPSCR_nzcvqc,2,VFC),
23974 REGDEF(vpr,12,VFC), REGDEF(VPR,12,VFC),
23975 REGDEF(fpcxt_ns,14,VFC), REGDEF(FPCXT_NS,14,VFC),
23976 REGDEF(fpcxt_s,15,VFC), REGDEF(FPCXT_S,15,VFC),
ee3272d4
SP
23977 REGDEF(fpcxtns,14,VFC), REGDEF(FPCXTNS,14,VFC),
23978 REGDEF(fpcxts,15,VFC), REGDEF(FPCXTS,15,VFC),
c19d1205
ZW
23979
23980 /* Maverick DSP coprocessor registers. */
23981 REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
23982 REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
23983
23984 REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
23985 REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
23986 REGDEF(dspsc,0,DSPSC),
23987
23988 REGNUM(MVAX,0,MVAX), REGNUM(MVAX,1,MVAX),
23989 REGNUM(MVAX,2,MVAX), REGNUM(MVAX,3,MVAX),
23990 REGDEF(DSPSC,0,DSPSC),
23991
23992 /* iWMMXt data registers - p0, c0-15. */
23993 REGSET(wr,MMXWR), REGSET(wR,MMXWR), REGSET(WR, MMXWR),
23994
23995 /* iWMMXt control registers - p1, c0-3. */
23996 REGDEF(wcid, 0,MMXWC), REGDEF(wCID, 0,MMXWC), REGDEF(WCID, 0,MMXWC),
23997 REGDEF(wcon, 1,MMXWC), REGDEF(wCon, 1,MMXWC), REGDEF(WCON, 1,MMXWC),
23998 REGDEF(wcssf, 2,MMXWC), REGDEF(wCSSF, 2,MMXWC), REGDEF(WCSSF, 2,MMXWC),
23999 REGDEF(wcasf, 3,MMXWC), REGDEF(wCASF, 3,MMXWC), REGDEF(WCASF, 3,MMXWC),
24000
24001 /* iWMMXt scalar (constant/offset) registers - p1, c8-11. */
24002 REGDEF(wcgr0, 8,MMXWCG), REGDEF(wCGR0, 8,MMXWCG), REGDEF(WCGR0, 8,MMXWCG),
24003 REGDEF(wcgr1, 9,MMXWCG), REGDEF(wCGR1, 9,MMXWCG), REGDEF(WCGR1, 9,MMXWCG),
24004 REGDEF(wcgr2,10,MMXWCG), REGDEF(wCGR2,10,MMXWCG), REGDEF(WCGR2,10,MMXWCG),
24005 REGDEF(wcgr3,11,MMXWCG), REGDEF(wCGR3,11,MMXWCG), REGDEF(WCGR3,11,MMXWCG),
24006
24007 /* XScale accumulator registers. */
24008 REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
0264bf6f 24009
8c299995
TB
24010 /* DWARF ABI defines RA_AUTH_CODE to 143. It also reserves 134-142 for future
24011 expansion. RA_AUTH_CODE here is given the value 143 % 134 to make it easy
24012 for tc_arm_regname_to_dw2regnum to translate to DWARF reg number using
24013 134 + reg_number should the range 134 to 142 be used for more pseudo regs
24014 in the future. This also helps fit RA_AUTH_CODE into a bitmask. */
3363d856 24015 REGDEF(ra_auth_code,12,PSEUDO),
c19d1205
ZW
24016};
24017#undef REGDEF
24018#undef REGNUM
24019#undef REGSET
7ed4c4c5 24020
c19d1205
ZW
24021/* Table of all PSR suffixes. Bare "CPSR" and "SPSR" are handled
24022 within psr_required_here. */
24023static const struct asm_psr psrs[] =
24024{
24025 /* Backward compatibility notation. Note that "all" is no longer
24026 truly all possible PSR bits. */
24027 {"all", PSR_c | PSR_f},
24028 {"flg", PSR_f},
24029 {"ctl", PSR_c},
24030
24031 /* Individual flags. */
24032 {"f", PSR_f},
24033 {"c", PSR_c},
24034 {"x", PSR_x},
24035 {"s", PSR_s},
59b42a0d 24036
c19d1205
ZW
24037 /* Combinations of flags. */
24038 {"fs", PSR_f | PSR_s},
24039 {"fx", PSR_f | PSR_x},
24040 {"fc", PSR_f | PSR_c},
24041 {"sf", PSR_s | PSR_f},
24042 {"sx", PSR_s | PSR_x},
24043 {"sc", PSR_s | PSR_c},
24044 {"xf", PSR_x | PSR_f},
24045 {"xs", PSR_x | PSR_s},
24046 {"xc", PSR_x | PSR_c},
24047 {"cf", PSR_c | PSR_f},
24048 {"cs", PSR_c | PSR_s},
24049 {"cx", PSR_c | PSR_x},
24050 {"fsx", PSR_f | PSR_s | PSR_x},
24051 {"fsc", PSR_f | PSR_s | PSR_c},
24052 {"fxs", PSR_f | PSR_x | PSR_s},
24053 {"fxc", PSR_f | PSR_x | PSR_c},
24054 {"fcs", PSR_f | PSR_c | PSR_s},
24055 {"fcx", PSR_f | PSR_c | PSR_x},
24056 {"sfx", PSR_s | PSR_f | PSR_x},
24057 {"sfc", PSR_s | PSR_f | PSR_c},
24058 {"sxf", PSR_s | PSR_x | PSR_f},
24059 {"sxc", PSR_s | PSR_x | PSR_c},
24060 {"scf", PSR_s | PSR_c | PSR_f},
24061 {"scx", PSR_s | PSR_c | PSR_x},
24062 {"xfs", PSR_x | PSR_f | PSR_s},
24063 {"xfc", PSR_x | PSR_f | PSR_c},
24064 {"xsf", PSR_x | PSR_s | PSR_f},
24065 {"xsc", PSR_x | PSR_s | PSR_c},
24066 {"xcf", PSR_x | PSR_c | PSR_f},
24067 {"xcs", PSR_x | PSR_c | PSR_s},
24068 {"cfs", PSR_c | PSR_f | PSR_s},
24069 {"cfx", PSR_c | PSR_f | PSR_x},
24070 {"csf", PSR_c | PSR_s | PSR_f},
24071 {"csx", PSR_c | PSR_s | PSR_x},
24072 {"cxf", PSR_c | PSR_x | PSR_f},
24073 {"cxs", PSR_c | PSR_x | PSR_s},
24074 {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
24075 {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
24076 {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
24077 {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
24078 {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
24079 {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
24080 {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
24081 {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
24082 {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
24083 {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
24084 {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
24085 {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
24086 {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
24087 {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
24088 {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
24089 {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
24090 {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
24091 {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
24092 {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
24093 {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
24094 {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
24095 {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
24096 {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
24097 {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
24098};
24099
62b3e311
PB
24100/* Table of V7M psr names. */
24101static const struct asm_psr v7m_psrs[] =
24102{
1a336194
TP
24103 {"apsr", 0x0 }, {"APSR", 0x0 },
24104 {"iapsr", 0x1 }, {"IAPSR", 0x1 },
24105 {"eapsr", 0x2 }, {"EAPSR", 0x2 },
24106 {"psr", 0x3 }, {"PSR", 0x3 },
24107 {"xpsr", 0x3 }, {"XPSR", 0x3 }, {"xPSR", 3 },
24108 {"ipsr", 0x5 }, {"IPSR", 0x5 },
24109 {"epsr", 0x6 }, {"EPSR", 0x6 },
24110 {"iepsr", 0x7 }, {"IEPSR", 0x7 },
24111 {"msp", 0x8 }, {"MSP", 0x8 },
24112 {"psp", 0x9 }, {"PSP", 0x9 },
24113 {"msplim", 0xa }, {"MSPLIM", 0xa },
24114 {"psplim", 0xb }, {"PSPLIM", 0xb },
24115 {"primask", 0x10}, {"PRIMASK", 0x10},
24116 {"basepri", 0x11}, {"BASEPRI", 0x11},
24117 {"basepri_max", 0x12}, {"BASEPRI_MAX", 0x12},
1a336194
TP
24118 {"faultmask", 0x13}, {"FAULTMASK", 0x13},
24119 {"control", 0x14}, {"CONTROL", 0x14},
24120 {"msp_ns", 0x88}, {"MSP_NS", 0x88},
24121 {"psp_ns", 0x89}, {"PSP_NS", 0x89},
24122 {"msplim_ns", 0x8a}, {"MSPLIM_NS", 0x8a},
24123 {"psplim_ns", 0x8b}, {"PSPLIM_NS", 0x8b},
24124 {"primask_ns", 0x90}, {"PRIMASK_NS", 0x90},
24125 {"basepri_ns", 0x91}, {"BASEPRI_NS", 0x91},
24126 {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
24127 {"control_ns", 0x94}, {"CONTROL_NS", 0x94},
24128 {"sp_ns", 0x98}, {"SP_NS", 0x98 }
62b3e311
PB
24129};
24130
c19d1205
ZW
24131/* Table of all shift-in-operand names. */
24132static const struct asm_shift_name shift_names [] =
b99bd4ef 24133{
c19d1205
ZW
24134 { "asl", SHIFT_LSL }, { "ASL", SHIFT_LSL },
24135 { "lsl", SHIFT_LSL }, { "LSL", SHIFT_LSL },
24136 { "lsr", SHIFT_LSR }, { "LSR", SHIFT_LSR },
24137 { "asr", SHIFT_ASR }, { "ASR", SHIFT_ASR },
24138 { "ror", SHIFT_ROR }, { "ROR", SHIFT_ROR },
f5f10c66
AV
24139 { "rrx", SHIFT_RRX }, { "RRX", SHIFT_RRX },
24140 { "uxtw", SHIFT_UXTW}, { "UXTW", SHIFT_UXTW}
c19d1205 24141};
b99bd4ef 24142
c19d1205
ZW
24143/* Table of all explicit relocation names. */
24144#ifdef OBJ_ELF
24145static struct reloc_entry reloc_names[] =
24146{
24147 { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
24148 { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
24149 { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
24150 { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
24151 { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
24152 { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
24153 { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
24154 { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
24155 { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
24156 { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
b43420e6 24157 { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32},
0855e32b
NS
24158 { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL},
24159 { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC},
477330fc 24160 { "TLSDESC", BFD_RELOC_ARM_TLS_GOTDESC},
0855e32b 24161 { "tlscall", BFD_RELOC_ARM_TLS_CALL},
477330fc 24162 { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
0855e32b 24163 { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
188fd7ae
CL
24164 { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ},
24165 { "gotfuncdesc", BFD_RELOC_ARM_GOTFUNCDESC },
24166 { "GOTFUNCDESC", BFD_RELOC_ARM_GOTFUNCDESC },
24167 { "gotofffuncdesc", BFD_RELOC_ARM_GOTOFFFUNCDESC },
24168 { "GOTOFFFUNCDESC", BFD_RELOC_ARM_GOTOFFFUNCDESC },
24169 { "funcdesc", BFD_RELOC_ARM_FUNCDESC },
5c5a4843
CL
24170 { "FUNCDESC", BFD_RELOC_ARM_FUNCDESC },
24171 { "tlsgd_fdpic", BFD_RELOC_ARM_TLS_GD32_FDPIC }, { "TLSGD_FDPIC", BFD_RELOC_ARM_TLS_GD32_FDPIC },
24172 { "tlsldm_fdpic", BFD_RELOC_ARM_TLS_LDM32_FDPIC }, { "TLSLDM_FDPIC", BFD_RELOC_ARM_TLS_LDM32_FDPIC },
24173 { "gottpoff_fdpic", BFD_RELOC_ARM_TLS_IE32_FDPIC }, { "GOTTPOFF_FDIC", BFD_RELOC_ARM_TLS_IE32_FDPIC },
c19d1205
ZW
24174};
24175#endif
b99bd4ef 24176
5ee91343 24177/* Table of all conditional affixes. */
c19d1205
ZW
24178static const struct asm_cond conds[] =
24179{
24180 {"eq", 0x0},
24181 {"ne", 0x1},
24182 {"cs", 0x2}, {"hs", 0x2},
24183 {"cc", 0x3}, {"ul", 0x3}, {"lo", 0x3},
24184 {"mi", 0x4},
24185 {"pl", 0x5},
24186 {"vs", 0x6},
24187 {"vc", 0x7},
24188 {"hi", 0x8},
24189 {"ls", 0x9},
24190 {"ge", 0xa},
24191 {"lt", 0xb},
24192 {"gt", 0xc},
24193 {"le", 0xd},
24194 {"al", 0xe}
24195};
5ee91343
AV
24196static const struct asm_cond vconds[] =
24197{
24198 {"t", 0xf},
24199 {"e", 0x10}
24200};
bfae80f2 24201
e797f7e0 24202#define UL_BARRIER(L,U,CODE,FEAT) \
823d2571
TG
24203 { L, CODE, ARM_FEATURE_CORE_LOW (FEAT) }, \
24204 { U, CODE, ARM_FEATURE_CORE_LOW (FEAT) }
e797f7e0 24205
62b3e311
PB
24206static struct asm_barrier_opt barrier_opt_names[] =
24207{
e797f7e0
MGD
24208 UL_BARRIER ("sy", "SY", 0xf, ARM_EXT_BARRIER),
24209 UL_BARRIER ("st", "ST", 0xe, ARM_EXT_BARRIER),
24210 UL_BARRIER ("ld", "LD", 0xd, ARM_EXT_V8),
24211 UL_BARRIER ("ish", "ISH", 0xb, ARM_EXT_BARRIER),
24212 UL_BARRIER ("sh", "SH", 0xb, ARM_EXT_BARRIER),
24213 UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER),
24214 UL_BARRIER ("shst", "SHST", 0xa, ARM_EXT_BARRIER),
24215 UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8),
24216 UL_BARRIER ("un", "UN", 0x7, ARM_EXT_BARRIER),
24217 UL_BARRIER ("nsh", "NSH", 0x7, ARM_EXT_BARRIER),
24218 UL_BARRIER ("unst", "UNST", 0x6, ARM_EXT_BARRIER),
24219 UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER),
24220 UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8),
24221 UL_BARRIER ("osh", "OSH", 0x3, ARM_EXT_BARRIER),
24222 UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER),
24223 UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8)
62b3e311
PB
24224};
24225
e797f7e0
MGD
24226#undef UL_BARRIER
24227
c19d1205
ZW
24228/* Table of ARM-format instructions. */
24229
24230/* Macros for gluing together operand strings. N.B. In all cases
24231 other than OPS0, the trailing OP_stop comes from default
24232 zero-initialization of the unspecified elements of the array. */
24233#define OPS0() { OP_stop, }
24234#define OPS1(a) { OP_##a, }
24235#define OPS2(a,b) { OP_##a,OP_##b, }
24236#define OPS3(a,b,c) { OP_##a,OP_##b,OP_##c, }
24237#define OPS4(a,b,c,d) { OP_##a,OP_##b,OP_##c,OP_##d, }
24238#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
24239#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
24240
5be8be5d
DG
24241/* These macros are similar to the OPSn, but do not prepend the OP_ prefix.
24242 This is useful when mixing operands for ARM and THUMB, i.e. using the
24243 MIX_ARM_THUMB_OPERANDS macro.
24244 In order to use these macros, prefix the number of operands with _
24245 e.g. _3. */
24246#define OPS_1(a) { a, }
24247#define OPS_2(a,b) { a,b, }
24248#define OPS_3(a,b,c) { a,b,c, }
24249#define OPS_4(a,b,c,d) { a,b,c,d, }
24250#define OPS_5(a,b,c,d,e) { a,b,c,d,e, }
24251#define OPS_6(a,b,c,d,e,f) { a,b,c,d,e,f, }
24252
c19d1205
ZW
24253/* These macros abstract out the exact format of the mnemonic table and
24254 save some repeated characters. */
24255
24256/* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix. */
24257#define TxCE(mnem, op, top, nops, ops, ae, te) \
21d799b5 24258 { mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
5ee91343 24259 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
24260
24261/* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
24262 a T_MNEM_xyz enumerator. */
24263#define TCE(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24264 TxCE (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 24265#define tCE(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24266 TxCE (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205
ZW
24267
24268/* Second most common sort of mnemonic: has a Thumb variant, takes a conditional
24269 infix after the third character. */
24270#define TxC3(mnem, op, top, nops, ops, ae, te) \
21d799b5 24271 { mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
5ee91343 24272 THUMB_VARIANT, do_##ae, do_##te, 0 }
088fa78e 24273#define TxC3w(mnem, op, top, nops, ops, ae, te) \
21d799b5 24274 { mnem, OPS##nops ops, OT_cinfix3_deprecated, 0x##op, top, ARM_VARIANT, \
5ee91343 24275 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 24276#define TC3(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24277 TxC3 (mnem, aop, 0x##top, nops, ops, ae, te)
088fa78e 24278#define TC3w(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24279 TxC3w (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 24280#define tC3(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24281 TxC3 (mnem, aop, T_MNEM##top, nops, ops, ae, te)
088fa78e 24282#define tC3w(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24283 TxC3w (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205 24284
c19d1205 24285/* Mnemonic that cannot be conditionalized. The ARM condition-code
dfa9f0d5
PB
24286 field is still 0xE. Many of the Thumb variants can be executed
24287 conditionally, so this is checked separately. */
c19d1205 24288#define TUE(mnem, op, top, nops, ops, ae, te) \
21d799b5 24289 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24290 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 24291
dd5181d5
KT
24292/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
24293 Used by mnemonics that have very minimal differences in the encoding for
24294 ARM and Thumb variants and can be handled in a common function. */
24295#define TUEc(mnem, op, top, nops, ops, en) \
24296 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24297 THUMB_VARIANT, do_##en, do_##en, 0 }
dd5181d5 24298
c19d1205
ZW
24299/* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
24300 condition code field. */
24301#define TUF(mnem, op, top, nops, ops, ae, te) \
21d799b5 24302 { mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24303 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
24304
24305/* ARM-only variants of all the above. */
6a86118a 24306#define CE(mnem, op, nops, ops, ae) \
5ee91343 24307 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24308
24309#define C3(mnem, op, nops, ops, ae) \
5ee91343 24310 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 24311
cf3cf39d
TP
24312/* Thumb-only variants of TCE and TUE. */
24313#define ToC(mnem, top, nops, ops, te) \
24314 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
5ee91343 24315 do_##te, 0 }
cf3cf39d
TP
24316
24317#define ToU(mnem, top, nops, ops, te) \
24318 { mnem, OPS##nops ops, OT_unconditional, 0x0, 0x##top, 0, THUMB_VARIANT, \
5ee91343 24319 NULL, do_##te, 0 }
cf3cf39d 24320
4389b29a
AV
24321/* T_MNEM_xyz enumerator variants of ToC. */
24322#define toC(mnem, top, nops, ops, te) \
24323 { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \
5ee91343 24324 do_##te, 0 }
4389b29a 24325
f6b2b12d
AV
24326/* T_MNEM_xyz enumerator variants of ToU. */
24327#define toU(mnem, top, nops, ops, te) \
24328 { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \
5ee91343 24329 NULL, do_##te, 0 }
f6b2b12d 24330
e3cb604e
PB
24331/* Legacy mnemonics that always have conditional infix after the third
24332 character. */
24333#define CL(mnem, op, nops, ops, ae) \
21d799b5 24334 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 24335 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
e3cb604e 24336
8f06b2d8
PB
24337/* Coprocessor instructions. Isomorphic between Arm and Thumb-2. */
24338#define cCE(mnem, op, nops, ops, ae) \
5ee91343 24339 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 24340
57785aa2
AV
24341/* mov instructions that are shared between coprocessor and MVE. */
24342#define mcCE(mnem, op, nops, ops, ae) \
24343 { #mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##ae, 0 }
24344
e3cb604e
PB
24345/* Legacy coprocessor instructions where conditional infix and conditional
24346 suffix are ambiguous. For consistency this includes all FPA instructions,
24347 not just the potentially ambiguous ones. */
24348#define cCL(mnem, op, nops, ops, ae) \
21d799b5 24349 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 24350 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
e3cb604e
PB
24351
24352/* Coprocessor, takes either a suffix or a position-3 infix
24353 (for an FPA corner case). */
24354#define C3E(mnem, op, nops, ops, ae) \
21d799b5 24355 { mnem, OPS##nops ops, OT_csuf_or_in3, \
5ee91343 24356 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 24357
6a86118a 24358#define xCM_(m1, m2, m3, op, nops, ops, ae) \
21d799b5
NC
24359 { m1 #m2 m3, OPS##nops ops, \
24360 sizeof (#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof (m1) - 1, \
5ee91343 24361 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24362
24363#define CM(m1, m2, op, nops, ops, ae) \
e07e6e58
NC
24364 xCM_ (m1, , m2, op, nops, ops, ae), \
24365 xCM_ (m1, eq, m2, op, nops, ops, ae), \
24366 xCM_ (m1, ne, m2, op, nops, ops, ae), \
24367 xCM_ (m1, cs, m2, op, nops, ops, ae), \
24368 xCM_ (m1, hs, m2, op, nops, ops, ae), \
24369 xCM_ (m1, cc, m2, op, nops, ops, ae), \
24370 xCM_ (m1, ul, m2, op, nops, ops, ae), \
24371 xCM_ (m1, lo, m2, op, nops, ops, ae), \
24372 xCM_ (m1, mi, m2, op, nops, ops, ae), \
24373 xCM_ (m1, pl, m2, op, nops, ops, ae), \
24374 xCM_ (m1, vs, m2, op, nops, ops, ae), \
24375 xCM_ (m1, vc, m2, op, nops, ops, ae), \
24376 xCM_ (m1, hi, m2, op, nops, ops, ae), \
24377 xCM_ (m1, ls, m2, op, nops, ops, ae), \
24378 xCM_ (m1, ge, m2, op, nops, ops, ae), \
24379 xCM_ (m1, lt, m2, op, nops, ops, ae), \
24380 xCM_ (m1, gt, m2, op, nops, ops, ae), \
24381 xCM_ (m1, le, m2, op, nops, ops, ae), \
24382 xCM_ (m1, al, m2, op, nops, ops, ae)
6a86118a
NC
24383
24384#define UE(mnem, op, nops, ops, ae) \
5ee91343 24385 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24386
24387#define UF(mnem, op, nops, ops, ae) \
5ee91343 24388 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 24389
5287ad62
JB
24390/* Neon data-processing. ARM versions are unconditional with cond=0xf.
24391 The Thumb and ARM variants are mostly the same (bits 0-23 and 24/28), so we
24392 use the same encoding function for each. */
24393#define NUF(mnem, op, nops, ops, enc) \
24394 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
5ee91343 24395 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
24396
24397/* Neon data processing, version which indirects through neon_enc_tab for
24398 the various overloaded versions of opcodes. */
24399#define nUF(mnem, op, nops, ops, enc) \
21d799b5 24400 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
5ee91343 24401 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
24402
24403/* Neon insn with conditional suffix for the ARM version, non-overloaded
24404 version. */
5ee91343 24405#define NCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
037e8744 24406 { #mnem, OPS##nops ops, tag, 0x##op, 0x##op, ARM_VARIANT, \
5ee91343 24407 THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 24408
037e8744 24409#define NCE(mnem, op, nops, ops, enc) \
5ee91343 24410 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
24411
24412#define NCEF(mnem, op, nops, ops, enc) \
5ee91343 24413 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
037e8744 24414
5287ad62 24415/* Neon insn with conditional suffix for the ARM version, overloaded types. */
5ee91343 24416#define nCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
21d799b5 24417 { #mnem, OPS##nops ops, tag, N_MNEM##op, N_MNEM##op, \
5ee91343 24418 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 24419
037e8744 24420#define nCE(mnem, op, nops, ops, enc) \
5ee91343 24421 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
24422
24423#define nCEF(mnem, op, nops, ops, enc) \
5ee91343
AV
24424 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
24425
24426/* */
24427#define mCEF(mnem, op, nops, ops, enc) \
a302e574 24428 { #mnem, OPS##nops ops, OT_csuffixF, M_MNEM##op, M_MNEM##op, \
5ee91343
AV
24429 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24430
24431
24432/* nCEF but for MVE predicated instructions. */
24433#define mnCEF(mnem, op, nops, ops, enc) \
24434 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
24435
24436/* nCE but for MVE predicated instructions. */
24437#define mnCE(mnem, op, nops, ops, enc) \
24438 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
037e8744 24439
5ee91343
AV
24440/* NUF but for potentially MVE predicated instructions. */
24441#define MNUF(mnem, op, nops, ops, enc) \
24442 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
24443 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24444
24445/* nUF but for potentially MVE predicated instructions. */
24446#define mnUF(mnem, op, nops, ops, enc) \
24447 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
24448 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24449
24450/* ToC but for potentially MVE predicated instructions. */
24451#define mToC(mnem, top, nops, ops, te) \
24452 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
24453 do_##te, 1 }
24454
24455/* NCE but for MVE predicated instructions. */
24456#define MNCE(mnem, op, nops, ops, enc) \
24457 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
24458
24459/* NCEF but for MVE predicated instructions. */
24460#define MNCEF(mnem, op, nops, ops, enc) \
24461 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
c19d1205
ZW
24462#define do_0 0
24463
c19d1205 24464static const struct asm_opcode insns[] =
bfae80f2 24465{
74db7efb
NC
24466#define ARM_VARIANT & arm_ext_v1 /* Core ARM Instructions. */
24467#define THUMB_VARIANT & arm_ext_v4t
21d799b5
NC
24468 tCE("and", 0000000, _and, 3, (RR, oRR, SH), arit, t_arit3c),
24469 tC3("ands", 0100000, _ands, 3, (RR, oRR, SH), arit, t_arit3c),
24470 tCE("eor", 0200000, _eor, 3, (RR, oRR, SH), arit, t_arit3c),
24471 tC3("eors", 0300000, _eors, 3, (RR, oRR, SH), arit, t_arit3c),
24472 tCE("sub", 0400000, _sub, 3, (RR, oRR, SH), arit, t_add_sub),
24473 tC3("subs", 0500000, _subs, 3, (RR, oRR, SH), arit, t_add_sub),
24474 tCE("add", 0800000, _add, 3, (RR, oRR, SHG), arit, t_add_sub),
24475 tC3("adds", 0900000, _adds, 3, (RR, oRR, SHG), arit, t_add_sub),
24476 tCE("adc", 0a00000, _adc, 3, (RR, oRR, SH), arit, t_arit3c),
24477 tC3("adcs", 0b00000, _adcs, 3, (RR, oRR, SH), arit, t_arit3c),
24478 tCE("sbc", 0c00000, _sbc, 3, (RR, oRR, SH), arit, t_arit3),
24479 tC3("sbcs", 0d00000, _sbcs, 3, (RR, oRR, SH), arit, t_arit3),
24480 tCE("orr", 1800000, _orr, 3, (RR, oRR, SH), arit, t_arit3c),
24481 tC3("orrs", 1900000, _orrs, 3, (RR, oRR, SH), arit, t_arit3c),
24482 tCE("bic", 1c00000, _bic, 3, (RR, oRR, SH), arit, t_arit3),
24483 tC3("bics", 1d00000, _bics, 3, (RR, oRR, SH), arit, t_arit3),
c19d1205
ZW
24484
24485 /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
24486 for setting PSR flag bits. They are obsolete in V6 and do not
24487 have Thumb equivalents. */
21d799b5
NC
24488 tCE("tst", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
24489 tC3w("tsts", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
24490 CL("tstp", 110f000, 2, (RR, SH), cmp),
24491 tCE("cmp", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
24492 tC3w("cmps", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
24493 CL("cmpp", 150f000, 2, (RR, SH), cmp),
24494 tCE("cmn", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
24495 tC3w("cmns", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
24496 CL("cmnp", 170f000, 2, (RR, SH), cmp),
24497
24498 tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
72d98d16 24499 tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
21d799b5
NC
24500 tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
24501 tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
24502
24503 tCE("ldr", 4100000, _ldr, 2, (RR, ADDRGLDR),ldst, t_ldst),
5be8be5d
DG
24504 tC3("ldrb", 4500000, _ldrb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
24505 tCE("str", 4000000, _str, _2, (MIX_ARM_THUMB_OPERANDS (OP_RR,
24506 OP_RRnpc),
24507 OP_ADDRGLDR),ldst, t_ldst),
24508 tC3("strb", 4400000, _strb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
21d799b5
NC
24509
24510 tCE("stm", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24511 tC3("stmia", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24512 tC3("stmea", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24513 tCE("ldm", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24514 tC3("ldmia", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24515 tC3("ldmfd", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24516
21d799b5
NC
24517 tCE("b", a000000, _b, 1, (EXPr), branch, t_branch),
24518 TCE("bl", b000000, f000f800, 1, (EXPr), bl, t_branch23),
bfae80f2 24519
c19d1205 24520 /* Pseudo ops. */
21d799b5 24521 tCE("adr", 28f0000, _adr, 2, (RR, EXP), adr, t_adr),
2fc8bdac 24522 C3(adrl, 28f0000, 2, (RR, EXP), adrl),
21d799b5 24523 tCE("nop", 1a00000, _nop, 1, (oI255c), nop, t_nop),
74db7efb 24524 tCE("udf", 7f000f0, _udf, 1, (oIffffb), bkpt, t_udf),
c19d1205
ZW
24525
24526 /* Thumb-compatibility pseudo ops. */
21d799b5
NC
24527 tCE("lsl", 1a00000, _lsl, 3, (RR, oRR, SH), shift, t_shift),
24528 tC3("lsls", 1b00000, _lsls, 3, (RR, oRR, SH), shift, t_shift),
24529 tCE("lsr", 1a00020, _lsr, 3, (RR, oRR, SH), shift, t_shift),
24530 tC3("lsrs", 1b00020, _lsrs, 3, (RR, oRR, SH), shift, t_shift),
24531 tCE("asr", 1a00040, _asr, 3, (RR, oRR, SH), shift, t_shift),
24532 tC3("asrs", 1b00040, _asrs, 3, (RR, oRR, SH), shift, t_shift),
24533 tCE("ror", 1a00060, _ror, 3, (RR, oRR, SH), shift, t_shift),
24534 tC3("rors", 1b00060, _rors, 3, (RR, oRR, SH), shift, t_shift),
24535 tCE("neg", 2600000, _neg, 2, (RR, RR), rd_rn, t_neg),
24536 tC3("negs", 2700000, _negs, 2, (RR, RR), rd_rn, t_neg),
24537 tCE("push", 92d0000, _push, 1, (REGLST), push_pop, t_push_pop),
24538 tCE("pop", 8bd0000, _pop, 1, (REGLST), push_pop, t_push_pop),
c19d1205 24539
16a4cf17 24540 /* These may simplify to neg. */
21d799b5
NC
24541 TCE("rsb", 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
24542 TC3("rsbs", 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
16a4cf17 24543
173205ca
TP
24544#undef THUMB_VARIANT
24545#define THUMB_VARIANT & arm_ext_os
24546
24547 TCE("swi", f000000, df00, 1, (EXPi), swi, t_swi),
24548 TCE("svc", f000000, df00, 1, (EXPi), swi, t_swi),
24549
c921be7d
NC
24550#undef THUMB_VARIANT
24551#define THUMB_VARIANT & arm_ext_v6
24552
21d799b5 24553 TCE("cpy", 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
c19d1205
ZW
24554
24555 /* V1 instructions with no Thumb analogue prior to V6T2. */
c921be7d
NC
24556#undef THUMB_VARIANT
24557#define THUMB_VARIANT & arm_ext_v6t2
24558
21d799b5
NC
24559 TCE("teq", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
24560 TC3w("teqs", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
24561 CL("teqp", 130f000, 2, (RR, SH), cmp),
c19d1205 24562
5be8be5d
DG
24563 TC3("ldrt", 4300000, f8500e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
24564 TC3("ldrbt", 4700000, f8100e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
24565 TC3("strt", 4200000, f8400e00, 2, (RR_npcsp, ADDR), ldstt, t_ldstt),
24566 TC3("strbt", 4600000, f8000e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
c19d1205 24567
21d799b5
NC
24568 TC3("stmdb", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24569 TC3("stmfd", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205 24570
21d799b5
NC
24571 TC3("ldmdb", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24572 TC3("ldmea", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205
ZW
24573
24574 /* V1 instructions with no Thumb analogue at all. */
21d799b5 24575 CE("rsc", 0e00000, 3, (RR, oRR, SH), arit),
c19d1205
ZW
24576 C3(rscs, 0f00000, 3, (RR, oRR, SH), arit),
24577
24578 C3(stmib, 9800000, 2, (RRw, REGLST), ldmstm),
24579 C3(stmfa, 9800000, 2, (RRw, REGLST), ldmstm),
24580 C3(stmda, 8000000, 2, (RRw, REGLST), ldmstm),
24581 C3(stmed, 8000000, 2, (RRw, REGLST), ldmstm),
24582 C3(ldmib, 9900000, 2, (RRw, REGLST), ldmstm),
24583 C3(ldmed, 9900000, 2, (RRw, REGLST), ldmstm),
24584 C3(ldmda, 8100000, 2, (RRw, REGLST), ldmstm),
24585 C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm),
24586
c921be7d
NC
24587#undef ARM_VARIANT
24588#define ARM_VARIANT & arm_ext_v2 /* ARM 2 - multiplies. */
24589#undef THUMB_VARIANT
24590#define THUMB_VARIANT & arm_ext_v4t
24591
21d799b5
NC
24592 tCE("mul", 0000090, _mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
24593 tC3("muls", 0100090, _muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
c19d1205 24594
c921be7d
NC
24595#undef THUMB_VARIANT
24596#define THUMB_VARIANT & arm_ext_v6t2
24597
21d799b5 24598 TCE("mla", 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
c19d1205
ZW
24599 C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
24600
24601 /* Generic coprocessor instructions. */
21d799b5
NC
24602 TCE("cdp", e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
24603 TCE("ldc", c100000, ec100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24604 TC3("ldcl", c500000, ec500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24605 TCE("stc", c000000, ec000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24606 TC3("stcl", c400000, ec400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24607 TCE("mcr", e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
db472d6f 24608 TCE("mrc", e100010, ee100010, 6, (RCP, I7b, APSR_RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 24609
c921be7d
NC
24610#undef ARM_VARIANT
24611#define ARM_VARIANT & arm_ext_v2s /* ARM 3 - swp instructions. */
24612
21d799b5 24613 CE("swp", 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
c19d1205
ZW
24614 C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
24615
c921be7d
NC
24616#undef ARM_VARIANT
24617#define ARM_VARIANT & arm_ext_v3 /* ARM 6 Status register instructions. */
24618#undef THUMB_VARIANT
24619#define THUMB_VARIANT & arm_ext_msr
24620
d2cd1205
JB
24621 TCE("mrs", 1000000, f3e08000, 2, (RRnpc, rPSR), mrs, t_mrs),
24622 TCE("msr", 120f000, f3808000, 2, (wPSR, RR_EXi), msr, t_msr),
c19d1205 24623
c921be7d
NC
24624#undef ARM_VARIANT
24625#define ARM_VARIANT & arm_ext_v3m /* ARM 7M long multiplies. */
24626#undef THUMB_VARIANT
24627#define THUMB_VARIANT & arm_ext_v6t2
24628
21d799b5
NC
24629 TCE("smull", 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24630 CM("smull","s", 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24631 TCE("umull", 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24632 CM("umull","s", 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24633 TCE("smlal", 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24634 CM("smlal","s", 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24635 TCE("umlal", 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24636 CM("umlal","s", 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
c19d1205 24637
c921be7d
NC
24638#undef ARM_VARIANT
24639#define ARM_VARIANT & arm_ext_v4 /* ARM Architecture 4. */
24640#undef THUMB_VARIANT
24641#define THUMB_VARIANT & arm_ext_v4t
24642
5be8be5d
DG
24643 tC3("ldrh", 01000b0, _ldrh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24644 tC3("strh", 00000b0, _strh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24645 tC3("ldrsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24646 tC3("ldrsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
56c0a61f
RE
24647 tC3("ldsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24648 tC3("ldsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
c19d1205 24649
c921be7d
NC
24650#undef ARM_VARIANT
24651#define ARM_VARIANT & arm_ext_v4t_5
24652
c19d1205
ZW
24653 /* ARM Architecture 4T. */
24654 /* Note: bx (and blx) are required on V5, even if the processor does
24655 not support Thumb. */
21d799b5 24656 TCE("bx", 12fff10, 4700, 1, (RR), bx, t_bx),
c19d1205 24657
c921be7d
NC
24658#undef ARM_VARIANT
24659#define ARM_VARIANT & arm_ext_v5 /* ARM Architecture 5T. */
24660#undef THUMB_VARIANT
24661#define THUMB_VARIANT & arm_ext_v5t
24662
c19d1205
ZW
24663 /* Note: blx has 2 variants; the .value coded here is for
24664 BLX(2). Only this variant has conditional execution. */
21d799b5
NC
24665 TCE("blx", 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
24666 TUE("bkpt", 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
c19d1205 24667
c921be7d
NC
24668#undef THUMB_VARIANT
24669#define THUMB_VARIANT & arm_ext_v6t2
24670
21d799b5
NC
24671 TCE("clz", 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
24672 TUF("ldc2", c100000, fc100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24673 TUF("ldc2l", c500000, fc500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24674 TUF("stc2", c000000, fc000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24675 TUF("stc2l", c400000, fc400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24676 TUF("cdp2", e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
24677 TUF("mcr2", e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
24678 TUF("mrc2", e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 24679
c921be7d 24680#undef ARM_VARIANT
74db7efb
NC
24681#define ARM_VARIANT & arm_ext_v5exp /* ARM Architecture 5TExP. */
24682#undef THUMB_VARIANT
24683#define THUMB_VARIANT & arm_ext_v5exp
c921be7d 24684
21d799b5
NC
24685 TCE("smlabb", 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24686 TCE("smlatb", 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24687 TCE("smlabt", 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24688 TCE("smlatt", 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 24689
21d799b5
NC
24690 TCE("smlawb", 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24691 TCE("smlawt", 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 24692
21d799b5
NC
24693 TCE("smlalbb", 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24694 TCE("smlaltb", 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24695 TCE("smlalbt", 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24696 TCE("smlaltt", 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
c19d1205 24697
21d799b5
NC
24698 TCE("smulbb", 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24699 TCE("smultb", 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24700 TCE("smulbt", 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24701 TCE("smultt", 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 24702
21d799b5
NC
24703 TCE("smulwb", 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24704 TCE("smulwt", 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 24705
03ee1b7f
NC
24706 TCE("qadd", 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24707 TCE("qdadd", 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24708 TCE("qsub", 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24709 TCE("qdsub", 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
c19d1205 24710
c921be7d 24711#undef ARM_VARIANT
74db7efb
NC
24712#define ARM_VARIANT & arm_ext_v5e /* ARM Architecture 5TE. */
24713#undef THUMB_VARIANT
24714#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 24715
21d799b5 24716 TUF("pld", 450f000, f810f000, 1, (ADDR), pld, t_pld),
5be8be5d
DG
24717 TC3("ldrd", 00000d0, e8500000, 3, (RRnpc_npcsp, oRRnpc_npcsp, ADDRGLDRS),
24718 ldrd, t_ldstd),
24719 TC3("strd", 00000f0, e8400000, 3, (RRnpc_npcsp, oRRnpc_npcsp,
24720 ADDRGLDRS), ldrd, t_ldstd),
c19d1205 24721
21d799b5
NC
24722 TCE("mcrr", c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
24723 TCE("mrrc", c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
c19d1205 24724
c921be7d
NC
24725#undef ARM_VARIANT
24726#define ARM_VARIANT & arm_ext_v5j /* ARM Architecture 5TEJ. */
24727
21d799b5 24728 TCE("bxj", 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
c19d1205 24729
c921be7d
NC
24730#undef ARM_VARIANT
24731#define ARM_VARIANT & arm_ext_v6 /* ARM V6. */
24732#undef THUMB_VARIANT
24733#define THUMB_VARIANT & arm_ext_v6
24734
21d799b5
NC
24735 TUF("cpsie", 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
24736 TUF("cpsid", 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
24737 tCE("rev", 6bf0f30, _rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24738 tCE("rev16", 6bf0fb0, _rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24739 tCE("revsh", 6ff0fb0, _revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24740 tCE("sxth", 6bf0070, _sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24741 tCE("uxth", 6ff0070, _uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24742 tCE("sxtb", 6af0070, _sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24743 tCE("uxtb", 6ef0070, _uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24744 TUF("setend", 1010000, b650, 1, (ENDI), setend, t_setend),
c19d1205 24745
c921be7d 24746#undef THUMB_VARIANT
ff8646ee 24747#define THUMB_VARIANT & arm_ext_v6t2_v8m
c921be7d 24748
5be8be5d
DG
24749 TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
24750 TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
24751 strex, t_strex),
ff8646ee
TP
24752#undef THUMB_VARIANT
24753#define THUMB_VARIANT & arm_ext_v6t2
24754
21d799b5
NC
24755 TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
24756 TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
62b3e311 24757
21d799b5
NC
24758 TCE("ssat", 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
24759 TCE("usat", 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
62b3e311 24760
9e3c6df6 24761/* ARM V6 not included in V7M. */
c921be7d
NC
24762#undef THUMB_VARIANT
24763#define THUMB_VARIANT & arm_ext_v6_notm
9e3c6df6 24764 TUF("rfeia", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6 24765 TUF("rfe", 8900a00, e990c000, 1, (RRw), rfe, rfe),
9e3c6df6
PB
24766 UF(rfeib, 9900a00, 1, (RRw), rfe),
24767 UF(rfeda, 8100a00, 1, (RRw), rfe),
24768 TUF("rfedb", 9100a00, e810c000, 1, (RRw), rfe, rfe),
24769 TUF("rfefd", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6
RE
24770 UF(rfefa, 8100a00, 1, (RRw), rfe),
24771 TUF("rfeea", 9100a00, e810c000, 1, (RRw), rfe, rfe),
24772 UF(rfeed, 9900a00, 1, (RRw), rfe),
9e3c6df6 24773 TUF("srsia", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
d709e4e6
RE
24774 TUF("srs", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
24775 TUF("srsea", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
9e3c6df6 24776 UF(srsib, 9c00500, 2, (oRRw, I31w), srs),
d709e4e6 24777 UF(srsfa, 9c00500, 2, (oRRw, I31w), srs),
9e3c6df6 24778 UF(srsda, 8400500, 2, (oRRw, I31w), srs),
d709e4e6 24779 UF(srsed, 8400500, 2, (oRRw, I31w), srs),
9e3c6df6 24780 TUF("srsdb", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
d709e4e6 24781 TUF("srsfd", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
941c9cad 24782 TUF("cps", 1020000, f3af8100, 1, (I31b), imm0, t_cps),
c921be7d 24783
9e3c6df6
PB
24784/* ARM V6 not included in V7M (eg. integer SIMD). */
24785#undef THUMB_VARIANT
24786#define THUMB_VARIANT & arm_ext_v6_dsp
21d799b5
NC
24787 TCE("pkhbt", 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
24788 TCE("pkhtb", 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
24789 TCE("qadd16", 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24790 TCE("qadd8", 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24791 TCE("qasx", 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24792 /* Old name for QASX. */
74db7efb 24793 TCE("qaddsubx",6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 24794 TCE("qsax", 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24795 /* Old name for QSAX. */
74db7efb 24796 TCE("qsubaddx",6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24797 TCE("qsub16", 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24798 TCE("qsub8", 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24799 TCE("sadd16", 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24800 TCE("sadd8", 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24801 TCE("sasx", 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24802 /* Old name for SASX. */
74db7efb 24803 TCE("saddsubx",6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24804 TCE("shadd16", 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24805 TCE("shadd8", 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24806 TCE("shasx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24807 /* Old name for SHASX. */
21d799b5 24808 TCE("shaddsubx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24809 TCE("shsax", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24810 /* Old name for SHSAX. */
21d799b5
NC
24811 TCE("shsubaddx", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24812 TCE("shsub16", 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24813 TCE("shsub8", 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24814 TCE("ssax", 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24815 /* Old name for SSAX. */
74db7efb 24816 TCE("ssubaddx",6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24817 TCE("ssub16", 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24818 TCE("ssub8", 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24819 TCE("uadd16", 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24820 TCE("uadd8", 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24821 TCE("uasx", 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24822 /* Old name for UASX. */
74db7efb 24823 TCE("uaddsubx",6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24824 TCE("uhadd16", 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24825 TCE("uhadd8", 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24826 TCE("uhasx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24827 /* Old name for UHASX. */
21d799b5
NC
24828 TCE("uhaddsubx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24829 TCE("uhsax", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24830 /* Old name for UHSAX. */
21d799b5
NC
24831 TCE("uhsubaddx", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24832 TCE("uhsub16", 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24833 TCE("uhsub8", 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24834 TCE("uqadd16", 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24835 TCE("uqadd8", 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24836 TCE("uqasx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24837 /* Old name for UQASX. */
21d799b5
NC
24838 TCE("uqaddsubx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24839 TCE("uqsax", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24840 /* Old name for UQSAX. */
21d799b5
NC
24841 TCE("uqsubaddx", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24842 TCE("uqsub16", 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24843 TCE("uqsub8", 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24844 TCE("usub16", 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24845 TCE("usax", 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24846 /* Old name for USAX. */
74db7efb 24847 TCE("usubaddx",6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 24848 TCE("usub8", 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24849 TCE("sxtah", 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24850 TCE("sxtab16", 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24851 TCE("sxtab", 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24852 TCE("sxtb16", 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24853 TCE("uxtah", 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24854 TCE("uxtab16", 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24855 TCE("uxtab", 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24856 TCE("uxtb16", 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24857 TCE("sel", 6800fb0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24858 TCE("smlad", 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24859 TCE("smladx", 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24860 TCE("smlald", 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24861 TCE("smlaldx", 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24862 TCE("smlsd", 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24863 TCE("smlsdx", 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24864 TCE("smlsld", 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24865 TCE("smlsldx", 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24866 TCE("smmla", 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24867 TCE("smmlar", 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24868 TCE("smmls", 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24869 TCE("smmlsr", 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24870 TCE("smmul", 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24871 TCE("smmulr", 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24872 TCE("smuad", 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24873 TCE("smuadx", 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24874 TCE("smusd", 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24875 TCE("smusdx", 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
21d799b5
NC
24876 TCE("ssat16", 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
24877 TCE("umaal", 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
24878 TCE("usad8", 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24879 TCE("usada8", 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24880 TCE("usat16", 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
c19d1205 24881
c921be7d 24882#undef ARM_VARIANT
55e8aae7 24883#define ARM_VARIANT & arm_ext_v6k_v6t2
c921be7d 24884#undef THUMB_VARIANT
55e8aae7 24885#define THUMB_VARIANT & arm_ext_v6k_v6t2
c921be7d 24886
21d799b5
NC
24887 tCE("yield", 320f001, _yield, 0, (), noargs, t_hint),
24888 tCE("wfe", 320f002, _wfe, 0, (), noargs, t_hint),
24889 tCE("wfi", 320f003, _wfi, 0, (), noargs, t_hint),
24890 tCE("sev", 320f004, _sev, 0, (), noargs, t_hint),
c19d1205 24891
c921be7d
NC
24892#undef THUMB_VARIANT
24893#define THUMB_VARIANT & arm_ext_v6_notm
5be8be5d
DG
24894 TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc_npcsp, oRRnpc_npcsp, RRnpcb),
24895 ldrexd, t_ldrexd),
24896 TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc_npcsp, RRnpc_npcsp, oRRnpc_npcsp,
24897 RRnpcb), strexd, t_strexd),
ebdca51a 24898
c921be7d 24899#undef THUMB_VARIANT
ff8646ee 24900#define THUMB_VARIANT & arm_ext_v6t2_v8m
5be8be5d
DG
24901 TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
24902 rd_rn, rd_rn),
24903 TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
24904 rd_rn, rd_rn),
24905 TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 24906 strex, t_strexbh),
5be8be5d 24907 TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 24908 strex, t_strexbh),
21d799b5 24909 TUF("clrex", 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
c19d1205 24910
c921be7d 24911#undef ARM_VARIANT
f4c65163 24912#define ARM_VARIANT & arm_ext_sec
74db7efb 24913#undef THUMB_VARIANT
f4c65163 24914#define THUMB_VARIANT & arm_ext_sec
c921be7d 24915
21d799b5 24916 TCE("smc", 1600070, f7f08000, 1, (EXPi), smc, t_smc),
c19d1205 24917
90ec0d68
MGD
24918#undef ARM_VARIANT
24919#define ARM_VARIANT & arm_ext_virt
24920#undef THUMB_VARIANT
24921#define THUMB_VARIANT & arm_ext_virt
24922
24923 TCE("hvc", 1400070, f7e08000, 1, (EXPi), hvc, t_hvc),
24924 TCE("eret", 160006e, f3de8f00, 0, (), noargs, noargs),
24925
ddfded2f
MW
24926#undef ARM_VARIANT
24927#define ARM_VARIANT & arm_ext_pan
24928#undef THUMB_VARIANT
24929#define THUMB_VARIANT & arm_ext_pan
24930
24931 TUF("setpan", 1100000, b610, 1, (I7), setpan, t_setpan),
24932
c921be7d 24933#undef ARM_VARIANT
74db7efb 24934#define ARM_VARIANT & arm_ext_v6t2
f4c65163
MGD
24935#undef THUMB_VARIANT
24936#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 24937
21d799b5
NC
24938 TCE("bfc", 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
24939 TCE("bfi", 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
24940 TCE("sbfx", 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
24941 TCE("ubfx", 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
c19d1205 24942
21d799b5 24943 TCE("mls", 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
21d799b5 24944 TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
c19d1205 24945
5be8be5d
DG
24946 TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24947 TC3("ldrsht", 03000f0, f9300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24948 TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24949 TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
c19d1205 24950
91d8b670
JG
24951#undef ARM_VARIANT
24952#define ARM_VARIANT & arm_ext_v3
24953#undef THUMB_VARIANT
24954#define THUMB_VARIANT & arm_ext_v6t2
24955
24956 TUE("csdb", 320f014, f3af8014, 0, (), noargs, t_csdb),
c597cc3d
SD
24957 TUF("ssbb", 57ff040, f3bf8f40, 0, (), noargs, t_csdb),
24958 TUF("pssbb", 57ff044, f3bf8f44, 0, (), noargs, t_csdb),
91d8b670
JG
24959
24960#undef ARM_VARIANT
24961#define ARM_VARIANT & arm_ext_v6t2
ff8646ee
TP
24962#undef THUMB_VARIANT
24963#define THUMB_VARIANT & arm_ext_v6t2_v8m
24964 TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
24965 TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
24966
bf3eeda7 24967 /* Thumb-only instructions. */
74db7efb 24968#undef ARM_VARIANT
bf3eeda7
NS
24969#define ARM_VARIANT NULL
24970 TUE("cbnz", 0, b900, 2, (RR, EXP), 0, t_cbz),
24971 TUE("cbz", 0, b100, 2, (RR, EXP), 0, t_cbz),
c921be7d
NC
24972
24973 /* ARM does not really have an IT instruction, so always allow it.
24974 The opcode is copied from Thumb in order to allow warnings in
24975 -mimplicit-it=[never | arm] modes. */
24976#undef ARM_VARIANT
24977#define ARM_VARIANT & arm_ext_v1
ff8646ee
TP
24978#undef THUMB_VARIANT
24979#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 24980
21d799b5
NC
24981 TUE("it", bf08, bf08, 1, (COND), it, t_it),
24982 TUE("itt", bf0c, bf0c, 1, (COND), it, t_it),
24983 TUE("ite", bf04, bf04, 1, (COND), it, t_it),
24984 TUE("ittt", bf0e, bf0e, 1, (COND), it, t_it),
24985 TUE("itet", bf06, bf06, 1, (COND), it, t_it),
24986 TUE("itte", bf0a, bf0a, 1, (COND), it, t_it),
24987 TUE("itee", bf02, bf02, 1, (COND), it, t_it),
24988 TUE("itttt", bf0f, bf0f, 1, (COND), it, t_it),
24989 TUE("itett", bf07, bf07, 1, (COND), it, t_it),
24990 TUE("ittet", bf0b, bf0b, 1, (COND), it, t_it),
24991 TUE("iteet", bf03, bf03, 1, (COND), it, t_it),
24992 TUE("ittte", bf0d, bf0d, 1, (COND), it, t_it),
24993 TUE("itete", bf05, bf05, 1, (COND), it, t_it),
24994 TUE("ittee", bf09, bf09, 1, (COND), it, t_it),
24995 TUE("iteee", bf01, bf01, 1, (COND), it, t_it),
1c444d06 24996 /* ARM/Thumb-2 instructions with no Thumb-1 equivalent. */
21d799b5
NC
24997 TC3("rrx", 01a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rrx),
24998 TC3("rrxs", 01b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rrx),
c19d1205 24999
92e90b6e 25000 /* Thumb2 only instructions. */
c921be7d
NC
25001#undef ARM_VARIANT
25002#define ARM_VARIANT NULL
92e90b6e 25003
21d799b5
NC
25004 TCE("addw", 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
25005 TCE("subw", 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
25006 TCE("orn", 0, ea600000, 3, (RR, oRR, SH), 0, t_orn),
25007 TCE("orns", 0, ea700000, 3, (RR, oRR, SH), 0, t_orn),
25008 TCE("tbb", 0, e8d0f000, 1, (TB), 0, t_tb),
25009 TCE("tbh", 0, e8d0f010, 1, (TB), 0, t_tb),
92e90b6e 25010
eea54501
MGD
25011 /* Hardware division instructions. */
25012#undef ARM_VARIANT
25013#define ARM_VARIANT & arm_ext_adiv
c921be7d
NC
25014#undef THUMB_VARIANT
25015#define THUMB_VARIANT & arm_ext_div
25016
eea54501
MGD
25017 TCE("sdiv", 710f010, fb90f0f0, 3, (RR, oRR, RR), div, t_div),
25018 TCE("udiv", 730f010, fbb0f0f0, 3, (RR, oRR, RR), div, t_div),
62b3e311 25019
7e806470 25020 /* ARM V6M/V7 instructions. */
c921be7d
NC
25021#undef ARM_VARIANT
25022#define ARM_VARIANT & arm_ext_barrier
25023#undef THUMB_VARIANT
25024#define THUMB_VARIANT & arm_ext_barrier
25025
ccb84d65
JB
25026 TUF("dmb", 57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier, barrier),
25027 TUF("dsb", 57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier, barrier),
25028 TUF("isb", 57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier, barrier),
7e806470 25029
62b3e311 25030 /* ARM V7 instructions. */
c921be7d
NC
25031#undef ARM_VARIANT
25032#define ARM_VARIANT & arm_ext_v7
25033#undef THUMB_VARIANT
25034#define THUMB_VARIANT & arm_ext_v7
25035
21d799b5
NC
25036 TUF("pli", 450f000, f910f000, 1, (ADDR), pli, t_pld),
25037 TCE("dbg", 320f0f0, f3af80f0, 1, (I15), dbg, t_dbg),
62b3e311 25038
74db7efb 25039#undef ARM_VARIANT
60e5ef9f 25040#define ARM_VARIANT & arm_ext_mp
74db7efb 25041#undef THUMB_VARIANT
60e5ef9f
MGD
25042#define THUMB_VARIANT & arm_ext_mp
25043
25044 TUF("pldw", 410f000, f830f000, 1, (ADDR), pld, t_pld),
25045
53c4b28b
MGD
25046 /* AArchv8 instructions. */
25047#undef ARM_VARIANT
25048#define ARM_VARIANT & arm_ext_v8
4ed7ed8d
TP
25049
25050/* Instructions shared between armv8-a and armv8-m. */
53c4b28b 25051#undef THUMB_VARIANT
4ed7ed8d 25052#define THUMB_VARIANT & arm_ext_atomics
53c4b28b 25053
4ed7ed8d
TP
25054 TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25055 TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25056 TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25057 TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
25058 TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
25059 TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
4b8c8c02 25060 TCE("ldaex", 1900e9f, e8d00fef, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
4b8c8c02
RE
25061 TCE("ldaexb", 1d00e9f, e8d00fcf, 2, (RRnpc,RRnpcb), rd_rn, rd_rn),
25062 TCE("ldaexh", 1f00e9f, e8d00fdf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25063 TCE("stlex", 1800e90, e8c00fe0, 3, (RRnpc, RRnpc, RRnpcb),
25064 stlex, t_stlex),
4b8c8c02
RE
25065 TCE("stlexb", 1c00e90, e8c00fc0, 3, (RRnpc, RRnpc, RRnpcb),
25066 stlex, t_stlex),
25067 TCE("stlexh", 1e00e90, e8c00fd0, 3, (RRnpc, RRnpc, RRnpcb),
25068 stlex, t_stlex),
4ed7ed8d
TP
25069#undef THUMB_VARIANT
25070#define THUMB_VARIANT & arm_ext_v8
53c4b28b 25071
4ed7ed8d 25072 tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
4ed7ed8d
TP
25073 TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
25074 ldrexd, t_ldrexd),
25075 TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
25076 strexd, t_strexd),
26417f19
AC
25077#undef THUMB_VARIANT
25078#define THUMB_VARIANT & arm_ext_v8r
25079#undef ARM_VARIANT
25080#define ARM_VARIANT & arm_ext_v8r
25081
25082/* ARMv8-R instructions. */
25083 TUF("dfb", 57ff04c, f3bf8f4c, 0, (), noargs, noargs),
f7dd2fb2
TC
25084
25085/* Defined in V8 but is in undefined encoding space for earlier
25086 architectures. However earlier architectures are required to treat
25087 this instuction as a semihosting trap as well. Hence while not explicitly
25088 defined as such, it is in fact correct to define the instruction for all
25089 architectures. */
25090#undef THUMB_VARIANT
25091#define THUMB_VARIANT & arm_ext_v1
25092#undef ARM_VARIANT
25093#define ARM_VARIANT & arm_ext_v1
25094 TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
25095
8884b720 25096 /* ARMv8 T32 only. */
74db7efb 25097#undef ARM_VARIANT
b79f7053
MGD
25098#define ARM_VARIANT NULL
25099 TUF("dcps1", 0, f78f8001, 0, (), noargs, noargs),
25100 TUF("dcps2", 0, f78f8002, 0, (), noargs, noargs),
25101 TUF("dcps3", 0, f78f8003, 0, (), noargs, noargs),
25102
33399f07
MGD
25103 /* FP for ARMv8. */
25104#undef ARM_VARIANT
a715796b 25105#define ARM_VARIANT & fpu_vfp_ext_armv8xd
33399f07 25106#undef THUMB_VARIANT
a715796b 25107#define THUMB_VARIANT & fpu_vfp_ext_armv8xd
33399f07
MGD
25108
25109 nUF(vseleq, _vseleq, 3, (RVSD, RVSD, RVSD), vsel),
25110 nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD), vsel),
25111 nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD), vsel),
25112 nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD), vsel),
30bdf752 25113 nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ), vrintr),
a710b305
AV
25114 mnCE(vrintz, _vrintr, 2, (RNSDQMQ, oRNSDQMQ), vrintz),
25115 mnCE(vrintx, _vrintr, 2, (RNSDQMQ, oRNSDQMQ), vrintx),
25116 mnUF(vrinta, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrinta),
25117 mnUF(vrintn, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintn),
25118 mnUF(vrintp, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintp),
25119 mnUF(vrintm, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintm),
33399f07 25120
91ff7894
MGD
25121 /* Crypto v1 extensions. */
25122#undef ARM_VARIANT
25123#define ARM_VARIANT & fpu_crypto_ext_armv8
25124#undef THUMB_VARIANT
25125#define THUMB_VARIANT & fpu_crypto_ext_armv8
25126
25127 nUF(aese, _aes, 2, (RNQ, RNQ), aese),
25128 nUF(aesd, _aes, 2, (RNQ, RNQ), aesd),
25129 nUF(aesmc, _aes, 2, (RNQ, RNQ), aesmc),
25130 nUF(aesimc, _aes, 2, (RNQ, RNQ), aesimc),
48adcd8e
MGD
25131 nUF(sha1c, _sha3op, 3, (RNQ, RNQ, RNQ), sha1c),
25132 nUF(sha1p, _sha3op, 3, (RNQ, RNQ, RNQ), sha1p),
25133 nUF(sha1m, _sha3op, 3, (RNQ, RNQ, RNQ), sha1m),
25134 nUF(sha1su0, _sha3op, 3, (RNQ, RNQ, RNQ), sha1su0),
25135 nUF(sha256h, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h),
25136 nUF(sha256h2, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h2),
25137 nUF(sha256su1, _sha3op, 3, (RNQ, RNQ, RNQ), sha256su1),
3c9017d2
MGD
25138 nUF(sha1h, _sha1h, 2, (RNQ, RNQ), sha1h),
25139 nUF(sha1su1, _sha2op, 2, (RNQ, RNQ), sha1su1),
25140 nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
91ff7894 25141
dd5181d5 25142#undef ARM_VARIANT
8b301fbb 25143#define ARM_VARIANT & arm_ext_crc
dd5181d5 25144#undef THUMB_VARIANT
8b301fbb 25145#define THUMB_VARIANT & arm_ext_crc
dd5181d5
KT
25146 TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
25147 TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
25148 TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
25149 TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
25150 TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
25151 TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
25152
105bde57
MW
25153 /* ARMv8.2 RAS extension. */
25154#undef ARM_VARIANT
4d1464f2 25155#define ARM_VARIANT & arm_ext_ras
105bde57 25156#undef THUMB_VARIANT
4d1464f2 25157#define THUMB_VARIANT & arm_ext_ras
105bde57
MW
25158 TUE ("esb", 320f010, f3af8010, 0, (), noargs, noargs),
25159
49e8a725
SN
25160#undef ARM_VARIANT
25161#define ARM_VARIANT & arm_ext_v8_3
25162#undef THUMB_VARIANT
25163#define THUMB_VARIANT & arm_ext_v8_3
25164 NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
25165
c604a79a
JW
25166#undef ARM_VARIANT
25167#define ARM_VARIANT & fpu_neon_ext_dotprod
25168#undef THUMB_VARIANT
25169#define THUMB_VARIANT & fpu_neon_ext_dotprod
25170 NUF (vsdot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_s),
25171 NUF (vudot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_u),
25172
c921be7d
NC
25173#undef ARM_VARIANT
25174#define ARM_VARIANT & fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
53c4b28b
MGD
25175#undef THUMB_VARIANT
25176#define THUMB_VARIANT NULL
c921be7d 25177
21d799b5
NC
25178 cCE("wfs", e200110, 1, (RR), rd),
25179 cCE("rfs", e300110, 1, (RR), rd),
25180 cCE("wfc", e400110, 1, (RR), rd),
25181 cCE("rfc", e500110, 1, (RR), rd),
25182
25183 cCL("ldfs", c100100, 2, (RF, ADDRGLDC), rd_cpaddr),
25184 cCL("ldfd", c108100, 2, (RF, ADDRGLDC), rd_cpaddr),
25185 cCL("ldfe", c500100, 2, (RF, ADDRGLDC), rd_cpaddr),
25186 cCL("ldfp", c508100, 2, (RF, ADDRGLDC), rd_cpaddr),
25187
25188 cCL("stfs", c000100, 2, (RF, ADDRGLDC), rd_cpaddr),
25189 cCL("stfd", c008100, 2, (RF, ADDRGLDC), rd_cpaddr),
25190 cCL("stfe", c400100, 2, (RF, ADDRGLDC), rd_cpaddr),
25191 cCL("stfp", c408100, 2, (RF, ADDRGLDC), rd_cpaddr),
25192
25193 cCL("mvfs", e008100, 2, (RF, RF_IF), rd_rm),
25194 cCL("mvfsp", e008120, 2, (RF, RF_IF), rd_rm),
25195 cCL("mvfsm", e008140, 2, (RF, RF_IF), rd_rm),
25196 cCL("mvfsz", e008160, 2, (RF, RF_IF), rd_rm),
25197 cCL("mvfd", e008180, 2, (RF, RF_IF), rd_rm),
25198 cCL("mvfdp", e0081a0, 2, (RF, RF_IF), rd_rm),
25199 cCL("mvfdm", e0081c0, 2, (RF, RF_IF), rd_rm),
25200 cCL("mvfdz", e0081e0, 2, (RF, RF_IF), rd_rm),
25201 cCL("mvfe", e088100, 2, (RF, RF_IF), rd_rm),
25202 cCL("mvfep", e088120, 2, (RF, RF_IF), rd_rm),
25203 cCL("mvfem", e088140, 2, (RF, RF_IF), rd_rm),
25204 cCL("mvfez", e088160, 2, (RF, RF_IF), rd_rm),
25205
25206 cCL("mnfs", e108100, 2, (RF, RF_IF), rd_rm),
25207 cCL("mnfsp", e108120, 2, (RF, RF_IF), rd_rm),
25208 cCL("mnfsm", e108140, 2, (RF, RF_IF), rd_rm),
25209 cCL("mnfsz", e108160, 2, (RF, RF_IF), rd_rm),
25210 cCL("mnfd", e108180, 2, (RF, RF_IF), rd_rm),
25211 cCL("mnfdp", e1081a0, 2, (RF, RF_IF), rd_rm),
25212 cCL("mnfdm", e1081c0, 2, (RF, RF_IF), rd_rm),
25213 cCL("mnfdz", e1081e0, 2, (RF, RF_IF), rd_rm),
25214 cCL("mnfe", e188100, 2, (RF, RF_IF), rd_rm),
25215 cCL("mnfep", e188120, 2, (RF, RF_IF), rd_rm),
25216 cCL("mnfem", e188140, 2, (RF, RF_IF), rd_rm),
25217 cCL("mnfez", e188160, 2, (RF, RF_IF), rd_rm),
25218
25219 cCL("abss", e208100, 2, (RF, RF_IF), rd_rm),
25220 cCL("abssp", e208120, 2, (RF, RF_IF), rd_rm),
25221 cCL("abssm", e208140, 2, (RF, RF_IF), rd_rm),
25222 cCL("abssz", e208160, 2, (RF, RF_IF), rd_rm),
25223 cCL("absd", e208180, 2, (RF, RF_IF), rd_rm),
25224 cCL("absdp", e2081a0, 2, (RF, RF_IF), rd_rm),
25225 cCL("absdm", e2081c0, 2, (RF, RF_IF), rd_rm),
25226 cCL("absdz", e2081e0, 2, (RF, RF_IF), rd_rm),
25227 cCL("abse", e288100, 2, (RF, RF_IF), rd_rm),
25228 cCL("absep", e288120, 2, (RF, RF_IF), rd_rm),
25229 cCL("absem", e288140, 2, (RF, RF_IF), rd_rm),
25230 cCL("absez", e288160, 2, (RF, RF_IF), rd_rm),
25231
25232 cCL("rnds", e308100, 2, (RF, RF_IF), rd_rm),
25233 cCL("rndsp", e308120, 2, (RF, RF_IF), rd_rm),
25234 cCL("rndsm", e308140, 2, (RF, RF_IF), rd_rm),
25235 cCL("rndsz", e308160, 2, (RF, RF_IF), rd_rm),
25236 cCL("rndd", e308180, 2, (RF, RF_IF), rd_rm),
25237 cCL("rnddp", e3081a0, 2, (RF, RF_IF), rd_rm),
25238 cCL("rnddm", e3081c0, 2, (RF, RF_IF), rd_rm),
25239 cCL("rnddz", e3081e0, 2, (RF, RF_IF), rd_rm),
25240 cCL("rnde", e388100, 2, (RF, RF_IF), rd_rm),
25241 cCL("rndep", e388120, 2, (RF, RF_IF), rd_rm),
25242 cCL("rndem", e388140, 2, (RF, RF_IF), rd_rm),
25243 cCL("rndez", e388160, 2, (RF, RF_IF), rd_rm),
25244
25245 cCL("sqts", e408100, 2, (RF, RF_IF), rd_rm),
25246 cCL("sqtsp", e408120, 2, (RF, RF_IF), rd_rm),
25247 cCL("sqtsm", e408140, 2, (RF, RF_IF), rd_rm),
25248 cCL("sqtsz", e408160, 2, (RF, RF_IF), rd_rm),
25249 cCL("sqtd", e408180, 2, (RF, RF_IF), rd_rm),
25250 cCL("sqtdp", e4081a0, 2, (RF, RF_IF), rd_rm),
25251 cCL("sqtdm", e4081c0, 2, (RF, RF_IF), rd_rm),
25252 cCL("sqtdz", e4081e0, 2, (RF, RF_IF), rd_rm),
25253 cCL("sqte", e488100, 2, (RF, RF_IF), rd_rm),
25254 cCL("sqtep", e488120, 2, (RF, RF_IF), rd_rm),
25255 cCL("sqtem", e488140, 2, (RF, RF_IF), rd_rm),
25256 cCL("sqtez", e488160, 2, (RF, RF_IF), rd_rm),
25257
25258 cCL("logs", e508100, 2, (RF, RF_IF), rd_rm),
25259 cCL("logsp", e508120, 2, (RF, RF_IF), rd_rm),
25260 cCL("logsm", e508140, 2, (RF, RF_IF), rd_rm),
25261 cCL("logsz", e508160, 2, (RF, RF_IF), rd_rm),
25262 cCL("logd", e508180, 2, (RF, RF_IF), rd_rm),
25263 cCL("logdp", e5081a0, 2, (RF, RF_IF), rd_rm),
25264 cCL("logdm", e5081c0, 2, (RF, RF_IF), rd_rm),
25265 cCL("logdz", e5081e0, 2, (RF, RF_IF), rd_rm),
25266 cCL("loge", e588100, 2, (RF, RF_IF), rd_rm),
25267 cCL("logep", e588120, 2, (RF, RF_IF), rd_rm),
25268 cCL("logem", e588140, 2, (RF, RF_IF), rd_rm),
25269 cCL("logez", e588160, 2, (RF, RF_IF), rd_rm),
25270
25271 cCL("lgns", e608100, 2, (RF, RF_IF), rd_rm),
25272 cCL("lgnsp", e608120, 2, (RF, RF_IF), rd_rm),
25273 cCL("lgnsm", e608140, 2, (RF, RF_IF), rd_rm),
25274 cCL("lgnsz", e608160, 2, (RF, RF_IF), rd_rm),
25275 cCL("lgnd", e608180, 2, (RF, RF_IF), rd_rm),
25276 cCL("lgndp", e6081a0, 2, (RF, RF_IF), rd_rm),
25277 cCL("lgndm", e6081c0, 2, (RF, RF_IF), rd_rm),
25278 cCL("lgndz", e6081e0, 2, (RF, RF_IF), rd_rm),
25279 cCL("lgne", e688100, 2, (RF, RF_IF), rd_rm),
25280 cCL("lgnep", e688120, 2, (RF, RF_IF), rd_rm),
25281 cCL("lgnem", e688140, 2, (RF, RF_IF), rd_rm),
25282 cCL("lgnez", e688160, 2, (RF, RF_IF), rd_rm),
25283
25284 cCL("exps", e708100, 2, (RF, RF_IF), rd_rm),
25285 cCL("expsp", e708120, 2, (RF, RF_IF), rd_rm),
25286 cCL("expsm", e708140, 2, (RF, RF_IF), rd_rm),
25287 cCL("expsz", e708160, 2, (RF, RF_IF), rd_rm),
25288 cCL("expd", e708180, 2, (RF, RF_IF), rd_rm),
25289 cCL("expdp", e7081a0, 2, (RF, RF_IF), rd_rm),
25290 cCL("expdm", e7081c0, 2, (RF, RF_IF), rd_rm),
25291 cCL("expdz", e7081e0, 2, (RF, RF_IF), rd_rm),
25292 cCL("expe", e788100, 2, (RF, RF_IF), rd_rm),
25293 cCL("expep", e788120, 2, (RF, RF_IF), rd_rm),
25294 cCL("expem", e788140, 2, (RF, RF_IF), rd_rm),
25295 cCL("expdz", e788160, 2, (RF, RF_IF), rd_rm),
25296
25297 cCL("sins", e808100, 2, (RF, RF_IF), rd_rm),
25298 cCL("sinsp", e808120, 2, (RF, RF_IF), rd_rm),
25299 cCL("sinsm", e808140, 2, (RF, RF_IF), rd_rm),
25300 cCL("sinsz", e808160, 2, (RF, RF_IF), rd_rm),
25301 cCL("sind", e808180, 2, (RF, RF_IF), rd_rm),
25302 cCL("sindp", e8081a0, 2, (RF, RF_IF), rd_rm),
25303 cCL("sindm", e8081c0, 2, (RF, RF_IF), rd_rm),
25304 cCL("sindz", e8081e0, 2, (RF, RF_IF), rd_rm),
25305 cCL("sine", e888100, 2, (RF, RF_IF), rd_rm),
25306 cCL("sinep", e888120, 2, (RF, RF_IF), rd_rm),
25307 cCL("sinem", e888140, 2, (RF, RF_IF), rd_rm),
25308 cCL("sinez", e888160, 2, (RF, RF_IF), rd_rm),
25309
25310 cCL("coss", e908100, 2, (RF, RF_IF), rd_rm),
25311 cCL("cossp", e908120, 2, (RF, RF_IF), rd_rm),
25312 cCL("cossm", e908140, 2, (RF, RF_IF), rd_rm),
25313 cCL("cossz", e908160, 2, (RF, RF_IF), rd_rm),
25314 cCL("cosd", e908180, 2, (RF, RF_IF), rd_rm),
25315 cCL("cosdp", e9081a0, 2, (RF, RF_IF), rd_rm),
25316 cCL("cosdm", e9081c0, 2, (RF, RF_IF), rd_rm),
25317 cCL("cosdz", e9081e0, 2, (RF, RF_IF), rd_rm),
25318 cCL("cose", e988100, 2, (RF, RF_IF), rd_rm),
25319 cCL("cosep", e988120, 2, (RF, RF_IF), rd_rm),
25320 cCL("cosem", e988140, 2, (RF, RF_IF), rd_rm),
25321 cCL("cosez", e988160, 2, (RF, RF_IF), rd_rm),
25322
25323 cCL("tans", ea08100, 2, (RF, RF_IF), rd_rm),
25324 cCL("tansp", ea08120, 2, (RF, RF_IF), rd_rm),
25325 cCL("tansm", ea08140, 2, (RF, RF_IF), rd_rm),
25326 cCL("tansz", ea08160, 2, (RF, RF_IF), rd_rm),
25327 cCL("tand", ea08180, 2, (RF, RF_IF), rd_rm),
25328 cCL("tandp", ea081a0, 2, (RF, RF_IF), rd_rm),
25329 cCL("tandm", ea081c0, 2, (RF, RF_IF), rd_rm),
25330 cCL("tandz", ea081e0, 2, (RF, RF_IF), rd_rm),
25331 cCL("tane", ea88100, 2, (RF, RF_IF), rd_rm),
25332 cCL("tanep", ea88120, 2, (RF, RF_IF), rd_rm),
25333 cCL("tanem", ea88140, 2, (RF, RF_IF), rd_rm),
25334 cCL("tanez", ea88160, 2, (RF, RF_IF), rd_rm),
25335
25336 cCL("asns", eb08100, 2, (RF, RF_IF), rd_rm),
25337 cCL("asnsp", eb08120, 2, (RF, RF_IF), rd_rm),
25338 cCL("asnsm", eb08140, 2, (RF, RF_IF), rd_rm),
25339 cCL("asnsz", eb08160, 2, (RF, RF_IF), rd_rm),
25340 cCL("asnd", eb08180, 2, (RF, RF_IF), rd_rm),
25341 cCL("asndp", eb081a0, 2, (RF, RF_IF), rd_rm),
25342 cCL("asndm", eb081c0, 2, (RF, RF_IF), rd_rm),
25343 cCL("asndz", eb081e0, 2, (RF, RF_IF), rd_rm),
25344 cCL("asne", eb88100, 2, (RF, RF_IF), rd_rm),
25345 cCL("asnep", eb88120, 2, (RF, RF_IF), rd_rm),
25346 cCL("asnem", eb88140, 2, (RF, RF_IF), rd_rm),
25347 cCL("asnez", eb88160, 2, (RF, RF_IF), rd_rm),
25348
25349 cCL("acss", ec08100, 2, (RF, RF_IF), rd_rm),
25350 cCL("acssp", ec08120, 2, (RF, RF_IF), rd_rm),
25351 cCL("acssm", ec08140, 2, (RF, RF_IF), rd_rm),
25352 cCL("acssz", ec08160, 2, (RF, RF_IF), rd_rm),
25353 cCL("acsd", ec08180, 2, (RF, RF_IF), rd_rm),
25354 cCL("acsdp", ec081a0, 2, (RF, RF_IF), rd_rm),
25355 cCL("acsdm", ec081c0, 2, (RF, RF_IF), rd_rm),
25356 cCL("acsdz", ec081e0, 2, (RF, RF_IF), rd_rm),
25357 cCL("acse", ec88100, 2, (RF, RF_IF), rd_rm),
25358 cCL("acsep", ec88120, 2, (RF, RF_IF), rd_rm),
25359 cCL("acsem", ec88140, 2, (RF, RF_IF), rd_rm),
25360 cCL("acsez", ec88160, 2, (RF, RF_IF), rd_rm),
25361
25362 cCL("atns", ed08100, 2, (RF, RF_IF), rd_rm),
25363 cCL("atnsp", ed08120, 2, (RF, RF_IF), rd_rm),
25364 cCL("atnsm", ed08140, 2, (RF, RF_IF), rd_rm),
25365 cCL("atnsz", ed08160, 2, (RF, RF_IF), rd_rm),
25366 cCL("atnd", ed08180, 2, (RF, RF_IF), rd_rm),
25367 cCL("atndp", ed081a0, 2, (RF, RF_IF), rd_rm),
25368 cCL("atndm", ed081c0, 2, (RF, RF_IF), rd_rm),
25369 cCL("atndz", ed081e0, 2, (RF, RF_IF), rd_rm),
25370 cCL("atne", ed88100, 2, (RF, RF_IF), rd_rm),
25371 cCL("atnep", ed88120, 2, (RF, RF_IF), rd_rm),
25372 cCL("atnem", ed88140, 2, (RF, RF_IF), rd_rm),
25373 cCL("atnez", ed88160, 2, (RF, RF_IF), rd_rm),
25374
25375 cCL("urds", ee08100, 2, (RF, RF_IF), rd_rm),
25376 cCL("urdsp", ee08120, 2, (RF, RF_IF), rd_rm),
25377 cCL("urdsm", ee08140, 2, (RF, RF_IF), rd_rm),
25378 cCL("urdsz", ee08160, 2, (RF, RF_IF), rd_rm),
25379 cCL("urdd", ee08180, 2, (RF, RF_IF), rd_rm),
25380 cCL("urddp", ee081a0, 2, (RF, RF_IF), rd_rm),
25381 cCL("urddm", ee081c0, 2, (RF, RF_IF), rd_rm),
25382 cCL("urddz", ee081e0, 2, (RF, RF_IF), rd_rm),
25383 cCL("urde", ee88100, 2, (RF, RF_IF), rd_rm),
25384 cCL("urdep", ee88120, 2, (RF, RF_IF), rd_rm),
25385 cCL("urdem", ee88140, 2, (RF, RF_IF), rd_rm),
25386 cCL("urdez", ee88160, 2, (RF, RF_IF), rd_rm),
25387
25388 cCL("nrms", ef08100, 2, (RF, RF_IF), rd_rm),
25389 cCL("nrmsp", ef08120, 2, (RF, RF_IF), rd_rm),
25390 cCL("nrmsm", ef08140, 2, (RF, RF_IF), rd_rm),
25391 cCL("nrmsz", ef08160, 2, (RF, RF_IF), rd_rm),
25392 cCL("nrmd", ef08180, 2, (RF, RF_IF), rd_rm),
25393 cCL("nrmdp", ef081a0, 2, (RF, RF_IF), rd_rm),
25394 cCL("nrmdm", ef081c0, 2, (RF, RF_IF), rd_rm),
25395 cCL("nrmdz", ef081e0, 2, (RF, RF_IF), rd_rm),
25396 cCL("nrme", ef88100, 2, (RF, RF_IF), rd_rm),
25397 cCL("nrmep", ef88120, 2, (RF, RF_IF), rd_rm),
25398 cCL("nrmem", ef88140, 2, (RF, RF_IF), rd_rm),
25399 cCL("nrmez", ef88160, 2, (RF, RF_IF), rd_rm),
25400
25401 cCL("adfs", e000100, 3, (RF, RF, RF_IF), rd_rn_rm),
25402 cCL("adfsp", e000120, 3, (RF, RF, RF_IF), rd_rn_rm),
25403 cCL("adfsm", e000140, 3, (RF, RF, RF_IF), rd_rn_rm),
25404 cCL("adfsz", e000160, 3, (RF, RF, RF_IF), rd_rn_rm),
25405 cCL("adfd", e000180, 3, (RF, RF, RF_IF), rd_rn_rm),
25406 cCL("adfdp", e0001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25407 cCL("adfdm", e0001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25408 cCL("adfdz", e0001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25409 cCL("adfe", e080100, 3, (RF, RF, RF_IF), rd_rn_rm),
25410 cCL("adfep", e080120, 3, (RF, RF, RF_IF), rd_rn_rm),
25411 cCL("adfem", e080140, 3, (RF, RF, RF_IF), rd_rn_rm),
25412 cCL("adfez", e080160, 3, (RF, RF, RF_IF), rd_rn_rm),
25413
25414 cCL("sufs", e200100, 3, (RF, RF, RF_IF), rd_rn_rm),
25415 cCL("sufsp", e200120, 3, (RF, RF, RF_IF), rd_rn_rm),
25416 cCL("sufsm", e200140, 3, (RF, RF, RF_IF), rd_rn_rm),
25417 cCL("sufsz", e200160, 3, (RF, RF, RF_IF), rd_rn_rm),
25418 cCL("sufd", e200180, 3, (RF, RF, RF_IF), rd_rn_rm),
25419 cCL("sufdp", e2001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25420 cCL("sufdm", e2001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25421 cCL("sufdz", e2001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25422 cCL("sufe", e280100, 3, (RF, RF, RF_IF), rd_rn_rm),
25423 cCL("sufep", e280120, 3, (RF, RF, RF_IF), rd_rn_rm),
25424 cCL("sufem", e280140, 3, (RF, RF, RF_IF), rd_rn_rm),
25425 cCL("sufez", e280160, 3, (RF, RF, RF_IF), rd_rn_rm),
25426
25427 cCL("rsfs", e300100, 3, (RF, RF, RF_IF), rd_rn_rm),
25428 cCL("rsfsp", e300120, 3, (RF, RF, RF_IF), rd_rn_rm),
25429 cCL("rsfsm", e300140, 3, (RF, RF, RF_IF), rd_rn_rm),
25430 cCL("rsfsz", e300160, 3, (RF, RF, RF_IF), rd_rn_rm),
25431 cCL("rsfd", e300180, 3, (RF, RF, RF_IF), rd_rn_rm),
25432 cCL("rsfdp", e3001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25433 cCL("rsfdm", e3001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25434 cCL("rsfdz", e3001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25435 cCL("rsfe", e380100, 3, (RF, RF, RF_IF), rd_rn_rm),
25436 cCL("rsfep", e380120, 3, (RF, RF, RF_IF), rd_rn_rm),
25437 cCL("rsfem", e380140, 3, (RF, RF, RF_IF), rd_rn_rm),
25438 cCL("rsfez", e380160, 3, (RF, RF, RF_IF), rd_rn_rm),
25439
25440 cCL("mufs", e100100, 3, (RF, RF, RF_IF), rd_rn_rm),
25441 cCL("mufsp", e100120, 3, (RF, RF, RF_IF), rd_rn_rm),
25442 cCL("mufsm", e100140, 3, (RF, RF, RF_IF), rd_rn_rm),
25443 cCL("mufsz", e100160, 3, (RF, RF, RF_IF), rd_rn_rm),
25444 cCL("mufd", e100180, 3, (RF, RF, RF_IF), rd_rn_rm),
25445 cCL("mufdp", e1001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25446 cCL("mufdm", e1001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25447 cCL("mufdz", e1001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25448 cCL("mufe", e180100, 3, (RF, RF, RF_IF), rd_rn_rm),
25449 cCL("mufep", e180120, 3, (RF, RF, RF_IF), rd_rn_rm),
25450 cCL("mufem", e180140, 3, (RF, RF, RF_IF), rd_rn_rm),
25451 cCL("mufez", e180160, 3, (RF, RF, RF_IF), rd_rn_rm),
25452
25453 cCL("dvfs", e400100, 3, (RF, RF, RF_IF), rd_rn_rm),
25454 cCL("dvfsp", e400120, 3, (RF, RF, RF_IF), rd_rn_rm),
25455 cCL("dvfsm", e400140, 3, (RF, RF, RF_IF), rd_rn_rm),
25456 cCL("dvfsz", e400160, 3, (RF, RF, RF_IF), rd_rn_rm),
25457 cCL("dvfd", e400180, 3, (RF, RF, RF_IF), rd_rn_rm),
25458 cCL("dvfdp", e4001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25459 cCL("dvfdm", e4001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25460 cCL("dvfdz", e4001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25461 cCL("dvfe", e480100, 3, (RF, RF, RF_IF), rd_rn_rm),
25462 cCL("dvfep", e480120, 3, (RF, RF, RF_IF), rd_rn_rm),
25463 cCL("dvfem", e480140, 3, (RF, RF, RF_IF), rd_rn_rm),
25464 cCL("dvfez", e480160, 3, (RF, RF, RF_IF), rd_rn_rm),
25465
25466 cCL("rdfs", e500100, 3, (RF, RF, RF_IF), rd_rn_rm),
25467 cCL("rdfsp", e500120, 3, (RF, RF, RF_IF), rd_rn_rm),
25468 cCL("rdfsm", e500140, 3, (RF, RF, RF_IF), rd_rn_rm),
25469 cCL("rdfsz", e500160, 3, (RF, RF, RF_IF), rd_rn_rm),
25470 cCL("rdfd", e500180, 3, (RF, RF, RF_IF), rd_rn_rm),
25471 cCL("rdfdp", e5001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25472 cCL("rdfdm", e5001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25473 cCL("rdfdz", e5001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25474 cCL("rdfe", e580100, 3, (RF, RF, RF_IF), rd_rn_rm),
25475 cCL("rdfep", e580120, 3, (RF, RF, RF_IF), rd_rn_rm),
25476 cCL("rdfem", e580140, 3, (RF, RF, RF_IF), rd_rn_rm),
25477 cCL("rdfez", e580160, 3, (RF, RF, RF_IF), rd_rn_rm),
25478
25479 cCL("pows", e600100, 3, (RF, RF, RF_IF), rd_rn_rm),
25480 cCL("powsp", e600120, 3, (RF, RF, RF_IF), rd_rn_rm),
25481 cCL("powsm", e600140, 3, (RF, RF, RF_IF), rd_rn_rm),
25482 cCL("powsz", e600160, 3, (RF, RF, RF_IF), rd_rn_rm),
25483 cCL("powd", e600180, 3, (RF, RF, RF_IF), rd_rn_rm),
25484 cCL("powdp", e6001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25485 cCL("powdm", e6001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25486 cCL("powdz", e6001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25487 cCL("powe", e680100, 3, (RF, RF, RF_IF), rd_rn_rm),
25488 cCL("powep", e680120, 3, (RF, RF, RF_IF), rd_rn_rm),
25489 cCL("powem", e680140, 3, (RF, RF, RF_IF), rd_rn_rm),
25490 cCL("powez", e680160, 3, (RF, RF, RF_IF), rd_rn_rm),
25491
25492 cCL("rpws", e700100, 3, (RF, RF, RF_IF), rd_rn_rm),
25493 cCL("rpwsp", e700120, 3, (RF, RF, RF_IF), rd_rn_rm),
25494 cCL("rpwsm", e700140, 3, (RF, RF, RF_IF), rd_rn_rm),
25495 cCL("rpwsz", e700160, 3, (RF, RF, RF_IF), rd_rn_rm),
25496 cCL("rpwd", e700180, 3, (RF, RF, RF_IF), rd_rn_rm),
25497 cCL("rpwdp", e7001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25498 cCL("rpwdm", e7001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25499 cCL("rpwdz", e7001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25500 cCL("rpwe", e780100, 3, (RF, RF, RF_IF), rd_rn_rm),
25501 cCL("rpwep", e780120, 3, (RF, RF, RF_IF), rd_rn_rm),
25502 cCL("rpwem", e780140, 3, (RF, RF, RF_IF), rd_rn_rm),
25503 cCL("rpwez", e780160, 3, (RF, RF, RF_IF), rd_rn_rm),
25504
25505 cCL("rmfs", e800100, 3, (RF, RF, RF_IF), rd_rn_rm),
25506 cCL("rmfsp", e800120, 3, (RF, RF, RF_IF), rd_rn_rm),
25507 cCL("rmfsm", e800140, 3, (RF, RF, RF_IF), rd_rn_rm),
25508 cCL("rmfsz", e800160, 3, (RF, RF, RF_IF), rd_rn_rm),
25509 cCL("rmfd", e800180, 3, (RF, RF, RF_IF), rd_rn_rm),
25510 cCL("rmfdp", e8001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25511 cCL("rmfdm", e8001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25512 cCL("rmfdz", e8001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25513 cCL("rmfe", e880100, 3, (RF, RF, RF_IF), rd_rn_rm),
25514 cCL("rmfep", e880120, 3, (RF, RF, RF_IF), rd_rn_rm),
25515 cCL("rmfem", e880140, 3, (RF, RF, RF_IF), rd_rn_rm),
25516 cCL("rmfez", e880160, 3, (RF, RF, RF_IF), rd_rn_rm),
25517
25518 cCL("fmls", e900100, 3, (RF, RF, RF_IF), rd_rn_rm),
25519 cCL("fmlsp", e900120, 3, (RF, RF, RF_IF), rd_rn_rm),
25520 cCL("fmlsm", e900140, 3, (RF, RF, RF_IF), rd_rn_rm),
25521 cCL("fmlsz", e900160, 3, (RF, RF, RF_IF), rd_rn_rm),
25522 cCL("fmld", e900180, 3, (RF, RF, RF_IF), rd_rn_rm),
25523 cCL("fmldp", e9001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25524 cCL("fmldm", e9001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25525 cCL("fmldz", e9001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25526 cCL("fmle", e980100, 3, (RF, RF, RF_IF), rd_rn_rm),
25527 cCL("fmlep", e980120, 3, (RF, RF, RF_IF), rd_rn_rm),
25528 cCL("fmlem", e980140, 3, (RF, RF, RF_IF), rd_rn_rm),
25529 cCL("fmlez", e980160, 3, (RF, RF, RF_IF), rd_rn_rm),
25530
25531 cCL("fdvs", ea00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25532 cCL("fdvsp", ea00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25533 cCL("fdvsm", ea00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25534 cCL("fdvsz", ea00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25535 cCL("fdvd", ea00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25536 cCL("fdvdp", ea001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25537 cCL("fdvdm", ea001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25538 cCL("fdvdz", ea001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25539 cCL("fdve", ea80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25540 cCL("fdvep", ea80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25541 cCL("fdvem", ea80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25542 cCL("fdvez", ea80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25543
25544 cCL("frds", eb00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25545 cCL("frdsp", eb00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25546 cCL("frdsm", eb00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25547 cCL("frdsz", eb00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25548 cCL("frdd", eb00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25549 cCL("frddp", eb001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25550 cCL("frddm", eb001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25551 cCL("frddz", eb001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25552 cCL("frde", eb80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25553 cCL("frdep", eb80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25554 cCL("frdem", eb80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25555 cCL("frdez", eb80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25556
25557 cCL("pols", ec00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25558 cCL("polsp", ec00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25559 cCL("polsm", ec00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25560 cCL("polsz", ec00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25561 cCL("pold", ec00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25562 cCL("poldp", ec001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25563 cCL("poldm", ec001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25564 cCL("poldz", ec001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25565 cCL("pole", ec80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25566 cCL("polep", ec80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25567 cCL("polem", ec80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25568 cCL("polez", ec80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25569
25570 cCE("cmf", e90f110, 2, (RF, RF_IF), fpa_cmp),
25571 C3E("cmfe", ed0f110, 2, (RF, RF_IF), fpa_cmp),
25572 cCE("cnf", eb0f110, 2, (RF, RF_IF), fpa_cmp),
25573 C3E("cnfe", ef0f110, 2, (RF, RF_IF), fpa_cmp),
25574
25575 cCL("flts", e000110, 2, (RF, RR), rn_rd),
25576 cCL("fltsp", e000130, 2, (RF, RR), rn_rd),
25577 cCL("fltsm", e000150, 2, (RF, RR), rn_rd),
25578 cCL("fltsz", e000170, 2, (RF, RR), rn_rd),
25579 cCL("fltd", e000190, 2, (RF, RR), rn_rd),
25580 cCL("fltdp", e0001b0, 2, (RF, RR), rn_rd),
25581 cCL("fltdm", e0001d0, 2, (RF, RR), rn_rd),
25582 cCL("fltdz", e0001f0, 2, (RF, RR), rn_rd),
25583 cCL("flte", e080110, 2, (RF, RR), rn_rd),
25584 cCL("fltep", e080130, 2, (RF, RR), rn_rd),
25585 cCL("fltem", e080150, 2, (RF, RR), rn_rd),
25586 cCL("fltez", e080170, 2, (RF, RR), rn_rd),
b99bd4ef 25587
c19d1205
ZW
25588 /* The implementation of the FIX instruction is broken on some
25589 assemblers, in that it accepts a precision specifier as well as a
25590 rounding specifier, despite the fact that this is meaningless.
25591 To be more compatible, we accept it as well, though of course it
25592 does not set any bits. */
21d799b5
NC
25593 cCE("fix", e100110, 2, (RR, RF), rd_rm),
25594 cCL("fixp", e100130, 2, (RR, RF), rd_rm),
25595 cCL("fixm", e100150, 2, (RR, RF), rd_rm),
25596 cCL("fixz", e100170, 2, (RR, RF), rd_rm),
25597 cCL("fixsp", e100130, 2, (RR, RF), rd_rm),
25598 cCL("fixsm", e100150, 2, (RR, RF), rd_rm),
25599 cCL("fixsz", e100170, 2, (RR, RF), rd_rm),
25600 cCL("fixdp", e100130, 2, (RR, RF), rd_rm),
25601 cCL("fixdm", e100150, 2, (RR, RF), rd_rm),
25602 cCL("fixdz", e100170, 2, (RR, RF), rd_rm),
25603 cCL("fixep", e100130, 2, (RR, RF), rd_rm),
25604 cCL("fixem", e100150, 2, (RR, RF), rd_rm),
25605 cCL("fixez", e100170, 2, (RR, RF), rd_rm),
bfae80f2 25606
c19d1205 25607 /* Instructions that were new with the real FPA, call them V2. */
c921be7d
NC
25608#undef ARM_VARIANT
25609#define ARM_VARIANT & fpu_fpa_ext_v2
25610
21d799b5
NC
25611 cCE("lfm", c100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25612 cCL("lfmfd", c900200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25613 cCL("lfmea", d100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25614 cCE("sfm", c000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25615 cCL("sfmfd", d000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25616 cCL("sfmea", c800200, 3, (RF, I4b, ADDR), fpa_ldmstm),
c19d1205 25617
c921be7d
NC
25618#undef ARM_VARIANT
25619#define ARM_VARIANT & fpu_vfp_ext_v1xd /* VFP V1xD (single precision). */
ba6cd17f
SD
25620#undef THUMB_VARIANT
25621#define THUMB_VARIANT & arm_ext_v6t2
25622 mcCE(vmrs, ef00a10, 2, (APSR_RR, RVC), vmrs),
25623 mcCE(vmsr, ee00a10, 2, (RVC, RR), vmsr),
ef8f595f
MI
25624 mcCE(fldd, d100b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
25625 mcCE(fstd, d000b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
25626 mcCE(flds, d100a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
25627 mcCE(fsts, d000a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
90e9955a
SP
25628
25629 /* Memory operations. */
25630 mcCE(fldmias, c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
25631 mcCE(fldmdbs, d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25632 mcCE(fstmias, c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
25633 mcCE(fstmdbs, d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
ba6cd17f 25634#undef THUMB_VARIANT
c921be7d 25635
c19d1205 25636 /* Moves and type conversions. */
21d799b5
NC
25637 cCE("fmstat", ef1fa10, 0, (), noargs),
25638 cCE("fsitos", eb80ac0, 2, (RVS, RVS), vfp_sp_monadic),
25639 cCE("fuitos", eb80a40, 2, (RVS, RVS), vfp_sp_monadic),
25640 cCE("ftosis", ebd0a40, 2, (RVS, RVS), vfp_sp_monadic),
25641 cCE("ftosizs", ebd0ac0, 2, (RVS, RVS), vfp_sp_monadic),
25642 cCE("ftouis", ebc0a40, 2, (RVS, RVS), vfp_sp_monadic),
25643 cCE("ftouizs", ebc0ac0, 2, (RVS, RVS), vfp_sp_monadic),
25644 cCE("fmrx", ef00a10, 2, (RR, RVC), rd_rn),
25645 cCE("fmxr", ee00a10, 2, (RVC, RR), rn_rd),
c19d1205
ZW
25646
25647 /* Memory operations. */
55881a11 25648 cCE("fldmfds", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
55881a11
MGD
25649 cCE("fldmeas", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25650 cCE("fldmiax", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25651 cCE("fldmfdx", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25652 cCE("fldmdbx", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
25653 cCE("fldmeax", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
55881a11 25654 cCE("fstmeas", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
55881a11
MGD
25655 cCE("fstmfds", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25656 cCE("fstmiax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25657 cCE("fstmeax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25658 cCE("fstmdbx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
25659 cCE("fstmfdx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
bfae80f2 25660
c19d1205 25661 /* Monadic operations. */
21d799b5
NC
25662 cCE("fabss", eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
25663 cCE("fnegs", eb10a40, 2, (RVS, RVS), vfp_sp_monadic),
25664 cCE("fsqrts", eb10ac0, 2, (RVS, RVS), vfp_sp_monadic),
c19d1205
ZW
25665
25666 /* Dyadic operations. */
21d799b5
NC
25667 cCE("fadds", e300a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25668 cCE("fsubs", e300a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25669 cCE("fmuls", e200a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25670 cCE("fdivs", e800a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25671 cCE("fmacs", e000a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25672 cCE("fmscs", e100a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25673 cCE("fnmuls", e200a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25674 cCE("fnmacs", e000a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25675 cCE("fnmscs", e100a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
b99bd4ef 25676
c19d1205 25677 /* Comparisons. */
21d799b5
NC
25678 cCE("fcmps", eb40a40, 2, (RVS, RVS), vfp_sp_monadic),
25679 cCE("fcmpzs", eb50a40, 1, (RVS), vfp_sp_compare_z),
25680 cCE("fcmpes", eb40ac0, 2, (RVS, RVS), vfp_sp_monadic),
25681 cCE("fcmpezs", eb50ac0, 1, (RVS), vfp_sp_compare_z),
b99bd4ef 25682
62f3b8c8
PB
25683 /* Double precision load/store are still present on single precision
25684 implementations. */
55881a11
MGD
25685 cCE("fldmiad", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25686 cCE("fldmfdd", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25687 cCE("fldmdbd", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25688 cCE("fldmead", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25689 cCE("fstmiad", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25690 cCE("fstmead", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25691 cCE("fstmdbd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25692 cCE("fstmfdd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
62f3b8c8 25693
c921be7d
NC
25694#undef ARM_VARIANT
25695#define ARM_VARIANT & fpu_vfp_ext_v1 /* VFP V1 (Double precision). */
25696
c19d1205 25697 /* Moves and type conversions. */
21d799b5
NC
25698 cCE("fcvtds", eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt),
25699 cCE("fcvtsd", eb70bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
25700 cCE("fmdhr", e200b10, 2, (RVD, RR), vfp_dp_rn_rd),
25701 cCE("fmdlr", e000b10, 2, (RVD, RR), vfp_dp_rn_rd),
25702 cCE("fmrdh", e300b10, 2, (RR, RVD), vfp_dp_rd_rn),
25703 cCE("fmrdl", e100b10, 2, (RR, RVD), vfp_dp_rd_rn),
25704 cCE("fsitod", eb80bc0, 2, (RVD, RVS), vfp_dp_sp_cvt),
25705 cCE("fuitod", eb80b40, 2, (RVD, RVS), vfp_dp_sp_cvt),
25706 cCE("ftosid", ebd0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
25707 cCE("ftosizd", ebd0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
25708 cCE("ftouid", ebc0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
25709 cCE("ftouizd", ebc0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
c19d1205 25710
c19d1205 25711 /* Monadic operations. */
21d799b5
NC
25712 cCE("fabsd", eb00bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
25713 cCE("fnegd", eb10b40, 2, (RVD, RVD), vfp_dp_rd_rm),
25714 cCE("fsqrtd", eb10bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
c19d1205
ZW
25715
25716 /* Dyadic operations. */
21d799b5
NC
25717 cCE("faddd", e300b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25718 cCE("fsubd", e300b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25719 cCE("fmuld", e200b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25720 cCE("fdivd", e800b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25721 cCE("fmacd", e000b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25722 cCE("fmscd", e100b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25723 cCE("fnmuld", e200b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25724 cCE("fnmacd", e000b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25725 cCE("fnmscd", e100b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
b99bd4ef 25726
c19d1205 25727 /* Comparisons. */
21d799b5
NC
25728 cCE("fcmpd", eb40b40, 2, (RVD, RVD), vfp_dp_rd_rm),
25729 cCE("fcmpzd", eb50b40, 1, (RVD), vfp_dp_rd),
25730 cCE("fcmped", eb40bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
25731 cCE("fcmpezd", eb50bc0, 1, (RVD), vfp_dp_rd),
c19d1205 25732
037e8744
JB
25733/* Instructions which may belong to either the Neon or VFP instruction sets.
25734 Individual encoder functions perform additional architecture checks. */
c921be7d
NC
25735#undef ARM_VARIANT
25736#define ARM_VARIANT & fpu_vfp_ext_v1xd
ef8f595f
MI
25737#undef THUMB_VARIANT
25738#define THUMB_VARIANT & arm_ext_v6t2
25739
25740 NCE(vldm, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25741 NCE(vldmia, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25742 NCE(vldmdb, d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25743 NCE(vstm, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25744 NCE(vstmia, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25745 NCE(vstmdb, d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25746
25747 NCE(vpop, 0, 1, (VRSDLST), vfp_nsyn_pop),
25748 NCE(vpush, 0, 1, (VRSDLST), vfp_nsyn_push),
25749
c921be7d
NC
25750#undef THUMB_VARIANT
25751#define THUMB_VARIANT & fpu_vfp_ext_v1xd
25752
037e8744
JB
25753 /* These mnemonics are unique to VFP. */
25754 NCE(vsqrt, 0, 2, (RVSD, RVSD), vfp_nsyn_sqrt),
25755 NCE(vdiv, 0, 3, (RVSD, RVSD, RVSD), vfp_nsyn_div),
21d799b5
NC
25756 nCE(vnmul, _vnmul, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
25757 nCE(vnmla, _vnmla, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
25758 nCE(vnmls, _vnmls, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
037e8744
JB
25759 NCE(vcvtz, 0, 2, (RVSD, RVSD), vfp_nsyn_cvtz),
25760
25761 /* Mnemonics shared by Neon and VFP. */
21d799b5 25762 nCEF(vmls, _vmls, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
037e8744 25763
dd9634d9 25764 mnCEF(vcvt, _vcvt, 3, (RNSDQMQ, RNSDQMQ, oI32z), neon_cvt),
e3e535bc 25765 nCEF(vcvtr, _vcvt, 2, (RNSDQ, RNSDQ), neon_cvtr),
dd9634d9
AV
25766 MNCEF(vcvtb, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtb),
25767 MNCEF(vcvtt, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtt),
f31fef98 25768
037e8744
JB
25769
25770 /* NOTE: All VMOV encoding is special-cased! */
037e8744
JB
25771 NCE(vmovq, 0, 1, (VMOV), neon_mov),
25772
32c36c3c
AV
25773#undef THUMB_VARIANT
25774/* Could be either VLDR/VSTR or VLDR/VSTR (system register) which are guarded
25775 by different feature bits. Since we are setting the Thumb guard, we can
25776 require Thumb-1 which makes it a nop guard and set the right feature bit in
25777 do_vldr_vstr (). */
25778#define THUMB_VARIANT & arm_ext_v4t
25779 NCE(vldr, d100b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
25780 NCE(vstr, d000b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
25781
9db2f6b4
RL
25782#undef ARM_VARIANT
25783#define ARM_VARIANT & arm_ext_fp16
25784#undef THUMB_VARIANT
25785#define THUMB_VARIANT & arm_ext_fp16
25786 /* New instructions added from v8.2, allowing the extraction and insertion of
25787 the upper 16 bits of a 32-bit vector register. */
25788 NCE (vmovx, eb00a40, 2, (RVS, RVS), neon_movhf),
25789 NCE (vins, eb00ac0, 2, (RVS, RVS), neon_movhf),
25790
dec41383 25791 /* New backported fma/fms instructions optional in v8.2. */
aab2c27d
MM
25792 NUF (vfmsl, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmsl),
25793 NUF (vfmal, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmal),
dec41383 25794
c921be7d
NC
25795#undef THUMB_VARIANT
25796#define THUMB_VARIANT & fpu_neon_ext_v1
25797#undef ARM_VARIANT
25798#define ARM_VARIANT & fpu_neon_ext_v1
25799
5287ad62
JB
25800 /* Data processing with three registers of the same length. */
25801 /* integer ops, valid types S8 S16 S32 U8 U16 U32. */
25802 NUF(vaba, 0000710, 3, (RNDQ, RNDQ, RNDQ), neon_dyadic_i_su),
25803 NUF(vabaq, 0000710, 3, (RNQ, RNQ, RNQ), neon_dyadic_i_su),
5287ad62 25804 NUF(vhaddq, 0000000, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62 25805 NUF(vrhaddq, 0000100, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62
JB
25806 NUF(vhsubq, 0000200, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
25807 /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62 25808 NUF(vqaddq, 0000010, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
5287ad62 25809 NUF(vqsubq, 0000210, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
627907b7 25810 NUF(vrshlq, 0000500, 3, (RNQ, oRNQ, RNQ), neon_rshl),
627907b7 25811 NUF(vqrshlq, 0000510, 3, (RNQ, oRNQ, RNQ), neon_rshl),
5287ad62 25812 /* If not immediate, fall back to neon_dyadic_i64_su.
5150f0d8
AV
25813 shl should accept I8 I16 I32 I64,
25814 qshl should accept S8 S16 S32 S64 U8 U16 U32 U64. */
25815 nUF(vshlq, _vshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_shl),
25816 nUF(vqshlq, _vqshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_qshl),
5287ad62 25817 /* Logic ops, types optional & ignored. */
4316f0d2 25818 nUF(vandq, _vand, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25819 nUF(vbicq, _vbic, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25820 nUF(vorrq, _vorr, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25821 nUF(vornq, _vorn, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25822 nUF(veorq, _veor, 3, (RNQ, oRNQ, RNQ), neon_logic),
5287ad62
JB
25823 /* Bitfield ops, untyped. */
25824 NUF(vbsl, 1100110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25825 NUF(vbslq, 1100110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
25826 NUF(vbit, 1200110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25827 NUF(vbitq, 1200110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
25828 NUF(vbif, 1300110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25829 NUF(vbifq, 1300110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
cc933301 25830 /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32. */
21d799b5 25831 nUF(vabdq, _vabd, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 25832 nUF(vmaxq, _vmax, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 25833 nUF(vminq, _vmin, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
5287ad62
JB
25834 /* Comparisons. Types S8 S16 S32 U8 U16 U32 F32. Non-immediate versions fall
25835 back to neon_dyadic_if_su. */
21d799b5
NC
25836 nUF(vcge, _vcge, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
25837 nUF(vcgeq, _vcge, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
25838 nUF(vcgt, _vcgt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
25839 nUF(vcgtq, _vcgt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
25840 nUF(vclt, _vclt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
25841 nUF(vcltq, _vclt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
25842 nUF(vcle, _vcle, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
25843 nUF(vcleq, _vcle, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
428e3f1f 25844 /* Comparison. Type I8 I16 I32 F32. */
21d799b5
NC
25845 nUF(vceq, _vceq, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_ceq),
25846 nUF(vceqq, _vceq, 3, (RNQ, oRNQ, RNDQ_I0), neon_ceq),
5287ad62 25847 /* As above, D registers only. */
21d799b5
NC
25848 nUF(vpmax, _vpmax, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
25849 nUF(vpmin, _vpmin, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
5287ad62 25850 /* Int and float variants, signedness unimportant. */
21d799b5
NC
25851 nUF(vmlaq, _vmla, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
25852 nUF(vmlsq, _vmls, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
25853 nUF(vpadd, _vpadd, 3, (RND, oRND, RND), neon_dyadic_if_i_d),
5287ad62 25854 /* Add/sub take types I8 I16 I32 I64 F32. */
21d799b5
NC
25855 nUF(vaddq, _vadd, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
25856 nUF(vsubq, _vsub, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
5287ad62
JB
25857 /* vtst takes sizes 8, 16, 32. */
25858 NUF(vtst, 0000810, 3, (RNDQ, oRNDQ, RNDQ), neon_tst),
25859 NUF(vtstq, 0000810, 3, (RNQ, oRNQ, RNQ), neon_tst),
25860 /* VMUL takes I8 I16 I32 F32 P8. */
21d799b5 25861 nUF(vmulq, _vmul, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mul),
5287ad62 25862 /* VQD{R}MULH takes S16 S32. */
21d799b5 25863 nUF(vqdmulhq, _vqdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
21d799b5 25864 nUF(vqrdmulhq, _vqrdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
5287ad62
JB
25865 NUF(vacge, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
25866 NUF(vacgeq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
25867 NUF(vacgt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
25868 NUF(vacgtq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
92559b5b
PB
25869 NUF(vaclt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
25870 NUF(vacltq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
25871 NUF(vacle, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
25872 NUF(vacleq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
5287ad62
JB
25873 NUF(vrecps, 0000f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
25874 NUF(vrecpsq, 0000f10, 3, (RNQ, oRNQ, RNQ), neon_step),
25875 NUF(vrsqrts, 0200f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
25876 NUF(vrsqrtsq, 0200f10, 3, (RNQ, oRNQ, RNQ), neon_step),
d6b4b13e 25877 /* ARM v8.1 extension. */
643afb90
MW
25878 nUF (vqrdmlahq, _vqrdmlah, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
25879 nUF (vqrdmlsh, _vqrdmlsh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
25880 nUF (vqrdmlshq, _vqrdmlsh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
5287ad62
JB
25881
25882 /* Two address, int/float. Types S8 S16 S32 F32. */
5287ad62 25883 NUF(vabsq, 1b10300, 2, (RNQ, RNQ), neon_abs_neg),
5287ad62
JB
25884 NUF(vnegq, 1b10380, 2, (RNQ, RNQ), neon_abs_neg),
25885
25886 /* Data processing with two registers and a shift amount. */
25887 /* Right shifts, and variants with rounding.
25888 Types accepted S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62 25889 NUF(vshrq, 0800010, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
5287ad62
JB
25890 NUF(vrshrq, 0800210, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
25891 NUF(vsra, 0800110, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
25892 NUF(vsraq, 0800110, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
25893 NUF(vrsra, 0800310, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
25894 NUF(vrsraq, 0800310, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
25895 /* Shift and insert. Sizes accepted 8 16 32 64. */
5287ad62 25896 NUF(vsliq, 1800510, 3, (RNQ, oRNQ, I63), neon_sli),
5287ad62
JB
25897 NUF(vsriq, 1800410, 3, (RNQ, oRNQ, I64), neon_sri),
25898 /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62
JB
25899 NUF(vqshluq, 1800610, 3, (RNQ, oRNQ, I63), neon_qshlu_imm),
25900 /* Right shift immediate, saturating & narrowing, with rounding variants.
25901 Types accepted S16 S32 S64 U16 U32 U64. */
25902 NUF(vqshrn, 0800910, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
25903 NUF(vqrshrn, 0800950, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
25904 /* As above, unsigned. Types accepted S16 S32 S64. */
25905 NUF(vqshrun, 0800810, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
25906 NUF(vqrshrun, 0800850, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
25907 /* Right shift narrowing. Types accepted I16 I32 I64. */
25908 NUF(vshrn, 0800810, 3, (RND, RNQ, I32z), neon_rshift_narrow),
25909 NUF(vrshrn, 0800850, 3, (RND, RNQ, I32z), neon_rshift_narrow),
25910 /* Special case. Types S8 S16 S32 U8 U16 U32. Handles max shift variant. */
21d799b5 25911 nUF(vshll, _vshll, 3, (RNQ, RND, I32), neon_shll),
5287ad62 25912 /* CVT with optional immediate for fixed-point variant. */
21d799b5 25913 nUF(vcvtq, _vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
b7fc2769 25914
4316f0d2 25915 nUF(vmvnq, _vmvn, 2, (RNQ, RNDQ_Ibig), neon_mvn),
5287ad62
JB
25916
25917 /* Data processing, three registers of different lengths. */
25918 /* Dyadic, long insns. Types S8 S16 S32 U8 U16 U32. */
25919 NUF(vabal, 0800500, 3, (RNQ, RND, RND), neon_abal),
5287ad62
JB
25920 /* If not scalar, fall back to neon_dyadic_long.
25921 Vector types as above, scalar types S16 S32 U16 U32. */
21d799b5
NC
25922 nUF(vmlal, _vmlal, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
25923 nUF(vmlsl, _vmlsl, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
5287ad62
JB
25924 /* Dyadic, widening insns. Types S8 S16 S32 U8 U16 U32. */
25925 NUF(vaddw, 0800100, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
25926 NUF(vsubw, 0800300, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
25927 /* Dyadic, narrowing insns. Types I16 I32 I64. */
25928 NUF(vaddhn, 0800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25929 NUF(vraddhn, 1800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25930 NUF(vsubhn, 0800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25931 NUF(vrsubhn, 1800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25932 /* Saturating doubling multiplies. Types S16 S32. */
21d799b5
NC
25933 nUF(vqdmlal, _vqdmlal, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
25934 nUF(vqdmlsl, _vqdmlsl, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
25935 nUF(vqdmull, _vqdmull, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
5287ad62
JB
25936 /* VMULL. Vector types S8 S16 S32 U8 U16 U32 P8, scalar types
25937 S16 S32 U16 U32. */
21d799b5 25938 nUF(vmull, _vmull, 3, (RNQ, RND, RND_RNSC), neon_vmull),
5287ad62
JB
25939
25940 /* Extract. Size 8. */
3b8d421e
PB
25941 NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I15), neon_ext),
25942 NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I15), neon_ext),
5287ad62
JB
25943
25944 /* Two registers, miscellaneous. */
25945 /* Reverse. Sizes 8 16 32 (must be < size in opcode). */
5287ad62 25946 NUF(vrev64q, 1b00000, 2, (RNQ, RNQ), neon_rev),
5287ad62 25947 NUF(vrev32q, 1b00080, 2, (RNQ, RNQ), neon_rev),
5287ad62
JB
25948 NUF(vrev16q, 1b00100, 2, (RNQ, RNQ), neon_rev),
25949 /* Vector replicate. Sizes 8 16 32. */
21d799b5 25950 nCE(vdupq, _vdup, 2, (RNQ, RR_RNSC), neon_dup),
5287ad62
JB
25951 /* VMOVL. Types S8 S16 S32 U8 U16 U32. */
25952 NUF(vmovl, 0800a10, 2, (RNQ, RND), neon_movl),
25953 /* VMOVN. Types I16 I32 I64. */
21d799b5 25954 nUF(vmovn, _vmovn, 2, (RND, RNQ), neon_movn),
5287ad62 25955 /* VQMOVN. Types S16 S32 S64 U16 U32 U64. */
21d799b5 25956 nUF(vqmovn, _vqmovn, 2, (RND, RNQ), neon_qmovn),
5287ad62 25957 /* VQMOVUN. Types S16 S32 S64. */
21d799b5 25958 nUF(vqmovun, _vqmovun, 2, (RND, RNQ), neon_qmovun),
5287ad62
JB
25959 /* VZIP / VUZP. Sizes 8 16 32. */
25960 NUF(vzip, 1b20180, 2, (RNDQ, RNDQ), neon_zip_uzp),
25961 NUF(vzipq, 1b20180, 2, (RNQ, RNQ), neon_zip_uzp),
25962 NUF(vuzp, 1b20100, 2, (RNDQ, RNDQ), neon_zip_uzp),
25963 NUF(vuzpq, 1b20100, 2, (RNQ, RNQ), neon_zip_uzp),
25964 /* VQABS / VQNEG. Types S8 S16 S32. */
5287ad62 25965 NUF(vqabsq, 1b00700, 2, (RNQ, RNQ), neon_sat_abs_neg),
5287ad62
JB
25966 NUF(vqnegq, 1b00780, 2, (RNQ, RNQ), neon_sat_abs_neg),
25967 /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32. */
25968 NUF(vpadal, 1b00600, 2, (RNDQ, RNDQ), neon_pair_long),
25969 NUF(vpadalq, 1b00600, 2, (RNQ, RNQ), neon_pair_long),
25970 NUF(vpaddl, 1b00200, 2, (RNDQ, RNDQ), neon_pair_long),
25971 NUF(vpaddlq, 1b00200, 2, (RNQ, RNQ), neon_pair_long),
cc933301 25972 /* Reciprocal estimates. Types U32 F16 F32. */
5287ad62
JB
25973 NUF(vrecpe, 1b30400, 2, (RNDQ, RNDQ), neon_recip_est),
25974 NUF(vrecpeq, 1b30400, 2, (RNQ, RNQ), neon_recip_est),
25975 NUF(vrsqrte, 1b30480, 2, (RNDQ, RNDQ), neon_recip_est),
25976 NUF(vrsqrteq, 1b30480, 2, (RNQ, RNQ), neon_recip_est),
25977 /* VCLS. Types S8 S16 S32. */
5287ad62
JB
25978 NUF(vclsq, 1b00400, 2, (RNQ, RNQ), neon_cls),
25979 /* VCLZ. Types I8 I16 I32. */
5287ad62
JB
25980 NUF(vclzq, 1b00480, 2, (RNQ, RNQ), neon_clz),
25981 /* VCNT. Size 8. */
25982 NUF(vcnt, 1b00500, 2, (RNDQ, RNDQ), neon_cnt),
25983 NUF(vcntq, 1b00500, 2, (RNQ, RNQ), neon_cnt),
25984 /* Two address, untyped. */
25985 NUF(vswp, 1b20000, 2, (RNDQ, RNDQ), neon_swp),
25986 NUF(vswpq, 1b20000, 2, (RNQ, RNQ), neon_swp),
25987 /* VTRN. Sizes 8 16 32. */
21d799b5
NC
25988 nUF(vtrn, _vtrn, 2, (RNDQ, RNDQ), neon_trn),
25989 nUF(vtrnq, _vtrn, 2, (RNQ, RNQ), neon_trn),
5287ad62
JB
25990
25991 /* Table lookup. Size 8. */
25992 NUF(vtbl, 1b00800, 3, (RND, NRDLST, RND), neon_tbl_tbx),
25993 NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
25994
c921be7d
NC
25995#undef THUMB_VARIANT
25996#define THUMB_VARIANT & fpu_vfp_v3_or_neon_ext
25997#undef ARM_VARIANT
25998#define ARM_VARIANT & fpu_vfp_v3_or_neon_ext
25999
5287ad62 26000 /* Neon element/structure load/store. */
21d799b5
NC
26001 nUF(vld1, _vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
26002 nUF(vst1, _vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
26003 nUF(vld2, _vld2, 2, (NSTRLST, ADDR), neon_ldx_stx),
26004 nUF(vst2, _vst2, 2, (NSTRLST, ADDR), neon_ldx_stx),
26005 nUF(vld3, _vld3, 2, (NSTRLST, ADDR), neon_ldx_stx),
26006 nUF(vst3, _vst3, 2, (NSTRLST, ADDR), neon_ldx_stx),
26007 nUF(vld4, _vld4, 2, (NSTRLST, ADDR), neon_ldx_stx),
26008 nUF(vst4, _vst4, 2, (NSTRLST, ADDR), neon_ldx_stx),
5287ad62 26009
c921be7d 26010#undef THUMB_VARIANT
74db7efb
NC
26011#define THUMB_VARIANT & fpu_vfp_ext_v3xd
26012#undef ARM_VARIANT
26013#define ARM_VARIANT & fpu_vfp_ext_v3xd
62f3b8c8
PB
26014 cCE("fconsts", eb00a00, 2, (RVS, I255), vfp_sp_const),
26015 cCE("fshtos", eba0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26016 cCE("fsltos", eba0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26017 cCE("fuhtos", ebb0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26018 cCE("fultos", ebb0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26019 cCE("ftoshs", ebe0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26020 cCE("ftosls", ebe0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26021 cCE("ftouhs", ebf0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26022 cCE("ftouls", ebf0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26023
74db7efb 26024#undef THUMB_VARIANT
c921be7d
NC
26025#define THUMB_VARIANT & fpu_vfp_ext_v3
26026#undef ARM_VARIANT
26027#define ARM_VARIANT & fpu_vfp_ext_v3
26028
21d799b5 26029 cCE("fconstd", eb00b00, 2, (RVD, I255), vfp_dp_const),
21d799b5 26030 cCE("fshtod", eba0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26031 cCE("fsltod", eba0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 26032 cCE("fuhtod", ebb0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26033 cCE("fultod", ebb0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 26034 cCE("ftoshd", ebe0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26035 cCE("ftosld", ebe0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 26036 cCE("ftouhd", ebf0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26037 cCE("ftould", ebf0bc0, 2, (RVD, I32), vfp_dp_conv_32),
c19d1205 26038
74db7efb
NC
26039#undef ARM_VARIANT
26040#define ARM_VARIANT & fpu_vfp_ext_fma
26041#undef THUMB_VARIANT
26042#define THUMB_VARIANT & fpu_vfp_ext_fma
aab2c27d 26043 /* Mnemonics shared by Neon, VFP, MVE and BF16. These are included in the
62f3b8c8
PB
26044 VFP FMA variant; NEON and VFP FMA always includes the NEON
26045 FMA instructions. */
d58196e0 26046 mnCEF(vfma, _vfma, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_fmac),
aab2c27d 26047 TUF ("vfmat", c300850, fc300850, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), mve_vfma, mve_vfma),
d58196e0
AV
26048 mnCEF(vfms, _vfms, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), neon_fmac),
26049
62f3b8c8
PB
26050 /* ffmas/ffmad/ffmss/ffmsd are dummy mnemonics to satisfy gas;
26051 the v form should always be used. */
26052 cCE("ffmas", ea00a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
26053 cCE("ffnmas", ea00a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
26054 cCE("ffmad", ea00b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
26055 cCE("ffnmad", ea00b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
26056 nCE(vfnma, _vfnma, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
26057 nCE(vfnms, _vfnms, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
26058
5287ad62 26059#undef THUMB_VARIANT
c921be7d
NC
26060#undef ARM_VARIANT
26061#define ARM_VARIANT & arm_cext_xscale /* Intel XScale extensions. */
26062
21d799b5
NC
26063 cCE("mia", e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26064 cCE("miaph", e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26065 cCE("miabb", e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26066 cCE("miabt", e2d0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26067 cCE("miatb", e2e0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26068 cCE("miatt", e2f0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26069 cCE("mar", c400000, 3, (RXA, RRnpc, RRnpc), xsc_mar),
26070 cCE("mra", c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra),
c19d1205 26071
c921be7d
NC
26072#undef ARM_VARIANT
26073#define ARM_VARIANT & arm_cext_iwmmxt /* Intel Wireless MMX technology. */
26074
21d799b5
NC
26075 cCE("tandcb", e13f130, 1, (RR), iwmmxt_tandorc),
26076 cCE("tandch", e53f130, 1, (RR), iwmmxt_tandorc),
26077 cCE("tandcw", e93f130, 1, (RR), iwmmxt_tandorc),
26078 cCE("tbcstb", e400010, 2, (RIWR, RR), rn_rd),
26079 cCE("tbcsth", e400050, 2, (RIWR, RR), rn_rd),
26080 cCE("tbcstw", e400090, 2, (RIWR, RR), rn_rd),
26081 cCE("textrcb", e130170, 2, (RR, I7), iwmmxt_textrc),
26082 cCE("textrch", e530170, 2, (RR, I7), iwmmxt_textrc),
26083 cCE("textrcw", e930170, 2, (RR, I7), iwmmxt_textrc),
74db7efb
NC
26084 cCE("textrmub",e100070, 3, (RR, RIWR, I7), iwmmxt_textrm),
26085 cCE("textrmuh",e500070, 3, (RR, RIWR, I7), iwmmxt_textrm),
26086 cCE("textrmuw",e900070, 3, (RR, RIWR, I7), iwmmxt_textrm),
26087 cCE("textrmsb",e100078, 3, (RR, RIWR, I7), iwmmxt_textrm),
26088 cCE("textrmsh",e500078, 3, (RR, RIWR, I7), iwmmxt_textrm),
26089 cCE("textrmsw",e900078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21d799b5
NC
26090 cCE("tinsrb", e600010, 3, (RIWR, RR, I7), iwmmxt_tinsr),
26091 cCE("tinsrh", e600050, 3, (RIWR, RR, I7), iwmmxt_tinsr),
26092 cCE("tinsrw", e600090, 3, (RIWR, RR, I7), iwmmxt_tinsr),
26093 cCE("tmcr", e000110, 2, (RIWC_RIWG, RR), rn_rd),
26094 cCE("tmcrr", c400000, 3, (RIWR, RR, RR), rm_rd_rn),
26095 cCE("tmia", e200010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26096 cCE("tmiaph", e280010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26097 cCE("tmiabb", e2c0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26098 cCE("tmiabt", e2d0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26099 cCE("tmiatb", e2e0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26100 cCE("tmiatt", e2f0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
74db7efb
NC
26101 cCE("tmovmskb",e100030, 2, (RR, RIWR), rd_rn),
26102 cCE("tmovmskh",e500030, 2, (RR, RIWR), rd_rn),
26103 cCE("tmovmskw",e900030, 2, (RR, RIWR), rd_rn),
21d799b5
NC
26104 cCE("tmrc", e100110, 2, (RR, RIWC_RIWG), rd_rn),
26105 cCE("tmrrc", c500000, 3, (RR, RR, RIWR), rd_rn_rm),
26106 cCE("torcb", e13f150, 1, (RR), iwmmxt_tandorc),
26107 cCE("torch", e53f150, 1, (RR), iwmmxt_tandorc),
26108 cCE("torcw", e93f150, 1, (RR), iwmmxt_tandorc),
26109 cCE("waccb", e0001c0, 2, (RIWR, RIWR), rd_rn),
26110 cCE("wacch", e4001c0, 2, (RIWR, RIWR), rd_rn),
26111 cCE("waccw", e8001c0, 2, (RIWR, RIWR), rd_rn),
26112 cCE("waddbss", e300180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26113 cCE("waddb", e000180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26114 cCE("waddbus", e100180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26115 cCE("waddhss", e700180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26116 cCE("waddh", e400180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26117 cCE("waddhus", e500180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26118 cCE("waddwss", eb00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26119 cCE("waddw", e800180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26120 cCE("waddwus", e900180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26121 cCE("waligni", e000020, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_waligni),
74db7efb
NC
26122 cCE("walignr0",e800020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26123 cCE("walignr1",e900020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26124 cCE("walignr2",ea00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26125 cCE("walignr3",eb00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
26126 cCE("wand", e200000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26127 cCE("wandn", e300000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26128 cCE("wavg2b", e800000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26129 cCE("wavg2br", e900000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26130 cCE("wavg2h", ec00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26131 cCE("wavg2hr", ed00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26132 cCE("wcmpeqb", e000060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26133 cCE("wcmpeqh", e400060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26134 cCE("wcmpeqw", e800060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
26135 cCE("wcmpgtub",e100060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26136 cCE("wcmpgtuh",e500060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26137 cCE("wcmpgtuw",e900060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26138 cCE("wcmpgtsb",e300060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26139 cCE("wcmpgtsh",e700060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26140 cCE("wcmpgtsw",eb00060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
26141 cCE("wldrb", c100000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26142 cCE("wldrh", c500000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26143 cCE("wldrw", c100100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
26144 cCE("wldrd", c500100, 2, (RIWR, ADDR), iwmmxt_wldstd),
26145 cCE("wmacs", e600100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26146 cCE("wmacsz", e700100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26147 cCE("wmacu", e400100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26148 cCE("wmacuz", e500100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26149 cCE("wmadds", ea00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26150 cCE("wmaddu", e800100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26151 cCE("wmaxsb", e200160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26152 cCE("wmaxsh", e600160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26153 cCE("wmaxsw", ea00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26154 cCE("wmaxub", e000160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26155 cCE("wmaxuh", e400160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26156 cCE("wmaxuw", e800160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26157 cCE("wminsb", e300160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26158 cCE("wminsh", e700160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26159 cCE("wminsw", eb00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26160 cCE("wminub", e100160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26161 cCE("wminuh", e500160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26162 cCE("wminuw", e900160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26163 cCE("wmov", e000000, 2, (RIWR, RIWR), iwmmxt_wmov),
26164 cCE("wmulsm", e300100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26165 cCE("wmulsl", e200100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26166 cCE("wmulum", e100100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26167 cCE("wmulul", e000100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26168 cCE("wor", e000000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
26169 cCE("wpackhss",e700080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26170 cCE("wpackhus",e500080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26171 cCE("wpackwss",eb00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26172 cCE("wpackwus",e900080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26173 cCE("wpackdss",ef00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26174 cCE("wpackdus",ed00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
26175 cCE("wrorh", e700040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26176 cCE("wrorhg", e700148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26177 cCE("wrorw", eb00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26178 cCE("wrorwg", eb00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26179 cCE("wrord", ef00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26180 cCE("wrordg", ef00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26181 cCE("wsadb", e000120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26182 cCE("wsadbz", e100120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26183 cCE("wsadh", e400120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26184 cCE("wsadhz", e500120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26185 cCE("wshufh", e0001e0, 3, (RIWR, RIWR, I255), iwmmxt_wshufh),
26186 cCE("wsllh", e500040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26187 cCE("wsllhg", e500148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26188 cCE("wsllw", e900040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26189 cCE("wsllwg", e900148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26190 cCE("wslld", ed00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26191 cCE("wslldg", ed00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26192 cCE("wsrah", e400040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26193 cCE("wsrahg", e400148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26194 cCE("wsraw", e800040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26195 cCE("wsrawg", e800148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26196 cCE("wsrad", ec00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26197 cCE("wsradg", ec00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26198 cCE("wsrlh", e600040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26199 cCE("wsrlhg", e600148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26200 cCE("wsrlw", ea00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26201 cCE("wsrlwg", ea00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26202 cCE("wsrld", ee00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26203 cCE("wsrldg", ee00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26204 cCE("wstrb", c000000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26205 cCE("wstrh", c400000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26206 cCE("wstrw", c000100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
26207 cCE("wstrd", c400100, 2, (RIWR, ADDR), iwmmxt_wldstd),
26208 cCE("wsubbss", e3001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26209 cCE("wsubb", e0001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26210 cCE("wsubbus", e1001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26211 cCE("wsubhss", e7001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26212 cCE("wsubh", e4001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26213 cCE("wsubhus", e5001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26214 cCE("wsubwss", eb001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26215 cCE("wsubw", e8001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26216 cCE("wsubwus", e9001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26217 cCE("wunpckehub",e0000c0, 2, (RIWR, RIWR), rd_rn),
26218 cCE("wunpckehuh",e4000c0, 2, (RIWR, RIWR), rd_rn),
26219 cCE("wunpckehuw",e8000c0, 2, (RIWR, RIWR), rd_rn),
26220 cCE("wunpckehsb",e2000c0, 2, (RIWR, RIWR), rd_rn),
26221 cCE("wunpckehsh",e6000c0, 2, (RIWR, RIWR), rd_rn),
26222 cCE("wunpckehsw",ea000c0, 2, (RIWR, RIWR), rd_rn),
26223 cCE("wunpckihb", e1000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26224 cCE("wunpckihh", e5000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26225 cCE("wunpckihw", e9000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26226 cCE("wunpckelub",e0000e0, 2, (RIWR, RIWR), rd_rn),
26227 cCE("wunpckeluh",e4000e0, 2, (RIWR, RIWR), rd_rn),
26228 cCE("wunpckeluw",e8000e0, 2, (RIWR, RIWR), rd_rn),
26229 cCE("wunpckelsb",e2000e0, 2, (RIWR, RIWR), rd_rn),
26230 cCE("wunpckelsh",e6000e0, 2, (RIWR, RIWR), rd_rn),
26231 cCE("wunpckelsw",ea000e0, 2, (RIWR, RIWR), rd_rn),
26232 cCE("wunpckilb", e1000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26233 cCE("wunpckilh", e5000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26234 cCE("wunpckilw", e9000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26235 cCE("wxor", e100000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26236 cCE("wzero", e300000, 1, (RIWR), iwmmxt_wzero),
c19d1205 26237
c921be7d
NC
26238#undef ARM_VARIANT
26239#define ARM_VARIANT & arm_cext_iwmmxt2 /* Intel Wireless MMX technology, version 2. */
26240
21d799b5
NC
26241 cCE("torvscb", e12f190, 1, (RR), iwmmxt_tandorc),
26242 cCE("torvsch", e52f190, 1, (RR), iwmmxt_tandorc),
26243 cCE("torvscw", e92f190, 1, (RR), iwmmxt_tandorc),
26244 cCE("wabsb", e2001c0, 2, (RIWR, RIWR), rd_rn),
26245 cCE("wabsh", e6001c0, 2, (RIWR, RIWR), rd_rn),
26246 cCE("wabsw", ea001c0, 2, (RIWR, RIWR), rd_rn),
26247 cCE("wabsdiffb", e1001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26248 cCE("wabsdiffh", e5001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26249 cCE("wabsdiffw", e9001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26250 cCE("waddbhusl", e2001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26251 cCE("waddbhusm", e6001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26252 cCE("waddhc", e600180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26253 cCE("waddwc", ea00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26254 cCE("waddsubhx", ea001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26255 cCE("wavg4", e400000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26256 cCE("wavg4r", e500000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26257 cCE("wmaddsn", ee00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26258 cCE("wmaddsx", eb00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26259 cCE("wmaddun", ec00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26260 cCE("wmaddux", e900100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26261 cCE("wmerge", e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
26262 cCE("wmiabb", e0000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26263 cCE("wmiabt", e1000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26264 cCE("wmiatb", e2000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26265 cCE("wmiatt", e3000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26266 cCE("wmiabbn", e4000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26267 cCE("wmiabtn", e5000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26268 cCE("wmiatbn", e6000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26269 cCE("wmiattn", e7000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26270 cCE("wmiawbb", e800120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26271 cCE("wmiawbt", e900120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26272 cCE("wmiawtb", ea00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26273 cCE("wmiawtt", eb00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26274 cCE("wmiawbbn", ec00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26275 cCE("wmiawbtn", ed00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26276 cCE("wmiawtbn", ee00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26277 cCE("wmiawttn", ef00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26278 cCE("wmulsmr", ef00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26279 cCE("wmulumr", ed00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26280 cCE("wmulwumr", ec000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26281 cCE("wmulwsmr", ee000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26282 cCE("wmulwum", ed000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26283 cCE("wmulwsm", ef000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26284 cCE("wmulwl", eb000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26285 cCE("wqmiabb", e8000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26286 cCE("wqmiabt", e9000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26287 cCE("wqmiatb", ea000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26288 cCE("wqmiatt", eb000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26289 cCE("wqmiabbn", ec000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26290 cCE("wqmiabtn", ed000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26291 cCE("wqmiatbn", ee000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26292 cCE("wqmiattn", ef000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26293 cCE("wqmulm", e100080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26294 cCE("wqmulmr", e300080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26295 cCE("wqmulwm", ec000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26296 cCE("wqmulwmr", ee000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26297 cCE("wsubaddhx", ed001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
2d447fca 26298
c921be7d
NC
26299#undef ARM_VARIANT
26300#define ARM_VARIANT & arm_cext_maverick /* Cirrus Maverick instructions. */
26301
21d799b5
NC
26302 cCE("cfldrs", c100400, 2, (RMF, ADDRGLDC), rd_cpaddr),
26303 cCE("cfldrd", c500400, 2, (RMD, ADDRGLDC), rd_cpaddr),
26304 cCE("cfldr32", c100500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
26305 cCE("cfldr64", c500500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
26306 cCE("cfstrs", c000400, 2, (RMF, ADDRGLDC), rd_cpaddr),
26307 cCE("cfstrd", c400400, 2, (RMD, ADDRGLDC), rd_cpaddr),
26308 cCE("cfstr32", c000500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
26309 cCE("cfstr64", c400500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
26310 cCE("cfmvsr", e000450, 2, (RMF, RR), rn_rd),
26311 cCE("cfmvrs", e100450, 2, (RR, RMF), rd_rn),
26312 cCE("cfmvdlr", e000410, 2, (RMD, RR), rn_rd),
26313 cCE("cfmvrdl", e100410, 2, (RR, RMD), rd_rn),
26314 cCE("cfmvdhr", e000430, 2, (RMD, RR), rn_rd),
26315 cCE("cfmvrdh", e100430, 2, (RR, RMD), rd_rn),
74db7efb
NC
26316 cCE("cfmv64lr",e000510, 2, (RMDX, RR), rn_rd),
26317 cCE("cfmvr64l",e100510, 2, (RR, RMDX), rd_rn),
26318 cCE("cfmv64hr",e000530, 2, (RMDX, RR), rn_rd),
26319 cCE("cfmvr64h",e100530, 2, (RR, RMDX), rd_rn),
26320 cCE("cfmval32",e200440, 2, (RMAX, RMFX), rd_rn),
26321 cCE("cfmv32al",e100440, 2, (RMFX, RMAX), rd_rn),
26322 cCE("cfmvam32",e200460, 2, (RMAX, RMFX), rd_rn),
26323 cCE("cfmv32am",e100460, 2, (RMFX, RMAX), rd_rn),
26324 cCE("cfmvah32",e200480, 2, (RMAX, RMFX), rd_rn),
26325 cCE("cfmv32ah",e100480, 2, (RMFX, RMAX), rd_rn),
21d799b5
NC
26326 cCE("cfmva32", e2004a0, 2, (RMAX, RMFX), rd_rn),
26327 cCE("cfmv32a", e1004a0, 2, (RMFX, RMAX), rd_rn),
26328 cCE("cfmva64", e2004c0, 2, (RMAX, RMDX), rd_rn),
26329 cCE("cfmv64a", e1004c0, 2, (RMDX, RMAX), rd_rn),
74db7efb
NC
26330 cCE("cfmvsc32",e2004e0, 2, (RMDS, RMDX), mav_dspsc),
26331 cCE("cfmv32sc",e1004e0, 2, (RMDX, RMDS), rd),
21d799b5
NC
26332 cCE("cfcpys", e000400, 2, (RMF, RMF), rd_rn),
26333 cCE("cfcpyd", e000420, 2, (RMD, RMD), rd_rn),
26334 cCE("cfcvtsd", e000460, 2, (RMD, RMF), rd_rn),
26335 cCE("cfcvtds", e000440, 2, (RMF, RMD), rd_rn),
74db7efb
NC
26336 cCE("cfcvt32s",e000480, 2, (RMF, RMFX), rd_rn),
26337 cCE("cfcvt32d",e0004a0, 2, (RMD, RMFX), rd_rn),
26338 cCE("cfcvt64s",e0004c0, 2, (RMF, RMDX), rd_rn),
26339 cCE("cfcvt64d",e0004e0, 2, (RMD, RMDX), rd_rn),
26340 cCE("cfcvts32",e100580, 2, (RMFX, RMF), rd_rn),
26341 cCE("cfcvtd32",e1005a0, 2, (RMFX, RMD), rd_rn),
21d799b5
NC
26342 cCE("cftruncs32",e1005c0, 2, (RMFX, RMF), rd_rn),
26343 cCE("cftruncd32",e1005e0, 2, (RMFX, RMD), rd_rn),
74db7efb
NC
26344 cCE("cfrshl32",e000550, 3, (RMFX, RMFX, RR), mav_triple),
26345 cCE("cfrshl64",e000570, 3, (RMDX, RMDX, RR), mav_triple),
21d799b5
NC
26346 cCE("cfsh32", e000500, 3, (RMFX, RMFX, I63s), mav_shift),
26347 cCE("cfsh64", e200500, 3, (RMDX, RMDX, I63s), mav_shift),
26348 cCE("cfcmps", e100490, 3, (RR, RMF, RMF), rd_rn_rm),
26349 cCE("cfcmpd", e1004b0, 3, (RR, RMD, RMD), rd_rn_rm),
26350 cCE("cfcmp32", e100590, 3, (RR, RMFX, RMFX), rd_rn_rm),
26351 cCE("cfcmp64", e1005b0, 3, (RR, RMDX, RMDX), rd_rn_rm),
26352 cCE("cfabss", e300400, 2, (RMF, RMF), rd_rn),
26353 cCE("cfabsd", e300420, 2, (RMD, RMD), rd_rn),
26354 cCE("cfnegs", e300440, 2, (RMF, RMF), rd_rn),
26355 cCE("cfnegd", e300460, 2, (RMD, RMD), rd_rn),
26356 cCE("cfadds", e300480, 3, (RMF, RMF, RMF), rd_rn_rm),
26357 cCE("cfaddd", e3004a0, 3, (RMD, RMD, RMD), rd_rn_rm),
26358 cCE("cfsubs", e3004c0, 3, (RMF, RMF, RMF), rd_rn_rm),
26359 cCE("cfsubd", e3004e0, 3, (RMD, RMD, RMD), rd_rn_rm),
26360 cCE("cfmuls", e100400, 3, (RMF, RMF, RMF), rd_rn_rm),
26361 cCE("cfmuld", e100420, 3, (RMD, RMD, RMD), rd_rn_rm),
26362 cCE("cfabs32", e300500, 2, (RMFX, RMFX), rd_rn),
26363 cCE("cfabs64", e300520, 2, (RMDX, RMDX), rd_rn),
26364 cCE("cfneg32", e300540, 2, (RMFX, RMFX), rd_rn),
26365 cCE("cfneg64", e300560, 2, (RMDX, RMDX), rd_rn),
26366 cCE("cfadd32", e300580, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26367 cCE("cfadd64", e3005a0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26368 cCE("cfsub32", e3005c0, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26369 cCE("cfsub64", e3005e0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26370 cCE("cfmul32", e100500, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26371 cCE("cfmul64", e100520, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26372 cCE("cfmac32", e100540, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26373 cCE("cfmsc32", e100560, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
74db7efb
NC
26374 cCE("cfmadd32",e000600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
26375 cCE("cfmsub32",e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21d799b5
NC
26376 cCE("cfmadda32", e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
26377 cCE("cfmsuba32", e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
4ed7ed8d 26378
7fadb25d
SD
26379 /* ARMv8.5-A instructions. */
26380#undef ARM_VARIANT
26381#define ARM_VARIANT & arm_ext_sb
26382#undef THUMB_VARIANT
26383#define THUMB_VARIANT & arm_ext_sb
26384 TUF("sb", 57ff070, f3bf8f70, 0, (), noargs, noargs),
26385
dad0c3bf
SD
26386#undef ARM_VARIANT
26387#define ARM_VARIANT & arm_ext_predres
26388#undef THUMB_VARIANT
26389#define THUMB_VARIANT & arm_ext_predres
26390 CE("cfprctx", e070f93, 1, (RRnpc), rd),
26391 CE("dvprctx", e070fb3, 1, (RRnpc), rd),
26392 CE("cpprctx", e070ff3, 1, (RRnpc), rd),
26393
16a1fa25 26394 /* ARMv8-M instructions. */
4ed7ed8d
TP
26395#undef ARM_VARIANT
26396#define ARM_VARIANT NULL
26397#undef THUMB_VARIANT
26398#define THUMB_VARIANT & arm_ext_v8m
cf3cf39d
TP
26399 ToU("sg", e97fe97f, 0, (), noargs),
26400 ToC("blxns", 4784, 1, (RRnpc), t_blx),
26401 ToC("bxns", 4704, 1, (RRnpc), t_bx),
26402 ToC("tt", e840f000, 2, (RRnpc, RRnpc), tt),
26403 ToC("ttt", e840f040, 2, (RRnpc, RRnpc), tt),
26404 ToC("tta", e840f080, 2, (RRnpc, RRnpc), tt),
26405 ToC("ttat", e840f0c0, 2, (RRnpc, RRnpc), tt),
16a1fa25
TP
26406
26407 /* FP for ARMv8-M Mainline. Enabled for ARMv8-M Mainline because the
26408 instructions behave as nop if no VFP is present. */
26409#undef THUMB_VARIANT
26410#define THUMB_VARIANT & arm_ext_v8m_main
cf3cf39d
TP
26411 ToC("vlldm", ec300a00, 1, (RRnpc), rn),
26412 ToC("vlstm", ec200a00, 1, (RRnpc), rn),
4389b29a
AV
26413
26414 /* Armv8.1-M Mainline instructions. */
26415#undef THUMB_VARIANT
26416#define THUMB_VARIANT & arm_ext_v8_1m_main
e43ca2cb 26417 toU("aut", _aut, 3, (R12, LR, SP), t_pacbti),
be05908c 26418 toU("autg", _autg, 3, (RR, RR, RR), t_pacbti_nonop),
3751264c 26419 ToU("bti", f3af800f, 0, (), noargs),
e07352fa 26420 toU("bxaut", _bxaut, 3, (RR, RR, RR), t_pacbti_nonop),
ce537a7d 26421 toU("pac", _pac, 3, (R12, LR, SP), t_pacbti),
f1e1d7f3 26422 toU("pacbti", _pacbti, 3, (R12, LR, SP), t_pacbti),
5c43020d 26423 toU("pacg", _pacg, 3, (RR, RR, RR), t_pacbti_pacg),
e39c1607
SD
26424 toU("cinc", _cinc, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26425 toU("cinv", _cinv, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26426 toU("cneg", _cneg, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26427 toU("csel", _csel, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26428 toU("csetm", _csetm, 2, (RRnpcsp, COND), t_cond),
26429 toU("cset", _cset, 2, (RRnpcsp, COND), t_cond),
26430 toU("csinc", _csinc, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26431 toU("csinv", _csinv, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26432 toU("csneg", _csneg, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26433
4389b29a 26434 toC("bf", _bf, 2, (EXPs, EXPs), t_branch_future),
f6b2b12d 26435 toU("bfcsel", _bfcsel, 4, (EXPs, EXPs, EXPs, COND), t_branch_future),
f1c7f421 26436 toC("bfx", _bfx, 2, (EXPs, RRnpcsp), t_branch_future),
65d1bc05 26437 toC("bfl", _bfl, 2, (EXPs, EXPs), t_branch_future),
f1c7f421 26438 toC("bflx", _bflx, 2, (EXPs, RRnpcsp), t_branch_future),
60f993ce
AV
26439
26440 toU("dls", _dls, 2, (LR, RRnpcsp), t_loloop),
26441 toU("wls", _wls, 3, (LR, RRnpcsp, EXP), t_loloop),
26442 toU("le", _le, 2, (oLR, EXP), t_loloop),
4b5a202f 26443
efd6b359 26444 ToC("clrm", e89f0000, 1, (CLRMLST), t_clrm),
5ee91343
AV
26445 ToC("vscclrm", ec9f0a00, 1, (VRSDVLST), t_vscclrm),
26446
26447#undef THUMB_VARIANT
26448#define THUMB_VARIANT & mve_ext
23d00a41
SD
26449 ToC("lsll", ea50010d, 3, (RRe, RRo, RRnpcsp_I32), mve_scalar_shift),
26450 ToC("lsrl", ea50011f, 3, (RRe, RRo, I32), mve_scalar_shift),
26451 ToC("asrl", ea50012d, 3, (RRe, RRo, RRnpcsp_I32), mve_scalar_shift),
08132bdd
SP
26452 ToC("uqrshll", ea51010d, 4, (RRe, RRo, I48_I64, RRnpcsp), mve_scalar_shift1),
26453 ToC("sqrshrl", ea51012d, 4, (RRe, RRo, I48_I64, RRnpcsp), mve_scalar_shift1),
23d00a41
SD
26454 ToC("uqshll", ea51010f, 3, (RRe, RRo, I32), mve_scalar_shift),
26455 ToC("urshrl", ea51011f, 3, (RRe, RRo, I32), mve_scalar_shift),
26456 ToC("srshrl", ea51012f, 3, (RRe, RRo, I32), mve_scalar_shift),
26457 ToC("sqshll", ea51013f, 3, (RRe, RRo, I32), mve_scalar_shift),
26458 ToC("uqrshl", ea500f0d, 2, (RRnpcsp, RRnpcsp), mve_scalar_shift),
26459 ToC("sqrshr", ea500f2d, 2, (RRnpcsp, RRnpcsp), mve_scalar_shift),
26460 ToC("uqshl", ea500f0f, 2, (RRnpcsp, I32), mve_scalar_shift),
26461 ToC("urshr", ea500f1f, 2, (RRnpcsp, I32), mve_scalar_shift),
26462 ToC("srshr", ea500f2f, 2, (RRnpcsp, I32), mve_scalar_shift),
26463 ToC("sqshl", ea500f3f, 2, (RRnpcsp, I32), mve_scalar_shift),
1b883319
AV
26464
26465 ToC("vpt", ee410f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26466 ToC("vptt", ee018f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26467 ToC("vpte", ee418f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26468 ToC("vpttt", ee014f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26469 ToC("vptte", ee01cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26470 ToC("vptet", ee41cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26471 ToC("vptee", ee414f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26472 ToC("vptttt", ee012f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26473 ToC("vpttte", ee016f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26474 ToC("vpttet", ee01ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26475 ToC("vpttee", ee01af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26476 ToC("vptett", ee41af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26477 ToC("vptete", ee41ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26478 ToC("vpteet", ee416f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26479 ToC("vpteee", ee412f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26480
5ee91343
AV
26481 ToC("vpst", fe710f4d, 0, (), mve_vpt),
26482 ToC("vpstt", fe318f4d, 0, (), mve_vpt),
26483 ToC("vpste", fe718f4d, 0, (), mve_vpt),
26484 ToC("vpsttt", fe314f4d, 0, (), mve_vpt),
26485 ToC("vpstte", fe31cf4d, 0, (), mve_vpt),
26486 ToC("vpstet", fe71cf4d, 0, (), mve_vpt),
26487 ToC("vpstee", fe714f4d, 0, (), mve_vpt),
26488 ToC("vpstttt", fe312f4d, 0, (), mve_vpt),
26489 ToC("vpsttte", fe316f4d, 0, (), mve_vpt),
26490 ToC("vpsttet", fe31ef4d, 0, (), mve_vpt),
26491 ToC("vpsttee", fe31af4d, 0, (), mve_vpt),
26492 ToC("vpstett", fe71af4d, 0, (), mve_vpt),
26493 ToC("vpstete", fe71ef4d, 0, (), mve_vpt),
26494 ToC("vpsteet", fe716f4d, 0, (), mve_vpt),
26495 ToC("vpsteee", fe712f4d, 0, (), mve_vpt),
26496
a302e574 26497 /* MVE and MVE FP only. */
7df54120 26498 mToC("vhcadd", ee000f00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vhcadd),
efd0b310 26499 mCEF(vctp, _vctp, 1, (RRnpc), mve_vctp),
c2dafc2a
AV
26500 mCEF(vadc, _vadc, 3, (RMQ, RMQ, RMQ), mve_vadc),
26501 mCEF(vadci, _vadci, 3, (RMQ, RMQ, RMQ), mve_vadc),
26502 mToC("vsbc", fe300f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
26503 mToC("vsbci", fe301f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
886e1c73 26504 mCEF(vmullb, _vmullb, 3, (RMQ, RMQ, RMQ), mve_vmull),
a302e574
AV
26505 mCEF(vabav, _vabav, 3, (RRnpcsp, RMQ, RMQ), mve_vabav),
26506 mCEF(vmladav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26507 mCEF(vmladava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26508 mCEF(vmladavx, _vmladavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
26509 mCEF(vmladavax, _vmladavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
26510 mCEF(vmlav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26511 mCEF(vmlava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26512 mCEF(vmlsdav, _vmlsdav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26513 mCEF(vmlsdava, _vmlsdava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26514 mCEF(vmlsdavx, _vmlsdavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
26515 mCEF(vmlsdavax, _vmlsdavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
26516
35c228db
AV
26517 mCEF(vst20, _vst20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26518 mCEF(vst21, _vst21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26519 mCEF(vst40, _vst40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26520 mCEF(vst41, _vst41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26521 mCEF(vst42, _vst42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26522 mCEF(vst43, _vst43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26523 mCEF(vld20, _vld20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26524 mCEF(vld21, _vld21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26525 mCEF(vld40, _vld40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26526 mCEF(vld41, _vld41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26527 mCEF(vld42, _vld42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26528 mCEF(vld43, _vld43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
f5f10c66
AV
26529 mCEF(vstrb, _vstrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26530 mCEF(vstrh, _vstrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26531 mCEF(vstrw, _vstrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26532 mCEF(vstrd, _vstrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26533 mCEF(vldrb, _vldrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26534 mCEF(vldrh, _vldrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26535 mCEF(vldrw, _vldrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26536 mCEF(vldrd, _vldrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
35c228db 26537
57785aa2
AV
26538 mCEF(vmovnt, _vmovnt, 2, (RMQ, RMQ), mve_movn),
26539 mCEF(vmovnb, _vmovnb, 2, (RMQ, RMQ), mve_movn),
c2dafc2a 26540 mCEF(vbrsr, _vbrsr, 3, (RMQ, RMQ, RR), mve_vbrsr),
26c1e780
AV
26541 mCEF(vaddlv, _vaddlv, 3, (RRe, RRo, RMQ), mve_vaddlv),
26542 mCEF(vaddlva, _vaddlva, 3, (RRe, RRo, RMQ), mve_vaddlv),
26543 mCEF(vaddv, _vaddv, 2, (RRe, RMQ), mve_vaddv),
26544 mCEF(vaddva, _vaddva, 2, (RRe, RMQ), mve_vaddv),
b409bdb6
AV
26545 mCEF(vddup, _vddup, 3, (RMQ, RRe, EXPi), mve_viddup),
26546 mCEF(vdwdup, _vdwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
26547 mCEF(vidup, _vidup, 3, (RMQ, RRe, EXPi), mve_viddup),
26548 mCEF(viwdup, _viwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
935295b5
AV
26549 mToC("vmaxa", ee330e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
26550 mToC("vmina", ee331e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
13ccd4c0
AV
26551 mCEF(vmaxv, _vmaxv, 2, (RR, RMQ), mve_vmaxv),
26552 mCEF(vmaxav, _vmaxav, 2, (RR, RMQ), mve_vmaxv),
26553 mCEF(vminv, _vminv, 2, (RR, RMQ), mve_vmaxv),
26554 mCEF(vminav, _vminav, 2, (RR, RMQ), mve_vmaxv),
57785aa2 26555
93925576
AV
26556 mCEF(vmlaldav, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26557 mCEF(vmlaldava, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26558 mCEF(vmlaldavx, _vmlaldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26559 mCEF(vmlaldavax, _vmlaldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26560 mCEF(vmlalv, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26561 mCEF(vmlalva, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26562 mCEF(vmlsldav, _vmlsldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26563 mCEF(vmlsldava, _vmlsldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26564 mCEF(vmlsldavx, _vmlsldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26565 mCEF(vmlsldavax, _vmlsldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26566 mToC("vrmlaldavh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26567 mToC("vrmlaldavha",ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26568 mCEF(vrmlaldavhx, _vrmlaldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26569 mCEF(vrmlaldavhax, _vrmlaldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26570 mToC("vrmlalvh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26571 mToC("vrmlalvha", ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26572 mCEF(vrmlsldavh, _vrmlsldavh, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26573 mCEF(vrmlsldavha, _vrmlsldavha, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26574 mCEF(vrmlsldavhx, _vrmlsldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26575 mCEF(vrmlsldavhax, _vrmlsldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26576
2d78f95b
AV
26577 mToC("vmlas", ee011e40, 3, (RMQ, RMQ, RR), mve_vmlas),
26578 mToC("vmulh", ee010e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
26579 mToC("vrmulh", ee011e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
3063888e
AV
26580 mToC("vpnot", fe310f4d, 0, (), mve_vpnot),
26581 mToC("vpsel", fe310f01, 3, (RMQ, RMQ, RMQ), mve_vpsel),
2d78f95b 26582
8b8b22a4
AV
26583 mToC("vqdmladh", ee000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26584 mToC("vqdmladhx", ee001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26585 mToC("vqrdmladh", ee000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26586 mToC("vqrdmladhx",ee001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26587 mToC("vqdmlsdh", fe000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26588 mToC("vqdmlsdhx", fe001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26589 mToC("vqrdmlsdh", fe000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26590 mToC("vqrdmlsdhx",fe001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
42b16635
AV
26591 mToC("vqdmlah", ee000e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
26592 mToC("vqdmlash", ee001e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
26593 mToC("vqrdmlash", ee001e40, 3, (RMQ, RMQ, RR), mve_vqdmlah),
35d1cfc2
AV
26594 mToC("vqdmullt", ee301f00, 3, (RMQ, RMQ, RMQRR), mve_vqdmull),
26595 mToC("vqdmullb", ee300f00, 3, (RMQ, RMQ, RMQRR), mve_vqdmull),
1be7aba3
AV
26596 mCEF(vqmovnt, _vqmovnt, 2, (RMQ, RMQ), mve_vqmovn),
26597 mCEF(vqmovnb, _vqmovnb, 2, (RMQ, RMQ), mve_vqmovn),
26598 mCEF(vqmovunt, _vqmovunt, 2, (RMQ, RMQ), mve_vqmovn),
26599 mCEF(vqmovunb, _vqmovunb, 2, (RMQ, RMQ), mve_vqmovn),
8b8b22a4 26600
4aa88b50
AV
26601 mCEF(vshrnt, _vshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26602 mCEF(vshrnb, _vshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26603 mCEF(vrshrnt, _vrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26604 mCEF(vrshrnb, _vrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26605 mCEF(vqshrnt, _vqrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26606 mCEF(vqshrnb, _vqrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26607 mCEF(vqshrunt, _vqrshrunt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26608 mCEF(vqshrunb, _vqrshrunb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26609 mCEF(vqrshrnt, _vqrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26610 mCEF(vqrshrnb, _vqrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26611 mCEF(vqrshrunt, _vqrshrunt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26612 mCEF(vqrshrunb, _vqrshrunb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26613
acca5630
AV
26614 mToC("vshlc", eea00fc0, 3, (RMQ, RR, I32z), mve_vshlc),
26615 mToC("vshllt", ee201e00, 3, (RMQ, RMQ, I32), mve_vshll),
26616 mToC("vshllb", ee200e00, 3, (RMQ, RMQ, I32), mve_vshll),
26617
1f6234a3
AV
26618 toU("dlstp", _dlstp, 2, (LR, RR), t_loloop),
26619 toU("wlstp", _wlstp, 3, (LR, RR, EXP), t_loloop),
26620 toU("letp", _letp, 2, (LR, EXP), t_loloop),
26621 toU("lctp", _lctp, 0, (), t_loloop),
26622
5d281bf0
AV
26623#undef THUMB_VARIANT
26624#define THUMB_VARIANT & mve_fp_ext
26625 mToC("vcmul", ee300e00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vcmul),
f30ee27c 26626 mToC("vfmas", ee311e40, 3, (RMQ, RMQ, RR), mve_vfmas),
935295b5
AV
26627 mToC("vmaxnma", ee3f0e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
26628 mToC("vminnma", ee3f1e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
8cd78170
AV
26629 mToC("vmaxnmv", eeee0f00, 2, (RR, RMQ), mve_vmaxnmv),
26630 mToC("vmaxnmav",eeec0f00, 2, (RR, RMQ), mve_vmaxnmv),
26631 mToC("vminnmv", eeee0f80, 2, (RR, RMQ), mve_vmaxnmv),
26632 mToC("vminnmav",eeec0f80, 2, (RR, RMQ), mve_vmaxnmv),
5d281bf0 26633
5ee91343 26634#undef ARM_VARIANT
57785aa2 26635#define ARM_VARIANT & fpu_vfp_ext_v1
5ee91343
AV
26636#undef THUMB_VARIANT
26637#define THUMB_VARIANT & arm_ext_v6t2
26638
57785aa2
AV
26639 mcCE(fcpyd, eb00b40, 2, (RVD, RVD), vfp_dp_rd_rm),
26640
26641#undef ARM_VARIANT
26642#define ARM_VARIANT & fpu_vfp_ext_v1xd
26643
48f4d8ce
AV
26644 mnCEF(vmla, _vmla, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mac_maybe_scalar),
26645 mnCEF(vmul, _vmul, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mul),
57785aa2
AV
26646 MNCE(vmov, 0, 1, (VMOV), neon_mov),
26647 mcCE(fmrs, e100a10, 2, (RR, RVS), vfp_reg_from_sp),
26648 mcCE(fmsr, e000a10, 2, (RVS, RR), vfp_sp_from_reg),
26649 mcCE(fcpys, eb00a40, 2, (RVS, RVS), vfp_sp_monadic),
26650
886e1c73
AV
26651 mCEF(vmullt, _vmullt, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ), mve_vmull),
26652 mnCEF(vadd, _vadd, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
26653 mnCEF(vsub, _vsub, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
5ee91343 26654
485dee97
AV
26655 MNCEF(vabs, 1b10300, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
26656 MNCEF(vneg, 1b10380, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
26657
57785aa2
AV
26658 mCEF(vmovlt, _vmovlt, 1, (VMOV), mve_movl),
26659 mCEF(vmovlb, _vmovlb, 1, (VMOV), mve_movl),
26660
1b883319
AV
26661 mnCE(vcmp, _vcmp, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
26662 mnCE(vcmpe, _vcmpe, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
26663
57785aa2
AV
26664#undef ARM_VARIANT
26665#define ARM_VARIANT & fpu_vfp_ext_v2
26666
26667 mcCE(fmsrr, c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
26668 mcCE(fmrrs, c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
26669 mcCE(fmdrr, c400b10, 3, (RVD, RR, RR), vfp_dp_rm_rd_rn),
26670 mcCE(fmrrd, c500b10, 3, (RR, RR, RVD), vfp_dp_rd_rn_rm),
26671
dd9634d9
AV
26672#undef ARM_VARIANT
26673#define ARM_VARIANT & fpu_vfp_ext_armv8xd
26674 mnUF(vcvta, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvta),
26675 mnUF(vcvtp, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtp),
26676 mnUF(vcvtn, _vcvta, 3, (RNSDQMQ, oRNSDQMQ, oI32z), neon_cvtn),
26677 mnUF(vcvtm, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtm),
935295b5
AV
26678 mnUF(vmaxnm, _vmaxnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
26679 mnUF(vminnm, _vminnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
dd9634d9
AV
26680
26681#undef ARM_VARIANT
5ee91343 26682#define ARM_VARIANT & fpu_neon_ext_v1
f601a00c 26683 mnUF(vabd, _vabd, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
5ee91343 26684 mnUF(vabdl, _vabdl, 3, (RNQMQ, RNDMQ, RNDMQ), neon_dyadic_long),
66d1f7cc
AV
26685 mnUF(vaddl, _vaddl, 3, (RNSDQMQ, oRNSDMQ, RNSDMQR), neon_dyadic_long),
26686 mnUF(vsubl, _vsubl, 3, (RNSDQMQ, oRNSDMQ, RNSDMQR), neon_dyadic_long),
f601a00c
AV
26687 mnUF(vand, _vand, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26688 mnUF(vbic, _vbic, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26689 mnUF(vorr, _vorr, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26690 mnUF(vorn, _vorn, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26691 mnUF(veor, _veor, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_logic),
f30ee27c
AV
26692 MNUF(vcls, 1b00400, 2, (RNDQMQ, RNDQMQ), neon_cls),
26693 MNUF(vclz, 1b00480, 2, (RNDQMQ, RNDQMQ), neon_clz),
b409bdb6 26694 mnCE(vdup, _vdup, 2, (RNDQMQ, RR_RNSC), neon_dup),
7df54120
AV
26695 MNUF(vhadd, 00000000, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
26696 MNUF(vrhadd, 00000100, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_i_su),
26697 MNUF(vhsub, 00000200, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
935295b5
AV
26698 mnUF(vmin, _vmin, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
26699 mnUF(vmax, _vmax, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
a8465a06
AV
26700 MNUF(vqadd, 0000010, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
26701 MNUF(vqsub, 0000210, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
1a186d29
AV
26702 mnUF(vmvn, _vmvn, 2, (RNDQMQ, RNDQMQ_Ibig), neon_mvn),
26703 MNUF(vqabs, 1b00700, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
26704 MNUF(vqneg, 1b00780, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
42b16635
AV
26705 mnUF(vqrdmlah, _vqrdmlah,3, (RNDQMQ, oRNDQMQ, RNDQ_RNSC_RR), neon_qrdmlah),
26706 mnUF(vqdmulh, _vqdmulh, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
26707 mnUF(vqrdmulh, _vqrdmulh,3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
1be7aba3
AV
26708 MNUF(vqrshl, 0000510, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
26709 MNUF(vrshl, 0000500, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
4401c241
AV
26710 MNUF(vshr, 0800010, 3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
26711 MNUF(vrshr, 0800210, 3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
26712 MNUF(vsli, 1800510, 3, (RNDQMQ, oRNDQMQ, I63), neon_sli),
26713 MNUF(vsri, 1800410, 3, (RNDQMQ, oRNDQMQ, I64z), neon_sri),
26714 MNUF(vrev64, 1b00000, 2, (RNDQMQ, RNDQMQ), neon_rev),
26715 MNUF(vrev32, 1b00080, 2, (RNDQMQ, RNDQMQ), neon_rev),
26716 MNUF(vrev16, 1b00100, 2, (RNDQMQ, RNDQMQ), neon_rev),
5150f0d8
AV
26717 mnUF(vshl, _vshl, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_shl),
26718 mnUF(vqshl, _vqshl, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_qshl),
26719 MNUF(vqshlu, 1800610, 3, (RNDQMQ, oRNDQMQ, I63), neon_qshlu_imm),
5d281bf0
AV
26720
26721#undef ARM_VARIANT
26722#define ARM_VARIANT & arm_ext_v8_3
26723#undef THUMB_VARIANT
26724#define THUMB_VARIANT & arm_ext_v6t2_v8m
26725 MNUF (vcadd, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ, EXPi), vcadd),
26726 MNUF (vcmla, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ_RNSC, EXPi), vcmla),
aab2c27d
MM
26727
26728#undef ARM_VARIANT
26729#define ARM_VARIANT &arm_ext_bf16
26730#undef THUMB_VARIANT
26731#define THUMB_VARIANT &arm_ext_bf16
26732 TUF ("vdot", c000d00, fc000d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), vdot, vdot),
26733 TUF ("vmmla", c000c40, fc000c40, 3, (RNQ, RNQ, RNQ), vmmla, vmmla),
26734 TUF ("vfmab", c300810, fc300810, 3, (RNDQ, RNDQ, RNDQ_RNSC), bfloat_vfma, bfloat_vfma),
26735
26736#undef ARM_VARIANT
26737#define ARM_VARIANT &arm_ext_i8mm
26738#undef THUMB_VARIANT
26739#define THUMB_VARIANT &arm_ext_i8mm
26740 TUF ("vsmmla", c200c40, fc200c40, 3, (RNQ, RNQ, RNQ), vsmmla, vsmmla),
26741 TUF ("vummla", c200c50, fc200c50, 3, (RNQ, RNQ, RNQ), vummla, vummla),
616ce08e 26742 TUF ("vusmmla", ca00c40, fca00c40, 3, (RNQ, RNQ, RNQ), vsmmla, vsmmla),
aab2c27d
MM
26743 TUF ("vusdot", c800d00, fc800d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), vusdot, vusdot),
26744 TUF ("vsudot", c800d10, fc800d10, 3, (RNDQ, RNDQ, RNSC), vsudot, vsudot),
4934a27c
MM
26745
26746#undef ARM_VARIANT
26747#undef THUMB_VARIANT
26748#define THUMB_VARIANT &arm_ext_cde
26749 ToC ("cx1", ee000000, 3, (RCP, APSR_RR, I8191), cx1),
26750 ToC ("cx1a", fe000000, 3, (RCP, APSR_RR, I8191), cx1a),
26751 ToC ("cx1d", ee000040, 4, (RCP, RR, APSR_RR, I8191), cx1d),
26752 ToC ("cx1da", fe000040, 4, (RCP, RR, APSR_RR, I8191), cx1da),
26753
26754 ToC ("cx2", ee400000, 4, (RCP, APSR_RR, APSR_RR, I511), cx2),
26755 ToC ("cx2a", fe400000, 4, (RCP, APSR_RR, APSR_RR, I511), cx2a),
26756 ToC ("cx2d", ee400040, 5, (RCP, RR, APSR_RR, APSR_RR, I511), cx2d),
26757 ToC ("cx2da", fe400040, 5, (RCP, RR, APSR_RR, APSR_RR, I511), cx2da),
26758
26759 ToC ("cx3", ee800000, 5, (RCP, APSR_RR, APSR_RR, APSR_RR, I63), cx3),
26760 ToC ("cx3a", fe800000, 5, (RCP, APSR_RR, APSR_RR, APSR_RR, I63), cx3a),
26761 ToC ("cx3d", ee800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3d),
26762 ToC ("cx3da", fe800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3da),
5aae9ae9
MM
26763
26764 mToC ("vcx1", ec200000, 3, (RCP, RNSDMQ, I4095), vcx1),
26765 mToC ("vcx1a", fc200000, 3, (RCP, RNSDMQ, I4095), vcx1),
26766
26767 mToC ("vcx2", ec300000, 4, (RCP, RNSDMQ, RNSDMQ, I127), vcx2),
26768 mToC ("vcx2a", fc300000, 4, (RCP, RNSDMQ, RNSDMQ, I127), vcx2),
26769
26770 mToC ("vcx3", ec800000, 5, (RCP, RNSDMQ, RNSDMQ, RNSDMQ, I15), vcx3),
26771 mToC ("vcx3a", fc800000, 5, (RCP, RNSDMQ, RNSDMQ, RNSDMQ, I15), vcx3),
c19d1205 26772};
5aae9ae9 26773
c19d1205
ZW
26774#undef ARM_VARIANT
26775#undef THUMB_VARIANT
26776#undef TCE
c19d1205
ZW
26777#undef TUE
26778#undef TUF
26779#undef TCC
8f06b2d8 26780#undef cCE
e3cb604e
PB
26781#undef cCL
26782#undef C3E
4389b29a 26783#undef C3
c19d1205
ZW
26784#undef CE
26785#undef CM
4389b29a 26786#undef CL
c19d1205
ZW
26787#undef UE
26788#undef UF
26789#undef UT
5287ad62
JB
26790#undef NUF
26791#undef nUF
26792#undef NCE
26793#undef nCE
c19d1205
ZW
26794#undef OPS0
26795#undef OPS1
26796#undef OPS2
26797#undef OPS3
26798#undef OPS4
26799#undef OPS5
26800#undef OPS6
26801#undef do_0
4389b29a
AV
26802#undef ToC
26803#undef toC
26804#undef ToU
f6b2b12d 26805#undef toU
c19d1205
ZW
26806\f
26807/* MD interface: bits in the object file. */
bfae80f2 26808
c19d1205
ZW
26809/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
26810 for use in the a.out file, and stores them in the array pointed to by buf.
26811 This knows about the endian-ness of the target machine and does
26812 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
26813 2 (short) and 4 (long) Floating numbers are put out as a series of
26814 LITTLENUMS (shorts, here at least). */
b99bd4ef 26815
c19d1205
ZW
26816void
26817md_number_to_chars (char * buf, valueT val, int n)
26818{
26819 if (target_big_endian)
26820 number_to_chars_bigendian (buf, val, n);
26821 else
26822 number_to_chars_littleendian (buf, val, n);
bfae80f2
RE
26823}
26824
c19d1205
ZW
26825static valueT
26826md_chars_to_number (char * buf, int n)
bfae80f2 26827{
c19d1205
ZW
26828 valueT result = 0;
26829 unsigned char * where = (unsigned char *) buf;
bfae80f2 26830
c19d1205 26831 if (target_big_endian)
b99bd4ef 26832 {
c19d1205
ZW
26833 while (n--)
26834 {
26835 result <<= 8;
26836 result |= (*where++ & 255);
26837 }
b99bd4ef 26838 }
c19d1205 26839 else
b99bd4ef 26840 {
c19d1205
ZW
26841 while (n--)
26842 {
26843 result <<= 8;
26844 result |= (where[n] & 255);
26845 }
bfae80f2 26846 }
b99bd4ef 26847
c19d1205 26848 return result;
bfae80f2 26849}
b99bd4ef 26850
c19d1205 26851/* MD interface: Sections. */
b99bd4ef 26852
fa94de6b
RM
26853/* Calculate the maximum variable size (i.e., excluding fr_fix)
26854 that an rs_machine_dependent frag may reach. */
26855
26856unsigned int
26857arm_frag_max_var (fragS *fragp)
26858{
26859 /* We only use rs_machine_dependent for variable-size Thumb instructions,
26860 which are either THUMB_SIZE (2) or INSN_SIZE (4).
26861
26862 Note that we generate relaxable instructions even for cases that don't
26863 really need it, like an immediate that's a trivial constant. So we're
26864 overestimating the instruction size for some of those cases. Rather
26865 than putting more intelligence here, it would probably be better to
26866 avoid generating a relaxation frag in the first place when it can be
26867 determined up front that a short instruction will suffice. */
26868
26869 gas_assert (fragp->fr_type == rs_machine_dependent);
26870 return INSN_SIZE;
26871}
26872
0110f2b8
PB
26873/* Estimate the size of a frag before relaxing. Assume everything fits in
26874 2 bytes. */
26875
c19d1205 26876int
0110f2b8 26877md_estimate_size_before_relax (fragS * fragp,
c19d1205
ZW
26878 segT segtype ATTRIBUTE_UNUSED)
26879{
0110f2b8
PB
26880 fragp->fr_var = 2;
26881 return 2;
26882}
26883
26884/* Convert a machine dependent frag. */
26885
26886void
26887md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
26888{
26889 unsigned long insn;
26890 unsigned long old_op;
26891 char *buf;
26892 expressionS exp;
26893 fixS *fixp;
26894 int reloc_type;
26895 int pc_rel;
26896 int opcode;
26897
26898 buf = fragp->fr_literal + fragp->fr_fix;
26899
26900 old_op = bfd_get_16(abfd, buf);
5f4273c7
NC
26901 if (fragp->fr_symbol)
26902 {
0110f2b8
PB
26903 exp.X_op = O_symbol;
26904 exp.X_add_symbol = fragp->fr_symbol;
5f4273c7
NC
26905 }
26906 else
26907 {
0110f2b8 26908 exp.X_op = O_constant;
5f4273c7 26909 }
0110f2b8
PB
26910 exp.X_add_number = fragp->fr_offset;
26911 opcode = fragp->fr_subtype;
26912 switch (opcode)
26913 {
26914 case T_MNEM_ldr_pc:
26915 case T_MNEM_ldr_pc2:
26916 case T_MNEM_ldr_sp:
26917 case T_MNEM_str_sp:
26918 case T_MNEM_ldr:
26919 case T_MNEM_ldrb:
26920 case T_MNEM_ldrh:
26921 case T_MNEM_str:
26922 case T_MNEM_strb:
26923 case T_MNEM_strh:
26924 if (fragp->fr_var == 4)
26925 {
5f4273c7 26926 insn = THUMB_OP32 (opcode);
0110f2b8
PB
26927 if ((old_op >> 12) == 4 || (old_op >> 12) == 9)
26928 {
26929 insn |= (old_op & 0x700) << 4;
26930 }
26931 else
26932 {
26933 insn |= (old_op & 7) << 12;
26934 insn |= (old_op & 0x38) << 13;
26935 }
26936 insn |= 0x00000c00;
26937 put_thumb32_insn (buf, insn);
26938 reloc_type = BFD_RELOC_ARM_T32_OFFSET_IMM;
26939 }
26940 else
26941 {
26942 reloc_type = BFD_RELOC_ARM_THUMB_OFFSET;
26943 }
26944 pc_rel = (opcode == T_MNEM_ldr_pc2);
26945 break;
26946 case T_MNEM_adr:
d3e52e12
TC
26947 /* Thumb bits should be set in the frag handling so we process them
26948 after all symbols have been seen. PR gas/25235. */
26949 if (exp.X_op == O_symbol
26950 && exp.X_add_symbol != NULL
26951 && S_IS_DEFINED (exp.X_add_symbol)
26952 && THUMB_IS_FUNC (exp.X_add_symbol))
26953 exp.X_add_number |= 1;
26954
0110f2b8
PB
26955 if (fragp->fr_var == 4)
26956 {
26957 insn = THUMB_OP32 (opcode);
26958 insn |= (old_op & 0xf0) << 4;
26959 put_thumb32_insn (buf, insn);
26960 reloc_type = BFD_RELOC_ARM_T32_ADD_PC12;
26961 }
26962 else
26963 {
26964 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
26965 exp.X_add_number -= 4;
26966 }
26967 pc_rel = 1;
26968 break;
26969 case T_MNEM_mov:
26970 case T_MNEM_movs:
26971 case T_MNEM_cmp:
26972 case T_MNEM_cmn:
26973 if (fragp->fr_var == 4)
26974 {
26975 int r0off = (opcode == T_MNEM_mov
26976 || opcode == T_MNEM_movs) ? 0 : 8;
26977 insn = THUMB_OP32 (opcode);
26978 insn = (insn & 0xe1ffffff) | 0x10000000;
26979 insn |= (old_op & 0x700) << r0off;
26980 put_thumb32_insn (buf, insn);
26981 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
26982 }
26983 else
26984 {
26985 reloc_type = BFD_RELOC_ARM_THUMB_IMM;
26986 }
26987 pc_rel = 0;
26988 break;
26989 case T_MNEM_b:
26990 if (fragp->fr_var == 4)
26991 {
26992 insn = THUMB_OP32(opcode);
26993 put_thumb32_insn (buf, insn);
26994 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH25;
26995 }
26996 else
26997 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH12;
26998 pc_rel = 1;
26999 break;
27000 case T_MNEM_bcond:
27001 if (fragp->fr_var == 4)
27002 {
27003 insn = THUMB_OP32(opcode);
27004 insn |= (old_op & 0xf00) << 14;
27005 put_thumb32_insn (buf, insn);
27006 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH20;
27007 }
27008 else
27009 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH9;
27010 pc_rel = 1;
27011 break;
27012 case T_MNEM_add_sp:
27013 case T_MNEM_add_pc:
27014 case T_MNEM_inc_sp:
27015 case T_MNEM_dec_sp:
27016 if (fragp->fr_var == 4)
27017 {
27018 /* ??? Choose between add and addw. */
27019 insn = THUMB_OP32 (opcode);
27020 insn |= (old_op & 0xf0) << 4;
27021 put_thumb32_insn (buf, insn);
16805f35
PB
27022 if (opcode == T_MNEM_add_pc)
27023 reloc_type = BFD_RELOC_ARM_T32_IMM12;
27024 else
27025 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
0110f2b8
PB
27026 }
27027 else
27028 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
27029 pc_rel = 0;
27030 break;
27031
27032 case T_MNEM_addi:
27033 case T_MNEM_addis:
27034 case T_MNEM_subi:
27035 case T_MNEM_subis:
27036 if (fragp->fr_var == 4)
27037 {
27038 insn = THUMB_OP32 (opcode);
27039 insn |= (old_op & 0xf0) << 4;
27040 insn |= (old_op & 0xf) << 16;
27041 put_thumb32_insn (buf, insn);
16805f35
PB
27042 if (insn & (1 << 20))
27043 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
27044 else
27045 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8
PB
27046 }
27047 else
27048 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
27049 pc_rel = 0;
27050 break;
27051 default:
5f4273c7 27052 abort ();
0110f2b8
PB
27053 }
27054 fixp = fix_new_exp (fragp, fragp->fr_fix, fragp->fr_var, &exp, pc_rel,
21d799b5 27055 (enum bfd_reloc_code_real) reloc_type);
0110f2b8
PB
27056 fixp->fx_file = fragp->fr_file;
27057 fixp->fx_line = fragp->fr_line;
27058 fragp->fr_fix += fragp->fr_var;
3cfdb781
TG
27059
27060 /* Set whether we use thumb-2 ISA based on final relaxation results. */
27061 if (thumb_mode && fragp->fr_var == 4 && no_cpu_selected ()
27062 && !ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2))
27063 ARM_MERGE_FEATURE_SETS (arm_arch_used, thumb_arch_used, arm_ext_v6t2);
0110f2b8
PB
27064}
27065
27066/* Return the size of a relaxable immediate operand instruction.
27067 SHIFT and SIZE specify the form of the allowable immediate. */
27068static int
27069relax_immediate (fragS *fragp, int size, int shift)
27070{
27071 offsetT offset;
27072 offsetT mask;
27073 offsetT low;
27074
27075 /* ??? Should be able to do better than this. */
27076 if (fragp->fr_symbol)
27077 return 4;
27078
27079 low = (1 << shift) - 1;
27080 mask = (1 << (shift + size)) - (1 << shift);
27081 offset = fragp->fr_offset;
27082 /* Force misaligned offsets to 32-bit variant. */
27083 if (offset & low)
5e77afaa 27084 return 4;
0110f2b8
PB
27085 if (offset & ~mask)
27086 return 4;
27087 return 2;
27088}
27089
5e77afaa
PB
27090/* Get the address of a symbol during relaxation. */
27091static addressT
5f4273c7 27092relaxed_symbol_addr (fragS *fragp, long stretch)
5e77afaa
PB
27093{
27094 fragS *sym_frag;
27095 addressT addr;
27096 symbolS *sym;
27097
27098 sym = fragp->fr_symbol;
27099 sym_frag = symbol_get_frag (sym);
27100 know (S_GET_SEGMENT (sym) != absolute_section
27101 || sym_frag == &zero_address_frag);
27102 addr = S_GET_VALUE (sym) + fragp->fr_offset;
27103
27104 /* If frag has yet to be reached on this pass, assume it will
27105 move by STRETCH just as we did. If this is not so, it will
27106 be because some frag between grows, and that will force
27107 another pass. */
27108
27109 if (stretch != 0
27110 && sym_frag->relax_marker != fragp->relax_marker)
4396b686
PB
27111 {
27112 fragS *f;
27113
27114 /* Adjust stretch for any alignment frag. Note that if have
27115 been expanding the earlier code, the symbol may be
27116 defined in what appears to be an earlier frag. FIXME:
27117 This doesn't handle the fr_subtype field, which specifies
27118 a maximum number of bytes to skip when doing an
27119 alignment. */
27120 for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
27121 {
27122 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
27123 {
27124 if (stretch < 0)
27125 stretch = - ((- stretch)
27126 & ~ ((1 << (int) f->fr_offset) - 1));
27127 else
27128 stretch &= ~ ((1 << (int) f->fr_offset) - 1);
27129 if (stretch == 0)
27130 break;
27131 }
27132 }
27133 if (f != NULL)
27134 addr += stretch;
27135 }
5e77afaa
PB
27136
27137 return addr;
27138}
27139
0110f2b8
PB
27140/* Return the size of a relaxable adr pseudo-instruction or PC-relative
27141 load. */
27142static int
5e77afaa 27143relax_adr (fragS *fragp, asection *sec, long stretch)
0110f2b8
PB
27144{
27145 addressT addr;
27146 offsetT val;
27147
27148 /* Assume worst case for symbols not known to be in the same section. */
974da60d
NC
27149 if (fragp->fr_symbol == NULL
27150 || !S_IS_DEFINED (fragp->fr_symbol)
77db8e2e 27151 || sec != S_GET_SEGMENT (fragp->fr_symbol)
d3e52e12
TC
27152 || S_IS_WEAK (fragp->fr_symbol)
27153 || THUMB_IS_FUNC (fragp->fr_symbol))
0110f2b8
PB
27154 return 4;
27155
5f4273c7 27156 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
27157 addr = fragp->fr_address + fragp->fr_fix;
27158 addr = (addr + 4) & ~3;
5e77afaa 27159 /* Force misaligned targets to 32-bit variant. */
0110f2b8 27160 if (val & 3)
5e77afaa 27161 return 4;
0110f2b8
PB
27162 val -= addr;
27163 if (val < 0 || val > 1020)
27164 return 4;
27165 return 2;
27166}
27167
27168/* Return the size of a relaxable add/sub immediate instruction. */
27169static int
27170relax_addsub (fragS *fragp, asection *sec)
27171{
27172 char *buf;
27173 int op;
27174
27175 buf = fragp->fr_literal + fragp->fr_fix;
27176 op = bfd_get_16(sec->owner, buf);
27177 if ((op & 0xf) == ((op >> 4) & 0xf))
27178 return relax_immediate (fragp, 8, 0);
27179 else
27180 return relax_immediate (fragp, 3, 0);
27181}
27182
e83a675f
RE
27183/* Return TRUE iff the definition of symbol S could be pre-empted
27184 (overridden) at link or load time. */
5b7c81bd 27185static bool
e83a675f
RE
27186symbol_preemptible (symbolS *s)
27187{
27188 /* Weak symbols can always be pre-empted. */
27189 if (S_IS_WEAK (s))
5b7c81bd 27190 return true;
e83a675f
RE
27191
27192 /* Non-global symbols cannot be pre-empted. */
27193 if (! S_IS_EXTERNAL (s))
5b7c81bd 27194 return false;
e83a675f
RE
27195
27196#ifdef OBJ_ELF
27197 /* In ELF, a global symbol can be marked protected, or private. In that
27198 case it can't be pre-empted (other definitions in the same link unit
27199 would violate the ODR). */
27200 if (ELF_ST_VISIBILITY (S_GET_OTHER (s)) > STV_DEFAULT)
5b7c81bd 27201 return false;
e83a675f
RE
27202#endif
27203
27204 /* Other global symbols might be pre-empted. */
5b7c81bd 27205 return true;
e83a675f 27206}
0110f2b8
PB
27207
27208/* Return the size of a relaxable branch instruction. BITS is the
27209 size of the offset field in the narrow instruction. */
27210
27211static int
5e77afaa 27212relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
0110f2b8
PB
27213{
27214 addressT addr;
27215 offsetT val;
27216 offsetT limit;
27217
27218 /* Assume worst case for symbols not known to be in the same section. */
5f4273c7 27219 if (!S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
27220 || sec != S_GET_SEGMENT (fragp->fr_symbol)
27221 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
27222 return 4;
27223
267bf995 27224#ifdef OBJ_ELF
e83a675f 27225 /* A branch to a function in ARM state will require interworking. */
267bf995
RR
27226 if (S_IS_DEFINED (fragp->fr_symbol)
27227 && ARM_IS_FUNC (fragp->fr_symbol))
27228 return 4;
e83a675f 27229#endif
0d9b4b55 27230
e83a675f 27231 if (symbol_preemptible (fragp->fr_symbol))
0d9b4b55 27232 return 4;
267bf995 27233
5f4273c7 27234 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
27235 addr = fragp->fr_address + fragp->fr_fix + 4;
27236 val -= addr;
27237
27238 /* Offset is a signed value *2 */
27239 limit = 1 << bits;
27240 if (val >= limit || val < -limit)
27241 return 4;
27242 return 2;
27243}
27244
27245
27246/* Relax a machine dependent frag. This returns the amount by which
27247 the current size of the frag should change. */
27248
27249int
5e77afaa 27250arm_relax_frag (asection *sec, fragS *fragp, long stretch)
0110f2b8
PB
27251{
27252 int oldsize;
27253 int newsize;
27254
27255 oldsize = fragp->fr_var;
27256 switch (fragp->fr_subtype)
27257 {
27258 case T_MNEM_ldr_pc2:
5f4273c7 27259 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
27260 break;
27261 case T_MNEM_ldr_pc:
27262 case T_MNEM_ldr_sp:
27263 case T_MNEM_str_sp:
5f4273c7 27264 newsize = relax_immediate (fragp, 8, 2);
0110f2b8
PB
27265 break;
27266 case T_MNEM_ldr:
27267 case T_MNEM_str:
5f4273c7 27268 newsize = relax_immediate (fragp, 5, 2);
0110f2b8
PB
27269 break;
27270 case T_MNEM_ldrh:
27271 case T_MNEM_strh:
5f4273c7 27272 newsize = relax_immediate (fragp, 5, 1);
0110f2b8
PB
27273 break;
27274 case T_MNEM_ldrb:
27275 case T_MNEM_strb:
5f4273c7 27276 newsize = relax_immediate (fragp, 5, 0);
0110f2b8
PB
27277 break;
27278 case T_MNEM_adr:
5f4273c7 27279 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
27280 break;
27281 case T_MNEM_mov:
27282 case T_MNEM_movs:
27283 case T_MNEM_cmp:
27284 case T_MNEM_cmn:
5f4273c7 27285 newsize = relax_immediate (fragp, 8, 0);
0110f2b8
PB
27286 break;
27287 case T_MNEM_b:
5f4273c7 27288 newsize = relax_branch (fragp, sec, 11, stretch);
0110f2b8
PB
27289 break;
27290 case T_MNEM_bcond:
5f4273c7 27291 newsize = relax_branch (fragp, sec, 8, stretch);
0110f2b8
PB
27292 break;
27293 case T_MNEM_add_sp:
27294 case T_MNEM_add_pc:
27295 newsize = relax_immediate (fragp, 8, 2);
27296 break;
27297 case T_MNEM_inc_sp:
27298 case T_MNEM_dec_sp:
27299 newsize = relax_immediate (fragp, 7, 2);
27300 break;
27301 case T_MNEM_addi:
27302 case T_MNEM_addis:
27303 case T_MNEM_subi:
27304 case T_MNEM_subis:
27305 newsize = relax_addsub (fragp, sec);
27306 break;
27307 default:
5f4273c7 27308 abort ();
0110f2b8 27309 }
5e77afaa
PB
27310
27311 fragp->fr_var = newsize;
27312 /* Freeze wide instructions that are at or before the same location as
27313 in the previous pass. This avoids infinite loops.
5f4273c7
NC
27314 Don't freeze them unconditionally because targets may be artificially
27315 misaligned by the expansion of preceding frags. */
5e77afaa 27316 if (stretch <= 0 && newsize > 2)
0110f2b8 27317 {
0110f2b8 27318 md_convert_frag (sec->owner, sec, fragp);
5f4273c7 27319 frag_wane (fragp);
0110f2b8 27320 }
5e77afaa 27321
0110f2b8 27322 return newsize - oldsize;
c19d1205 27323}
b99bd4ef 27324
c19d1205 27325/* Round up a section size to the appropriate boundary. */
b99bd4ef 27326
c19d1205
ZW
27327valueT
27328md_section_align (segT segment ATTRIBUTE_UNUSED,
27329 valueT size)
27330{
6844c0cc 27331 return size;
bfae80f2 27332}
b99bd4ef 27333
c19d1205
ZW
27334/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
27335 of an rs_align_code fragment. */
27336
27337void
27338arm_handle_align (fragS * fragP)
bfae80f2 27339{
d9235011 27340 static unsigned char const arm_noop[2][2][4] =
e7495e45
NS
27341 {
27342 { /* ARMv1 */
27343 {0x00, 0x00, 0xa0, 0xe1}, /* LE */
27344 {0xe1, 0xa0, 0x00, 0x00}, /* BE */
27345 },
27346 { /* ARMv6k */
27347 {0x00, 0xf0, 0x20, 0xe3}, /* LE */
27348 {0xe3, 0x20, 0xf0, 0x00}, /* BE */
27349 },
27350 };
d9235011 27351 static unsigned char const thumb_noop[2][2][2] =
e7495e45
NS
27352 {
27353 { /* Thumb-1 */
27354 {0xc0, 0x46}, /* LE */
27355 {0x46, 0xc0}, /* BE */
27356 },
27357 { /* Thumb-2 */
27358 {0x00, 0xbf}, /* LE */
27359 {0xbf, 0x00} /* BE */
27360 }
27361 };
d9235011 27362 static unsigned char const wide_thumb_noop[2][4] =
e7495e45
NS
27363 { /* Wide Thumb-2 */
27364 {0xaf, 0xf3, 0x00, 0x80}, /* LE */
27365 {0xf3, 0xaf, 0x80, 0x00}, /* BE */
27366 };
c921be7d 27367
e7495e45 27368 unsigned bytes, fix, noop_size;
c19d1205 27369 char * p;
d9235011
TS
27370 const unsigned char * noop;
27371 const unsigned char *narrow_noop = NULL;
cd000bff
DJ
27372#ifdef OBJ_ELF
27373 enum mstate state;
27374#endif
bfae80f2 27375
c19d1205 27376 if (fragP->fr_type != rs_align_code)
bfae80f2
RE
27377 return;
27378
c19d1205
ZW
27379 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
27380 p = fragP->fr_literal + fragP->fr_fix;
27381 fix = 0;
bfae80f2 27382
c19d1205
ZW
27383 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
27384 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
bfae80f2 27385
cd000bff 27386 gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
8dc2430f 27387
cd000bff 27388 if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
a737bd4d 27389 {
7f78eb34
JW
27390 if (ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
27391 ? selected_cpu : arm_arch_none, arm_ext_v6t2))
e7495e45
NS
27392 {
27393 narrow_noop = thumb_noop[1][target_big_endian];
27394 noop = wide_thumb_noop[target_big_endian];
27395 }
c19d1205 27396 else
e7495e45
NS
27397 noop = thumb_noop[0][target_big_endian];
27398 noop_size = 2;
cd000bff
DJ
27399#ifdef OBJ_ELF
27400 state = MAP_THUMB;
27401#endif
7ed4c4c5
NC
27402 }
27403 else
27404 {
7f78eb34
JW
27405 noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
27406 ? selected_cpu : arm_arch_none,
27407 arm_ext_v6k) != 0]
e7495e45
NS
27408 [target_big_endian];
27409 noop_size = 4;
cd000bff
DJ
27410#ifdef OBJ_ELF
27411 state = MAP_ARM;
27412#endif
7ed4c4c5 27413 }
c921be7d 27414
e7495e45 27415 fragP->fr_var = noop_size;
c921be7d 27416
c19d1205 27417 if (bytes & (noop_size - 1))
7ed4c4c5 27418 {
c19d1205 27419 fix = bytes & (noop_size - 1);
cd000bff
DJ
27420#ifdef OBJ_ELF
27421 insert_data_mapping_symbol (state, fragP->fr_fix, fragP, fix);
27422#endif
c19d1205
ZW
27423 memset (p, 0, fix);
27424 p += fix;
27425 bytes -= fix;
a737bd4d 27426 }
a737bd4d 27427
e7495e45
NS
27428 if (narrow_noop)
27429 {
27430 if (bytes & noop_size)
27431 {
27432 /* Insert a narrow noop. */
27433 memcpy (p, narrow_noop, noop_size);
27434 p += noop_size;
27435 bytes -= noop_size;
27436 fix += noop_size;
27437 }
27438
27439 /* Use wide noops for the remainder */
27440 noop_size = 4;
27441 }
27442
c19d1205 27443 while (bytes >= noop_size)
a737bd4d 27444 {
c19d1205
ZW
27445 memcpy (p, noop, noop_size);
27446 p += noop_size;
27447 bytes -= noop_size;
27448 fix += noop_size;
a737bd4d
NC
27449 }
27450
c19d1205 27451 fragP->fr_fix += fix;
a737bd4d
NC
27452}
27453
c19d1205
ZW
27454/* Called from md_do_align. Used to create an alignment
27455 frag in a code section. */
27456
27457void
27458arm_frag_align_code (int n, int max)
bfae80f2 27459{
c19d1205 27460 char * p;
7ed4c4c5 27461
c19d1205 27462 /* We assume that there will never be a requirement
6ec8e702 27463 to support alignments greater than MAX_MEM_FOR_RS_ALIGN_CODE bytes. */
c19d1205 27464 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
6ec8e702
NC
27465 {
27466 char err_msg[128];
27467
fa94de6b 27468 sprintf (err_msg,
477330fc
RM
27469 _("alignments greater than %d bytes not supported in .text sections."),
27470 MAX_MEM_FOR_RS_ALIGN_CODE + 1);
20203fb9 27471 as_fatal ("%s", err_msg);
6ec8e702 27472 }
bfae80f2 27473
c19d1205
ZW
27474 p = frag_var (rs_align_code,
27475 MAX_MEM_FOR_RS_ALIGN_CODE,
27476 1,
27477 (relax_substateT) max,
27478 (symbolS *) NULL,
27479 (offsetT) n,
27480 (char *) NULL);
27481 *p = 0;
27482}
bfae80f2 27483
8dc2430f
NC
27484/* Perform target specific initialisation of a frag.
27485 Note - despite the name this initialisation is not done when the frag
27486 is created, but only when its type is assigned. A frag can be created
27487 and used a long time before its type is set, so beware of assuming that
33eaf5de 27488 this initialisation is performed first. */
bfae80f2 27489
cd000bff
DJ
27490#ifndef OBJ_ELF
27491void
27492arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
27493{
27494 /* Record whether this frag is in an ARM or a THUMB area. */
2e98972e 27495 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
cd000bff
DJ
27496}
27497
27498#else /* OBJ_ELF is defined. */
c19d1205 27499void
cd000bff 27500arm_init_frag (fragS * fragP, int max_chars)
c19d1205 27501{
5b7c81bd 27502 bool frag_thumb_mode;
b968d18a 27503
8dc2430f
NC
27504 /* If the current ARM vs THUMB mode has not already
27505 been recorded into this frag then do so now. */
cd000bff 27506 if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
b968d18a
JW
27507 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
27508
e8d84ca1
NC
27509 /* PR 21809: Do not set a mapping state for debug sections
27510 - it just confuses other tools. */
fd361982 27511 if (bfd_section_flags (now_seg) & SEC_DEBUGGING)
e8d84ca1
NC
27512 return;
27513
b968d18a 27514 frag_thumb_mode = fragP->tc_frag_data.thumb_mode ^ MODE_RECORDED;
cd000bff 27515
f9c1b181
RL
27516 /* Record a mapping symbol for alignment frags. We will delete this
27517 later if the alignment ends up empty. */
27518 switch (fragP->fr_type)
27519 {
27520 case rs_align:
27521 case rs_align_test:
27522 case rs_fill:
27523 mapping_state_2 (MAP_DATA, max_chars);
27524 break;
27525 case rs_align_code:
b968d18a 27526 mapping_state_2 (frag_thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
f9c1b181
RL
27527 break;
27528 default:
27529 break;
cd000bff 27530 }
bfae80f2
RE
27531}
27532
c19d1205
ZW
27533/* When we change sections we need to issue a new mapping symbol. */
27534
27535void
27536arm_elf_change_section (void)
bfae80f2 27537{
c19d1205
ZW
27538 /* Link an unlinked unwind index table section to the .text section. */
27539 if (elf_section_type (now_seg) == SHT_ARM_EXIDX
27540 && elf_linked_to_section (now_seg) == NULL)
27541 elf_linked_to_section (now_seg) = text_section;
bfae80f2
RE
27542}
27543
c19d1205
ZW
27544int
27545arm_elf_section_type (const char * str, size_t len)
e45d0630 27546{
d34049e8 27547 if (len == 5 && startswith (str, "exidx"))
c19d1205 27548 return SHT_ARM_EXIDX;
e45d0630 27549
c19d1205
ZW
27550 return -1;
27551}
27552\f
27553/* Code to deal with unwinding tables. */
e45d0630 27554
c19d1205 27555static void add_unwind_adjustsp (offsetT);
e45d0630 27556
5f4273c7 27557/* Generate any deferred unwind frame offset. */
e45d0630 27558
bfae80f2 27559static void
c19d1205 27560flush_pending_unwind (void)
bfae80f2 27561{
c19d1205 27562 offsetT offset;
bfae80f2 27563
c19d1205
ZW
27564 offset = unwind.pending_offset;
27565 unwind.pending_offset = 0;
27566 if (offset != 0)
27567 add_unwind_adjustsp (offset);
bfae80f2
RE
27568}
27569
c19d1205
ZW
27570/* Add an opcode to this list for this function. Two-byte opcodes should
27571 be passed as op[0] << 8 | op[1]. The list of opcodes is built in reverse
27572 order. */
27573
bfae80f2 27574static void
c19d1205 27575add_unwind_opcode (valueT op, int length)
bfae80f2 27576{
c19d1205
ZW
27577 /* Add any deferred stack adjustment. */
27578 if (unwind.pending_offset)
27579 flush_pending_unwind ();
bfae80f2 27580
c19d1205 27581 unwind.sp_restored = 0;
bfae80f2 27582
c19d1205 27583 if (unwind.opcode_count + length > unwind.opcode_alloc)
bfae80f2 27584 {
c19d1205
ZW
27585 unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
27586 if (unwind.opcodes)
325801bd
TS
27587 unwind.opcodes = XRESIZEVEC (unsigned char, unwind.opcodes,
27588 unwind.opcode_alloc);
c19d1205 27589 else
325801bd 27590 unwind.opcodes = XNEWVEC (unsigned char, unwind.opcode_alloc);
bfae80f2 27591 }
c19d1205 27592 while (length > 0)
bfae80f2 27593 {
c19d1205
ZW
27594 length--;
27595 unwind.opcodes[unwind.opcode_count] = op & 0xff;
27596 op >>= 8;
27597 unwind.opcode_count++;
bfae80f2 27598 }
bfae80f2
RE
27599}
27600
c19d1205
ZW
27601/* Add unwind opcodes to adjust the stack pointer. */
27602
bfae80f2 27603static void
c19d1205 27604add_unwind_adjustsp (offsetT offset)
bfae80f2 27605{
c19d1205 27606 valueT op;
bfae80f2 27607
c19d1205 27608 if (offset > 0x200)
bfae80f2 27609 {
c19d1205
ZW
27610 /* We need at most 5 bytes to hold a 32-bit value in a uleb128. */
27611 char bytes[5];
27612 int n;
27613 valueT o;
bfae80f2 27614
c19d1205
ZW
27615 /* Long form: 0xb2, uleb128. */
27616 /* This might not fit in a word so add the individual bytes,
27617 remembering the list is built in reverse order. */
27618 o = (valueT) ((offset - 0x204) >> 2);
27619 if (o == 0)
27620 add_unwind_opcode (0, 1);
bfae80f2 27621
c19d1205
ZW
27622 /* Calculate the uleb128 encoding of the offset. */
27623 n = 0;
27624 while (o)
27625 {
27626 bytes[n] = o & 0x7f;
27627 o >>= 7;
27628 if (o)
27629 bytes[n] |= 0x80;
27630 n++;
27631 }
27632 /* Add the insn. */
27633 for (; n; n--)
27634 add_unwind_opcode (bytes[n - 1], 1);
27635 add_unwind_opcode (0xb2, 1);
27636 }
27637 else if (offset > 0x100)
bfae80f2 27638 {
c19d1205
ZW
27639 /* Two short opcodes. */
27640 add_unwind_opcode (0x3f, 1);
27641 op = (offset - 0x104) >> 2;
27642 add_unwind_opcode (op, 1);
bfae80f2 27643 }
c19d1205
ZW
27644 else if (offset > 0)
27645 {
27646 /* Short opcode. */
27647 op = (offset - 4) >> 2;
27648 add_unwind_opcode (op, 1);
27649 }
27650 else if (offset < 0)
bfae80f2 27651 {
c19d1205
ZW
27652 offset = -offset;
27653 while (offset > 0x100)
bfae80f2 27654 {
c19d1205
ZW
27655 add_unwind_opcode (0x7f, 1);
27656 offset -= 0x100;
bfae80f2 27657 }
c19d1205
ZW
27658 op = ((offset - 4) >> 2) | 0x40;
27659 add_unwind_opcode (op, 1);
bfae80f2 27660 }
bfae80f2
RE
27661}
27662
c19d1205 27663/* Finish the list of unwind opcodes for this function. */
0198d5e6 27664
c19d1205
ZW
27665static void
27666finish_unwind_opcodes (void)
bfae80f2 27667{
c19d1205 27668 valueT op;
bfae80f2 27669
c19d1205 27670 if (unwind.fp_used)
bfae80f2 27671 {
708587a4 27672 /* Adjust sp as necessary. */
c19d1205
ZW
27673 unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
27674 flush_pending_unwind ();
bfae80f2 27675
c19d1205
ZW
27676 /* After restoring sp from the frame pointer. */
27677 op = 0x90 | unwind.fp_reg;
27678 add_unwind_opcode (op, 1);
27679 }
27680 else
27681 flush_pending_unwind ();
bfae80f2
RE
27682}
27683
bfae80f2 27684
c19d1205
ZW
27685/* Start an exception table entry. If idx is nonzero this is an index table
27686 entry. */
bfae80f2
RE
27687
27688static void
c19d1205 27689start_unwind_section (const segT text_seg, int idx)
bfae80f2 27690{
c19d1205
ZW
27691 const char * text_name;
27692 const char * prefix;
27693 const char * prefix_once;
a8c4d40b 27694 struct elf_section_match match;
c19d1205 27695 char * sec_name;
c19d1205
ZW
27696 int type;
27697 int flags;
27698 int linkonce;
bfae80f2 27699
c19d1205 27700 if (idx)
bfae80f2 27701 {
c19d1205
ZW
27702 prefix = ELF_STRING_ARM_unwind;
27703 prefix_once = ELF_STRING_ARM_unwind_once;
27704 type = SHT_ARM_EXIDX;
bfae80f2 27705 }
c19d1205 27706 else
bfae80f2 27707 {
c19d1205
ZW
27708 prefix = ELF_STRING_ARM_unwind_info;
27709 prefix_once = ELF_STRING_ARM_unwind_info_once;
27710 type = SHT_PROGBITS;
bfae80f2
RE
27711 }
27712
c19d1205
ZW
27713 text_name = segment_name (text_seg);
27714 if (streq (text_name, ".text"))
27715 text_name = "";
27716
d34049e8 27717 if (startswith (text_name, ".gnu.linkonce.t."))
bfae80f2 27718 {
c19d1205
ZW
27719 prefix = prefix_once;
27720 text_name += strlen (".gnu.linkonce.t.");
bfae80f2
RE
27721 }
27722
29a2809e 27723 sec_name = concat (prefix, text_name, (char *) NULL);
bfae80f2 27724
c19d1205
ZW
27725 flags = SHF_ALLOC;
27726 linkonce = 0;
a8c4d40b 27727 memset (&match, 0, sizeof (match));
bfae80f2 27728
c19d1205
ZW
27729 /* Handle COMDAT group. */
27730 if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
bfae80f2 27731 {
a8c4d40b
L
27732 match.group_name = elf_group_name (text_seg);
27733 if (match.group_name == NULL)
c19d1205 27734 {
bd3ba5d1 27735 as_bad (_("Group section `%s' has no group signature"),
c19d1205
ZW
27736 segment_name (text_seg));
27737 ignore_rest_of_line ();
27738 return;
27739 }
27740 flags |= SHF_GROUP;
27741 linkonce = 1;
bfae80f2
RE
27742 }
27743
a8c4d40b 27744 obj_elf_change_section (sec_name, type, flags, 0, &match,
a91e1603 27745 linkonce, 0);
bfae80f2 27746
5f4273c7 27747 /* Set the section link for index tables. */
c19d1205
ZW
27748 if (idx)
27749 elf_linked_to_section (now_seg) = text_seg;
bfae80f2
RE
27750}
27751
bfae80f2 27752
c19d1205
ZW
27753/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
27754 personality routine data. Returns zero, or the index table value for
cad0da33 27755 an inline entry. */
c19d1205
ZW
27756
27757static valueT
27758create_unwind_entry (int have_data)
bfae80f2 27759{
c19d1205
ZW
27760 int size;
27761 addressT where;
27762 char *ptr;
27763 /* The current word of data. */
27764 valueT data;
27765 /* The number of bytes left in this word. */
27766 int n;
bfae80f2 27767
c19d1205 27768 finish_unwind_opcodes ();
bfae80f2 27769
c19d1205
ZW
27770 /* Remember the current text section. */
27771 unwind.saved_seg = now_seg;
27772 unwind.saved_subseg = now_subseg;
bfae80f2 27773
c19d1205 27774 start_unwind_section (now_seg, 0);
bfae80f2 27775
c19d1205 27776 if (unwind.personality_routine == NULL)
bfae80f2 27777 {
c19d1205
ZW
27778 if (unwind.personality_index == -2)
27779 {
27780 if (have_data)
5f4273c7 27781 as_bad (_("handlerdata in cantunwind frame"));
c19d1205
ZW
27782 return 1; /* EXIDX_CANTUNWIND. */
27783 }
bfae80f2 27784
c19d1205
ZW
27785 /* Use a default personality routine if none is specified. */
27786 if (unwind.personality_index == -1)
27787 {
27788 if (unwind.opcode_count > 3)
27789 unwind.personality_index = 1;
27790 else
27791 unwind.personality_index = 0;
27792 }
bfae80f2 27793
c19d1205
ZW
27794 /* Space for the personality routine entry. */
27795 if (unwind.personality_index == 0)
27796 {
27797 if (unwind.opcode_count > 3)
27798 as_bad (_("too many unwind opcodes for personality routine 0"));
bfae80f2 27799
c19d1205
ZW
27800 if (!have_data)
27801 {
27802 /* All the data is inline in the index table. */
27803 data = 0x80;
27804 n = 3;
27805 while (unwind.opcode_count > 0)
27806 {
27807 unwind.opcode_count--;
27808 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
27809 n--;
27810 }
bfae80f2 27811
c19d1205
ZW
27812 /* Pad with "finish" opcodes. */
27813 while (n--)
27814 data = (data << 8) | 0xb0;
bfae80f2 27815
c19d1205
ZW
27816 return data;
27817 }
27818 size = 0;
27819 }
27820 else
27821 /* We get two opcodes "free" in the first word. */
27822 size = unwind.opcode_count - 2;
27823 }
27824 else
5011093d 27825 {
cad0da33
NC
27826 /* PR 16765: Missing or misplaced unwind directives can trigger this. */
27827 if (unwind.personality_index != -1)
27828 {
27829 as_bad (_("attempt to recreate an unwind entry"));
27830 return 1;
27831 }
5011093d
NC
27832
27833 /* An extra byte is required for the opcode count. */
27834 size = unwind.opcode_count + 1;
27835 }
bfae80f2 27836
c19d1205
ZW
27837 size = (size + 3) >> 2;
27838 if (size > 0xff)
27839 as_bad (_("too many unwind opcodes"));
bfae80f2 27840
c19d1205
ZW
27841 frag_align (2, 0, 0);
27842 record_alignment (now_seg, 2);
27843 unwind.table_entry = expr_build_dot ();
27844
27845 /* Allocate the table entry. */
27846 ptr = frag_more ((size << 2) + 4);
74929e7b
NC
27847 /* PR 13449: Zero the table entries in case some of them are not used. */
27848 memset (ptr, 0, (size << 2) + 4);
c19d1205 27849 where = frag_now_fix () - ((size << 2) + 4);
bfae80f2 27850
c19d1205 27851 switch (unwind.personality_index)
bfae80f2 27852 {
c19d1205
ZW
27853 case -1:
27854 /* ??? Should this be a PLT generating relocation? */
27855 /* Custom personality routine. */
27856 fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
27857 BFD_RELOC_ARM_PREL31);
bfae80f2 27858
c19d1205
ZW
27859 where += 4;
27860 ptr += 4;
bfae80f2 27861
c19d1205 27862 /* Set the first byte to the number of additional words. */
5011093d 27863 data = size > 0 ? size - 1 : 0;
c19d1205
ZW
27864 n = 3;
27865 break;
bfae80f2 27866
c19d1205
ZW
27867 /* ABI defined personality routines. */
27868 case 0:
27869 /* Three opcodes bytes are packed into the first word. */
27870 data = 0x80;
27871 n = 3;
27872 break;
bfae80f2 27873
c19d1205
ZW
27874 case 1:
27875 case 2:
27876 /* The size and first two opcode bytes go in the first word. */
27877 data = ((0x80 + unwind.personality_index) << 8) | size;
27878 n = 2;
27879 break;
bfae80f2 27880
c19d1205
ZW
27881 default:
27882 /* Should never happen. */
27883 abort ();
27884 }
bfae80f2 27885
c19d1205
ZW
27886 /* Pack the opcodes into words (MSB first), reversing the list at the same
27887 time. */
27888 while (unwind.opcode_count > 0)
27889 {
27890 if (n == 0)
27891 {
27892 md_number_to_chars (ptr, data, 4);
27893 ptr += 4;
27894 n = 4;
27895 data = 0;
27896 }
27897 unwind.opcode_count--;
27898 n--;
27899 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
27900 }
27901
27902 /* Finish off the last word. */
27903 if (n < 4)
27904 {
27905 /* Pad with "finish" opcodes. */
27906 while (n--)
27907 data = (data << 8) | 0xb0;
27908
27909 md_number_to_chars (ptr, data, 4);
27910 }
27911
27912 if (!have_data)
27913 {
27914 /* Add an empty descriptor if there is no user-specified data. */
27915 ptr = frag_more (4);
27916 md_number_to_chars (ptr, 0, 4);
27917 }
27918
27919 return 0;
bfae80f2
RE
27920}
27921
f0927246
NC
27922
27923/* Initialize the DWARF-2 unwind information for this procedure. */
27924
27925void
27926tc_arm_frame_initial_instructions (void)
27927{
27928 cfi_add_CFA_def_cfa (REG_SP, 0);
27929}
27930#endif /* OBJ_ELF */
27931
c19d1205
ZW
27932/* Convert REGNAME to a DWARF-2 register number. */
27933
27934int
1df69f4f 27935tc_arm_regname_to_dw2regnum (char *regname)
bfae80f2 27936{
1df69f4f 27937 int reg = arm_reg_parse (&regname, REG_TYPE_RN);
1f5afe1c
NC
27938 if (reg != FAIL)
27939 return reg;
c19d1205 27940
1f5afe1c
NC
27941 /* PR 16694: Allow VFP registers as well. */
27942 reg = arm_reg_parse (&regname, REG_TYPE_VFS);
27943 if (reg != FAIL)
27944 return 64 + reg;
c19d1205 27945
1f5afe1c
NC
27946 reg = arm_reg_parse (&regname, REG_TYPE_VFD);
27947 if (reg != FAIL)
27948 return reg + 256;
27949
0198d5e6 27950 return FAIL;
bfae80f2
RE
27951}
27952
f0927246 27953#ifdef TE_PE
c19d1205 27954void
f0927246 27955tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
bfae80f2 27956{
91d6fa6a 27957 expressionS exp;
bfae80f2 27958
91d6fa6a
NC
27959 exp.X_op = O_secrel;
27960 exp.X_add_symbol = symbol;
27961 exp.X_add_number = 0;
27962 emit_expr (&exp, size);
f0927246
NC
27963}
27964#endif
bfae80f2 27965
c19d1205 27966/* MD interface: Symbol and relocation handling. */
bfae80f2 27967
2fc8bdac
ZW
27968/* Return the address within the segment that a PC-relative fixup is
27969 relative to. For ARM, PC-relative fixups applied to instructions
27970 are generally relative to the location of the fixup plus 8 bytes.
27971 Thumb branches are offset by 4, and Thumb loads relative to PC
27972 require special handling. */
bfae80f2 27973
c19d1205 27974long
2fc8bdac 27975md_pcrel_from_section (fixS * fixP, segT seg)
bfae80f2 27976{
2fc8bdac
ZW
27977 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
27978
27979 /* If this is pc-relative and we are going to emit a relocation
27980 then we just want to put out any pipeline compensation that the linker
53baae48
NC
27981 will need. Otherwise we want to use the calculated base.
27982 For WinCE we skip the bias for externals as well, since this
27983 is how the MS ARM-CE assembler behaves and we want to be compatible. */
5f4273c7 27984 if (fixP->fx_pcrel
2fc8bdac 27985 && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
53baae48
NC
27986 || (arm_force_relocation (fixP)
27987#ifdef TE_WINCE
27988 && !S_IS_EXTERNAL (fixP->fx_addsy)
27989#endif
27990 )))
2fc8bdac 27991 base = 0;
bfae80f2 27992
267bf995 27993
c19d1205 27994 switch (fixP->fx_r_type)
bfae80f2 27995 {
2fc8bdac
ZW
27996 /* PC relative addressing on the Thumb is slightly odd as the
27997 bottom two bits of the PC are forced to zero for the
27998 calculation. This happens *after* application of the
27999 pipeline offset. However, Thumb adrl already adjusts for
28000 this, so we need not do it again. */
c19d1205 28001 case BFD_RELOC_ARM_THUMB_ADD:
2fc8bdac 28002 return base & ~3;
c19d1205
ZW
28003
28004 case BFD_RELOC_ARM_THUMB_OFFSET:
28005 case BFD_RELOC_ARM_T32_OFFSET_IMM:
e9f89963 28006 case BFD_RELOC_ARM_T32_ADD_PC12:
8f06b2d8 28007 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
2fc8bdac 28008 return (base + 4) & ~3;
c19d1205 28009
2fc8bdac 28010 /* Thumb branches are simply offset by +4. */
e12437dc 28011 case BFD_RELOC_THUMB_PCREL_BRANCH5:
2fc8bdac
ZW
28012 case BFD_RELOC_THUMB_PCREL_BRANCH7:
28013 case BFD_RELOC_THUMB_PCREL_BRANCH9:
28014 case BFD_RELOC_THUMB_PCREL_BRANCH12:
28015 case BFD_RELOC_THUMB_PCREL_BRANCH20:
2fc8bdac 28016 case BFD_RELOC_THUMB_PCREL_BRANCH25:
f6b2b12d 28017 case BFD_RELOC_THUMB_PCREL_BFCSEL:
e5d6e09e 28018 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 28019 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 28020 case BFD_RELOC_ARM_THUMB_BF13:
60f993ce 28021 case BFD_RELOC_ARM_THUMB_LOOP12:
2fc8bdac 28022 return base + 4;
bfae80f2 28023
267bf995 28024 case BFD_RELOC_THUMB_PCREL_BRANCH23:
486499d0
CL
28025 if (fixP->fx_addsy
28026 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28027 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995 28028 && ARM_IS_FUNC (fixP->fx_addsy)
477330fc
RM
28029 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28030 base = fixP->fx_where + fixP->fx_frag->fr_address;
267bf995
RR
28031 return base + 4;
28032
00adf2d4
JB
28033 /* BLX is like branches above, but forces the low two bits of PC to
28034 zero. */
486499d0
CL
28035 case BFD_RELOC_THUMB_PCREL_BLX:
28036 if (fixP->fx_addsy
28037 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28038 && !S_FORCE_RELOC (fixP->fx_addsy, true)
477330fc
RM
28039 && THUMB_IS_FUNC (fixP->fx_addsy)
28040 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28041 base = fixP->fx_where + fixP->fx_frag->fr_address;
00adf2d4
JB
28042 return (base + 4) & ~3;
28043
2fc8bdac
ZW
28044 /* ARM mode branches are offset by +8. However, the Windows CE
28045 loader expects the relocation not to take this into account. */
267bf995 28046 case BFD_RELOC_ARM_PCREL_BLX:
486499d0
CL
28047 if (fixP->fx_addsy
28048 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28049 && !S_FORCE_RELOC (fixP->fx_addsy, true)
477330fc
RM
28050 && ARM_IS_FUNC (fixP->fx_addsy)
28051 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28052 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 28053 return base + 8;
267bf995 28054
486499d0
CL
28055 case BFD_RELOC_ARM_PCREL_CALL:
28056 if (fixP->fx_addsy
28057 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28058 && !S_FORCE_RELOC (fixP->fx_addsy, true)
477330fc
RM
28059 && THUMB_IS_FUNC (fixP->fx_addsy)
28060 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28061 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 28062 return base + 8;
267bf995 28063
2fc8bdac 28064 case BFD_RELOC_ARM_PCREL_BRANCH:
39b41c9c 28065 case BFD_RELOC_ARM_PCREL_JUMP:
2fc8bdac 28066 case BFD_RELOC_ARM_PLT32:
c19d1205 28067#ifdef TE_WINCE
5f4273c7 28068 /* When handling fixups immediately, because we have already
477330fc 28069 discovered the value of a symbol, or the address of the frag involved
53baae48 28070 we must account for the offset by +8, as the OS loader will never see the reloc.
477330fc
RM
28071 see fixup_segment() in write.c
28072 The S_IS_EXTERNAL test handles the case of global symbols.
28073 Those need the calculated base, not just the pipe compensation the linker will need. */
53baae48
NC
28074 if (fixP->fx_pcrel
28075 && fixP->fx_addsy != NULL
28076 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28077 && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP)))
28078 return base + 8;
2fc8bdac 28079 return base;
c19d1205 28080#else
2fc8bdac 28081 return base + 8;
c19d1205 28082#endif
2fc8bdac 28083
267bf995 28084
2fc8bdac
ZW
28085 /* ARM mode loads relative to PC are also offset by +8. Unlike
28086 branches, the Windows CE loader *does* expect the relocation
28087 to take this into account. */
28088 case BFD_RELOC_ARM_OFFSET_IMM:
28089 case BFD_RELOC_ARM_OFFSET_IMM8:
28090 case BFD_RELOC_ARM_HWLITERAL:
28091 case BFD_RELOC_ARM_LITERAL:
28092 case BFD_RELOC_ARM_CP_OFF_IMM:
28093 return base + 8;
28094
28095
28096 /* Other PC-relative relocations are un-offset. */
28097 default:
28098 return base;
28099 }
bfae80f2
RE
28100}
28101
5b7c81bd 28102static bool flag_warn_syms = true;
8b2d793c 28103
5b7c81bd 28104bool
ae8714c2 28105arm_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char * name)
bfae80f2 28106{
8b2d793c
NC
28107 /* PR 18347 - Warn if the user attempts to create a symbol with the same
28108 name as an ARM instruction. Whilst strictly speaking it is allowed, it
28109 does mean that the resulting code might be very confusing to the reader.
28110 Also this warning can be triggered if the user omits an operand before
28111 an immediate address, eg:
28112
28113 LDR =foo
28114
28115 GAS treats this as an assignment of the value of the symbol foo to a
28116 symbol LDR, and so (without this code) it will not issue any kind of
28117 warning or error message.
28118
28119 Note - ARM instructions are case-insensitive but the strings in the hash
28120 table are all stored in lower case, so we must first ensure that name is
ae8714c2
NC
28121 lower case too. */
28122 if (flag_warn_syms && arm_ops_hsh)
8b2d793c
NC
28123 {
28124 char * nbuf = strdup (name);
28125 char * p;
28126
28127 for (p = nbuf; *p; p++)
28128 *p = TOLOWER (*p);
629310ab 28129 if (str_hash_find (arm_ops_hsh, nbuf) != NULL)
8b2d793c 28130 {
629310ab 28131 static htab_t already_warned = NULL;
8b2d793c
NC
28132
28133 if (already_warned == NULL)
629310ab 28134 already_warned = str_htab_create ();
8b2d793c 28135 /* Only warn about the symbol once. To keep the code
629310ab
ML
28136 simple we let str_hash_insert do the lookup for us. */
28137 if (str_hash_find (already_warned, nbuf) == NULL)
28138 {
28139 as_warn (_("[-mwarn-syms]: Assignment makes a symbol match an ARM instruction: %s"), name);
fe0e921f 28140 str_hash_insert (already_warned, nbuf, NULL, 0);
629310ab 28141 }
8b2d793c
NC
28142 }
28143 else
28144 free (nbuf);
28145 }
3739860c 28146
5b7c81bd 28147 return false;
ae8714c2
NC
28148}
28149
28150/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
28151 Otherwise we have no need to default values of symbols. */
28152
28153symbolS *
28154md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
28155{
28156#ifdef OBJ_ELF
28157 if (name[0] == '_' && name[1] == 'G'
28158 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
28159 {
28160 if (!GOT_symbol)
28161 {
28162 if (symbol_find (name))
28163 as_bad (_("GOT already in the symbol table"));
28164
28165 GOT_symbol = symbol_new (name, undefined_section,
e01e1cee 28166 &zero_address_frag, 0);
ae8714c2
NC
28167 }
28168
28169 return GOT_symbol;
28170 }
28171#endif
28172
c921be7d 28173 return NULL;
bfae80f2
RE
28174}
28175
55cf6793 28176/* Subroutine of md_apply_fix. Check to see if an immediate can be
c19d1205
ZW
28177 computed as two separate immediate values, added together. We
28178 already know that this value cannot be computed by just one ARM
28179 instruction. */
28180
28181static unsigned int
28182validate_immediate_twopart (unsigned int val,
28183 unsigned int * highpart)
bfae80f2 28184{
c19d1205
ZW
28185 unsigned int a;
28186 unsigned int i;
bfae80f2 28187
c19d1205
ZW
28188 for (i = 0; i < 32; i += 2)
28189 if (((a = rotate_left (val, i)) & 0xff) != 0)
28190 {
28191 if (a & 0xff00)
28192 {
28193 if (a & ~ 0xffff)
28194 continue;
28195 * highpart = (a >> 8) | ((i + 24) << 7);
28196 }
28197 else if (a & 0xff0000)
28198 {
28199 if (a & 0xff000000)
28200 continue;
28201 * highpart = (a >> 16) | ((i + 16) << 7);
28202 }
28203 else
28204 {
9c2799c2 28205 gas_assert (a & 0xff000000);
c19d1205
ZW
28206 * highpart = (a >> 24) | ((i + 8) << 7);
28207 }
bfae80f2 28208
c19d1205
ZW
28209 return (a & 0xff) | (i << 7);
28210 }
bfae80f2 28211
c19d1205 28212 return FAIL;
bfae80f2
RE
28213}
28214
c19d1205
ZW
28215static int
28216validate_offset_imm (unsigned int val, int hwse)
28217{
28218 if ((hwse && val > 255) || val > 4095)
28219 return FAIL;
28220 return val;
28221}
bfae80f2 28222
55cf6793 28223/* Subroutine of md_apply_fix. Do those data_ops which can take a
c19d1205
ZW
28224 negative immediate constant by altering the instruction. A bit of
28225 a hack really.
28226 MOV <-> MVN
28227 AND <-> BIC
28228 ADC <-> SBC
28229 by inverting the second operand, and
28230 ADD <-> SUB
28231 CMP <-> CMN
28232 by negating the second operand. */
bfae80f2 28233
c19d1205
ZW
28234static int
28235negate_data_op (unsigned long * instruction,
28236 unsigned long value)
bfae80f2 28237{
c19d1205
ZW
28238 int op, new_inst;
28239 unsigned long negated, inverted;
bfae80f2 28240
c19d1205
ZW
28241 negated = encode_arm_immediate (-value);
28242 inverted = encode_arm_immediate (~value);
bfae80f2 28243
c19d1205
ZW
28244 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
28245 switch (op)
bfae80f2 28246 {
c19d1205
ZW
28247 /* First negates. */
28248 case OPCODE_SUB: /* ADD <-> SUB */
28249 new_inst = OPCODE_ADD;
28250 value = negated;
28251 break;
bfae80f2 28252
c19d1205
ZW
28253 case OPCODE_ADD:
28254 new_inst = OPCODE_SUB;
28255 value = negated;
28256 break;
bfae80f2 28257
c19d1205
ZW
28258 case OPCODE_CMP: /* CMP <-> CMN */
28259 new_inst = OPCODE_CMN;
28260 value = negated;
28261 break;
bfae80f2 28262
c19d1205
ZW
28263 case OPCODE_CMN:
28264 new_inst = OPCODE_CMP;
28265 value = negated;
28266 break;
bfae80f2 28267
c19d1205
ZW
28268 /* Now Inverted ops. */
28269 case OPCODE_MOV: /* MOV <-> MVN */
28270 new_inst = OPCODE_MVN;
28271 value = inverted;
28272 break;
bfae80f2 28273
c19d1205
ZW
28274 case OPCODE_MVN:
28275 new_inst = OPCODE_MOV;
28276 value = inverted;
28277 break;
bfae80f2 28278
c19d1205
ZW
28279 case OPCODE_AND: /* AND <-> BIC */
28280 new_inst = OPCODE_BIC;
28281 value = inverted;
28282 break;
bfae80f2 28283
c19d1205
ZW
28284 case OPCODE_BIC:
28285 new_inst = OPCODE_AND;
28286 value = inverted;
28287 break;
bfae80f2 28288
c19d1205
ZW
28289 case OPCODE_ADC: /* ADC <-> SBC */
28290 new_inst = OPCODE_SBC;
28291 value = inverted;
28292 break;
bfae80f2 28293
c19d1205
ZW
28294 case OPCODE_SBC:
28295 new_inst = OPCODE_ADC;
28296 value = inverted;
28297 break;
bfae80f2 28298
c19d1205
ZW
28299 /* We cannot do anything. */
28300 default:
28301 return FAIL;
b99bd4ef
NC
28302 }
28303
c19d1205
ZW
28304 if (value == (unsigned) FAIL)
28305 return FAIL;
28306
28307 *instruction &= OPCODE_MASK;
28308 *instruction |= new_inst << DATA_OP_SHIFT;
28309 return value;
b99bd4ef
NC
28310}
28311
ef8d22e6
PB
28312/* Like negate_data_op, but for Thumb-2. */
28313
28314static unsigned int
7af67752 28315thumb32_negate_data_op (valueT *instruction, unsigned int value)
ef8d22e6 28316{
7af67752
AM
28317 unsigned int op, new_inst;
28318 unsigned int rd;
16dd5e42 28319 unsigned int negated, inverted;
ef8d22e6
PB
28320
28321 negated = encode_thumb32_immediate (-value);
28322 inverted = encode_thumb32_immediate (~value);
28323
28324 rd = (*instruction >> 8) & 0xf;
28325 op = (*instruction >> T2_DATA_OP_SHIFT) & 0xf;
28326 switch (op)
28327 {
28328 /* ADD <-> SUB. Includes CMP <-> CMN. */
28329 case T2_OPCODE_SUB:
28330 new_inst = T2_OPCODE_ADD;
28331 value = negated;
28332 break;
28333
28334 case T2_OPCODE_ADD:
28335 new_inst = T2_OPCODE_SUB;
28336 value = negated;
28337 break;
28338
28339 /* ORR <-> ORN. Includes MOV <-> MVN. */
28340 case T2_OPCODE_ORR:
28341 new_inst = T2_OPCODE_ORN;
28342 value = inverted;
28343 break;
28344
28345 case T2_OPCODE_ORN:
28346 new_inst = T2_OPCODE_ORR;
28347 value = inverted;
28348 break;
28349
28350 /* AND <-> BIC. TST has no inverted equivalent. */
28351 case T2_OPCODE_AND:
28352 new_inst = T2_OPCODE_BIC;
28353 if (rd == 15)
28354 value = FAIL;
28355 else
28356 value = inverted;
28357 break;
28358
28359 case T2_OPCODE_BIC:
28360 new_inst = T2_OPCODE_AND;
28361 value = inverted;
28362 break;
28363
28364 /* ADC <-> SBC */
28365 case T2_OPCODE_ADC:
28366 new_inst = T2_OPCODE_SBC;
28367 value = inverted;
28368 break;
28369
28370 case T2_OPCODE_SBC:
28371 new_inst = T2_OPCODE_ADC;
28372 value = inverted;
28373 break;
28374
28375 /* We cannot do anything. */
28376 default:
28377 return FAIL;
28378 }
28379
16dd5e42 28380 if (value == (unsigned int)FAIL)
ef8d22e6
PB
28381 return FAIL;
28382
28383 *instruction &= T2_OPCODE_MASK;
28384 *instruction |= new_inst << T2_DATA_OP_SHIFT;
28385 return value;
28386}
28387
8f06b2d8 28388/* Read a 32-bit thumb instruction from buf. */
0198d5e6 28389
8f06b2d8
PB
28390static unsigned long
28391get_thumb32_insn (char * buf)
28392{
28393 unsigned long insn;
28394 insn = md_chars_to_number (buf, THUMB_SIZE) << 16;
28395 insn |= md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28396
28397 return insn;
28398}
28399
a8bc6c78
PB
28400/* We usually want to set the low bit on the address of thumb function
28401 symbols. In particular .word foo - . should have the low bit set.
28402 Generic code tries to fold the difference of two symbols to
28403 a constant. Prevent this and force a relocation when the first symbols
28404 is a thumb function. */
c921be7d 28405
5b7c81bd 28406bool
a8bc6c78
PB
28407arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
28408{
28409 if (op == O_subtract
28410 && l->X_op == O_symbol
28411 && r->X_op == O_symbol
28412 && THUMB_IS_FUNC (l->X_add_symbol))
28413 {
28414 l->X_op = O_subtract;
28415 l->X_op_symbol = r->X_add_symbol;
28416 l->X_add_number -= r->X_add_number;
5b7c81bd 28417 return true;
a8bc6c78 28418 }
c921be7d 28419
a8bc6c78 28420 /* Process as normal. */
5b7c81bd 28421 return false;
a8bc6c78
PB
28422}
28423
4a42ebbc
RR
28424/* Encode Thumb2 unconditional branches and calls. The encoding
28425 for the 2 are identical for the immediate values. */
28426
28427static void
28428encode_thumb2_b_bl_offset (char * buf, offsetT value)
28429{
28430#define T2I1I2MASK ((1 << 13) | (1 << 11))
28431 offsetT newval;
28432 offsetT newval2;
28433 addressT S, I1, I2, lo, hi;
28434
28435 S = (value >> 24) & 0x01;
28436 I1 = (value >> 23) & 0x01;
28437 I2 = (value >> 22) & 0x01;
28438 hi = (value >> 12) & 0x3ff;
fa94de6b 28439 lo = (value >> 1) & 0x7ff;
4a42ebbc
RR
28440 newval = md_chars_to_number (buf, THUMB_SIZE);
28441 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28442 newval |= (S << 10) | hi;
28443 newval2 &= ~T2I1I2MASK;
28444 newval2 |= (((I1 ^ S) << 13) | ((I2 ^ S) << 11) | lo) ^ T2I1I2MASK;
28445 md_number_to_chars (buf, newval, THUMB_SIZE);
28446 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
28447}
28448
c19d1205 28449void
55cf6793 28450md_apply_fix (fixS * fixP,
c19d1205
ZW
28451 valueT * valP,
28452 segT seg)
28453{
7af67752
AM
28454 valueT value = * valP;
28455 valueT newval;
c19d1205
ZW
28456 unsigned int newimm;
28457 unsigned long temp;
28458 int sign;
28459 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
b99bd4ef 28460
9c2799c2 28461 gas_assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
b99bd4ef 28462
c19d1205 28463 /* Note whether this will delete the relocation. */
4962c51a 28464
c19d1205
ZW
28465 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
28466 fixP->fx_done = 1;
b99bd4ef 28467
adbaf948 28468 /* On a 64-bit host, silently truncate 'value' to 32 bits for
5f4273c7 28469 consistency with the behaviour on 32-bit hosts. Remember value
adbaf948
ZW
28470 for emit_reloc. */
28471 value &= 0xffffffff;
28472 value ^= 0x80000000;
5f4273c7 28473 value -= 0x80000000;
adbaf948
ZW
28474
28475 *valP = value;
c19d1205 28476 fixP->fx_addnumber = value;
b99bd4ef 28477
adbaf948
ZW
28478 /* Same treatment for fixP->fx_offset. */
28479 fixP->fx_offset &= 0xffffffff;
28480 fixP->fx_offset ^= 0x80000000;
28481 fixP->fx_offset -= 0x80000000;
28482
c19d1205 28483 switch (fixP->fx_r_type)
b99bd4ef 28484 {
c19d1205
ZW
28485 case BFD_RELOC_NONE:
28486 /* This will need to go in the object file. */
28487 fixP->fx_done = 0;
28488 break;
b99bd4ef 28489
c19d1205
ZW
28490 case BFD_RELOC_ARM_IMMEDIATE:
28491 /* We claim that this fixup has been processed here,
28492 even if in fact we generate an error because we do
28493 not have a reloc for it, so tc_gen_reloc will reject it. */
28494 fixP->fx_done = 1;
b99bd4ef 28495
77db8e2e 28496 if (fixP->fx_addsy)
b99bd4ef 28497 {
77db8e2e 28498 const char *msg = 0;
b99bd4ef 28499
77db8e2e
NC
28500 if (! S_IS_DEFINED (fixP->fx_addsy))
28501 msg = _("undefined symbol %s used as an immediate value");
28502 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
28503 msg = _("symbol %s is in a different section");
28504 else if (S_IS_WEAK (fixP->fx_addsy))
28505 msg = _("symbol %s is weak and may be overridden later");
28506
28507 if (msg)
28508 {
28509 as_bad_where (fixP->fx_file, fixP->fx_line,
28510 msg, S_GET_NAME (fixP->fx_addsy));
28511 break;
28512 }
42e5fcbf
AS
28513 }
28514
c19d1205
ZW
28515 temp = md_chars_to_number (buf, INSN_SIZE);
28516
5e73442d 28517 /* If the offset is negative, we should use encoding A2 for ADR. */
7af67752 28518 if ((temp & 0xfff0000) == 0x28f0000 && (offsetT) value < 0)
5e73442d
SL
28519 newimm = negate_data_op (&temp, value);
28520 else
28521 {
28522 newimm = encode_arm_immediate (value);
28523
28524 /* If the instruction will fail, see if we can fix things up by
28525 changing the opcode. */
28526 if (newimm == (unsigned int) FAIL)
28527 newimm = negate_data_op (&temp, value);
bada4342
JW
28528 /* MOV accepts both ARM modified immediate (A1 encoding) and
28529 UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
28530 When disassembling, MOV is preferred when there is no encoding
28531 overlap. */
28532 if (newimm == (unsigned int) FAIL
28533 && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
28534 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
28535 && !((temp >> SBIT_SHIFT) & 0x1)
7af67752 28536 && value <= 0xffff)
bada4342
JW
28537 {
28538 /* Clear bits[23:20] to change encoding from A1 to A2. */
28539 temp &= 0xff0fffff;
28540 /* Encoding high 4bits imm. Code below will encode the remaining
28541 low 12bits. */
28542 temp |= (value & 0x0000f000) << 4;
28543 newimm = value & 0x00000fff;
28544 }
5e73442d
SL
28545 }
28546
28547 if (newimm == (unsigned int) FAIL)
b99bd4ef 28548 {
c19d1205
ZW
28549 as_bad_where (fixP->fx_file, fixP->fx_line,
28550 _("invalid constant (%lx) after fixup"),
28551 (unsigned long) value);
28552 break;
b99bd4ef 28553 }
b99bd4ef 28554
c19d1205
ZW
28555 newimm |= (temp & 0xfffff000);
28556 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
28557 break;
b99bd4ef 28558
c19d1205
ZW
28559 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
28560 {
28561 unsigned int highpart = 0;
28562 unsigned int newinsn = 0xe1a00000; /* nop. */
b99bd4ef 28563
77db8e2e 28564 if (fixP->fx_addsy)
42e5fcbf 28565 {
77db8e2e 28566 const char *msg = 0;
42e5fcbf 28567
77db8e2e
NC
28568 if (! S_IS_DEFINED (fixP->fx_addsy))
28569 msg = _("undefined symbol %s used as an immediate value");
28570 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
28571 msg = _("symbol %s is in a different section");
28572 else if (S_IS_WEAK (fixP->fx_addsy))
28573 msg = _("symbol %s is weak and may be overridden later");
42e5fcbf 28574
77db8e2e
NC
28575 if (msg)
28576 {
28577 as_bad_where (fixP->fx_file, fixP->fx_line,
28578 msg, S_GET_NAME (fixP->fx_addsy));
28579 break;
28580 }
28581 }
fa94de6b 28582
c19d1205
ZW
28583 newimm = encode_arm_immediate (value);
28584 temp = md_chars_to_number (buf, INSN_SIZE);
b99bd4ef 28585
c19d1205
ZW
28586 /* If the instruction will fail, see if we can fix things up by
28587 changing the opcode. */
28588 if (newimm == (unsigned int) FAIL
28589 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
28590 {
28591 /* No ? OK - try using two ADD instructions to generate
28592 the value. */
28593 newimm = validate_immediate_twopart (value, & highpart);
b99bd4ef 28594
c19d1205
ZW
28595 /* Yes - then make sure that the second instruction is
28596 also an add. */
28597 if (newimm != (unsigned int) FAIL)
28598 newinsn = temp;
28599 /* Still No ? Try using a negated value. */
28600 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
28601 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
28602 /* Otherwise - give up. */
28603 else
28604 {
28605 as_bad_where (fixP->fx_file, fixP->fx_line,
28606 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
28607 (long) value);
28608 break;
28609 }
b99bd4ef 28610
c19d1205
ZW
28611 /* Replace the first operand in the 2nd instruction (which
28612 is the PC) with the destination register. We have
28613 already added in the PC in the first instruction and we
28614 do not want to do it again. */
28615 newinsn &= ~ 0xf0000;
28616 newinsn |= ((newinsn & 0x0f000) << 4);
28617 }
b99bd4ef 28618
c19d1205
ZW
28619 newimm |= (temp & 0xfffff000);
28620 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
b99bd4ef 28621
c19d1205
ZW
28622 highpart |= (newinsn & 0xfffff000);
28623 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
28624 }
28625 break;
b99bd4ef 28626
c19d1205 28627 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
28628 if (!fixP->fx_done && seg->use_rela_p)
28629 value = 0;
1a0670f3 28630 /* Fall through. */
00a97672 28631
c19d1205 28632 case BFD_RELOC_ARM_LITERAL:
7af67752 28633 sign = (offsetT) value > 0;
b99bd4ef 28634
7af67752 28635 if ((offsetT) value < 0)
c19d1205 28636 value = - value;
b99bd4ef 28637
c19d1205 28638 if (validate_offset_imm (value, 0) == FAIL)
f03698e6 28639 {
c19d1205
ZW
28640 if (fixP->fx_r_type == BFD_RELOC_ARM_LITERAL)
28641 as_bad_where (fixP->fx_file, fixP->fx_line,
28642 _("invalid literal constant: pool needs to be closer"));
28643 else
28644 as_bad_where (fixP->fx_file, fixP->fx_line,
28645 _("bad immediate value for offset (%ld)"),
28646 (long) value);
28647 break;
f03698e6
RE
28648 }
28649
c19d1205 28650 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
28651 if (value == 0)
28652 newval &= 0xfffff000;
28653 else
28654 {
28655 newval &= 0xff7ff000;
28656 newval |= value | (sign ? INDEX_UP : 0);
28657 }
c19d1205
ZW
28658 md_number_to_chars (buf, newval, INSN_SIZE);
28659 break;
b99bd4ef 28660
c19d1205
ZW
28661 case BFD_RELOC_ARM_OFFSET_IMM8:
28662 case BFD_RELOC_ARM_HWLITERAL:
7af67752 28663 sign = (offsetT) value > 0;
b99bd4ef 28664
7af67752 28665 if ((offsetT) value < 0)
c19d1205 28666 value = - value;
b99bd4ef 28667
c19d1205 28668 if (validate_offset_imm (value, 1) == FAIL)
b99bd4ef 28669 {
c19d1205
ZW
28670 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
28671 as_bad_where (fixP->fx_file, fixP->fx_line,
28672 _("invalid literal constant: pool needs to be closer"));
28673 else
427d0db6
RM
28674 as_bad_where (fixP->fx_file, fixP->fx_line,
28675 _("bad immediate value for 8-bit offset (%ld)"),
28676 (long) value);
c19d1205 28677 break;
b99bd4ef
NC
28678 }
28679
c19d1205 28680 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
28681 if (value == 0)
28682 newval &= 0xfffff0f0;
28683 else
28684 {
28685 newval &= 0xff7ff0f0;
28686 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
28687 }
c19d1205
ZW
28688 md_number_to_chars (buf, newval, INSN_SIZE);
28689 break;
b99bd4ef 28690
c19d1205 28691 case BFD_RELOC_ARM_T32_OFFSET_U8:
7af67752 28692 if (value > 1020 || value % 4 != 0)
c19d1205
ZW
28693 as_bad_where (fixP->fx_file, fixP->fx_line,
28694 _("bad immediate value for offset (%ld)"), (long) value);
28695 value /= 4;
b99bd4ef 28696
c19d1205 28697 newval = md_chars_to_number (buf+2, THUMB_SIZE);
c19d1205
ZW
28698 newval |= value;
28699 md_number_to_chars (buf+2, newval, THUMB_SIZE);
28700 break;
b99bd4ef 28701
c19d1205
ZW
28702 case BFD_RELOC_ARM_T32_OFFSET_IMM:
28703 /* This is a complicated relocation used for all varieties of Thumb32
28704 load/store instruction with immediate offset:
28705
28706 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
477330fc 28707 *4, optional writeback(W)
c19d1205
ZW
28708 (doubleword load/store)
28709
28710 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
28711 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
28712 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
28713 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
28714 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
28715
28716 Uppercase letters indicate bits that are already encoded at
28717 this point. Lowercase letters are our problem. For the
28718 second block of instructions, the secondary opcode nybble
28719 (bits 8..11) is present, and bit 23 is zero, even if this is
28720 a PC-relative operation. */
28721 newval = md_chars_to_number (buf, THUMB_SIZE);
28722 newval <<= 16;
28723 newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
b99bd4ef 28724
c19d1205 28725 if ((newval & 0xf0000000) == 0xe0000000)
b99bd4ef 28726 {
c19d1205 28727 /* Doubleword load/store: 8-bit offset, scaled by 4. */
7af67752 28728 if ((offsetT) value >= 0)
c19d1205
ZW
28729 newval |= (1 << 23);
28730 else
28731 value = -value;
28732 if (value % 4 != 0)
28733 {
28734 as_bad_where (fixP->fx_file, fixP->fx_line,
28735 _("offset not a multiple of 4"));
28736 break;
28737 }
28738 value /= 4;
216d22bc 28739 if (value > 0xff)
c19d1205
ZW
28740 {
28741 as_bad_where (fixP->fx_file, fixP->fx_line,
28742 _("offset out of range"));
28743 break;
28744 }
28745 newval &= ~0xff;
b99bd4ef 28746 }
c19d1205 28747 else if ((newval & 0x000f0000) == 0x000f0000)
b99bd4ef 28748 {
c19d1205 28749 /* PC-relative, 12-bit offset. */
7af67752 28750 if ((offsetT) value >= 0)
c19d1205
ZW
28751 newval |= (1 << 23);
28752 else
28753 value = -value;
216d22bc 28754 if (value > 0xfff)
c19d1205
ZW
28755 {
28756 as_bad_where (fixP->fx_file, fixP->fx_line,
28757 _("offset out of range"));
28758 break;
28759 }
28760 newval &= ~0xfff;
b99bd4ef 28761 }
c19d1205 28762 else if ((newval & 0x00000100) == 0x00000100)
b99bd4ef 28763 {
c19d1205 28764 /* Writeback: 8-bit, +/- offset. */
7af67752 28765 if ((offsetT) value >= 0)
c19d1205
ZW
28766 newval |= (1 << 9);
28767 else
28768 value = -value;
216d22bc 28769 if (value > 0xff)
c19d1205
ZW
28770 {
28771 as_bad_where (fixP->fx_file, fixP->fx_line,
28772 _("offset out of range"));
28773 break;
28774 }
28775 newval &= ~0xff;
b99bd4ef 28776 }
c19d1205 28777 else if ((newval & 0x00000f00) == 0x00000e00)
b99bd4ef 28778 {
c19d1205 28779 /* T-instruction: positive 8-bit offset. */
7af67752 28780 if (value > 0xff)
b99bd4ef 28781 {
c19d1205
ZW
28782 as_bad_where (fixP->fx_file, fixP->fx_line,
28783 _("offset out of range"));
28784 break;
b99bd4ef 28785 }
c19d1205
ZW
28786 newval &= ~0xff;
28787 newval |= value;
b99bd4ef
NC
28788 }
28789 else
b99bd4ef 28790 {
c19d1205 28791 /* Positive 12-bit or negative 8-bit offset. */
7af67752
AM
28792 unsigned int limit;
28793 if ((offsetT) value >= 0)
b99bd4ef 28794 {
c19d1205
ZW
28795 newval |= (1 << 23);
28796 limit = 0xfff;
28797 }
28798 else
28799 {
28800 value = -value;
28801 limit = 0xff;
28802 }
28803 if (value > limit)
28804 {
28805 as_bad_where (fixP->fx_file, fixP->fx_line,
28806 _("offset out of range"));
28807 break;
b99bd4ef 28808 }
c19d1205 28809 newval &= ~limit;
b99bd4ef 28810 }
b99bd4ef 28811
c19d1205
ZW
28812 newval |= value;
28813 md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
28814 md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
28815 break;
404ff6b5 28816
c19d1205
ZW
28817 case BFD_RELOC_ARM_SHIFT_IMM:
28818 newval = md_chars_to_number (buf, INSN_SIZE);
7af67752 28819 if (value > 32
c19d1205
ZW
28820 || (value == 32
28821 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
28822 {
28823 as_bad_where (fixP->fx_file, fixP->fx_line,
28824 _("shift expression is too large"));
28825 break;
28826 }
404ff6b5 28827
c19d1205
ZW
28828 if (value == 0)
28829 /* Shifts of zero must be done as lsl. */
28830 newval &= ~0x60;
28831 else if (value == 32)
28832 value = 0;
28833 newval &= 0xfffff07f;
28834 newval |= (value & 0x1f) << 7;
28835 md_number_to_chars (buf, newval, INSN_SIZE);
28836 break;
404ff6b5 28837
c19d1205 28838 case BFD_RELOC_ARM_T32_IMMEDIATE:
16805f35 28839 case BFD_RELOC_ARM_T32_ADD_IMM:
92e90b6e 28840 case BFD_RELOC_ARM_T32_IMM12:
e9f89963 28841 case BFD_RELOC_ARM_T32_ADD_PC12:
c19d1205
ZW
28842 /* We claim that this fixup has been processed here,
28843 even if in fact we generate an error because we do
28844 not have a reloc for it, so tc_gen_reloc will reject it. */
28845 fixP->fx_done = 1;
404ff6b5 28846
c19d1205
ZW
28847 if (fixP->fx_addsy
28848 && ! S_IS_DEFINED (fixP->fx_addsy))
28849 {
28850 as_bad_where (fixP->fx_file, fixP->fx_line,
28851 _("undefined symbol %s used as an immediate value"),
28852 S_GET_NAME (fixP->fx_addsy));
28853 break;
28854 }
404ff6b5 28855
c19d1205
ZW
28856 newval = md_chars_to_number (buf, THUMB_SIZE);
28857 newval <<= 16;
28858 newval |= md_chars_to_number (buf+2, THUMB_SIZE);
404ff6b5 28859
16805f35 28860 newimm = FAIL;
bada4342
JW
28861 if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
28862 /* ARMv8-M Baseline MOV will reach here, but it doesn't support
28863 Thumb2 modified immediate encoding (T2). */
28864 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
16805f35 28865 || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
ef8d22e6
PB
28866 {
28867 newimm = encode_thumb32_immediate (value);
28868 if (newimm == (unsigned int) FAIL)
28869 newimm = thumb32_negate_data_op (&newval, value);
28870 }
bada4342 28871 if (newimm == (unsigned int) FAIL)
92e90b6e 28872 {
bada4342 28873 if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
e9f89963 28874 {
bada4342
JW
28875 /* Turn add/sum into addw/subw. */
28876 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
28877 newval = (newval & 0xfeffffff) | 0x02000000;
28878 /* No flat 12-bit imm encoding for addsw/subsw. */
28879 if ((newval & 0x00100000) == 0)
40f246e3 28880 {
bada4342 28881 /* 12 bit immediate for addw/subw. */
7af67752 28882 if ((offsetT) value < 0)
bada4342
JW
28883 {
28884 value = -value;
28885 newval ^= 0x00a00000;
28886 }
28887 if (value > 0xfff)
28888 newimm = (unsigned int) FAIL;
28889 else
28890 newimm = value;
28891 }
28892 }
28893 else
28894 {
28895 /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
28896 UINT16 (T3 encoding), MOVW only accepts UINT16. When
28897 disassembling, MOV is preferred when there is no encoding
db7bf105 28898 overlap. */
bada4342 28899 if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
db7bf105
NC
28900 /* NOTE: MOV uses the ORR opcode in Thumb 2 mode
28901 but with the Rn field [19:16] set to 1111. */
28902 && (((newval >> 16) & 0xf) == 0xf)
bada4342
JW
28903 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
28904 && !((newval >> T2_SBIT_SHIFT) & 0x1)
7af67752 28905 && value <= 0xffff)
bada4342
JW
28906 {
28907 /* Toggle bit[25] to change encoding from T2 to T3. */
28908 newval ^= 1 << 25;
28909 /* Clear bits[19:16]. */
28910 newval &= 0xfff0ffff;
28911 /* Encoding high 4bits imm. Code below will encode the
28912 remaining low 12bits. */
28913 newval |= (value & 0x0000f000) << 4;
28914 newimm = value & 0x00000fff;
40f246e3 28915 }
e9f89963 28916 }
92e90b6e 28917 }
cc8a6dd0 28918
c19d1205 28919 if (newimm == (unsigned int)FAIL)
3631a3c8 28920 {
c19d1205
ZW
28921 as_bad_where (fixP->fx_file, fixP->fx_line,
28922 _("invalid constant (%lx) after fixup"),
28923 (unsigned long) value);
28924 break;
3631a3c8
NC
28925 }
28926
c19d1205
ZW
28927 newval |= (newimm & 0x800) << 15;
28928 newval |= (newimm & 0x700) << 4;
28929 newval |= (newimm & 0x0ff);
cc8a6dd0 28930
c19d1205
ZW
28931 md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
28932 md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
28933 break;
a737bd4d 28934
3eb17e6b 28935 case BFD_RELOC_ARM_SMC:
7af67752 28936 if (value > 0xf)
c19d1205 28937 as_bad_where (fixP->fx_file, fixP->fx_line,
3eb17e6b 28938 _("invalid smc expression"));
ba85f98c 28939
2fc8bdac 28940 newval = md_chars_to_number (buf, INSN_SIZE);
ba85f98c 28941 newval |= (value & 0xf);
c19d1205
ZW
28942 md_number_to_chars (buf, newval, INSN_SIZE);
28943 break;
a737bd4d 28944
90ec0d68 28945 case BFD_RELOC_ARM_HVC:
7af67752 28946 if (value > 0xffff)
90ec0d68
MGD
28947 as_bad_where (fixP->fx_file, fixP->fx_line,
28948 _("invalid hvc expression"));
28949 newval = md_chars_to_number (buf, INSN_SIZE);
28950 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
28951 md_number_to_chars (buf, newval, INSN_SIZE);
28952 break;
28953
c19d1205 28954 case BFD_RELOC_ARM_SWI:
adbaf948 28955 if (fixP->tc_fix_data != 0)
c19d1205 28956 {
7af67752 28957 if (value > 0xff)
c19d1205
ZW
28958 as_bad_where (fixP->fx_file, fixP->fx_line,
28959 _("invalid swi expression"));
2fc8bdac 28960 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205
ZW
28961 newval |= value;
28962 md_number_to_chars (buf, newval, THUMB_SIZE);
28963 }
28964 else
28965 {
7af67752 28966 if (value > 0x00ffffff)
c19d1205
ZW
28967 as_bad_where (fixP->fx_file, fixP->fx_line,
28968 _("invalid swi expression"));
2fc8bdac 28969 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
28970 newval |= value;
28971 md_number_to_chars (buf, newval, INSN_SIZE);
28972 }
28973 break;
a737bd4d 28974
c19d1205 28975 case BFD_RELOC_ARM_MULTI:
7af67752 28976 if (value > 0xffff)
c19d1205
ZW
28977 as_bad_where (fixP->fx_file, fixP->fx_line,
28978 _("invalid expression in load/store multiple"));
28979 newval = value | md_chars_to_number (buf, INSN_SIZE);
28980 md_number_to_chars (buf, newval, INSN_SIZE);
28981 break;
a737bd4d 28982
c19d1205 28983#ifdef OBJ_ELF
39b41c9c 28984 case BFD_RELOC_ARM_PCREL_CALL:
267bf995
RR
28985
28986 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
28987 && fixP->fx_addsy
5b7c81bd 28988 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
28989 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28990 && THUMB_IS_FUNC (fixP->fx_addsy))
28991 /* Flip the bl to blx. This is a simple flip
28992 bit here because we generate PCREL_CALL for
28993 unconditional bls. */
28994 {
28995 newval = md_chars_to_number (buf, INSN_SIZE);
28996 newval = newval | 0x10000000;
28997 md_number_to_chars (buf, newval, INSN_SIZE);
28998 temp = 1;
28999 fixP->fx_done = 1;
29000 }
39b41c9c
PB
29001 else
29002 temp = 3;
29003 goto arm_branch_common;
29004
29005 case BFD_RELOC_ARM_PCREL_JUMP:
267bf995
RR
29006 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
29007 && fixP->fx_addsy
5b7c81bd 29008 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29009 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29010 && THUMB_IS_FUNC (fixP->fx_addsy))
29011 {
29012 /* This would map to a bl<cond>, b<cond>,
29013 b<always> to a Thumb function. We
29014 need to force a relocation for this particular
29015 case. */
29016 newval = md_chars_to_number (buf, INSN_SIZE);
29017 fixP->fx_done = 0;
29018 }
1a0670f3 29019 /* Fall through. */
267bf995 29020
2fc8bdac 29021 case BFD_RELOC_ARM_PLT32:
c19d1205 29022#endif
39b41c9c
PB
29023 case BFD_RELOC_ARM_PCREL_BRANCH:
29024 temp = 3;
29025 goto arm_branch_common;
a737bd4d 29026
39b41c9c 29027 case BFD_RELOC_ARM_PCREL_BLX:
267bf995 29028
39b41c9c 29029 temp = 1;
267bf995
RR
29030 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
29031 && fixP->fx_addsy
5b7c81bd 29032 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29033 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29034 && ARM_IS_FUNC (fixP->fx_addsy))
29035 {
29036 /* Flip the blx to a bl and warn. */
29037 const char *name = S_GET_NAME (fixP->fx_addsy);
29038 newval = 0xeb000000;
29039 as_warn_where (fixP->fx_file, fixP->fx_line,
29040 _("blx to '%s' an ARM ISA state function changed to bl"),
29041 name);
29042 md_number_to_chars (buf, newval, INSN_SIZE);
29043 temp = 3;
29044 fixP->fx_done = 1;
29045 }
29046
29047#ifdef OBJ_ELF
29048 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
477330fc 29049 fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
267bf995
RR
29050#endif
29051
39b41c9c 29052 arm_branch_common:
c19d1205 29053 /* We are going to store value (shifted right by two) in the
39b41c9c
PB
29054 instruction, in a 24 bit, signed field. Bits 26 through 32 either
29055 all clear or all set and bit 0 must be clear. For B/BL bit 1 must
de194d85 29056 also be clear. */
39b41c9c 29057 if (value & temp)
c19d1205 29058 as_bad_where (fixP->fx_file, fixP->fx_line,
2fc8bdac 29059 _("misaligned branch destination"));
7af67752
AM
29060 if ((value & 0xfe000000) != 0
29061 && (value & 0xfe000000) != 0xfe000000)
08f10d51 29062 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 29063
2fc8bdac 29064 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 29065 {
2fc8bdac
ZW
29066 newval = md_chars_to_number (buf, INSN_SIZE);
29067 newval |= (value >> 2) & 0x00ffffff;
7ae2971b
PB
29068 /* Set the H bit on BLX instructions. */
29069 if (temp == 1)
29070 {
29071 if (value & 2)
29072 newval |= 0x01000000;
29073 else
29074 newval &= ~0x01000000;
29075 }
2fc8bdac 29076 md_number_to_chars (buf, newval, INSN_SIZE);
c19d1205 29077 }
c19d1205 29078 break;
a737bd4d 29079
25fe350b
MS
29080 case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CBZ */
29081 /* CBZ can only branch forward. */
a737bd4d 29082
738755b0 29083 /* Attempts to use CBZ to branch to the next instruction
477330fc
RM
29084 (which, strictly speaking, are prohibited) will be turned into
29085 no-ops.
738755b0
MS
29086
29087 FIXME: It may be better to remove the instruction completely and
29088 perform relaxation. */
7af67752 29089 if ((offsetT) value == -2)
2fc8bdac
ZW
29090 {
29091 newval = md_chars_to_number (buf, THUMB_SIZE);
738755b0 29092 newval = 0xbf00; /* NOP encoding T1 */
2fc8bdac
ZW
29093 md_number_to_chars (buf, newval, THUMB_SIZE);
29094 }
738755b0
MS
29095 else
29096 {
29097 if (value & ~0x7e)
08f10d51 29098 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
738755b0 29099
477330fc 29100 if (fixP->fx_done || !seg->use_rela_p)
738755b0
MS
29101 {
29102 newval = md_chars_to_number (buf, THUMB_SIZE);
29103 newval |= ((value & 0x3e) << 2) | ((value & 0x40) << 3);
29104 md_number_to_chars (buf, newval, THUMB_SIZE);
29105 }
29106 }
c19d1205 29107 break;
a737bd4d 29108
c19d1205 29109 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
e8f8842d 29110 if (out_of_range_p (value, 8))
08f10d51 29111 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 29112
2fc8bdac
ZW
29113 if (fixP->fx_done || !seg->use_rela_p)
29114 {
29115 newval = md_chars_to_number (buf, THUMB_SIZE);
29116 newval |= (value & 0x1ff) >> 1;
29117 md_number_to_chars (buf, newval, THUMB_SIZE);
29118 }
c19d1205 29119 break;
a737bd4d 29120
c19d1205 29121 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
e8f8842d 29122 if (out_of_range_p (value, 11))
08f10d51 29123 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 29124
2fc8bdac
ZW
29125 if (fixP->fx_done || !seg->use_rela_p)
29126 {
29127 newval = md_chars_to_number (buf, THUMB_SIZE);
29128 newval |= (value & 0xfff) >> 1;
29129 md_number_to_chars (buf, newval, THUMB_SIZE);
29130 }
c19d1205 29131 break;
a737bd4d 29132
e8f8842d 29133 /* This relocation is misnamed, it should be BRANCH21. */
c19d1205 29134 case BFD_RELOC_THUMB_PCREL_BRANCH20:
267bf995
RR
29135 if (fixP->fx_addsy
29136 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29137 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29138 && ARM_IS_FUNC (fixP->fx_addsy)
29139 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
29140 {
29141 /* Force a relocation for a branch 20 bits wide. */
29142 fixP->fx_done = 0;
29143 }
e8f8842d 29144 if (out_of_range_p (value, 20))
2fc8bdac
ZW
29145 as_bad_where (fixP->fx_file, fixP->fx_line,
29146 _("conditional branch out of range"));
404ff6b5 29147
2fc8bdac
ZW
29148 if (fixP->fx_done || !seg->use_rela_p)
29149 {
29150 offsetT newval2;
29151 addressT S, J1, J2, lo, hi;
404ff6b5 29152
2fc8bdac
ZW
29153 S = (value & 0x00100000) >> 20;
29154 J2 = (value & 0x00080000) >> 19;
29155 J1 = (value & 0x00040000) >> 18;
29156 hi = (value & 0x0003f000) >> 12;
29157 lo = (value & 0x00000ffe) >> 1;
6c43fab6 29158
2fc8bdac
ZW
29159 newval = md_chars_to_number (buf, THUMB_SIZE);
29160 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29161 newval |= (S << 10) | hi;
29162 newval2 |= (J1 << 13) | (J2 << 11) | lo;
29163 md_number_to_chars (buf, newval, THUMB_SIZE);
29164 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
29165 }
c19d1205 29166 break;
6c43fab6 29167
c19d1205 29168 case BFD_RELOC_THUMB_PCREL_BLX:
267bf995
RR
29169 /* If there is a blx from a thumb state function to
29170 another thumb function flip this to a bl and warn
29171 about it. */
29172
29173 if (fixP->fx_addsy
5b7c81bd 29174 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29175 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29176 && THUMB_IS_FUNC (fixP->fx_addsy))
29177 {
29178 const char *name = S_GET_NAME (fixP->fx_addsy);
29179 as_warn_where (fixP->fx_file, fixP->fx_line,
29180 _("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
29181 name);
29182 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29183 newval = newval | 0x1000;
29184 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
29185 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
29186 fixP->fx_done = 1;
29187 }
29188
29189
29190 goto thumb_bl_common;
29191
c19d1205 29192 case BFD_RELOC_THUMB_PCREL_BRANCH23:
267bf995
RR
29193 /* A bl from Thumb state ISA to an internal ARM state function
29194 is converted to a blx. */
29195 if (fixP->fx_addsy
29196 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29197 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29198 && ARM_IS_FUNC (fixP->fx_addsy)
29199 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
29200 {
29201 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29202 newval = newval & ~0x1000;
29203 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
29204 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
29205 fixP->fx_done = 1;
29206 }
29207
29208 thumb_bl_common:
29209
2fc8bdac
ZW
29210 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
29211 /* For a BLX instruction, make sure that the relocation is rounded up
29212 to a word boundary. This follows the semantics of the instruction
29213 which specifies that bit 1 of the target address will come from bit
29214 1 of the base address. */
d406f3e4
JB
29215 value = (value + 3) & ~ 3;
29216
29217#ifdef OBJ_ELF
29218 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
29219 && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
29220 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
29221#endif
404ff6b5 29222
e8f8842d 29223 if (out_of_range_p (value, 22))
2b2f5df9 29224 {
fc289b0a 29225 if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)))
2b2f5df9 29226 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
e8f8842d 29227 else if (out_of_range_p (value, 24))
2b2f5df9
NC
29228 as_bad_where (fixP->fx_file, fixP->fx_line,
29229 _("Thumb2 branch out of range"));
29230 }
4a42ebbc
RR
29231
29232 if (fixP->fx_done || !seg->use_rela_p)
29233 encode_thumb2_b_bl_offset (buf, value);
29234
c19d1205 29235 break;
404ff6b5 29236
c19d1205 29237 case BFD_RELOC_THUMB_PCREL_BRANCH25:
e8f8842d 29238 if (out_of_range_p (value, 24))
08f10d51 29239 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
6c43fab6 29240
2fc8bdac 29241 if (fixP->fx_done || !seg->use_rela_p)
4a42ebbc 29242 encode_thumb2_b_bl_offset (buf, value);
6c43fab6 29243
2fc8bdac 29244 break;
a737bd4d 29245
2fc8bdac
ZW
29246 case BFD_RELOC_8:
29247 if (fixP->fx_done || !seg->use_rela_p)
4b1a927e 29248 *buf = value;
c19d1205 29249 break;
a737bd4d 29250
c19d1205 29251 case BFD_RELOC_16:
2fc8bdac 29252 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 29253 md_number_to_chars (buf, value, 2);
c19d1205 29254 break;
a737bd4d 29255
c19d1205 29256#ifdef OBJ_ELF
0855e32b
NS
29257 case BFD_RELOC_ARM_TLS_CALL:
29258 case BFD_RELOC_ARM_THM_TLS_CALL:
29259 case BFD_RELOC_ARM_TLS_DESCSEQ:
29260 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
0855e32b 29261 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205
ZW
29262 case BFD_RELOC_ARM_TLS_GD32:
29263 case BFD_RELOC_ARM_TLS_LE32:
29264 case BFD_RELOC_ARM_TLS_IE32:
29265 case BFD_RELOC_ARM_TLS_LDM32:
29266 case BFD_RELOC_ARM_TLS_LDO32:
29267 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4b1a927e 29268 break;
6c43fab6 29269
5c5a4843
CL
29270 /* Same handling as above, but with the arm_fdpic guard. */
29271 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
29272 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
29273 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
29274 if (arm_fdpic)
29275 {
29276 S_SET_THREAD_LOCAL (fixP->fx_addsy);
29277 }
29278 else
29279 {
29280 as_bad_where (fixP->fx_file, fixP->fx_line,
29281 _("Relocation supported only in FDPIC mode"));
29282 }
29283 break;
29284
c19d1205
ZW
29285 case BFD_RELOC_ARM_GOT32:
29286 case BFD_RELOC_ARM_GOTOFF:
c19d1205 29287 break;
b43420e6
NC
29288
29289 case BFD_RELOC_ARM_GOT_PREL:
29290 if (fixP->fx_done || !seg->use_rela_p)
477330fc 29291 md_number_to_chars (buf, value, 4);
b43420e6
NC
29292 break;
29293
9a6f4e97
NS
29294 case BFD_RELOC_ARM_TARGET2:
29295 /* TARGET2 is not partial-inplace, so we need to write the
477330fc
RM
29296 addend here for REL targets, because it won't be written out
29297 during reloc processing later. */
9a6f4e97
NS
29298 if (fixP->fx_done || !seg->use_rela_p)
29299 md_number_to_chars (buf, fixP->fx_offset, 4);
29300 break;
188fd7ae
CL
29301
29302 /* Relocations for FDPIC. */
29303 case BFD_RELOC_ARM_GOTFUNCDESC:
29304 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
29305 case BFD_RELOC_ARM_FUNCDESC:
29306 if (arm_fdpic)
29307 {
29308 if (fixP->fx_done || !seg->use_rela_p)
29309 md_number_to_chars (buf, 0, 4);
29310 }
29311 else
29312 {
29313 as_bad_where (fixP->fx_file, fixP->fx_line,
29314 _("Relocation supported only in FDPIC mode"));
29315 }
29316 break;
c19d1205 29317#endif
6c43fab6 29318
c19d1205
ZW
29319 case BFD_RELOC_RVA:
29320 case BFD_RELOC_32:
29321 case BFD_RELOC_ARM_TARGET1:
29322 case BFD_RELOC_ARM_ROSEGREL32:
29323 case BFD_RELOC_ARM_SBREL32:
29324 case BFD_RELOC_32_PCREL:
f0927246
NC
29325#ifdef TE_PE
29326 case BFD_RELOC_32_SECREL:
29327#endif
2fc8bdac 29328 if (fixP->fx_done || !seg->use_rela_p)
53baae48
NC
29329#ifdef TE_WINCE
29330 /* For WinCE we only do this for pcrel fixups. */
29331 if (fixP->fx_done || fixP->fx_pcrel)
29332#endif
29333 md_number_to_chars (buf, value, 4);
c19d1205 29334 break;
6c43fab6 29335
c19d1205
ZW
29336#ifdef OBJ_ELF
29337 case BFD_RELOC_ARM_PREL31:
2fc8bdac 29338 if (fixP->fx_done || !seg->use_rela_p)
c19d1205
ZW
29339 {
29340 newval = md_chars_to_number (buf, 4) & 0x80000000;
29341 if ((value ^ (value >> 1)) & 0x40000000)
29342 {
29343 as_bad_where (fixP->fx_file, fixP->fx_line,
29344 _("rel31 relocation overflow"));
29345 }
29346 newval |= value & 0x7fffffff;
29347 md_number_to_chars (buf, newval, 4);
29348 }
29349 break;
c19d1205 29350#endif
a737bd4d 29351
c19d1205 29352 case BFD_RELOC_ARM_CP_OFF_IMM:
8f06b2d8 29353 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
32c36c3c 29354 case BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM:
9db2f6b4
RL
29355 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
29356 newval = md_chars_to_number (buf, INSN_SIZE);
29357 else
29358 newval = get_thumb32_insn (buf);
29359 if ((newval & 0x0f200f00) == 0x0d000900)
29360 {
29361 /* This is a fp16 vstr/vldr. The immediate offset in the mnemonic
7af67752 29362 has permitted values that are multiples of 2, in the range -510
9db2f6b4 29363 to 510. */
7af67752 29364 if (value + 510 > 510 + 510 || (value & 1))
9db2f6b4
RL
29365 as_bad_where (fixP->fx_file, fixP->fx_line,
29366 _("co-processor offset out of range"));
29367 }
32c36c3c
AV
29368 else if ((newval & 0xfe001f80) == 0xec000f80)
29369 {
7af67752 29370 if (value + 511 > 512 + 511 || (value & 3))
32c36c3c
AV
29371 as_bad_where (fixP->fx_file, fixP->fx_line,
29372 _("co-processor offset out of range"));
29373 }
7af67752 29374 else if (value + 1023 > 1023 + 1023 || (value & 3))
c19d1205
ZW
29375 as_bad_where (fixP->fx_file, fixP->fx_line,
29376 _("co-processor offset out of range"));
29377 cp_off_common:
7af67752
AM
29378 sign = (offsetT) value > 0;
29379 if ((offsetT) value < 0)
c19d1205 29380 value = -value;
8f06b2d8
PB
29381 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
29382 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
29383 newval = md_chars_to_number (buf, INSN_SIZE);
29384 else
29385 newval = get_thumb32_insn (buf);
26d97720 29386 if (value == 0)
32c36c3c
AV
29387 {
29388 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
29389 newval &= 0xffffff80;
29390 else
29391 newval &= 0xffffff00;
29392 }
26d97720
NS
29393 else
29394 {
32c36c3c
AV
29395 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
29396 newval &= 0xff7fff80;
29397 else
29398 newval &= 0xff7fff00;
9db2f6b4
RL
29399 if ((newval & 0x0f200f00) == 0x0d000900)
29400 {
29401 /* This is a fp16 vstr/vldr.
29402
29403 It requires the immediate offset in the instruction is shifted
29404 left by 1 to be a half-word offset.
29405
29406 Here, left shift by 1 first, and later right shift by 2
29407 should get the right offset. */
29408 value <<= 1;
29409 }
26d97720
NS
29410 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
29411 }
8f06b2d8
PB
29412 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
29413 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
29414 md_number_to_chars (buf, newval, INSN_SIZE);
29415 else
29416 put_thumb32_insn (buf, newval);
c19d1205 29417 break;
a737bd4d 29418
c19d1205 29419 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
8f06b2d8 29420 case BFD_RELOC_ARM_T32_CP_OFF_IMM_S2:
7af67752 29421 if (value + 255 > 255 + 255)
c19d1205
ZW
29422 as_bad_where (fixP->fx_file, fixP->fx_line,
29423 _("co-processor offset out of range"));
df7849c5 29424 value *= 4;
c19d1205 29425 goto cp_off_common;
6c43fab6 29426
c19d1205
ZW
29427 case BFD_RELOC_ARM_THUMB_OFFSET:
29428 newval = md_chars_to_number (buf, THUMB_SIZE);
29429 /* Exactly what ranges, and where the offset is inserted depends
29430 on the type of instruction, we can establish this from the
29431 top 4 bits. */
29432 switch (newval >> 12)
29433 {
29434 case 4: /* PC load. */
29435 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
29436 forced to zero for these loads; md_pcrel_from has already
29437 compensated for this. */
29438 if (value & 3)
29439 as_bad_where (fixP->fx_file, fixP->fx_line,
29440 _("invalid offset, target not word aligned (0x%08lX)"),
0359e808
NC
29441 (((unsigned long) fixP->fx_frag->fr_address
29442 + (unsigned long) fixP->fx_where) & ~3)
29443 + (unsigned long) value);
749479c8
AO
29444 else if (get_recorded_alignment (seg) < 2)
29445 as_warn_where (fixP->fx_file, fixP->fx_line,
29446 _("section does not have enough alignment to ensure safe PC-relative loads"));
a737bd4d 29447
c19d1205
ZW
29448 if (value & ~0x3fc)
29449 as_bad_where (fixP->fx_file, fixP->fx_line,
29450 _("invalid offset, value too big (0x%08lX)"),
29451 (long) value);
a737bd4d 29452
c19d1205
ZW
29453 newval |= value >> 2;
29454 break;
a737bd4d 29455
c19d1205
ZW
29456 case 9: /* SP load/store. */
29457 if (value & ~0x3fc)
29458 as_bad_where (fixP->fx_file, fixP->fx_line,
29459 _("invalid offset, value too big (0x%08lX)"),
29460 (long) value);
29461 newval |= value >> 2;
29462 break;
6c43fab6 29463
c19d1205
ZW
29464 case 6: /* Word load/store. */
29465 if (value & ~0x7c)
29466 as_bad_where (fixP->fx_file, fixP->fx_line,
29467 _("invalid offset, value too big (0x%08lX)"),
29468 (long) value);
29469 newval |= value << 4; /* 6 - 2. */
29470 break;
a737bd4d 29471
c19d1205
ZW
29472 case 7: /* Byte load/store. */
29473 if (value & ~0x1f)
29474 as_bad_where (fixP->fx_file, fixP->fx_line,
29475 _("invalid offset, value too big (0x%08lX)"),
29476 (long) value);
29477 newval |= value << 6;
29478 break;
a737bd4d 29479
c19d1205
ZW
29480 case 8: /* Halfword load/store. */
29481 if (value & ~0x3e)
29482 as_bad_where (fixP->fx_file, fixP->fx_line,
29483 _("invalid offset, value too big (0x%08lX)"),
29484 (long) value);
29485 newval |= value << 5; /* 6 - 1. */
29486 break;
a737bd4d 29487
c19d1205
ZW
29488 default:
29489 as_bad_where (fixP->fx_file, fixP->fx_line,
29490 "Unable to process relocation for thumb opcode: %lx",
29491 (unsigned long) newval);
29492 break;
29493 }
29494 md_number_to_chars (buf, newval, THUMB_SIZE);
29495 break;
a737bd4d 29496
c19d1205
ZW
29497 case BFD_RELOC_ARM_THUMB_ADD:
29498 /* This is a complicated relocation, since we use it for all of
29499 the following immediate relocations:
a737bd4d 29500
c19d1205
ZW
29501 3bit ADD/SUB
29502 8bit ADD/SUB
29503 9bit ADD/SUB SP word-aligned
29504 10bit ADD PC/SP word-aligned
a737bd4d 29505
c19d1205
ZW
29506 The type of instruction being processed is encoded in the
29507 instruction field:
a737bd4d 29508
c19d1205
ZW
29509 0x8000 SUB
29510 0x00F0 Rd
29511 0x000F Rs
29512 */
29513 newval = md_chars_to_number (buf, THUMB_SIZE);
29514 {
29515 int rd = (newval >> 4) & 0xf;
29516 int rs = newval & 0xf;
29517 int subtract = !!(newval & 0x8000);
a737bd4d 29518
c19d1205
ZW
29519 /* Check for HI regs, only very restricted cases allowed:
29520 Adjusting SP, and using PC or SP to get an address. */
29521 if ((rd > 7 && (rd != REG_SP || rs != REG_SP))
29522 || (rs > 7 && rs != REG_SP && rs != REG_PC))
29523 as_bad_where (fixP->fx_file, fixP->fx_line,
29524 _("invalid Hi register with immediate"));
a737bd4d 29525
c19d1205 29526 /* If value is negative, choose the opposite instruction. */
7af67752 29527 if ((offsetT) value < 0)
c19d1205
ZW
29528 {
29529 value = -value;
29530 subtract = !subtract;
7af67752 29531 if ((offsetT) value < 0)
c19d1205
ZW
29532 as_bad_where (fixP->fx_file, fixP->fx_line,
29533 _("immediate value out of range"));
29534 }
a737bd4d 29535
c19d1205
ZW
29536 if (rd == REG_SP)
29537 {
75c11999 29538 if (value & ~0x1fc)
c19d1205
ZW
29539 as_bad_where (fixP->fx_file, fixP->fx_line,
29540 _("invalid immediate for stack address calculation"));
29541 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
29542 newval |= value >> 2;
29543 }
29544 else if (rs == REG_PC || rs == REG_SP)
29545 {
c12d2c9d
NC
29546 /* PR gas/18541. If the addition is for a defined symbol
29547 within range of an ADR instruction then accept it. */
29548 if (subtract
29549 && value == 4
29550 && fixP->fx_addsy != NULL)
29551 {
29552 subtract = 0;
29553
29554 if (! S_IS_DEFINED (fixP->fx_addsy)
29555 || S_GET_SEGMENT (fixP->fx_addsy) != seg
29556 || S_IS_WEAK (fixP->fx_addsy))
29557 {
29558 as_bad_where (fixP->fx_file, fixP->fx_line,
29559 _("address calculation needs a strongly defined nearby symbol"));
29560 }
29561 else
29562 {
29563 offsetT v = fixP->fx_where + fixP->fx_frag->fr_address;
29564
29565 /* Round up to the next 4-byte boundary. */
29566 if (v & 3)
29567 v = (v + 3) & ~ 3;
29568 else
29569 v += 4;
29570 v = S_GET_VALUE (fixP->fx_addsy) - v;
29571
29572 if (v & ~0x3fc)
29573 {
29574 as_bad_where (fixP->fx_file, fixP->fx_line,
29575 _("symbol too far away"));
29576 }
29577 else
29578 {
29579 fixP->fx_done = 1;
29580 value = v;
29581 }
29582 }
29583 }
29584
c19d1205
ZW
29585 if (subtract || value & ~0x3fc)
29586 as_bad_where (fixP->fx_file, fixP->fx_line,
29587 _("invalid immediate for address calculation (value = 0x%08lX)"),
5fc177c8 29588 (unsigned long) (subtract ? - value : value));
c19d1205
ZW
29589 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
29590 newval |= rd << 8;
29591 newval |= value >> 2;
29592 }
29593 else if (rs == rd)
29594 {
29595 if (value & ~0xff)
29596 as_bad_where (fixP->fx_file, fixP->fx_line,
29597 _("immediate value out of range"));
29598 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
29599 newval |= (rd << 8) | value;
29600 }
29601 else
29602 {
29603 if (value & ~0x7)
29604 as_bad_where (fixP->fx_file, fixP->fx_line,
29605 _("immediate value out of range"));
29606 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
29607 newval |= rd | (rs << 3) | (value << 6);
29608 }
29609 }
29610 md_number_to_chars (buf, newval, THUMB_SIZE);
29611 break;
a737bd4d 29612
c19d1205
ZW
29613 case BFD_RELOC_ARM_THUMB_IMM:
29614 newval = md_chars_to_number (buf, THUMB_SIZE);
7af67752 29615 if (value > 255)
c19d1205 29616 as_bad_where (fixP->fx_file, fixP->fx_line,
4e6e072b 29617 _("invalid immediate: %ld is out of range"),
c19d1205
ZW
29618 (long) value);
29619 newval |= value;
29620 md_number_to_chars (buf, newval, THUMB_SIZE);
29621 break;
a737bd4d 29622
c19d1205
ZW
29623 case BFD_RELOC_ARM_THUMB_SHIFT:
29624 /* 5bit shift value (0..32). LSL cannot take 32. */
29625 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf83f;
29626 temp = newval & 0xf800;
7af67752 29627 if (value > 32 || (value == 32 && temp == T_OPCODE_LSL_I))
c19d1205
ZW
29628 as_bad_where (fixP->fx_file, fixP->fx_line,
29629 _("invalid shift value: %ld"), (long) value);
29630 /* Shifts of zero must be encoded as LSL. */
29631 if (value == 0)
29632 newval = (newval & 0x003f) | T_OPCODE_LSL_I;
29633 /* Shifts of 32 are encoded as zero. */
29634 else if (value == 32)
29635 value = 0;
29636 newval |= value << 6;
29637 md_number_to_chars (buf, newval, THUMB_SIZE);
29638 break;
a737bd4d 29639
c19d1205
ZW
29640 case BFD_RELOC_VTABLE_INHERIT:
29641 case BFD_RELOC_VTABLE_ENTRY:
29642 fixP->fx_done = 0;
29643 return;
6c43fab6 29644
b6895b4f
PB
29645 case BFD_RELOC_ARM_MOVW:
29646 case BFD_RELOC_ARM_MOVT:
29647 case BFD_RELOC_ARM_THUMB_MOVW:
29648 case BFD_RELOC_ARM_THUMB_MOVT:
29649 if (fixP->fx_done || !seg->use_rela_p)
29650 {
29651 /* REL format relocations are limited to a 16-bit addend. */
29652 if (!fixP->fx_done)
29653 {
7af67752 29654 if (value + 0x8000 > 0x7fff + 0x8000)
b6895b4f 29655 as_bad_where (fixP->fx_file, fixP->fx_line,
ff5075ca 29656 _("offset out of range"));
b6895b4f
PB
29657 }
29658 else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT
29659 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
29660 {
29661 value >>= 16;
29662 }
29663
29664 if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
29665 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
29666 {
29667 newval = get_thumb32_insn (buf);
29668 newval &= 0xfbf08f00;
29669 newval |= (value & 0xf000) << 4;
29670 newval |= (value & 0x0800) << 15;
29671 newval |= (value & 0x0700) << 4;
29672 newval |= (value & 0x00ff);
29673 put_thumb32_insn (buf, newval);
29674 }
29675 else
29676 {
29677 newval = md_chars_to_number (buf, 4);
29678 newval &= 0xfff0f000;
29679 newval |= value & 0x0fff;
29680 newval |= (value & 0xf000) << 4;
29681 md_number_to_chars (buf, newval, 4);
29682 }
29683 }
29684 return;
29685
72d98d16
MG
29686 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
29687 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
29688 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
29689 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
29690 gas_assert (!fixP->fx_done);
29691 {
29692 bfd_vma insn;
5b7c81bd 29693 bool is_mov;
72d98d16
MG
29694 bfd_vma encoded_addend = value;
29695
29696 /* Check that addend can be encoded in instruction. */
7af67752 29697 if (!seg->use_rela_p && value > 255)
72d98d16
MG
29698 as_bad_where (fixP->fx_file, fixP->fx_line,
29699 _("the offset 0x%08lX is not representable"),
29700 (unsigned long) encoded_addend);
29701
29702 /* Extract the instruction. */
29703 insn = md_chars_to_number (buf, THUMB_SIZE);
29704 is_mov = (insn & 0xf800) == 0x2000;
29705
29706 /* Encode insn. */
29707 if (is_mov)
29708 {
29709 if (!seg->use_rela_p)
29710 insn |= encoded_addend;
29711 }
29712 else
29713 {
29714 int rd, rs;
29715
29716 /* Extract the instruction. */
29717 /* Encoding is the following
29718 0x8000 SUB
29719 0x00F0 Rd
29720 0x000F Rs
29721 */
29722 /* The following conditions must be true :
29723 - ADD
29724 - Rd == Rs
29725 - Rd <= 7
29726 */
29727 rd = (insn >> 4) & 0xf;
29728 rs = insn & 0xf;
29729 if ((insn & 0x8000) || (rd != rs) || rd > 7)
29730 as_bad_where (fixP->fx_file, fixP->fx_line,
29731 _("Unable to process relocation for thumb opcode: %lx"),
29732 (unsigned long) insn);
29733
29734 /* Encode as ADD immediate8 thumb 1 code. */
29735 insn = 0x3000 | (rd << 8);
29736
29737 /* Place the encoded addend into the first 8 bits of the
29738 instruction. */
29739 if (!seg->use_rela_p)
29740 insn |= encoded_addend;
29741 }
29742
29743 /* Update the instruction. */
29744 md_number_to_chars (buf, insn, THUMB_SIZE);
29745 }
29746 break;
29747
4962c51a
MS
29748 case BFD_RELOC_ARM_ALU_PC_G0_NC:
29749 case BFD_RELOC_ARM_ALU_PC_G0:
29750 case BFD_RELOC_ARM_ALU_PC_G1_NC:
29751 case BFD_RELOC_ARM_ALU_PC_G1:
29752 case BFD_RELOC_ARM_ALU_PC_G2:
29753 case BFD_RELOC_ARM_ALU_SB_G0_NC:
29754 case BFD_RELOC_ARM_ALU_SB_G0:
29755 case BFD_RELOC_ARM_ALU_SB_G1_NC:
29756 case BFD_RELOC_ARM_ALU_SB_G1:
29757 case BFD_RELOC_ARM_ALU_SB_G2:
9c2799c2 29758 gas_assert (!fixP->fx_done);
4962c51a
MS
29759 if (!seg->use_rela_p)
29760 {
477330fc
RM
29761 bfd_vma insn;
29762 bfd_vma encoded_addend;
7af67752 29763 bfd_vma addend_abs = llabs ((offsetT) value);
477330fc
RM
29764
29765 /* Check that the absolute value of the addend can be
29766 expressed as an 8-bit constant plus a rotation. */
29767 encoded_addend = encode_arm_immediate (addend_abs);
29768 if (encoded_addend == (unsigned int) FAIL)
4962c51a 29769 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29770 _("the offset 0x%08lX is not representable"),
29771 (unsigned long) addend_abs);
29772
29773 /* Extract the instruction. */
29774 insn = md_chars_to_number (buf, INSN_SIZE);
29775
29776 /* If the addend is positive, use an ADD instruction.
29777 Otherwise use a SUB. Take care not to destroy the S bit. */
29778 insn &= 0xff1fffff;
7af67752 29779 if ((offsetT) value < 0)
477330fc
RM
29780 insn |= 1 << 22;
29781 else
29782 insn |= 1 << 23;
29783
29784 /* Place the encoded addend into the first 12 bits of the
29785 instruction. */
29786 insn &= 0xfffff000;
29787 insn |= encoded_addend;
29788
29789 /* Update the instruction. */
29790 md_number_to_chars (buf, insn, INSN_SIZE);
4962c51a
MS
29791 }
29792 break;
29793
29794 case BFD_RELOC_ARM_LDR_PC_G0:
29795 case BFD_RELOC_ARM_LDR_PC_G1:
29796 case BFD_RELOC_ARM_LDR_PC_G2:
29797 case BFD_RELOC_ARM_LDR_SB_G0:
29798 case BFD_RELOC_ARM_LDR_SB_G1:
29799 case BFD_RELOC_ARM_LDR_SB_G2:
9c2799c2 29800 gas_assert (!fixP->fx_done);
4962c51a 29801 if (!seg->use_rela_p)
477330fc
RM
29802 {
29803 bfd_vma insn;
7af67752 29804 bfd_vma addend_abs = llabs ((offsetT) value);
4962c51a 29805
477330fc
RM
29806 /* Check that the absolute value of the addend can be
29807 encoded in 12 bits. */
29808 if (addend_abs >= 0x1000)
4962c51a 29809 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29810 _("bad offset 0x%08lX (only 12 bits available for the magnitude)"),
29811 (unsigned long) addend_abs);
29812
29813 /* Extract the instruction. */
29814 insn = md_chars_to_number (buf, INSN_SIZE);
29815
29816 /* If the addend is negative, clear bit 23 of the instruction.
29817 Otherwise set it. */
7af67752 29818 if ((offsetT) value < 0)
477330fc
RM
29819 insn &= ~(1 << 23);
29820 else
29821 insn |= 1 << 23;
29822
29823 /* Place the absolute value of the addend into the first 12 bits
29824 of the instruction. */
29825 insn &= 0xfffff000;
29826 insn |= addend_abs;
29827
29828 /* Update the instruction. */
29829 md_number_to_chars (buf, insn, INSN_SIZE);
29830 }
4962c51a
MS
29831 break;
29832
29833 case BFD_RELOC_ARM_LDRS_PC_G0:
29834 case BFD_RELOC_ARM_LDRS_PC_G1:
29835 case BFD_RELOC_ARM_LDRS_PC_G2:
29836 case BFD_RELOC_ARM_LDRS_SB_G0:
29837 case BFD_RELOC_ARM_LDRS_SB_G1:
29838 case BFD_RELOC_ARM_LDRS_SB_G2:
9c2799c2 29839 gas_assert (!fixP->fx_done);
4962c51a 29840 if (!seg->use_rela_p)
477330fc
RM
29841 {
29842 bfd_vma insn;
7af67752 29843 bfd_vma addend_abs = llabs ((offsetT) value);
4962c51a 29844
477330fc
RM
29845 /* Check that the absolute value of the addend can be
29846 encoded in 8 bits. */
29847 if (addend_abs >= 0x100)
4962c51a 29848 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29849 _("bad offset 0x%08lX (only 8 bits available for the magnitude)"),
29850 (unsigned long) addend_abs);
29851
29852 /* Extract the instruction. */
29853 insn = md_chars_to_number (buf, INSN_SIZE);
29854
29855 /* If the addend is negative, clear bit 23 of the instruction.
29856 Otherwise set it. */
7af67752 29857 if ((offsetT) value < 0)
477330fc
RM
29858 insn &= ~(1 << 23);
29859 else
29860 insn |= 1 << 23;
29861
29862 /* Place the first four bits of the absolute value of the addend
29863 into the first 4 bits of the instruction, and the remaining
29864 four into bits 8 .. 11. */
29865 insn &= 0xfffff0f0;
29866 insn |= (addend_abs & 0xf) | ((addend_abs & 0xf0) << 4);
29867
29868 /* Update the instruction. */
29869 md_number_to_chars (buf, insn, INSN_SIZE);
29870 }
4962c51a
MS
29871 break;
29872
29873 case BFD_RELOC_ARM_LDC_PC_G0:
29874 case BFD_RELOC_ARM_LDC_PC_G1:
29875 case BFD_RELOC_ARM_LDC_PC_G2:
29876 case BFD_RELOC_ARM_LDC_SB_G0:
29877 case BFD_RELOC_ARM_LDC_SB_G1:
29878 case BFD_RELOC_ARM_LDC_SB_G2:
9c2799c2 29879 gas_assert (!fixP->fx_done);
4962c51a 29880 if (!seg->use_rela_p)
477330fc
RM
29881 {
29882 bfd_vma insn;
7af67752 29883 bfd_vma addend_abs = llabs ((offsetT) value);
4962c51a 29884
477330fc
RM
29885 /* Check that the absolute value of the addend is a multiple of
29886 four and, when divided by four, fits in 8 bits. */
29887 if (addend_abs & 0x3)
4962c51a 29888 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29889 _("bad offset 0x%08lX (must be word-aligned)"),
29890 (unsigned long) addend_abs);
4962c51a 29891
477330fc 29892 if ((addend_abs >> 2) > 0xff)
4962c51a 29893 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29894 _("bad offset 0x%08lX (must be an 8-bit number of words)"),
29895 (unsigned long) addend_abs);
29896
29897 /* Extract the instruction. */
29898 insn = md_chars_to_number (buf, INSN_SIZE);
29899
29900 /* If the addend is negative, clear bit 23 of the instruction.
29901 Otherwise set it. */
7af67752 29902 if ((offsetT) value < 0)
477330fc
RM
29903 insn &= ~(1 << 23);
29904 else
29905 insn |= 1 << 23;
29906
29907 /* Place the addend (divided by four) into the first eight
29908 bits of the instruction. */
29909 insn &= 0xfffffff0;
29910 insn |= addend_abs >> 2;
29911
29912 /* Update the instruction. */
29913 md_number_to_chars (buf, insn, INSN_SIZE);
29914 }
4962c51a
MS
29915 break;
29916
e12437dc
AV
29917 case BFD_RELOC_THUMB_PCREL_BRANCH5:
29918 if (fixP->fx_addsy
29919 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29920 && !S_FORCE_RELOC (fixP->fx_addsy, true)
e12437dc
AV
29921 && ARM_IS_FUNC (fixP->fx_addsy)
29922 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29923 {
29924 /* Force a relocation for a branch 5 bits wide. */
29925 fixP->fx_done = 0;
29926 }
5b7c81bd 29927 if (v8_1_branch_value_check (value, 5, false) == FAIL)
e12437dc
AV
29928 as_bad_where (fixP->fx_file, fixP->fx_line,
29929 BAD_BRANCH_OFF);
29930
29931 if (fixP->fx_done || !seg->use_rela_p)
29932 {
29933 addressT boff = value >> 1;
29934
29935 newval = md_chars_to_number (buf, THUMB_SIZE);
29936 newval |= (boff << 7);
29937 md_number_to_chars (buf, newval, THUMB_SIZE);
29938 }
29939 break;
29940
f6b2b12d
AV
29941 case BFD_RELOC_THUMB_PCREL_BFCSEL:
29942 if (fixP->fx_addsy
29943 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29944 && !S_FORCE_RELOC (fixP->fx_addsy, true)
f6b2b12d
AV
29945 && ARM_IS_FUNC (fixP->fx_addsy)
29946 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29947 {
29948 fixP->fx_done = 0;
29949 }
7af67752 29950 if ((value & ~0x7f) && ((value & ~0x3f) != (valueT) ~0x3f))
f6b2b12d
AV
29951 as_bad_where (fixP->fx_file, fixP->fx_line,
29952 _("branch out of range"));
29953
29954 if (fixP->fx_done || !seg->use_rela_p)
29955 {
29956 newval = md_chars_to_number (buf, THUMB_SIZE);
29957
29958 addressT boff = ((newval & 0x0780) >> 7) << 1;
29959 addressT diff = value - boff;
29960
29961 if (diff == 4)
29962 {
29963 newval |= 1 << 1; /* T bit. */
29964 }
29965 else if (diff != 2)
29966 {
29967 as_bad_where (fixP->fx_file, fixP->fx_line,
29968 _("out of range label-relative fixup value"));
29969 }
29970 md_number_to_chars (buf, newval, THUMB_SIZE);
29971 }
29972 break;
29973
e5d6e09e
AV
29974 case BFD_RELOC_ARM_THUMB_BF17:
29975 if (fixP->fx_addsy
29976 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29977 && !S_FORCE_RELOC (fixP->fx_addsy, true)
e5d6e09e
AV
29978 && ARM_IS_FUNC (fixP->fx_addsy)
29979 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29980 {
29981 /* Force a relocation for a branch 17 bits wide. */
29982 fixP->fx_done = 0;
29983 }
29984
5b7c81bd 29985 if (v8_1_branch_value_check (value, 17, true) == FAIL)
e5d6e09e
AV
29986 as_bad_where (fixP->fx_file, fixP->fx_line,
29987 BAD_BRANCH_OFF);
29988
29989 if (fixP->fx_done || !seg->use_rela_p)
29990 {
29991 offsetT newval2;
29992 addressT immA, immB, immC;
29993
29994 immA = (value & 0x0001f000) >> 12;
29995 immB = (value & 0x00000ffc) >> 2;
29996 immC = (value & 0x00000002) >> 1;
29997
29998 newval = md_chars_to_number (buf, THUMB_SIZE);
29999 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30000 newval |= immA;
30001 newval2 |= (immC << 11) | (immB << 1);
30002 md_number_to_chars (buf, newval, THUMB_SIZE);
30003 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
30004 }
30005 break;
30006
1caf72a5
AV
30007 case BFD_RELOC_ARM_THUMB_BF19:
30008 if (fixP->fx_addsy
30009 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 30010 && !S_FORCE_RELOC (fixP->fx_addsy, true)
1caf72a5
AV
30011 && ARM_IS_FUNC (fixP->fx_addsy)
30012 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
30013 {
30014 /* Force a relocation for a branch 19 bits wide. */
30015 fixP->fx_done = 0;
30016 }
30017
5b7c81bd 30018 if (v8_1_branch_value_check (value, 19, true) == FAIL)
1caf72a5
AV
30019 as_bad_where (fixP->fx_file, fixP->fx_line,
30020 BAD_BRANCH_OFF);
30021
30022 if (fixP->fx_done || !seg->use_rela_p)
30023 {
30024 offsetT newval2;
30025 addressT immA, immB, immC;
30026
30027 immA = (value & 0x0007f000) >> 12;
30028 immB = (value & 0x00000ffc) >> 2;
30029 immC = (value & 0x00000002) >> 1;
30030
30031 newval = md_chars_to_number (buf, THUMB_SIZE);
30032 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30033 newval |= immA;
30034 newval2 |= (immC << 11) | (immB << 1);
30035 md_number_to_chars (buf, newval, THUMB_SIZE);
30036 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
30037 }
30038 break;
30039
1889da70
AV
30040 case BFD_RELOC_ARM_THUMB_BF13:
30041 if (fixP->fx_addsy
30042 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 30043 && !S_FORCE_RELOC (fixP->fx_addsy, true)
1889da70
AV
30044 && ARM_IS_FUNC (fixP->fx_addsy)
30045 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
30046 {
30047 /* Force a relocation for a branch 13 bits wide. */
30048 fixP->fx_done = 0;
30049 }
30050
5b7c81bd 30051 if (v8_1_branch_value_check (value, 13, true) == FAIL)
1889da70
AV
30052 as_bad_where (fixP->fx_file, fixP->fx_line,
30053 BAD_BRANCH_OFF);
30054
30055 if (fixP->fx_done || !seg->use_rela_p)
30056 {
30057 offsetT newval2;
30058 addressT immA, immB, immC;
30059
30060 immA = (value & 0x00001000) >> 12;
30061 immB = (value & 0x00000ffc) >> 2;
30062 immC = (value & 0x00000002) >> 1;
30063
30064 newval = md_chars_to_number (buf, THUMB_SIZE);
30065 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30066 newval |= immA;
30067 newval2 |= (immC << 11) | (immB << 1);
30068 md_number_to_chars (buf, newval, THUMB_SIZE);
30069 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
30070 }
30071 break;
30072
60f993ce
AV
30073 case BFD_RELOC_ARM_THUMB_LOOP12:
30074 if (fixP->fx_addsy
30075 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 30076 && !S_FORCE_RELOC (fixP->fx_addsy, true)
60f993ce
AV
30077 && ARM_IS_FUNC (fixP->fx_addsy)
30078 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
30079 {
30080 /* Force a relocation for a branch 12 bits wide. */
30081 fixP->fx_done = 0;
30082 }
30083
30084 bfd_vma insn = get_thumb32_insn (buf);
1f6234a3 30085 /* le lr, <label>, le <label> or letp lr, <label> */
60f993ce 30086 if (((insn & 0xffffffff) == 0xf00fc001)
1f6234a3
AV
30087 || ((insn & 0xffffffff) == 0xf02fc001)
30088 || ((insn & 0xffffffff) == 0xf01fc001))
60f993ce
AV
30089 value = -value;
30090
5b7c81bd 30091 if (v8_1_branch_value_check (value, 12, false) == FAIL)
60f993ce
AV
30092 as_bad_where (fixP->fx_file, fixP->fx_line,
30093 BAD_BRANCH_OFF);
30094 if (fixP->fx_done || !seg->use_rela_p)
30095 {
30096 addressT imml, immh;
30097
30098 immh = (value & 0x00000ffc) >> 2;
30099 imml = (value & 0x00000002) >> 1;
30100
30101 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30102 newval |= (imml << 11) | (immh << 1);
30103 md_number_to_chars (buf + THUMB_SIZE, newval, THUMB_SIZE);
30104 }
30105 break;
30106
845b51d6
PB
30107 case BFD_RELOC_ARM_V4BX:
30108 /* This will need to go in the object file. */
30109 fixP->fx_done = 0;
30110 break;
30111
c19d1205
ZW
30112 case BFD_RELOC_UNUSED:
30113 default:
30114 as_bad_where (fixP->fx_file, fixP->fx_line,
30115 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
30116 }
6c43fab6
RE
30117}
30118
c19d1205
ZW
30119/* Translate internal representation of relocation info to BFD target
30120 format. */
a737bd4d 30121
c19d1205 30122arelent *
00a97672 30123tc_gen_reloc (asection *section, fixS *fixp)
a737bd4d 30124{
c19d1205
ZW
30125 arelent * reloc;
30126 bfd_reloc_code_real_type code;
a737bd4d 30127
325801bd 30128 reloc = XNEW (arelent);
a737bd4d 30129
325801bd 30130 reloc->sym_ptr_ptr = XNEW (asymbol *);
c19d1205
ZW
30131 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
30132 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
a737bd4d 30133
2fc8bdac 30134 if (fixp->fx_pcrel)
00a97672
RS
30135 {
30136 if (section->use_rela_p)
30137 fixp->fx_offset -= md_pcrel_from_section (fixp, section);
30138 else
30139 fixp->fx_offset = reloc->address;
30140 }
c19d1205 30141 reloc->addend = fixp->fx_offset;
a737bd4d 30142
c19d1205 30143 switch (fixp->fx_r_type)
a737bd4d 30144 {
c19d1205
ZW
30145 case BFD_RELOC_8:
30146 if (fixp->fx_pcrel)
30147 {
30148 code = BFD_RELOC_8_PCREL;
30149 break;
30150 }
1a0670f3 30151 /* Fall through. */
a737bd4d 30152
c19d1205
ZW
30153 case BFD_RELOC_16:
30154 if (fixp->fx_pcrel)
30155 {
30156 code = BFD_RELOC_16_PCREL;
30157 break;
30158 }
1a0670f3 30159 /* Fall through. */
6c43fab6 30160
c19d1205
ZW
30161 case BFD_RELOC_32:
30162 if (fixp->fx_pcrel)
30163 {
30164 code = BFD_RELOC_32_PCREL;
30165 break;
30166 }
1a0670f3 30167 /* Fall through. */
a737bd4d 30168
b6895b4f
PB
30169 case BFD_RELOC_ARM_MOVW:
30170 if (fixp->fx_pcrel)
30171 {
30172 code = BFD_RELOC_ARM_MOVW_PCREL;
30173 break;
30174 }
1a0670f3 30175 /* Fall through. */
b6895b4f
PB
30176
30177 case BFD_RELOC_ARM_MOVT:
30178 if (fixp->fx_pcrel)
30179 {
30180 code = BFD_RELOC_ARM_MOVT_PCREL;
30181 break;
30182 }
1a0670f3 30183 /* Fall through. */
b6895b4f
PB
30184
30185 case BFD_RELOC_ARM_THUMB_MOVW:
30186 if (fixp->fx_pcrel)
30187 {
30188 code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
30189 break;
30190 }
1a0670f3 30191 /* Fall through. */
b6895b4f
PB
30192
30193 case BFD_RELOC_ARM_THUMB_MOVT:
30194 if (fixp->fx_pcrel)
30195 {
30196 code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
30197 break;
30198 }
1a0670f3 30199 /* Fall through. */
b6895b4f 30200
c19d1205
ZW
30201 case BFD_RELOC_NONE:
30202 case BFD_RELOC_ARM_PCREL_BRANCH:
30203 case BFD_RELOC_ARM_PCREL_BLX:
30204 case BFD_RELOC_RVA:
30205 case BFD_RELOC_THUMB_PCREL_BRANCH7:
30206 case BFD_RELOC_THUMB_PCREL_BRANCH9:
30207 case BFD_RELOC_THUMB_PCREL_BRANCH12:
30208 case BFD_RELOC_THUMB_PCREL_BRANCH20:
30209 case BFD_RELOC_THUMB_PCREL_BRANCH23:
30210 case BFD_RELOC_THUMB_PCREL_BRANCH25:
c19d1205
ZW
30211 case BFD_RELOC_VTABLE_ENTRY:
30212 case BFD_RELOC_VTABLE_INHERIT:
f0927246
NC
30213#ifdef TE_PE
30214 case BFD_RELOC_32_SECREL:
30215#endif
c19d1205
ZW
30216 code = fixp->fx_r_type;
30217 break;
a737bd4d 30218
00adf2d4
JB
30219 case BFD_RELOC_THUMB_PCREL_BLX:
30220#ifdef OBJ_ELF
30221 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
30222 code = BFD_RELOC_THUMB_PCREL_BRANCH23;
30223 else
30224#endif
30225 code = BFD_RELOC_THUMB_PCREL_BLX;
30226 break;
30227
c19d1205
ZW
30228 case BFD_RELOC_ARM_LITERAL:
30229 case BFD_RELOC_ARM_HWLITERAL:
30230 /* If this is called then the a literal has
30231 been referenced across a section boundary. */
30232 as_bad_where (fixp->fx_file, fixp->fx_line,
30233 _("literal referenced across section boundary"));
30234 return NULL;
a737bd4d 30235
c19d1205 30236#ifdef OBJ_ELF
0855e32b
NS
30237 case BFD_RELOC_ARM_TLS_CALL:
30238 case BFD_RELOC_ARM_THM_TLS_CALL:
30239 case BFD_RELOC_ARM_TLS_DESCSEQ:
30240 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
c19d1205
ZW
30241 case BFD_RELOC_ARM_GOT32:
30242 case BFD_RELOC_ARM_GOTOFF:
b43420e6 30243 case BFD_RELOC_ARM_GOT_PREL:
c19d1205
ZW
30244 case BFD_RELOC_ARM_PLT32:
30245 case BFD_RELOC_ARM_TARGET1:
30246 case BFD_RELOC_ARM_ROSEGREL32:
30247 case BFD_RELOC_ARM_SBREL32:
30248 case BFD_RELOC_ARM_PREL31:
30249 case BFD_RELOC_ARM_TARGET2:
c19d1205 30250 case BFD_RELOC_ARM_TLS_LDO32:
39b41c9c
PB
30251 case BFD_RELOC_ARM_PCREL_CALL:
30252 case BFD_RELOC_ARM_PCREL_JUMP:
4962c51a
MS
30253 case BFD_RELOC_ARM_ALU_PC_G0_NC:
30254 case BFD_RELOC_ARM_ALU_PC_G0:
30255 case BFD_RELOC_ARM_ALU_PC_G1_NC:
30256 case BFD_RELOC_ARM_ALU_PC_G1:
30257 case BFD_RELOC_ARM_ALU_PC_G2:
30258 case BFD_RELOC_ARM_LDR_PC_G0:
30259 case BFD_RELOC_ARM_LDR_PC_G1:
30260 case BFD_RELOC_ARM_LDR_PC_G2:
30261 case BFD_RELOC_ARM_LDRS_PC_G0:
30262 case BFD_RELOC_ARM_LDRS_PC_G1:
30263 case BFD_RELOC_ARM_LDRS_PC_G2:
30264 case BFD_RELOC_ARM_LDC_PC_G0:
30265 case BFD_RELOC_ARM_LDC_PC_G1:
30266 case BFD_RELOC_ARM_LDC_PC_G2:
30267 case BFD_RELOC_ARM_ALU_SB_G0_NC:
30268 case BFD_RELOC_ARM_ALU_SB_G0:
30269 case BFD_RELOC_ARM_ALU_SB_G1_NC:
30270 case BFD_RELOC_ARM_ALU_SB_G1:
30271 case BFD_RELOC_ARM_ALU_SB_G2:
30272 case BFD_RELOC_ARM_LDR_SB_G0:
30273 case BFD_RELOC_ARM_LDR_SB_G1:
30274 case BFD_RELOC_ARM_LDR_SB_G2:
30275 case BFD_RELOC_ARM_LDRS_SB_G0:
30276 case BFD_RELOC_ARM_LDRS_SB_G1:
30277 case BFD_RELOC_ARM_LDRS_SB_G2:
30278 case BFD_RELOC_ARM_LDC_SB_G0:
30279 case BFD_RELOC_ARM_LDC_SB_G1:
30280 case BFD_RELOC_ARM_LDC_SB_G2:
845b51d6 30281 case BFD_RELOC_ARM_V4BX:
72d98d16
MG
30282 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
30283 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
30284 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
30285 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
188fd7ae
CL
30286 case BFD_RELOC_ARM_GOTFUNCDESC:
30287 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
30288 case BFD_RELOC_ARM_FUNCDESC:
e5d6e09e 30289 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 30290 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 30291 case BFD_RELOC_ARM_THUMB_BF13:
c19d1205
ZW
30292 code = fixp->fx_r_type;
30293 break;
a737bd4d 30294
0855e32b 30295 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205 30296 case BFD_RELOC_ARM_TLS_GD32:
5c5a4843 30297 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
75c11999 30298 case BFD_RELOC_ARM_TLS_LE32:
c19d1205 30299 case BFD_RELOC_ARM_TLS_IE32:
5c5a4843 30300 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
c19d1205 30301 case BFD_RELOC_ARM_TLS_LDM32:
5c5a4843 30302 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
c19d1205
ZW
30303 /* BFD will include the symbol's address in the addend.
30304 But we don't want that, so subtract it out again here. */
30305 if (!S_IS_COMMON (fixp->fx_addsy))
30306 reloc->addend -= (*reloc->sym_ptr_ptr)->value;
30307 code = fixp->fx_r_type;
30308 break;
30309#endif
a737bd4d 30310
c19d1205
ZW
30311 case BFD_RELOC_ARM_IMMEDIATE:
30312 as_bad_where (fixp->fx_file, fixp->fx_line,
30313 _("internal relocation (type: IMMEDIATE) not fixed up"));
30314 return NULL;
a737bd4d 30315
c19d1205
ZW
30316 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
30317 as_bad_where (fixp->fx_file, fixp->fx_line,
30318 _("ADRL used for a symbol not defined in the same file"));
30319 return NULL;
a737bd4d 30320
e12437dc 30321 case BFD_RELOC_THUMB_PCREL_BRANCH5:
f6b2b12d 30322 case BFD_RELOC_THUMB_PCREL_BFCSEL:
60f993ce 30323 case BFD_RELOC_ARM_THUMB_LOOP12:
e12437dc
AV
30324 as_bad_where (fixp->fx_file, fixp->fx_line,
30325 _("%s used for a symbol not defined in the same file"),
30326 bfd_get_reloc_code_name (fixp->fx_r_type));
30327 return NULL;
30328
c19d1205 30329 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
30330 if (section->use_rela_p)
30331 {
30332 code = fixp->fx_r_type;
30333 break;
30334 }
30335
c19d1205
ZW
30336 if (fixp->fx_addsy != NULL
30337 && !S_IS_DEFINED (fixp->fx_addsy)
30338 && S_IS_LOCAL (fixp->fx_addsy))
a737bd4d 30339 {
c19d1205
ZW
30340 as_bad_where (fixp->fx_file, fixp->fx_line,
30341 _("undefined local label `%s'"),
30342 S_GET_NAME (fixp->fx_addsy));
30343 return NULL;
a737bd4d
NC
30344 }
30345
c19d1205
ZW
30346 as_bad_where (fixp->fx_file, fixp->fx_line,
30347 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
30348 return NULL;
a737bd4d 30349
c19d1205
ZW
30350 default:
30351 {
e0471c16 30352 const char * type;
6c43fab6 30353
c19d1205
ZW
30354 switch (fixp->fx_r_type)
30355 {
30356 case BFD_RELOC_NONE: type = "NONE"; break;
30357 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
30358 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
3eb17e6b 30359 case BFD_RELOC_ARM_SMC: type = "SMC"; break;
c19d1205
ZW
30360 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
30361 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
30362 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
db187cb9 30363 case BFD_RELOC_ARM_T32_OFFSET_IMM: type = "T32_OFFSET_IMM"; break;
8f06b2d8 30364 case BFD_RELOC_ARM_T32_CP_OFF_IMM: type = "T32_CP_OFF_IMM"; break;
c19d1205
ZW
30365 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
30366 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
30367 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
30368 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
30369 default: type = _("<unknown>"); break;
30370 }
30371 as_bad_where (fixp->fx_file, fixp->fx_line,
30372 _("cannot represent %s relocation in this object file format"),
30373 type);
30374 return NULL;
30375 }
a737bd4d 30376 }
6c43fab6 30377
c19d1205
ZW
30378#ifdef OBJ_ELF
30379 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
30380 && GOT_symbol
30381 && fixp->fx_addsy == GOT_symbol)
30382 {
30383 code = BFD_RELOC_ARM_GOTPC;
30384 reloc->addend = fixp->fx_offset = reloc->address;
30385 }
30386#endif
6c43fab6 30387
c19d1205 30388 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6c43fab6 30389
c19d1205
ZW
30390 if (reloc->howto == NULL)
30391 {
30392 as_bad_where (fixp->fx_file, fixp->fx_line,
30393 _("cannot represent %s relocation in this object file format"),
30394 bfd_get_reloc_code_name (code));
30395 return NULL;
30396 }
6c43fab6 30397
c19d1205
ZW
30398 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
30399 vtable entry to be used in the relocation's section offset. */
30400 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
30401 reloc->address = fixp->fx_offset;
6c43fab6 30402
c19d1205 30403 return reloc;
6c43fab6
RE
30404}
30405
c19d1205 30406/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6c43fab6 30407
c19d1205
ZW
30408void
30409cons_fix_new_arm (fragS * frag,
30410 int where,
30411 int size,
62ebcb5c
AM
30412 expressionS * exp,
30413 bfd_reloc_code_real_type reloc)
6c43fab6 30414{
c19d1205 30415 int pcrel = 0;
6c43fab6 30416
c19d1205
ZW
30417 /* Pick a reloc.
30418 FIXME: @@ Should look at CPU word size. */
30419 switch (size)
30420 {
30421 case 1:
62ebcb5c 30422 reloc = BFD_RELOC_8;
c19d1205
ZW
30423 break;
30424 case 2:
62ebcb5c 30425 reloc = BFD_RELOC_16;
c19d1205
ZW
30426 break;
30427 case 4:
30428 default:
62ebcb5c 30429 reloc = BFD_RELOC_32;
c19d1205
ZW
30430 break;
30431 case 8:
62ebcb5c 30432 reloc = BFD_RELOC_64;
c19d1205
ZW
30433 break;
30434 }
6c43fab6 30435
f0927246
NC
30436#ifdef TE_PE
30437 if (exp->X_op == O_secrel)
30438 {
30439 exp->X_op = O_symbol;
62ebcb5c 30440 reloc = BFD_RELOC_32_SECREL;
f0927246
NC
30441 }
30442#endif
30443
62ebcb5c 30444 fix_new_exp (frag, where, size, exp, pcrel, reloc);
c19d1205 30445}
6c43fab6 30446
4343666d 30447#if defined (OBJ_COFF)
c19d1205
ZW
30448void
30449arm_validate_fix (fixS * fixP)
6c43fab6 30450{
c19d1205
ZW
30451 /* If the destination of the branch is a defined symbol which does not have
30452 the THUMB_FUNC attribute, then we must be calling a function which has
30453 the (interfacearm) attribute. We look for the Thumb entry point to that
30454 function and change the branch to refer to that function instead. */
30455 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
30456 && fixP->fx_addsy != NULL
30457 && S_IS_DEFINED (fixP->fx_addsy)
30458 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6c43fab6 30459 {
c19d1205 30460 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6c43fab6 30461 }
c19d1205
ZW
30462}
30463#endif
6c43fab6 30464
267bf995 30465
c19d1205
ZW
30466int
30467arm_force_relocation (struct fix * fixp)
30468{
30469#if defined (OBJ_COFF) && defined (TE_PE)
30470 if (fixp->fx_r_type == BFD_RELOC_RVA)
30471 return 1;
30472#endif
6c43fab6 30473
267bf995
RR
30474 /* In case we have a call or a branch to a function in ARM ISA mode from
30475 a thumb function or vice-versa force the relocation. These relocations
30476 are cleared off for some cores that might have blx and simple transformations
30477 are possible. */
30478
30479#ifdef OBJ_ELF
30480 switch (fixp->fx_r_type)
30481 {
30482 case BFD_RELOC_ARM_PCREL_JUMP:
30483 case BFD_RELOC_ARM_PCREL_CALL:
30484 case BFD_RELOC_THUMB_PCREL_BLX:
30485 if (THUMB_IS_FUNC (fixp->fx_addsy))
30486 return 1;
30487 break;
30488
30489 case BFD_RELOC_ARM_PCREL_BLX:
30490 case BFD_RELOC_THUMB_PCREL_BRANCH25:
30491 case BFD_RELOC_THUMB_PCREL_BRANCH20:
30492 case BFD_RELOC_THUMB_PCREL_BRANCH23:
30493 if (ARM_IS_FUNC (fixp->fx_addsy))
30494 return 1;
30495 break;
30496
30497 default:
30498 break;
30499 }
30500#endif
30501
b5884301
PB
30502 /* Resolve these relocations even if the symbol is extern or weak.
30503 Technically this is probably wrong due to symbol preemption.
30504 In practice these relocations do not have enough range to be useful
30505 at dynamic link time, and some code (e.g. in the Linux kernel)
30506 expects these references to be resolved. */
c19d1205
ZW
30507 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
30508 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
b5884301 30509 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM8
0110f2b8 30510 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
b5884301
PB
30511 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
30512 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2
30513 || fixp->fx_r_type == BFD_RELOC_ARM_THUMB_OFFSET
b59d128a 30514 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH12
16805f35 30515 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
0110f2b8
PB
30516 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
30517 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
b5884301
PB
30518 || fixp->fx_r_type == BFD_RELOC_ARM_T32_OFFSET_IMM
30519 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12
30520 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM
30521 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM_S2)
c19d1205 30522 return 0;
a737bd4d 30523
4962c51a
MS
30524 /* Always leave these relocations for the linker. */
30525 if ((fixp->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
30526 && fixp->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
30527 || fixp->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
30528 return 1;
30529
f0291e4c
PB
30530 /* Always generate relocations against function symbols. */
30531 if (fixp->fx_r_type == BFD_RELOC_32
30532 && fixp->fx_addsy
30533 && (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION))
30534 return 1;
30535
c19d1205 30536 return generic_force_reloc (fixp);
404ff6b5
AH
30537}
30538
0ffdc86c 30539#if defined (OBJ_ELF) || defined (OBJ_COFF)
e28387c3
PB
30540/* Relocations against function names must be left unadjusted,
30541 so that the linker can use this information to generate interworking
30542 stubs. The MIPS version of this function
c19d1205
ZW
30543 also prevents relocations that are mips-16 specific, but I do not
30544 know why it does this.
404ff6b5 30545
c19d1205
ZW
30546 FIXME:
30547 There is one other problem that ought to be addressed here, but
30548 which currently is not: Taking the address of a label (rather
30549 than a function) and then later jumping to that address. Such
30550 addresses also ought to have their bottom bit set (assuming that
30551 they reside in Thumb code), but at the moment they will not. */
404ff6b5 30552
5b7c81bd 30553bool
c19d1205 30554arm_fix_adjustable (fixS * fixP)
404ff6b5 30555{
c19d1205
ZW
30556 if (fixP->fx_addsy == NULL)
30557 return 1;
404ff6b5 30558
e28387c3
PB
30559 /* Preserve relocations against symbols with function type. */
30560 if (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION)
5b7c81bd 30561 return false;
e28387c3 30562
c19d1205
ZW
30563 if (THUMB_IS_FUNC (fixP->fx_addsy)
30564 && fixP->fx_subsy == NULL)
5b7c81bd 30565 return false;
a737bd4d 30566
c19d1205
ZW
30567 /* We need the symbol name for the VTABLE entries. */
30568 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
30569 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5b7c81bd 30570 return false;
404ff6b5 30571
c19d1205
ZW
30572 /* Don't allow symbols to be discarded on GOT related relocs. */
30573 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
30574 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
30575 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
30576 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
5c5a4843 30577 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32_FDPIC
c19d1205
ZW
30578 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
30579 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
5c5a4843 30580 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32_FDPIC
c19d1205 30581 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
5c5a4843 30582 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32_FDPIC
c19d1205 30583 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
0855e32b
NS
30584 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GOTDESC
30585 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
30586 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_CALL
30587 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
30588 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_DESCSEQ
c19d1205 30589 || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
5b7c81bd 30590 return false;
a737bd4d 30591
4962c51a
MS
30592 /* Similarly for group relocations. */
30593 if ((fixP->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
30594 && fixP->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
30595 || fixP->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
5b7c81bd 30596 return false;
4962c51a 30597
79947c54
CD
30598 /* MOVW/MOVT REL relocations have limited offsets, so keep the symbols. */
30599 if (fixP->fx_r_type == BFD_RELOC_ARM_MOVW
30600 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT
30601 || fixP->fx_r_type == BFD_RELOC_ARM_MOVW_PCREL
30602 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT_PCREL
30603 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
30604 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT
30605 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW_PCREL
30606 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
5b7c81bd 30607 return false;
79947c54 30608
72d98d16
MG
30609 /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
30610 offsets, so keep these symbols. */
30611 if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
30612 && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
5b7c81bd 30613 return false;
72d98d16 30614
5b7c81bd 30615 return true;
a737bd4d 30616}
0ffdc86c
NC
30617#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
30618
30619#ifdef OBJ_ELF
c19d1205
ZW
30620const char *
30621elf32_arm_target_format (void)
404ff6b5 30622{
a57d1773 30623#if defined (TE_VXWORKS)
c19d1205
ZW
30624 return (target_big_endian
30625 ? "elf32-bigarm-vxworks"
30626 : "elf32-littlearm-vxworks");
b38cadfb
NC
30627#elif defined (TE_NACL)
30628 return (target_big_endian
30629 ? "elf32-bigarm-nacl"
30630 : "elf32-littlearm-nacl");
c19d1205 30631#else
18a20338
CL
30632 if (arm_fdpic)
30633 {
30634 if (target_big_endian)
30635 return "elf32-bigarm-fdpic";
30636 else
30637 return "elf32-littlearm-fdpic";
30638 }
c19d1205 30639 else
18a20338
CL
30640 {
30641 if (target_big_endian)
30642 return "elf32-bigarm";
30643 else
30644 return "elf32-littlearm";
30645 }
c19d1205 30646#endif
404ff6b5
AH
30647}
30648
c19d1205
ZW
30649void
30650armelf_frob_symbol (symbolS * symp,
30651 int * puntp)
404ff6b5 30652{
c19d1205
ZW
30653 elf_frob_symbol (symp, puntp);
30654}
30655#endif
404ff6b5 30656
c19d1205 30657/* MD interface: Finalization. */
a737bd4d 30658
c19d1205
ZW
30659void
30660arm_cleanup (void)
30661{
30662 literal_pool * pool;
a737bd4d 30663
5ee91343
AV
30664 /* Ensure that all the predication blocks are properly closed. */
30665 check_pred_blocks_finished ();
e07e6e58 30666
c19d1205
ZW
30667 for (pool = list_of_pools; pool; pool = pool->next)
30668 {
5f4273c7 30669 /* Put it at the end of the relevant section. */
c19d1205
ZW
30670 subseg_set (pool->section, pool->sub_section);
30671#ifdef OBJ_ELF
30672 arm_elf_change_section ();
30673#endif
30674 s_ltorg (0);
30675 }
404ff6b5
AH
30676}
30677
cd000bff
DJ
30678#ifdef OBJ_ELF
30679/* Remove any excess mapping symbols generated for alignment frags in
30680 SEC. We may have created a mapping symbol before a zero byte
30681 alignment; remove it if there's a mapping symbol after the
30682 alignment. */
30683static void
30684check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
30685 void *dummy ATTRIBUTE_UNUSED)
30686{
30687 segment_info_type *seginfo = seg_info (sec);
30688 fragS *fragp;
30689
30690 if (seginfo == NULL || seginfo->frchainP == NULL)
30691 return;
30692
30693 for (fragp = seginfo->frchainP->frch_root;
30694 fragp != NULL;
30695 fragp = fragp->fr_next)
30696 {
30697 symbolS *sym = fragp->tc_frag_data.last_map;
30698 fragS *next = fragp->fr_next;
30699
30700 /* Variable-sized frags have been converted to fixed size by
30701 this point. But if this was variable-sized to start with,
30702 there will be a fixed-size frag after it. So don't handle
30703 next == NULL. */
30704 if (sym == NULL || next == NULL)
30705 continue;
30706
30707 if (S_GET_VALUE (sym) < next->fr_address)
30708 /* Not at the end of this frag. */
30709 continue;
30710 know (S_GET_VALUE (sym) == next->fr_address);
30711
30712 do
30713 {
30714 if (next->tc_frag_data.first_map != NULL)
30715 {
30716 /* Next frag starts with a mapping symbol. Discard this
30717 one. */
30718 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
30719 break;
30720 }
30721
30722 if (next->fr_next == NULL)
30723 {
30724 /* This mapping symbol is at the end of the section. Discard
30725 it. */
30726 know (next->fr_fix == 0 && next->fr_var == 0);
30727 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
30728 break;
30729 }
30730
30731 /* As long as we have empty frags without any mapping symbols,
30732 keep looking. */
30733 /* If the next frag is non-empty and does not start with a
30734 mapping symbol, then this mapping symbol is required. */
30735 if (next->fr_address != next->fr_next->fr_address)
30736 break;
30737
30738 next = next->fr_next;
30739 }
30740 while (next != NULL);
30741 }
30742}
30743#endif
30744
c19d1205
ZW
30745/* Adjust the symbol table. This marks Thumb symbols as distinct from
30746 ARM ones. */
404ff6b5 30747
c19d1205
ZW
30748void
30749arm_adjust_symtab (void)
404ff6b5 30750{
c19d1205
ZW
30751#ifdef OBJ_COFF
30752 symbolS * sym;
404ff6b5 30753
c19d1205
ZW
30754 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
30755 {
30756 if (ARM_IS_THUMB (sym))
30757 {
30758 if (THUMB_IS_FUNC (sym))
30759 {
30760 /* Mark the symbol as a Thumb function. */
30761 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
30762 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
30763 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
404ff6b5 30764
c19d1205
ZW
30765 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
30766 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
30767 else
30768 as_bad (_("%s: unexpected function type: %d"),
30769 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
30770 }
30771 else switch (S_GET_STORAGE_CLASS (sym))
30772 {
30773 case C_EXT:
30774 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
30775 break;
30776 case C_STAT:
30777 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
30778 break;
30779 case C_LABEL:
30780 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
30781 break;
30782 default:
30783 /* Do nothing. */
30784 break;
30785 }
30786 }
a737bd4d 30787
c19d1205
ZW
30788 if (ARM_IS_INTERWORK (sym))
30789 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
404ff6b5 30790 }
c19d1205
ZW
30791#endif
30792#ifdef OBJ_ELF
30793 symbolS * sym;
30794 char bind;
404ff6b5 30795
c19d1205 30796 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
404ff6b5 30797 {
c19d1205
ZW
30798 if (ARM_IS_THUMB (sym))
30799 {
30800 elf_symbol_type * elf_sym;
404ff6b5 30801
c19d1205
ZW
30802 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
30803 bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
404ff6b5 30804
b0796911
PB
30805 if (! bfd_is_arm_special_symbol_name (elf_sym->symbol.name,
30806 BFD_ARM_SPECIAL_SYM_TYPE_ANY))
c19d1205
ZW
30807 {
30808 /* If it's a .thumb_func, declare it as so,
30809 otherwise tag label as .code 16. */
30810 if (THUMB_IS_FUNC (sym))
39d911fc
TP
30811 ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
30812 ST_BRANCH_TO_THUMB);
3ba67470 30813 else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
c19d1205
ZW
30814 elf_sym->internal_elf_sym.st_info =
30815 ELF_ST_INFO (bind, STT_ARM_16BIT);
30816 }
30817 }
30818 }
cd000bff
DJ
30819
30820 /* Remove any overlapping mapping symbols generated by alignment frags. */
30821 bfd_map_over_sections (stdoutput, check_mapping_symbols, (char *) 0);
709001e9
MM
30822 /* Now do generic ELF adjustments. */
30823 elf_adjust_symtab ();
c19d1205 30824#endif
404ff6b5
AH
30825}
30826
c19d1205 30827/* MD interface: Initialization. */
404ff6b5 30828
a737bd4d 30829static void
c19d1205 30830set_constant_flonums (void)
a737bd4d 30831{
c19d1205 30832 int i;
404ff6b5 30833
c19d1205
ZW
30834 for (i = 0; i < NUM_FLOAT_VALS; i++)
30835 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
30836 abort ();
a737bd4d 30837}
404ff6b5 30838
3e9e4fcf
JB
30839/* Auto-select Thumb mode if it's the only available instruction set for the
30840 given architecture. */
30841
30842static void
30843autoselect_thumb_from_cpu_variant (void)
30844{
30845 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
30846 opcode_select (16);
30847}
30848
c19d1205
ZW
30849void
30850md_begin (void)
a737bd4d 30851{
c19d1205
ZW
30852 unsigned mach;
30853 unsigned int i;
404ff6b5 30854
f16c3d4f
AM
30855 arm_ops_hsh = str_htab_create ();
30856 arm_cond_hsh = str_htab_create ();
30857 arm_vcond_hsh = str_htab_create ();
30858 arm_shift_hsh = str_htab_create ();
30859 arm_psr_hsh = str_htab_create ();
30860 arm_v7m_psr_hsh = str_htab_create ();
30861 arm_reg_hsh = str_htab_create ();
30862 arm_reloc_hsh = str_htab_create ();
30863 arm_barrier_opt_hsh = str_htab_create ();
c19d1205
ZW
30864
30865 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
629310ab 30866 if (str_hash_find (arm_ops_hsh, insns[i].template_name) == NULL)
fe0e921f 30867 str_hash_insert (arm_ops_hsh, insns[i].template_name, insns + i, 0);
c19d1205 30868 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
fe0e921f 30869 str_hash_insert (arm_cond_hsh, conds[i].template_name, conds + i, 0);
5ee91343 30870 for (i = 0; i < sizeof (vconds) / sizeof (struct asm_cond); i++)
fe0e921f 30871 str_hash_insert (arm_vcond_hsh, vconds[i].template_name, vconds + i, 0);
c19d1205 30872 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
fe0e921f 30873 str_hash_insert (arm_shift_hsh, shift_names[i].name, shift_names + i, 0);
c19d1205 30874 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
fe0e921f 30875 str_hash_insert (arm_psr_hsh, psrs[i].template_name, psrs + i, 0);
62b3e311 30876 for (i = 0; i < sizeof (v7m_psrs) / sizeof (struct asm_psr); i++)
629310ab 30877 str_hash_insert (arm_v7m_psr_hsh, v7m_psrs[i].template_name,
fe0e921f 30878 v7m_psrs + i, 0);
c19d1205 30879 for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
fe0e921f 30880 str_hash_insert (arm_reg_hsh, reg_names[i].name, reg_names + i, 0);
62b3e311
PB
30881 for (i = 0;
30882 i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
30883 i++)
629310ab 30884 str_hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
fe0e921f 30885 barrier_opt_names + i, 0);
c19d1205 30886#ifdef OBJ_ELF
3da1d841
NC
30887 for (i = 0; i < ARRAY_SIZE (reloc_names); i++)
30888 {
30889 struct reloc_entry * entry = reloc_names + i;
30890
30891 if (arm_is_eabi() && entry->reloc == BFD_RELOC_ARM_PLT32)
30892 /* This makes encode_branch() use the EABI versions of this relocation. */
30893 entry->reloc = BFD_RELOC_UNUSED;
30894
fe0e921f 30895 str_hash_insert (arm_reloc_hsh, entry->name, entry, 0);
3da1d841 30896 }
c19d1205
ZW
30897#endif
30898
30899 set_constant_flonums ();
404ff6b5 30900
c19d1205
ZW
30901 /* Set the cpu variant based on the command-line options. We prefer
30902 -mcpu= over -march= if both are set (as for GCC); and we prefer
30903 -mfpu= over any other way of setting the floating point unit.
30904 Use of legacy options with new options are faulted. */
e74cfd16 30905 if (legacy_cpu)
404ff6b5 30906 {
e74cfd16 30907 if (mcpu_cpu_opt || march_cpu_opt)
c19d1205
ZW
30908 as_bad (_("use of old and new-style options to set CPU type"));
30909
4d354d8b 30910 selected_arch = *legacy_cpu;
404ff6b5 30911 }
4d354d8b
TP
30912 else if (mcpu_cpu_opt)
30913 {
30914 selected_arch = *mcpu_cpu_opt;
30915 selected_ext = *mcpu_ext_opt;
30916 }
30917 else if (march_cpu_opt)
c168ce07 30918 {
4d354d8b
TP
30919 selected_arch = *march_cpu_opt;
30920 selected_ext = *march_ext_opt;
c168ce07 30921 }
4d354d8b 30922 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
404ff6b5 30923
e74cfd16 30924 if (legacy_fpu)
c19d1205 30925 {
e74cfd16 30926 if (mfpu_opt)
c19d1205 30927 as_bad (_("use of old and new-style options to set FPU type"));
03b1477f 30928
4d354d8b 30929 selected_fpu = *legacy_fpu;
03b1477f 30930 }
4d354d8b
TP
30931 else if (mfpu_opt)
30932 selected_fpu = *mfpu_opt;
30933 else
03b1477f 30934 {
45eb4c1b
NS
30935#if !(defined (EABI_DEFAULT) || defined (TE_LINUX) \
30936 || defined (TE_NetBSD) || defined (TE_VXWORKS))
39c2da32
RE
30937 /* Some environments specify a default FPU. If they don't, infer it
30938 from the processor. */
e74cfd16 30939 if (mcpu_fpu_opt)
4d354d8b 30940 selected_fpu = *mcpu_fpu_opt;
e7da50fa 30941 else if (march_fpu_opt)
4d354d8b 30942 selected_fpu = *march_fpu_opt;
39c2da32 30943#else
4d354d8b 30944 selected_fpu = fpu_default;
39c2da32 30945#endif
03b1477f
RE
30946 }
30947
4d354d8b 30948 if (ARM_FEATURE_ZERO (selected_fpu))
03b1477f 30949 {
4d354d8b
TP
30950 if (!no_cpu_selected ())
30951 selected_fpu = fpu_default;
03b1477f 30952 else
4d354d8b 30953 selected_fpu = fpu_arch_fpa;
03b1477f
RE
30954 }
30955
ee065d83 30956#ifdef CPU_DEFAULT
4d354d8b 30957 if (ARM_FEATURE_ZERO (selected_arch))
ee065d83 30958 {
4d354d8b
TP
30959 selected_arch = cpu_default;
30960 selected_cpu = selected_arch;
ee065d83 30961 }
4d354d8b 30962 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
e74cfd16 30963#else
4d354d8b
TP
30964 /* Autodection of feature mode: allow all features in cpu_variant but leave
30965 selected_cpu unset. It will be set in aeabi_set_public_attributes ()
30966 after all instruction have been processed and we can decide what CPU
30967 should be selected. */
30968 if (ARM_FEATURE_ZERO (selected_arch))
30969 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
ee065d83 30970 else
4d354d8b 30971 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 30972#endif
03b1477f 30973
3e9e4fcf
JB
30974 autoselect_thumb_from_cpu_variant ();
30975
e74cfd16 30976 arm_arch_used = thumb_arch_used = arm_arch_none;
ee065d83 30977
f17c130b 30978#if defined OBJ_COFF || defined OBJ_ELF
b99bd4ef 30979 {
7cc69913
NC
30980 unsigned int flags = 0;
30981
30982#if defined OBJ_ELF
30983 flags = meabi_flags;
d507cf36
PB
30984
30985 switch (meabi_flags)
33a392fb 30986 {
d507cf36 30987 case EF_ARM_EABI_UNKNOWN:
7cc69913 30988#endif
d507cf36
PB
30989 /* Set the flags in the private structure. */
30990 if (uses_apcs_26) flags |= F_APCS26;
30991 if (support_interwork) flags |= F_INTERWORK;
30992 if (uses_apcs_float) flags |= F_APCS_FLOAT;
c19d1205 30993 if (pic_code) flags |= F_PIC;
e74cfd16 30994 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_any_hard))
7cc69913
NC
30995 flags |= F_SOFT_FLOAT;
30996
d507cf36
PB
30997 switch (mfloat_abi_opt)
30998 {
30999 case ARM_FLOAT_ABI_SOFT:
31000 case ARM_FLOAT_ABI_SOFTFP:
31001 flags |= F_SOFT_FLOAT;
31002 break;
33a392fb 31003
d507cf36
PB
31004 case ARM_FLOAT_ABI_HARD:
31005 if (flags & F_SOFT_FLOAT)
31006 as_bad (_("hard-float conflicts with specified fpu"));
31007 break;
31008 }
03b1477f 31009
e74cfd16
PB
31010 /* Using pure-endian doubles (even if soft-float). */
31011 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
7cc69913 31012 flags |= F_VFP_FLOAT;
f17c130b 31013
fde78edd 31014#if defined OBJ_ELF
e74cfd16 31015 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_maverick))
d507cf36 31016 flags |= EF_ARM_MAVERICK_FLOAT;
d507cf36
PB
31017 break;
31018
8cb51566 31019 case EF_ARM_EABI_VER4:
3a4a14e9 31020 case EF_ARM_EABI_VER5:
c19d1205 31021 /* No additional flags to set. */
d507cf36
PB
31022 break;
31023
31024 default:
31025 abort ();
31026 }
7cc69913 31027#endif
b99bd4ef
NC
31028 bfd_set_private_flags (stdoutput, flags);
31029
31030 /* We have run out flags in the COFF header to encode the
31031 status of ATPCS support, so instead we create a dummy,
c19d1205 31032 empty, debug section called .arm.atpcs. */
b99bd4ef
NC
31033 if (atpcs)
31034 {
31035 asection * sec;
31036
31037 sec = bfd_make_section (stdoutput, ".arm.atpcs");
31038
31039 if (sec != NULL)
31040 {
fd361982
AM
31041 bfd_set_section_flags (sec, SEC_READONLY | SEC_DEBUGGING);
31042 bfd_set_section_size (sec, 0);
b99bd4ef
NC
31043 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
31044 }
31045 }
7cc69913 31046 }
f17c130b 31047#endif
b99bd4ef
NC
31048
31049 /* Record the CPU type as well. */
2d447fca
JM
31050 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
31051 mach = bfd_mach_arm_iWMMXt2;
31052 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
e16bb312 31053 mach = bfd_mach_arm_iWMMXt;
e74cfd16 31054 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
b99bd4ef 31055 mach = bfd_mach_arm_XScale;
e74cfd16 31056 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick))
fde78edd 31057 mach = bfd_mach_arm_ep9312;
e74cfd16 31058 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5e))
b99bd4ef 31059 mach = bfd_mach_arm_5TE;
e74cfd16 31060 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5))
b99bd4ef 31061 {
e74cfd16 31062 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
31063 mach = bfd_mach_arm_5T;
31064 else
31065 mach = bfd_mach_arm_5;
31066 }
e74cfd16 31067 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4))
b99bd4ef 31068 {
e74cfd16 31069 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
31070 mach = bfd_mach_arm_4T;
31071 else
31072 mach = bfd_mach_arm_4;
31073 }
e74cfd16 31074 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3m))
b99bd4ef 31075 mach = bfd_mach_arm_3M;
e74cfd16
PB
31076 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3))
31077 mach = bfd_mach_arm_3;
31078 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2s))
31079 mach = bfd_mach_arm_2a;
31080 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2))
31081 mach = bfd_mach_arm_2;
31082 else
31083 mach = bfd_mach_arm_unknown;
b99bd4ef
NC
31084
31085 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
31086}
31087
c19d1205 31088/* Command line processing. */
b99bd4ef 31089
c19d1205
ZW
31090/* md_parse_option
31091 Invocation line includes a switch not recognized by the base assembler.
31092 See if it's a processor-specific option.
b99bd4ef 31093
c19d1205
ZW
31094 This routine is somewhat complicated by the need for backwards
31095 compatibility (since older releases of gcc can't be changed).
31096 The new options try to make the interface as compatible as
31097 possible with GCC.
b99bd4ef 31098
c19d1205 31099 New options (supported) are:
b99bd4ef 31100
c19d1205
ZW
31101 -mcpu=<cpu name> Assemble for selected processor
31102 -march=<architecture name> Assemble for selected architecture
31103 -mfpu=<fpu architecture> Assemble for selected FPU.
31104 -EB/-mbig-endian Big-endian
31105 -EL/-mlittle-endian Little-endian
31106 -k Generate PIC code
31107 -mthumb Start in Thumb mode
31108 -mthumb-interwork Code supports ARM/Thumb interworking
b99bd4ef 31109
278df34e 31110 -m[no-]warn-deprecated Warn about deprecated features
8b2d793c 31111 -m[no-]warn-syms Warn when symbols match instructions
267bf995 31112
c19d1205 31113 For now we will also provide support for:
b99bd4ef 31114
c19d1205
ZW
31115 -mapcs-32 32-bit Program counter
31116 -mapcs-26 26-bit Program counter
31117 -macps-float Floats passed in FP registers
31118 -mapcs-reentrant Reentrant code
31119 -matpcs
31120 (sometime these will probably be replaced with -mapcs=<list of options>
31121 and -matpcs=<list of options>)
b99bd4ef 31122
c19d1205
ZW
31123 The remaining options are only supported for back-wards compatibility.
31124 Cpu variants, the arm part is optional:
31125 -m[arm]1 Currently not supported.
31126 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
31127 -m[arm]3 Arm 3 processor
31128 -m[arm]6[xx], Arm 6 processors
31129 -m[arm]7[xx][t][[d]m] Arm 7 processors
31130 -m[arm]8[10] Arm 8 processors
31131 -m[arm]9[20][tdmi] Arm 9 processors
31132 -mstrongarm[110[0]] StrongARM processors
31133 -mxscale XScale processors
31134 -m[arm]v[2345[t[e]]] Arm architectures
31135 -mall All (except the ARM1)
31136 FP variants:
31137 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
31138 -mfpe-old (No float load/store multiples)
31139 -mvfpxd VFP Single precision
31140 -mvfp All VFP
31141 -mno-fpu Disable all floating point instructions
b99bd4ef 31142
c19d1205
ZW
31143 The following CPU names are recognized:
31144 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
31145 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
31146 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
31147 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
31148 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
31149 arm10t arm10e, arm1020t, arm1020e, arm10200e,
31150 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
b99bd4ef 31151
c19d1205 31152 */
b99bd4ef 31153
c19d1205 31154const char * md_shortopts = "m:k";
b99bd4ef 31155
c19d1205
ZW
31156#ifdef ARM_BI_ENDIAN
31157#define OPTION_EB (OPTION_MD_BASE + 0)
31158#define OPTION_EL (OPTION_MD_BASE + 1)
b99bd4ef 31159#else
c19d1205
ZW
31160#if TARGET_BYTES_BIG_ENDIAN
31161#define OPTION_EB (OPTION_MD_BASE + 0)
b99bd4ef 31162#else
c19d1205
ZW
31163#define OPTION_EL (OPTION_MD_BASE + 1)
31164#endif
b99bd4ef 31165#endif
845b51d6 31166#define OPTION_FIX_V4BX (OPTION_MD_BASE + 2)
18a20338 31167#define OPTION_FDPIC (OPTION_MD_BASE + 3)
b99bd4ef 31168
c19d1205 31169struct option md_longopts[] =
b99bd4ef 31170{
c19d1205
ZW
31171#ifdef OPTION_EB
31172 {"EB", no_argument, NULL, OPTION_EB},
31173#endif
31174#ifdef OPTION_EL
31175 {"EL", no_argument, NULL, OPTION_EL},
b99bd4ef 31176#endif
845b51d6 31177 {"fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
18a20338
CL
31178#ifdef OBJ_ELF
31179 {"fdpic", no_argument, NULL, OPTION_FDPIC},
31180#endif
c19d1205
ZW
31181 {NULL, no_argument, NULL, 0}
31182};
b99bd4ef 31183
c19d1205 31184size_t md_longopts_size = sizeof (md_longopts);
b99bd4ef 31185
c19d1205 31186struct arm_option_table
b99bd4ef 31187{
0198d5e6
TC
31188 const char * option; /* Option name to match. */
31189 const char * help; /* Help information. */
31190 int * var; /* Variable to change. */
31191 int value; /* What to change it to. */
31192 const char * deprecated; /* If non-null, print this message. */
c19d1205 31193};
b99bd4ef 31194
c19d1205
ZW
31195struct arm_option_table arm_opts[] =
31196{
31197 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
31198 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
31199 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
31200 &support_interwork, 1, NULL},
31201 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
31202 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
31203 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
31204 1, NULL},
31205 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
31206 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
31207 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
31208 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
31209 NULL},
b99bd4ef 31210
c19d1205
ZW
31211 /* These are recognized by the assembler, but have no affect on code. */
31212 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
31213 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
278df34e
NS
31214
31215 {"mwarn-deprecated", NULL, &warn_on_deprecated, 1, NULL},
31216 {"mno-warn-deprecated", N_("do not warn on use of deprecated feature"),
31217 &warn_on_deprecated, 0, NULL},
24f19ccb
AV
31218
31219 {"mwarn-restrict-it", N_("warn about performance deprecated IT instructions"
31220 " in ARMv8-A and ARMv8-R"), &warn_on_restrict_it, 1, NULL},
31221 {"mno-warn-restrict-it", NULL, &warn_on_restrict_it, 0, NULL},
31222
5b7c81bd
AM
31223 {"mwarn-syms", N_("warn about symbols that match instruction names [default]"), (int *) (& flag_warn_syms), true, NULL},
31224 {"mno-warn-syms", N_("disable warnings about symobls that match instructions"), (int *) (& flag_warn_syms), false, NULL},
e74cfd16
PB
31225 {NULL, NULL, NULL, 0, NULL}
31226};
31227
31228struct arm_legacy_option_table
31229{
0198d5e6
TC
31230 const char * option; /* Option name to match. */
31231 const arm_feature_set ** var; /* Variable to change. */
31232 const arm_feature_set value; /* What to change it to. */
31233 const char * deprecated; /* If non-null, print this message. */
e74cfd16 31234};
b99bd4ef 31235
e74cfd16
PB
31236const struct arm_legacy_option_table arm_legacy_opts[] =
31237{
c19d1205
ZW
31238 /* DON'T add any new processors to this list -- we want the whole list
31239 to go away... Add them to the processors table instead. */
e74cfd16
PB
31240 {"marm1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
31241 {"m1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
31242 {"marm2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
31243 {"m2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
31244 {"marm250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
31245 {"m250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
31246 {"marm3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
31247 {"m3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
31248 {"marm6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
31249 {"m6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
31250 {"marm600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
31251 {"m600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
31252 {"marm610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
31253 {"m610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
31254 {"marm620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
31255 {"m620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
31256 {"marm7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
31257 {"m7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
31258 {"marm70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
31259 {"m70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
31260 {"marm700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
31261 {"m700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
31262 {"marm700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
31263 {"m700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
31264 {"marm710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
31265 {"m710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
31266 {"marm710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
31267 {"m710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
31268 {"marm720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
31269 {"m720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
31270 {"marm7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
31271 {"m7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
31272 {"marm7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
31273 {"m7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
31274 {"marm7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
31275 {"m7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
31276 {"marm7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
31277 {"m7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
31278 {"marm7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
31279 {"m7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
31280 {"marm7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
31281 {"m7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
31282 {"marm7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
31283 {"m7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
31284 {"marm7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
31285 {"m7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
31286 {"marm7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31287 {"m7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31288 {"marm7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31289 {"m7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31290 {"marm710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
31291 {"m710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
31292 {"marm720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
31293 {"m720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
31294 {"marm740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
31295 {"m740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
31296 {"marm8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
31297 {"m8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
31298 {"marm810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
31299 {"m810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
31300 {"marm9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
31301 {"m9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
31302 {"marm9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
31303 {"m9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
31304 {"marm920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
31305 {"m920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
31306 {"marm940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
31307 {"m940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
31308 {"mstrongarm", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
31309 {"mstrongarm110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31310 N_("use -mcpu=strongarm110")},
e74cfd16 31311 {"mstrongarm1100", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31312 N_("use -mcpu=strongarm1100")},
e74cfd16 31313 {"mstrongarm1110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31314 N_("use -mcpu=strongarm1110")},
e74cfd16
PB
31315 {"mxscale", &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
31316 {"miwmmxt", &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
31317 {"mall", &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
7ed4c4c5 31318
c19d1205 31319 /* Architecture variants -- don't add any more to this list either. */
e74cfd16
PB
31320 {"mv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
31321 {"marmv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
31322 {"mv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
31323 {"marmv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
31324 {"mv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
31325 {"marmv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
31326 {"mv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
31327 {"marmv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
31328 {"mv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
31329 {"marmv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
31330 {"mv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
31331 {"marmv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
31332 {"mv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
31333 {"marmv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
31334 {"mv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
31335 {"marmv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
31336 {"mv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
31337 {"marmv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
7ed4c4c5 31338
c19d1205 31339 /* Floating point variants -- don't add any more to this list either. */
0198d5e6
TC
31340 {"mfpe-old", &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
31341 {"mfpa10", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
31342 {"mfpa11", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
31343 {"mno-fpu", &legacy_fpu, ARM_ARCH_NONE,
c19d1205 31344 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
7ed4c4c5 31345
e74cfd16 31346 {NULL, NULL, ARM_ARCH_NONE, NULL}
c19d1205 31347};
7ed4c4c5 31348
c19d1205 31349struct arm_cpu_option_table
7ed4c4c5 31350{
0198d5e6
TC
31351 const char * name;
31352 size_t name_len;
31353 const arm_feature_set value;
31354 const arm_feature_set ext;
c19d1205
ZW
31355 /* For some CPUs we assume an FPU unless the user explicitly sets
31356 -mfpu=... */
0198d5e6 31357 const arm_feature_set default_fpu;
ee065d83
PB
31358 /* The canonical name of the CPU, or NULL to use NAME converted to upper
31359 case. */
0198d5e6 31360 const char * canonical_name;
c19d1205 31361};
7ed4c4c5 31362
c19d1205
ZW
31363/* This list should, at a minimum, contain all the cpu names
31364 recognized by GCC. */
996b5569 31365#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
0198d5e6 31366
e74cfd16 31367static const struct arm_cpu_option_table arm_cpus[] =
c19d1205 31368{
996b5569
TP
31369 ARM_CPU_OPT ("all", NULL, ARM_ANY,
31370 ARM_ARCH_NONE,
31371 FPU_ARCH_FPA),
31372 ARM_CPU_OPT ("arm1", NULL, ARM_ARCH_V1,
31373 ARM_ARCH_NONE,
31374 FPU_ARCH_FPA),
31375 ARM_CPU_OPT ("arm2", NULL, ARM_ARCH_V2,
31376 ARM_ARCH_NONE,
31377 FPU_ARCH_FPA),
31378 ARM_CPU_OPT ("arm250", NULL, ARM_ARCH_V2S,
31379 ARM_ARCH_NONE,
31380 FPU_ARCH_FPA),
31381 ARM_CPU_OPT ("arm3", NULL, ARM_ARCH_V2S,
31382 ARM_ARCH_NONE,
31383 FPU_ARCH_FPA),
31384 ARM_CPU_OPT ("arm6", NULL, ARM_ARCH_V3,
31385 ARM_ARCH_NONE,
31386 FPU_ARCH_FPA),
31387 ARM_CPU_OPT ("arm60", NULL, ARM_ARCH_V3,
31388 ARM_ARCH_NONE,
31389 FPU_ARCH_FPA),
31390 ARM_CPU_OPT ("arm600", NULL, ARM_ARCH_V3,
31391 ARM_ARCH_NONE,
31392 FPU_ARCH_FPA),
31393 ARM_CPU_OPT ("arm610", NULL, ARM_ARCH_V3,
31394 ARM_ARCH_NONE,
31395 FPU_ARCH_FPA),
31396 ARM_CPU_OPT ("arm620", NULL, ARM_ARCH_V3,
31397 ARM_ARCH_NONE,
31398 FPU_ARCH_FPA),
31399 ARM_CPU_OPT ("arm7", NULL, ARM_ARCH_V3,
31400 ARM_ARCH_NONE,
31401 FPU_ARCH_FPA),
31402 ARM_CPU_OPT ("arm7m", NULL, ARM_ARCH_V3M,
31403 ARM_ARCH_NONE,
31404 FPU_ARCH_FPA),
31405 ARM_CPU_OPT ("arm7d", NULL, ARM_ARCH_V3,
31406 ARM_ARCH_NONE,
31407 FPU_ARCH_FPA),
31408 ARM_CPU_OPT ("arm7dm", NULL, ARM_ARCH_V3M,
31409 ARM_ARCH_NONE,
31410 FPU_ARCH_FPA),
31411 ARM_CPU_OPT ("arm7di", NULL, ARM_ARCH_V3,
31412 ARM_ARCH_NONE,
31413 FPU_ARCH_FPA),
31414 ARM_CPU_OPT ("arm7dmi", NULL, ARM_ARCH_V3M,
31415 ARM_ARCH_NONE,
31416 FPU_ARCH_FPA),
31417 ARM_CPU_OPT ("arm70", NULL, ARM_ARCH_V3,
31418 ARM_ARCH_NONE,
31419 FPU_ARCH_FPA),
31420 ARM_CPU_OPT ("arm700", NULL, ARM_ARCH_V3,
31421 ARM_ARCH_NONE,
31422 FPU_ARCH_FPA),
31423 ARM_CPU_OPT ("arm700i", NULL, ARM_ARCH_V3,
31424 ARM_ARCH_NONE,
31425 FPU_ARCH_FPA),
31426 ARM_CPU_OPT ("arm710", NULL, ARM_ARCH_V3,
31427 ARM_ARCH_NONE,
31428 FPU_ARCH_FPA),
31429 ARM_CPU_OPT ("arm710t", NULL, ARM_ARCH_V4T,
31430 ARM_ARCH_NONE,
31431 FPU_ARCH_FPA),
31432 ARM_CPU_OPT ("arm720", NULL, ARM_ARCH_V3,
31433 ARM_ARCH_NONE,
31434 FPU_ARCH_FPA),
31435 ARM_CPU_OPT ("arm720t", NULL, ARM_ARCH_V4T,
31436 ARM_ARCH_NONE,
31437 FPU_ARCH_FPA),
31438 ARM_CPU_OPT ("arm740t", NULL, ARM_ARCH_V4T,
31439 ARM_ARCH_NONE,
31440 FPU_ARCH_FPA),
31441 ARM_CPU_OPT ("arm710c", NULL, ARM_ARCH_V3,
31442 ARM_ARCH_NONE,
31443 FPU_ARCH_FPA),
31444 ARM_CPU_OPT ("arm7100", NULL, ARM_ARCH_V3,
31445 ARM_ARCH_NONE,
31446 FPU_ARCH_FPA),
31447 ARM_CPU_OPT ("arm7500", NULL, ARM_ARCH_V3,
31448 ARM_ARCH_NONE,
31449 FPU_ARCH_FPA),
31450 ARM_CPU_OPT ("arm7500fe", NULL, ARM_ARCH_V3,
31451 ARM_ARCH_NONE,
31452 FPU_ARCH_FPA),
31453 ARM_CPU_OPT ("arm7t", NULL, ARM_ARCH_V4T,
31454 ARM_ARCH_NONE,
31455 FPU_ARCH_FPA),
31456 ARM_CPU_OPT ("arm7tdmi", NULL, ARM_ARCH_V4T,
31457 ARM_ARCH_NONE,
31458 FPU_ARCH_FPA),
31459 ARM_CPU_OPT ("arm7tdmi-s", NULL, ARM_ARCH_V4T,
31460 ARM_ARCH_NONE,
31461 FPU_ARCH_FPA),
31462 ARM_CPU_OPT ("arm8", NULL, ARM_ARCH_V4,
31463 ARM_ARCH_NONE,
31464 FPU_ARCH_FPA),
31465 ARM_CPU_OPT ("arm810", NULL, ARM_ARCH_V4,
31466 ARM_ARCH_NONE,
31467 FPU_ARCH_FPA),
31468 ARM_CPU_OPT ("strongarm", NULL, ARM_ARCH_V4,
31469 ARM_ARCH_NONE,
31470 FPU_ARCH_FPA),
31471 ARM_CPU_OPT ("strongarm1", NULL, ARM_ARCH_V4,
31472 ARM_ARCH_NONE,
31473 FPU_ARCH_FPA),
31474 ARM_CPU_OPT ("strongarm110", NULL, ARM_ARCH_V4,
31475 ARM_ARCH_NONE,
31476 FPU_ARCH_FPA),
31477 ARM_CPU_OPT ("strongarm1100", NULL, ARM_ARCH_V4,
31478 ARM_ARCH_NONE,
31479 FPU_ARCH_FPA),
31480 ARM_CPU_OPT ("strongarm1110", NULL, ARM_ARCH_V4,
31481 ARM_ARCH_NONE,
31482 FPU_ARCH_FPA),
31483 ARM_CPU_OPT ("arm9", NULL, ARM_ARCH_V4T,
31484 ARM_ARCH_NONE,
31485 FPU_ARCH_FPA),
31486 ARM_CPU_OPT ("arm920", "ARM920T", ARM_ARCH_V4T,
31487 ARM_ARCH_NONE,
31488 FPU_ARCH_FPA),
31489 ARM_CPU_OPT ("arm920t", NULL, ARM_ARCH_V4T,
31490 ARM_ARCH_NONE,
31491 FPU_ARCH_FPA),
31492 ARM_CPU_OPT ("arm922t", NULL, ARM_ARCH_V4T,
31493 ARM_ARCH_NONE,
31494 FPU_ARCH_FPA),
31495 ARM_CPU_OPT ("arm940t", NULL, ARM_ARCH_V4T,
31496 ARM_ARCH_NONE,
31497 FPU_ARCH_FPA),
31498 ARM_CPU_OPT ("arm9tdmi", NULL, ARM_ARCH_V4T,
31499 ARM_ARCH_NONE,
31500 FPU_ARCH_FPA),
31501 ARM_CPU_OPT ("fa526", NULL, ARM_ARCH_V4,
31502 ARM_ARCH_NONE,
31503 FPU_ARCH_FPA),
31504 ARM_CPU_OPT ("fa626", NULL, ARM_ARCH_V4,
31505 ARM_ARCH_NONE,
31506 FPU_ARCH_FPA),
31507
c19d1205
ZW
31508 /* For V5 or later processors we default to using VFP; but the user
31509 should really set the FPU type explicitly. */
996b5569
TP
31510 ARM_CPU_OPT ("arm9e-r0", NULL, ARM_ARCH_V5TExP,
31511 ARM_ARCH_NONE,
31512 FPU_ARCH_VFP_V2),
31513 ARM_CPU_OPT ("arm9e", NULL, ARM_ARCH_V5TE,
31514 ARM_ARCH_NONE,
31515 FPU_ARCH_VFP_V2),
31516 ARM_CPU_OPT ("arm926ej", "ARM926EJ-S", ARM_ARCH_V5TEJ,
31517 ARM_ARCH_NONE,
31518 FPU_ARCH_VFP_V2),
31519 ARM_CPU_OPT ("arm926ejs", "ARM926EJ-S", ARM_ARCH_V5TEJ,
31520 ARM_ARCH_NONE,
31521 FPU_ARCH_VFP_V2),
31522 ARM_CPU_OPT ("arm926ej-s", NULL, ARM_ARCH_V5TEJ,
31523 ARM_ARCH_NONE,
31524 FPU_ARCH_VFP_V2),
31525 ARM_CPU_OPT ("arm946e-r0", NULL, ARM_ARCH_V5TExP,
31526 ARM_ARCH_NONE,
31527 FPU_ARCH_VFP_V2),
31528 ARM_CPU_OPT ("arm946e", "ARM946E-S", ARM_ARCH_V5TE,
31529 ARM_ARCH_NONE,
31530 FPU_ARCH_VFP_V2),
31531 ARM_CPU_OPT ("arm946e-s", NULL, ARM_ARCH_V5TE,
31532 ARM_ARCH_NONE,
31533 FPU_ARCH_VFP_V2),
31534 ARM_CPU_OPT ("arm966e-r0", NULL, ARM_ARCH_V5TExP,
31535 ARM_ARCH_NONE,
31536 FPU_ARCH_VFP_V2),
31537 ARM_CPU_OPT ("arm966e", "ARM966E-S", ARM_ARCH_V5TE,
31538 ARM_ARCH_NONE,
31539 FPU_ARCH_VFP_V2),
31540 ARM_CPU_OPT ("arm966e-s", NULL, ARM_ARCH_V5TE,
31541 ARM_ARCH_NONE,
31542 FPU_ARCH_VFP_V2),
31543 ARM_CPU_OPT ("arm968e-s", NULL, ARM_ARCH_V5TE,
31544 ARM_ARCH_NONE,
31545 FPU_ARCH_VFP_V2),
31546 ARM_CPU_OPT ("arm10t", NULL, ARM_ARCH_V5T,
31547 ARM_ARCH_NONE,
31548 FPU_ARCH_VFP_V1),
31549 ARM_CPU_OPT ("arm10tdmi", NULL, ARM_ARCH_V5T,
31550 ARM_ARCH_NONE,
31551 FPU_ARCH_VFP_V1),
31552 ARM_CPU_OPT ("arm10e", NULL, ARM_ARCH_V5TE,
31553 ARM_ARCH_NONE,
31554 FPU_ARCH_VFP_V2),
31555 ARM_CPU_OPT ("arm1020", "ARM1020E", ARM_ARCH_V5TE,
31556 ARM_ARCH_NONE,
31557 FPU_ARCH_VFP_V2),
31558 ARM_CPU_OPT ("arm1020t", NULL, ARM_ARCH_V5T,
31559 ARM_ARCH_NONE,
31560 FPU_ARCH_VFP_V1),
31561 ARM_CPU_OPT ("arm1020e", NULL, ARM_ARCH_V5TE,
31562 ARM_ARCH_NONE,
31563 FPU_ARCH_VFP_V2),
31564 ARM_CPU_OPT ("arm1022e", NULL, ARM_ARCH_V5TE,
31565 ARM_ARCH_NONE,
31566 FPU_ARCH_VFP_V2),
31567 ARM_CPU_OPT ("arm1026ejs", "ARM1026EJ-S", ARM_ARCH_V5TEJ,
31568 ARM_ARCH_NONE,
31569 FPU_ARCH_VFP_V2),
31570 ARM_CPU_OPT ("arm1026ej-s", NULL, ARM_ARCH_V5TEJ,
31571 ARM_ARCH_NONE,
31572 FPU_ARCH_VFP_V2),
31573 ARM_CPU_OPT ("fa606te", NULL, ARM_ARCH_V5TE,
31574 ARM_ARCH_NONE,
31575 FPU_ARCH_VFP_V2),
31576 ARM_CPU_OPT ("fa616te", NULL, ARM_ARCH_V5TE,
31577 ARM_ARCH_NONE,
31578 FPU_ARCH_VFP_V2),
31579 ARM_CPU_OPT ("fa626te", NULL, ARM_ARCH_V5TE,
31580 ARM_ARCH_NONE,
31581 FPU_ARCH_VFP_V2),
31582 ARM_CPU_OPT ("fmp626", NULL, ARM_ARCH_V5TE,
31583 ARM_ARCH_NONE,
31584 FPU_ARCH_VFP_V2),
31585 ARM_CPU_OPT ("fa726te", NULL, ARM_ARCH_V5TE,
31586 ARM_ARCH_NONE,
31587 FPU_ARCH_VFP_V2),
31588 ARM_CPU_OPT ("arm1136js", "ARM1136J-S", ARM_ARCH_V6,
31589 ARM_ARCH_NONE,
31590 FPU_NONE),
31591 ARM_CPU_OPT ("arm1136j-s", NULL, ARM_ARCH_V6,
31592 ARM_ARCH_NONE,
31593 FPU_NONE),
31594 ARM_CPU_OPT ("arm1136jfs", "ARM1136JF-S", ARM_ARCH_V6,
31595 ARM_ARCH_NONE,
31596 FPU_ARCH_VFP_V2),
31597 ARM_CPU_OPT ("arm1136jf-s", NULL, ARM_ARCH_V6,
31598 ARM_ARCH_NONE,
31599 FPU_ARCH_VFP_V2),
31600 ARM_CPU_OPT ("mpcore", "MPCore", ARM_ARCH_V6K,
31601 ARM_ARCH_NONE,
31602 FPU_ARCH_VFP_V2),
31603 ARM_CPU_OPT ("mpcorenovfp", "MPCore", ARM_ARCH_V6K,
31604 ARM_ARCH_NONE,
31605 FPU_NONE),
31606 ARM_CPU_OPT ("arm1156t2-s", NULL, ARM_ARCH_V6T2,
31607 ARM_ARCH_NONE,
31608 FPU_NONE),
31609 ARM_CPU_OPT ("arm1156t2f-s", NULL, ARM_ARCH_V6T2,
31610 ARM_ARCH_NONE,
31611 FPU_ARCH_VFP_V2),
31612 ARM_CPU_OPT ("arm1176jz-s", NULL, ARM_ARCH_V6KZ,
31613 ARM_ARCH_NONE,
31614 FPU_NONE),
31615 ARM_CPU_OPT ("arm1176jzf-s", NULL, ARM_ARCH_V6KZ,
31616 ARM_ARCH_NONE,
31617 FPU_ARCH_VFP_V2),
31618 ARM_CPU_OPT ("cortex-a5", "Cortex-A5", ARM_ARCH_V7A,
31619 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31620 FPU_NONE),
31621 ARM_CPU_OPT ("cortex-a7", "Cortex-A7", ARM_ARCH_V7VE,
31622 ARM_ARCH_NONE,
31623 FPU_ARCH_NEON_VFP_V4),
31624 ARM_CPU_OPT ("cortex-a8", "Cortex-A8", ARM_ARCH_V7A,
31625 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
31626 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
31627 ARM_CPU_OPT ("cortex-a9", "Cortex-A9", ARM_ARCH_V7A,
31628 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31629 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
31630 ARM_CPU_OPT ("cortex-a12", "Cortex-A12", ARM_ARCH_V7VE,
31631 ARM_ARCH_NONE,
31632 FPU_ARCH_NEON_VFP_V4),
31633 ARM_CPU_OPT ("cortex-a15", "Cortex-A15", ARM_ARCH_V7VE,
31634 ARM_ARCH_NONE,
31635 FPU_ARCH_NEON_VFP_V4),
31636 ARM_CPU_OPT ("cortex-a17", "Cortex-A17", ARM_ARCH_V7VE,
31637 ARM_ARCH_NONE,
31638 FPU_ARCH_NEON_VFP_V4),
31639 ARM_CPU_OPT ("cortex-a32", "Cortex-A32", ARM_ARCH_V8A,
8b301fbb 31640 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31641 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31642 ARM_CPU_OPT ("cortex-a35", "Cortex-A35", ARM_ARCH_V8A,
8b301fbb 31643 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31644 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31645 ARM_CPU_OPT ("cortex-a53", "Cortex-A53", ARM_ARCH_V8A,
8b301fbb 31646 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31647 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
31648 ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A,
31649 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 31650 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569 31651 ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A,
8b301fbb 31652 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31653 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31654 ARM_CPU_OPT ("cortex-a72", "Cortex-A72", ARM_ARCH_V8A,
8b301fbb 31655 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31656 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31657 ARM_CPU_OPT ("cortex-a73", "Cortex-A73", ARM_ARCH_V8A,
8b301fbb 31658 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31659 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
31660 ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A,
31661 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 31662 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
7ebd1359 31663 ARM_CPU_OPT ("cortex-a76", "Cortex-A76", ARM_ARCH_V8_2A,
31664 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31665 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
0535e5d7
DZ
31666 ARM_CPU_OPT ("cortex-a76ae", "Cortex-A76AE", ARM_ARCH_V8_2A,
31667 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31668 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
31669 ARM_CPU_OPT ("cortex-a77", "Cortex-A77", ARM_ARCH_V8_2A,
31670 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31671 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
42c36b73
PW
31672 ARM_CPU_OPT ("cortex-a78", "Cortex-A78", ARM_ARCH_V8_2A,
31673 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
31674 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31675 ARM_CPU_OPT ("cortex-a78ae", "Cortex-A78AE", ARM_ARCH_V8_2A,
31676 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
31677 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
1bbda94f
PW
31678 ARM_CPU_OPT ("cortex-a78c", "Cortex-A78C", ARM_ARCH_V8_2A,
31679 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
31680 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
14f45859
PW
31681 ARM_CPU_OPT ("cortex-a710", "Cortex-A710", ARM_ARCH_V9A,
31682 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
31683 | ARM_EXT2_BF16
31684 | ARM_EXT2_I8MM),
31685 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
ef8df4ca
KT
31686 ARM_CPU_OPT ("ares", "Ares", ARM_ARCH_V8_2A,
31687 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31688 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
31689 ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R,
31690 ARM_ARCH_NONE,
31691 FPU_NONE),
31692 ARM_CPU_OPT ("cortex-r4f", "Cortex-R4F", ARM_ARCH_V7R,
31693 ARM_ARCH_NONE,
31694 FPU_ARCH_VFP_V3D16),
31695 ARM_CPU_OPT ("cortex-r5", "Cortex-R5", ARM_ARCH_V7R,
31696 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31697 FPU_NONE),
31698 ARM_CPU_OPT ("cortex-r7", "Cortex-R7", ARM_ARCH_V7R,
31699 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31700 FPU_ARCH_VFP_V3D16),
31701 ARM_CPU_OPT ("cortex-r8", "Cortex-R8", ARM_ARCH_V7R,
31702 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31703 FPU_ARCH_VFP_V3D16),
0cda1e19 31704 ARM_CPU_OPT ("cortex-r52", "Cortex-R52", ARM_ARCH_V8R,
8b301fbb 31705 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
0cda1e19 31706 FPU_ARCH_NEON_VFP_ARMV8),
80cfde76
PW
31707 ARM_CPU_OPT ("cortex-r52plus", "Cortex-R52+", ARM_ARCH_V8R,
31708 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
31709 FPU_ARCH_NEON_VFP_ARMV8),
0535e5d7
DZ
31710 ARM_CPU_OPT ("cortex-m35p", "Cortex-M35P", ARM_ARCH_V8M_MAIN,
31711 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
31712 FPU_NONE),
996b5569
TP
31713 ARM_CPU_OPT ("cortex-m33", "Cortex-M33", ARM_ARCH_V8M_MAIN,
31714 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
31715 FPU_NONE),
31716 ARM_CPU_OPT ("cortex-m23", "Cortex-M23", ARM_ARCH_V8M_BASE,
31717 ARM_ARCH_NONE,
31718 FPU_NONE),
31719 ARM_CPU_OPT ("cortex-m7", "Cortex-M7", ARM_ARCH_V7EM,
31720 ARM_ARCH_NONE,
31721 FPU_NONE),
31722 ARM_CPU_OPT ("cortex-m4", "Cortex-M4", ARM_ARCH_V7EM,
31723 ARM_ARCH_NONE,
31724 FPU_NONE),
31725 ARM_CPU_OPT ("cortex-m3", "Cortex-M3", ARM_ARCH_V7M,
31726 ARM_ARCH_NONE,
31727 FPU_NONE),
31728 ARM_CPU_OPT ("cortex-m1", "Cortex-M1", ARM_ARCH_V6SM,
31729 ARM_ARCH_NONE,
31730 FPU_NONE),
31731 ARM_CPU_OPT ("cortex-m0", "Cortex-M0", ARM_ARCH_V6SM,
31732 ARM_ARCH_NONE,
31733 FPU_NONE),
31734 ARM_CPU_OPT ("cortex-m0plus", "Cortex-M0+", ARM_ARCH_V6SM,
31735 ARM_ARCH_NONE,
31736 FPU_NONE),
394e9bf6 31737 ARM_CPU_OPT ("cortex-x1", "Cortex-X1", ARM_ARCH_V8_2A,
a417e439 31738 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
394e9bf6 31739 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
996b5569 31740 ARM_CPU_OPT ("exynos-m1", "Samsung Exynos M1", ARM_ARCH_V8A,
8b301fbb 31741 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31742 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
83f43c83
KT
31743 ARM_CPU_OPT ("neoverse-n1", "Neoverse N1", ARM_ARCH_V8_2A,
31744 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31745 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
f3034e25
AC
31746 ARM_CPU_OPT ("neoverse-n2", "Neoverse N2", ARM_ARCH_V8_5A,
31747 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
31748 | ARM_EXT2_BF16
31749 | ARM_EXT2_I8MM),
31750 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4),
6eee0315 31751 ARM_CPU_OPT ("neoverse-v1", "Neoverse V1", ARM_ARCH_V8_4A,
9bede61c
AC
31752 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
31753 | ARM_EXT2_BF16
31754 | ARM_EXT2_I8MM),
6eee0315 31755 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4),
c19d1205 31756 /* ??? XSCALE is really an architecture. */
996b5569
TP
31757 ARM_CPU_OPT ("xscale", NULL, ARM_ARCH_XSCALE,
31758 ARM_ARCH_NONE,
31759 FPU_ARCH_VFP_V2),
31760
c19d1205 31761 /* ??? iwmmxt is not a processor. */
996b5569
TP
31762 ARM_CPU_OPT ("iwmmxt", NULL, ARM_ARCH_IWMMXT,
31763 ARM_ARCH_NONE,
31764 FPU_ARCH_VFP_V2),
31765 ARM_CPU_OPT ("iwmmxt2", NULL, ARM_ARCH_IWMMXT2,
31766 ARM_ARCH_NONE,
31767 FPU_ARCH_VFP_V2),
31768 ARM_CPU_OPT ("i80200", NULL, ARM_ARCH_XSCALE,
31769 ARM_ARCH_NONE,
31770 FPU_ARCH_VFP_V2),
31771
0198d5e6 31772 /* Maverick. */
996b5569
TP
31773 ARM_CPU_OPT ("ep9312", "ARM920T",
31774 ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
31775 ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
31776
da4339ed 31777 /* Marvell processors. */
996b5569
TP
31778 ARM_CPU_OPT ("marvell-pj4", NULL, ARM_ARCH_V7A,
31779 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31780 FPU_ARCH_VFP_V3D16),
31781 ARM_CPU_OPT ("marvell-whitney", NULL, ARM_ARCH_V7A,
31782 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31783 FPU_ARCH_NEON_VFP_V4),
da4339ed 31784
996b5569
TP
31785 /* APM X-Gene family. */
31786 ARM_CPU_OPT ("xgene1", "APM X-Gene 1", ARM_ARCH_V8A,
31787 ARM_ARCH_NONE,
31788 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31789 ARM_CPU_OPT ("xgene2", "APM X-Gene 2", ARM_ARCH_V8A,
8b301fbb 31790 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31791 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31792
31793 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 31794};
f3bad469 31795#undef ARM_CPU_OPT
7ed4c4c5 31796
34ef62f4
AV
31797struct arm_ext_table
31798{
31799 const char * name;
31800 size_t name_len;
31801 const arm_feature_set merge;
31802 const arm_feature_set clear;
31803};
31804
c19d1205 31805struct arm_arch_option_table
7ed4c4c5 31806{
34ef62f4
AV
31807 const char * name;
31808 size_t name_len;
31809 const arm_feature_set value;
31810 const arm_feature_set default_fpu;
31811 const struct arm_ext_table * ext_table;
31812};
31813
31814/* Used to add support for +E and +noE extension. */
31815#define ARM_EXT(E, M, C) { E, sizeof (E) - 1, M, C }
31816/* Used to add support for a +E extension. */
31817#define ARM_ADD(E, M) { E, sizeof(E) - 1, M, ARM_ARCH_NONE }
31818/* Used to add support for a +noE extension. */
31819#define ARM_REMOVE(E, C) { E, sizeof(E) -1, ARM_ARCH_NONE, C }
31820
31821#define ALL_FP ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_FP16_FML, \
31822 ~0 & ~FPU_ENDIAN_PURE)
31823
31824static const struct arm_ext_table armv5te_ext_table[] =
31825{
31826 ARM_EXT ("fp", FPU_ARCH_VFP_V2, ALL_FP),
31827 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31828};
31829
31830static const struct arm_ext_table armv7_ext_table[] =
31831{
31832 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31833 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31834};
31835
31836static const struct arm_ext_table armv7ve_ext_table[] =
31837{
31838 ARM_EXT ("fp", FPU_ARCH_VFP_V4D16, ALL_FP),
31839 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16),
31840 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
31841 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31842 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
31843 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), /* Alias for +fp. */
31844 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
31845
31846 ARM_EXT ("simd", FPU_ARCH_NEON_VFP_V4,
31847 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
31848
31849 /* Aliases for +simd. */
31850 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
31851
31852 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31853 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31854 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
31855
31856 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31857};
31858
31859static const struct arm_ext_table armv7a_ext_table[] =
31860{
31861 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31862 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
31863 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
31864 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31865 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
31866 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16),
31867 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
31868
31869 ARM_EXT ("simd", FPU_ARCH_VFP_V3_PLUS_NEON_V1,
31870 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
31871
31872 /* Aliases for +simd. */
31873 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31874 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31875
31876 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
31877 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
31878
31879 ARM_ADD ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP)),
31880 ARM_ADD ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC)),
31881 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31882};
31883
31884static const struct arm_ext_table armv7r_ext_table[] =
31885{
31886 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V3xD),
31887 ARM_ADD ("vfpv3xd", FPU_ARCH_VFP_V3xD), /* Alias for +fp.sp. */
31888 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31889 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
31890 ARM_ADD ("vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16),
31891 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31892 ARM_EXT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
31893 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV)),
31894 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31895};
31896
31897static const struct arm_ext_table armv7em_ext_table[] =
31898{
31899 ARM_EXT ("fp", FPU_ARCH_VFP_V4_SP_D16, ALL_FP),
31900 /* Alias for +fp, used to be known as fpv4-sp-d16. */
31901 ARM_ADD ("vfpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16),
31902 ARM_ADD ("fpv5", FPU_ARCH_VFP_V5_SP_D16),
31903 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
31904 ARM_ADD ("fpv5-d16", FPU_ARCH_VFP_V5D16),
31905 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31906};
31907
31908static const struct arm_ext_table armv8a_ext_table[] =
31909{
8b301fbb 31910 ARM_ADD ("crc", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC)),
34ef62f4
AV
31911 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
31912 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
31913 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31914
31915 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31916 should use the +simd option to turn on FP. */
31917 ARM_REMOVE ("fp", ALL_FP),
31918 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31919 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31920 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31921};
31922
31923
31924static const struct arm_ext_table armv81a_ext_table[] =
31925{
31926 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
31927 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
31928 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31929
31930 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31931 should use the +simd option to turn on FP. */
31932 ARM_REMOVE ("fp", ALL_FP),
31933 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31934 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31935 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31936};
31937
31938static const struct arm_ext_table armv82a_ext_table[] =
31939{
31940 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
31941 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_2_FP16),
31942 ARM_ADD ("fp16fml", FPU_ARCH_NEON_VFP_ARMV8_2_FP16FML),
616ce08e
MM
31943 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
31944 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
31945 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
31946 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31947 ARM_ADD ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31948
31949 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31950 should use the +simd option to turn on FP. */
31951 ARM_REMOVE ("fp", ALL_FP),
31952 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31953 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31954 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31955};
31956
31957static const struct arm_ext_table armv84a_ext_table[] =
31958{
31959 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31960 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
616ce08e
MM
31961 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
31962 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
31963 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
31964 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31965
31966 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31967 should use the +simd option to turn on FP. */
31968 ARM_REMOVE ("fp", ALL_FP),
31969 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31970 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31971 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31972};
31973
31974static const struct arm_ext_table armv85a_ext_table[] =
31975{
31976 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31977 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
616ce08e
MM
31978 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
31979 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
31980 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
31981 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31982
31983 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31984 should use the +simd option to turn on FP. */
31985 ARM_REMOVE ("fp", ALL_FP),
31986 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31987};
31988
aab2c27d
MM
31989static const struct arm_ext_table armv86a_ext_table[] =
31990{
616ce08e 31991 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
aab2c27d
MM
31992 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31993};
31994
b3e4d932
RS
31995#define armv87a_ext_table armv86a_ext_table
31996#define armv88a_ext_table armv87a_ext_table
31997
3197e593
PW
31998static const struct arm_ext_table armv9a_ext_table[] =
31999{
32000 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
32001 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
32002 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
32003 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
32004 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
32005 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
32006
32007 /* Armv9-a does not allow an FP implementation without SIMD, so the user
32008 should use the +simd option to turn on FP. */
32009 ARM_REMOVE ("fp", ALL_FP),
32010 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32011};
32012
a2b1ea81
RS
32013#define armv91a_ext_table armv86a_ext_table
32014#define armv92a_ext_table armv91a_ext_table
32015#define armv93a_ext_table armv92a_ext_table
32016
4934a27c
MM
32017#define CDE_EXTENSIONS \
32018 ARM_ADD ("cdecp0", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE0)), \
32019 ARM_ADD ("cdecp1", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE1)), \
32020 ARM_ADD ("cdecp2", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE2)), \
32021 ARM_ADD ("cdecp3", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE3)), \
32022 ARM_ADD ("cdecp4", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE4)), \
32023 ARM_ADD ("cdecp5", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE5)), \
32024 ARM_ADD ("cdecp6", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE6)), \
32025 ARM_ADD ("cdecp7", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE7))
32026
34ef62f4
AV
32027static const struct arm_ext_table armv8m_main_ext_table[] =
32028{
92169145
AV
32029 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP),
32030 ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP)),
34ef62f4
AV
32031 ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP),
32032 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
4934a27c 32033 CDE_EXTENSIONS,
34ef62f4
AV
32034 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32035};
32036
92169145 32037
e0991585
AV
32038static const struct arm_ext_table armv8_1m_main_ext_table[] =
32039{
92169145
AV
32040 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP),
32041 ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP)),
e0991585
AV
32042 ARM_EXT ("fp",
32043 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
32044 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA),
32045 ALL_FP),
32046 ARM_ADD ("fp.dp",
32047 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
32048 FPU_VFP_V5D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
92169145 32049 ARM_EXT ("mve", ARM_FEATURE (ARM_AEXT_V8M_MAIN_DSP, ARM_EXT2_MVE, 0),
2da2eaf4 32050 ARM_FEATURE_CORE_HIGH (ARM_EXT2_MVE | ARM_EXT2_MVE_FP)),
a7ad558c 32051 ARM_ADD ("mve.fp",
92169145
AV
32052 ARM_FEATURE (ARM_AEXT_V8M_MAIN_DSP,
32053 ARM_EXT2_FP16_INST | ARM_EXT2_MVE | ARM_EXT2_MVE_FP,
2da2eaf4 32054 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
4934a27c 32055 CDE_EXTENSIONS,
5a0c7a81 32056 ARM_ADD ("pacbti", ARM_FEATURE_CORE_HIGH_HIGH (ARM_AEXT3_V8_1M_MAIN_PACBTI)),
e0991585
AV
32057 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32058};
32059
4934a27c
MM
32060#undef CDE_EXTENSIONS
32061
34ef62f4
AV
32062static const struct arm_ext_table armv8r_ext_table[] =
32063{
8b301fbb 32064 ARM_ADD ("crc", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC)),
34ef62f4
AV
32065 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
32066 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
32067 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
32068 ARM_REMOVE ("fp", ALL_FP),
32069 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V5_SP_D16),
32070 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
c19d1205 32071};
7ed4c4c5 32072
c19d1205
ZW
32073/* This list should, at a minimum, contain all the architecture names
32074 recognized by GCC. */
34ef62f4
AV
32075#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF, NULL }
32076#define ARM_ARCH_OPT2(N, V, DF, ext) \
32077 { N, sizeof (N) - 1, V, DF, ext##_ext_table }
0198d5e6 32078
e74cfd16 32079static const struct arm_arch_option_table arm_archs[] =
c19d1205 32080{
497d849d
TP
32081 ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
32082 ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
32083 ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
32084 ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
32085 ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
32086 ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
32087 ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
32088 ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
32089 ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
32090 ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
32091 ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
32092 ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
32093 ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
32094 ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
34ef62f4
AV
32095 ARM_ARCH_OPT2 ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP, armv5te),
32096 ARM_ARCH_OPT2 ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP, armv5te),
32097 ARM_ARCH_OPT2 ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP, armv5te),
32098 ARM_ARCH_OPT2 ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
32099 ARM_ARCH_OPT2 ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
32100 ARM_ARCH_OPT2 ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP, armv5te),
32101 ARM_ARCH_OPT2 ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP, armv5te),
f33026a9
MW
32102 /* The official spelling of this variant is ARMv6KZ, the name "armv6zk" is
32103 kept to preserve existing behaviour. */
34ef62f4
AV
32104 ARM_ARCH_OPT2 ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
32105 ARM_ARCH_OPT2 ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
32106 ARM_ARCH_OPT2 ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP, armv5te),
32107 ARM_ARCH_OPT2 ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP, armv5te),
32108 ARM_ARCH_OPT2 ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP, armv5te),
f33026a9
MW
32109 /* The official spelling of this variant is ARMv6KZ, the name "armv6zkt2" is
32110 kept to preserve existing behaviour. */
34ef62f4
AV
32111 ARM_ARCH_OPT2 ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
32112 ARM_ARCH_OPT2 ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
497d849d
TP
32113 ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
32114 ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
34ef62f4 32115 ARM_ARCH_OPT2 ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP, armv7),
c450d570
PB
32116 /* The official spelling of the ARMv7 profile variants is the dashed form.
32117 Accept the non-dashed form for compatibility with old toolchains. */
34ef62f4
AV
32118 ARM_ARCH_OPT2 ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
32119 ARM_ARCH_OPT2 ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP, armv7ve),
32120 ARM_ARCH_OPT2 ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 32121 ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4
AV
32122 ARM_ARCH_OPT2 ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
32123 ARM_ARCH_OPT2 ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 32124 ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4 32125 ARM_ARCH_OPT2 ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP, armv7em),
497d849d 32126 ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP),
34ef62f4
AV
32127 ARM_ARCH_OPT2 ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP,
32128 armv8m_main),
e0991585
AV
32129 ARM_ARCH_OPT2 ("armv8.1-m.main", ARM_ARCH_V8_1M_MAIN, FPU_ARCH_VFP,
32130 armv8_1m_main),
34ef62f4
AV
32131 ARM_ARCH_OPT2 ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP, armv8a),
32132 ARM_ARCH_OPT2 ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP, armv81a),
32133 ARM_ARCH_OPT2 ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP, armv82a),
32134 ARM_ARCH_OPT2 ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP, armv82a),
32135 ARM_ARCH_OPT2 ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP, armv8r),
32136 ARM_ARCH_OPT2 ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP, armv84a),
32137 ARM_ARCH_OPT2 ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP, armv85a),
aab2c27d 32138 ARM_ARCH_OPT2 ("armv8.6-a", ARM_ARCH_V8_6A, FPU_ARCH_VFP, armv86a),
b3e4d932
RS
32139 ARM_ARCH_OPT2 ("armv8.7-a", ARM_ARCH_V8_7A, FPU_ARCH_VFP, armv87a),
32140 ARM_ARCH_OPT2 ("armv8.8-a", ARM_ARCH_V8_8A, FPU_ARCH_VFP, armv88a),
a2b1ea81
RS
32141 ARM_ARCH_OPT2 ("armv9-a", ARM_ARCH_V9A, FPU_ARCH_VFP, armv9a),
32142 ARM_ARCH_OPT2 ("armv9.1-a", ARM_ARCH_V9_1A, FPU_ARCH_VFP, armv91a),
32143 ARM_ARCH_OPT2 ("armv9.2-a", ARM_ARCH_V9_2A, FPU_ARCH_VFP, armv92a),
32144 ARM_ARCH_OPT2 ("armv9.3-a", ARM_ARCH_V9_2A, FPU_ARCH_VFP, armv93a),
497d849d
TP
32145 ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
32146 ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
32147 ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP),
34ef62f4 32148 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 32149};
f3bad469 32150#undef ARM_ARCH_OPT
7ed4c4c5 32151
69133863 32152/* ISA extensions in the co-processor and main instruction set space. */
0198d5e6 32153
69133863 32154struct arm_option_extension_value_table
c19d1205 32155{
0198d5e6
TC
32156 const char * name;
32157 size_t name_len;
32158 const arm_feature_set merge_value;
32159 const arm_feature_set clear_value;
d942732e
TP
32160 /* List of architectures for which an extension is available. ARM_ARCH_NONE
32161 indicates that an extension is available for all architectures while
32162 ARM_ANY marks an empty entry. */
0198d5e6 32163 const arm_feature_set allowed_archs[2];
c19d1205 32164};
7ed4c4c5 32165
0198d5e6
TC
32166/* The following table must be in alphabetical order with a NULL last entry. */
32167
d942732e
TP
32168#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
32169#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
0198d5e6 32170
34ef62f4
AV
32171/* DEPRECATED: Refrain from using this table to add any new extensions, instead
32172 use the context sensitive approach using arm_ext_table's. */
69133863 32173static const struct arm_option_extension_value_table arm_extensions[] =
c19d1205 32174{
8b301fbb
MI
32175 ARM_EXT_OPT ("crc", ARM_FEATURE_CORE_HIGH(ARM_EXT2_CRC),
32176 ARM_FEATURE_CORE_HIGH(ARM_EXT2_CRC),
823d2571 32177 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
bca38921 32178 ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
823d2571
TG
32179 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
32180 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
c604a79a
JW
32181 ARM_EXT_OPT ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8,
32182 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
32183 ARM_ARCH_V8_2A),
15afaa63
TP
32184 ARM_EXT_OPT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
32185 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
32186 ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
823d2571
TG
32187 ARM_EXT_OPT ("fp", FPU_ARCH_VFP_ARMV8, ARM_FEATURE_COPROC (FPU_VFP_ARMV8),
32188 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
b8ec4e87
JW
32189 ARM_EXT_OPT ("fp16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
32190 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
32191 ARM_ARCH_V8_2A),
01f48020
TC
32192 ARM_EXT_OPT ("fp16fml", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
32193 | ARM_EXT2_FP16_FML),
32194 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
32195 | ARM_EXT2_FP16_FML),
32196 ARM_ARCH_V8_2A),
d942732e 32197 ARM_EXT_OPT2 ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
823d2571 32198 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
d942732e
TP
32199 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
32200 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
3d030cdb
TP
32201 /* Duplicate entry for the purpose of allowing ARMv7 to match in presence of
32202 Thumb divide instruction. Due to this having the same name as the
32203 previous entry, this will be ignored when doing command-line parsing and
32204 only considered by build attribute selection code. */
32205 ARM_EXT_OPT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
32206 ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
32207 ARM_FEATURE_CORE_LOW (ARM_EXT_V7)),
823d2571 32208 ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
d942732e 32209 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
823d2571 32210 ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
d942732e 32211 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ARCH_NONE),
823d2571 32212 ARM_EXT_OPT ("maverick", ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK),
d942732e
TP
32213 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ARCH_NONE),
32214 ARM_EXT_OPT2 ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
823d2571 32215 ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
d942732e
TP
32216 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
32217 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
823d2571
TG
32218 ARM_EXT_OPT ("os", ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
32219 ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
32220 ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
ddfded2f
MW
32221 ARM_EXT_OPT ("pan", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
32222 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
ced40572 32223 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
dad0c3bf
SD
32224 ARM_EXT_OPT ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
32225 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
32226 ARM_ARCH_V8A),
4d1464f2
MW
32227 ARM_EXT_OPT ("ras", ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
32228 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
ced40572 32229 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
643afb90
MW
32230 ARM_EXT_OPT ("rdma", FPU_ARCH_NEON_VFP_ARMV8_1,
32231 ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
ced40572 32232 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
7fadb25d
SD
32233 ARM_EXT_OPT ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
32234 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
32235 ARM_ARCH_V8A),
d942732e 32236 ARM_EXT_OPT2 ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
823d2571 32237 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
d942732e
TP
32238 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
32239 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
643afb90
MW
32240 ARM_EXT_OPT ("simd", FPU_ARCH_NEON_VFP_ARMV8,
32241 ARM_FEATURE_COPROC (FPU_NEON_ARMV8),
32242 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
823d2571
TG
32243 ARM_EXT_OPT ("virt", ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT | ARM_EXT_ADIV
32244 | ARM_EXT_DIV),
32245 ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT),
32246 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
32247 ARM_EXT_OPT ("xscale",ARM_FEATURE_COPROC (ARM_CEXT_XSCALE),
d942732e
TP
32248 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ARCH_NONE),
32249 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, { ARM_ARCH_NONE, ARM_ARCH_NONE } }
69133863 32250};
f3bad469 32251#undef ARM_EXT_OPT
69133863
MGD
32252
32253/* ISA floating-point and Advanced SIMD extensions. */
32254struct arm_option_fpu_value_table
32255{
0198d5e6
TC
32256 const char * name;
32257 const arm_feature_set value;
c19d1205 32258};
7ed4c4c5 32259
c19d1205
ZW
32260/* This list should, at a minimum, contain all the fpu names
32261 recognized by GCC. */
69133863 32262static const struct arm_option_fpu_value_table arm_fpus[] =
c19d1205
ZW
32263{
32264 {"softfpa", FPU_NONE},
32265 {"fpe", FPU_ARCH_FPE},
32266 {"fpe2", FPU_ARCH_FPE},
32267 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
32268 {"fpa", FPU_ARCH_FPA},
32269 {"fpa10", FPU_ARCH_FPA},
32270 {"fpa11", FPU_ARCH_FPA},
32271 {"arm7500fe", FPU_ARCH_FPA},
32272 {"softvfp", FPU_ARCH_VFP},
32273 {"softvfp+vfp", FPU_ARCH_VFP_V2},
32274 {"vfp", FPU_ARCH_VFP_V2},
32275 {"vfp9", FPU_ARCH_VFP_V2},
d5e0ba9c 32276 {"vfp3", FPU_ARCH_VFP_V3}, /* Undocumented, use vfpv3. */
c19d1205
ZW
32277 {"vfp10", FPU_ARCH_VFP_V2},
32278 {"vfp10-r0", FPU_ARCH_VFP_V1},
32279 {"vfpxd", FPU_ARCH_VFP_V1xD},
b1cc4aeb
PB
32280 {"vfpv2", FPU_ARCH_VFP_V2},
32281 {"vfpv3", FPU_ARCH_VFP_V3},
62f3b8c8 32282 {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16},
b1cc4aeb 32283 {"vfpv3-d16", FPU_ARCH_VFP_V3D16},
62f3b8c8
PB
32284 {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16},
32285 {"vfpv3xd", FPU_ARCH_VFP_V3xD},
32286 {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16},
c19d1205
ZW
32287 {"arm1020t", FPU_ARCH_VFP_V1},
32288 {"arm1020e", FPU_ARCH_VFP_V2},
d5e0ba9c 32289 {"arm1136jfs", FPU_ARCH_VFP_V2}, /* Undocumented, use arm1136jf-s. */
c19d1205
ZW
32290 {"arm1136jf-s", FPU_ARCH_VFP_V2},
32291 {"maverick", FPU_ARCH_MAVERICK},
d5e0ba9c 32292 {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
d3375ddd 32293 {"neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
8e79c3df 32294 {"neon-fp16", FPU_ARCH_NEON_FP16},
62f3b8c8
PB
32295 {"vfpv4", FPU_ARCH_VFP_V4},
32296 {"vfpv4-d16", FPU_ARCH_VFP_V4D16},
ada65aa3 32297 {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16},
a715796b
TG
32298 {"fpv5-d16", FPU_ARCH_VFP_V5D16},
32299 {"fpv5-sp-d16", FPU_ARCH_VFP_V5_SP_D16},
62f3b8c8 32300 {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4},
bca38921
MGD
32301 {"fp-armv8", FPU_ARCH_VFP_ARMV8},
32302 {"neon-fp-armv8", FPU_ARCH_NEON_VFP_ARMV8},
32303 {"crypto-neon-fp-armv8",
32304 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8},
d6b4b13e 32305 {"neon-fp-armv8.1", FPU_ARCH_NEON_VFP_ARMV8_1},
081e4c7d
MW
32306 {"crypto-neon-fp-armv8.1",
32307 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1},
e74cfd16
PB
32308 {NULL, ARM_ARCH_NONE}
32309};
32310
32311struct arm_option_value_table
32312{
e0471c16 32313 const char *name;
e74cfd16 32314 long value;
c19d1205 32315};
7ed4c4c5 32316
e74cfd16 32317static const struct arm_option_value_table arm_float_abis[] =
c19d1205
ZW
32318{
32319 {"hard", ARM_FLOAT_ABI_HARD},
32320 {"softfp", ARM_FLOAT_ABI_SOFTFP},
32321 {"soft", ARM_FLOAT_ABI_SOFT},
e74cfd16 32322 {NULL, 0}
c19d1205 32323};
7ed4c4c5 32324
c19d1205 32325#ifdef OBJ_ELF
3a4a14e9 32326/* We only know how to output GNU and ver 4/5 (AAELF) formats. */
e74cfd16 32327static const struct arm_option_value_table arm_eabis[] =
c19d1205
ZW
32328{
32329 {"gnu", EF_ARM_EABI_UNKNOWN},
32330 {"4", EF_ARM_EABI_VER4},
3a4a14e9 32331 {"5", EF_ARM_EABI_VER5},
e74cfd16 32332 {NULL, 0}
c19d1205
ZW
32333};
32334#endif
7ed4c4c5 32335
c19d1205
ZW
32336struct arm_long_option_table
32337{
5b7c81bd
AM
32338 const char *option; /* Substring to match. */
32339 const char *help; /* Help information. */
32340 bool (*func) (const char *subopt); /* Function to decode sub-option. */
32341 const char *deprecated; /* If non-null, print this message. */
c19d1205 32342};
7ed4c4c5 32343
5b7c81bd 32344static bool
c168ce07 32345arm_parse_extension (const char *str, const arm_feature_set *opt_set,
34ef62f4
AV
32346 arm_feature_set *ext_set,
32347 const struct arm_ext_table *ext_table)
7ed4c4c5 32348{
69133863 32349 /* We insist on extensions being specified in alphabetical order, and with
fa94de6b
RM
32350 extensions being added before being removed. We achieve this by having
32351 the global ARM_EXTENSIONS table in alphabetical order, and using the
69133863 32352 ADDING_VALUE variable to indicate whether we are adding an extension (1)
fa94de6b 32353 or removing it (0) and only allowing it to change in the order
69133863
MGD
32354 -1 -> 1 -> 0. */
32355 const struct arm_option_extension_value_table * opt = NULL;
d942732e 32356 const arm_feature_set arm_any = ARM_ANY;
69133863
MGD
32357 int adding_value = -1;
32358
c19d1205 32359 while (str != NULL && *str != 0)
7ed4c4c5 32360 {
82b8a785 32361 const char *ext;
f3bad469 32362 size_t len;
7ed4c4c5 32363
c19d1205
ZW
32364 if (*str != '+')
32365 {
32366 as_bad (_("invalid architectural extension"));
5b7c81bd 32367 return false;
c19d1205 32368 }
7ed4c4c5 32369
c19d1205
ZW
32370 str++;
32371 ext = strchr (str, '+');
7ed4c4c5 32372
c19d1205 32373 if (ext != NULL)
f3bad469 32374 len = ext - str;
c19d1205 32375 else
f3bad469 32376 len = strlen (str);
7ed4c4c5 32377
d34049e8 32378 if (len >= 2 && startswith (str, "no"))
69133863
MGD
32379 {
32380 if (adding_value != 0)
32381 {
32382 adding_value = 0;
32383 opt = arm_extensions;
32384 }
32385
f3bad469 32386 len -= 2;
69133863
MGD
32387 str += 2;
32388 }
f3bad469 32389 else if (len > 0)
69133863
MGD
32390 {
32391 if (adding_value == -1)
32392 {
32393 adding_value = 1;
32394 opt = arm_extensions;
32395 }
32396 else if (adding_value != 1)
32397 {
32398 as_bad (_("must specify extensions to add before specifying "
32399 "those to remove"));
5b7c81bd 32400 return false;
69133863
MGD
32401 }
32402 }
32403
f3bad469 32404 if (len == 0)
c19d1205
ZW
32405 {
32406 as_bad (_("missing architectural extension"));
5b7c81bd 32407 return false;
c19d1205 32408 }
7ed4c4c5 32409
69133863
MGD
32410 gas_assert (adding_value != -1);
32411 gas_assert (opt != NULL);
32412
34ef62f4
AV
32413 if (ext_table != NULL)
32414 {
32415 const struct arm_ext_table * ext_opt = ext_table;
5b7c81bd 32416 bool found = false;
34ef62f4
AV
32417 for (; ext_opt->name != NULL; ext_opt++)
32418 if (ext_opt->name_len == len
32419 && strncmp (ext_opt->name, str, len) == 0)
32420 {
32421 if (adding_value)
32422 {
32423 if (ARM_FEATURE_ZERO (ext_opt->merge))
32424 /* TODO: Option not supported. When we remove the
32425 legacy table this case should error out. */
32426 continue;
32427
32428 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, ext_opt->merge);
32429 }
32430 else
32431 {
32432 if (ARM_FEATURE_ZERO (ext_opt->clear))
32433 /* TODO: Option not supported. When we remove the
32434 legacy table this case should error out. */
32435 continue;
32436 ARM_CLEAR_FEATURE (*ext_set, *ext_set, ext_opt->clear);
32437 }
5b7c81bd 32438 found = true;
34ef62f4
AV
32439 break;
32440 }
32441 if (found)
32442 {
32443 str = ext;
32444 continue;
32445 }
32446 }
32447
69133863
MGD
32448 /* Scan over the options table trying to find an exact match. */
32449 for (; opt->name != NULL; opt++)
f3bad469 32450 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32451 {
d942732e
TP
32452 int i, nb_allowed_archs =
32453 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
69133863 32454 /* Check we can apply the extension to this architecture. */
d942732e
TP
32455 for (i = 0; i < nb_allowed_archs; i++)
32456 {
32457 /* Empty entry. */
32458 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
32459 continue;
c168ce07 32460 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set))
d942732e
TP
32461 break;
32462 }
32463 if (i == nb_allowed_archs)
69133863
MGD
32464 {
32465 as_bad (_("extension does not apply to the base architecture"));
5b7c81bd 32466 return false;
69133863
MGD
32467 }
32468
32469 /* Add or remove the extension. */
32470 if (adding_value)
4d354d8b 32471 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value);
69133863 32472 else
4d354d8b 32473 ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value);
69133863 32474
3d030cdb
TP
32475 /* Allowing Thumb division instructions for ARMv7 in autodetection
32476 rely on this break so that duplicate extensions (extensions
32477 with the same name as a previous extension in the list) are not
32478 considered for command-line parsing. */
c19d1205
ZW
32479 break;
32480 }
7ed4c4c5 32481
c19d1205
ZW
32482 if (opt->name == NULL)
32483 {
69133863
MGD
32484 /* Did we fail to find an extension because it wasn't specified in
32485 alphabetical order, or because it does not exist? */
32486
32487 for (opt = arm_extensions; opt->name != NULL; opt++)
f3bad469 32488 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
69133863
MGD
32489 break;
32490
32491 if (opt->name == NULL)
32492 as_bad (_("unknown architectural extension `%s'"), str);
32493 else
32494 as_bad (_("architectural extensions must be specified in "
32495 "alphabetical order"));
32496
5b7c81bd 32497 return false;
c19d1205 32498 }
69133863
MGD
32499 else
32500 {
32501 /* We should skip the extension we've just matched the next time
32502 round. */
32503 opt++;
32504 }
7ed4c4c5 32505
c19d1205
ZW
32506 str = ext;
32507 };
7ed4c4c5 32508
5b7c81bd 32509 return true;
c19d1205 32510}
7ed4c4c5 32511
5b7c81bd 32512static bool
5312fe52
BW
32513arm_parse_fp16_opt (const char *str)
32514{
32515 if (strcasecmp (str, "ieee") == 0)
32516 fp16_format = ARM_FP16_FORMAT_IEEE;
32517 else if (strcasecmp (str, "alternative") == 0)
32518 fp16_format = ARM_FP16_FORMAT_ALTERNATIVE;
32519 else
32520 {
32521 as_bad (_("unrecognised float16 format \"%s\""), str);
5b7c81bd 32522 return false;
5312fe52
BW
32523 }
32524
5b7c81bd 32525 return true;
5312fe52
BW
32526}
32527
5b7c81bd 32528static bool
17b9d67d 32529arm_parse_cpu (const char *str)
7ed4c4c5 32530{
f3bad469 32531 const struct arm_cpu_option_table *opt;
82b8a785 32532 const char *ext = strchr (str, '+');
f3bad469 32533 size_t len;
7ed4c4c5 32534
c19d1205 32535 if (ext != NULL)
f3bad469 32536 len = ext - str;
7ed4c4c5 32537 else
f3bad469 32538 len = strlen (str);
7ed4c4c5 32539
f3bad469 32540 if (len == 0)
7ed4c4c5 32541 {
c19d1205 32542 as_bad (_("missing cpu name `%s'"), str);
5b7c81bd 32543 return false;
7ed4c4c5
NC
32544 }
32545
c19d1205 32546 for (opt = arm_cpus; opt->name != NULL; opt++)
f3bad469 32547 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32548 {
c168ce07 32549 mcpu_cpu_opt = &opt->value;
4d354d8b
TP
32550 if (mcpu_ext_opt == NULL)
32551 mcpu_ext_opt = XNEW (arm_feature_set);
32552 *mcpu_ext_opt = opt->ext;
e74cfd16 32553 mcpu_fpu_opt = &opt->default_fpu;
ee065d83 32554 if (opt->canonical_name)
ef8e6722
JW
32555 {
32556 gas_assert (sizeof selected_cpu_name > strlen (opt->canonical_name));
32557 strcpy (selected_cpu_name, opt->canonical_name);
32558 }
ee065d83
PB
32559 else
32560 {
f3bad469 32561 size_t i;
c921be7d 32562
ef8e6722
JW
32563 if (len >= sizeof selected_cpu_name)
32564 len = (sizeof selected_cpu_name) - 1;
32565
f3bad469 32566 for (i = 0; i < len; i++)
ee065d83
PB
32567 selected_cpu_name[i] = TOUPPER (opt->name[i]);
32568 selected_cpu_name[i] = 0;
32569 }
7ed4c4c5 32570
c19d1205 32571 if (ext != NULL)
34ef62f4 32572 return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt, NULL);
7ed4c4c5 32573
5b7c81bd 32574 return true;
c19d1205 32575 }
7ed4c4c5 32576
c19d1205 32577 as_bad (_("unknown cpu `%s'"), str);
5b7c81bd 32578 return false;
7ed4c4c5
NC
32579}
32580
5b7c81bd 32581static bool
17b9d67d 32582arm_parse_arch (const char *str)
7ed4c4c5 32583{
e74cfd16 32584 const struct arm_arch_option_table *opt;
82b8a785 32585 const char *ext = strchr (str, '+');
f3bad469 32586 size_t len;
7ed4c4c5 32587
c19d1205 32588 if (ext != NULL)
f3bad469 32589 len = ext - str;
7ed4c4c5 32590 else
f3bad469 32591 len = strlen (str);
7ed4c4c5 32592
f3bad469 32593 if (len == 0)
7ed4c4c5 32594 {
c19d1205 32595 as_bad (_("missing architecture name `%s'"), str);
5b7c81bd 32596 return false;
7ed4c4c5
NC
32597 }
32598
c19d1205 32599 for (opt = arm_archs; opt->name != NULL; opt++)
f3bad469 32600 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32601 {
e74cfd16 32602 march_cpu_opt = &opt->value;
4d354d8b
TP
32603 if (march_ext_opt == NULL)
32604 march_ext_opt = XNEW (arm_feature_set);
32605 *march_ext_opt = arm_arch_none;
e74cfd16 32606 march_fpu_opt = &opt->default_fpu;
e20f9590 32607 selected_ctx_ext_table = opt->ext_table;
5f4273c7 32608 strcpy (selected_cpu_name, opt->name);
7ed4c4c5 32609
c19d1205 32610 if (ext != NULL)
34ef62f4
AV
32611 return arm_parse_extension (ext, march_cpu_opt, march_ext_opt,
32612 opt->ext_table);
7ed4c4c5 32613
5b7c81bd 32614 return true;
c19d1205
ZW
32615 }
32616
32617 as_bad (_("unknown architecture `%s'\n"), str);
5b7c81bd 32618 return false;
7ed4c4c5 32619}
eb043451 32620
5b7c81bd 32621static bool
17b9d67d 32622arm_parse_fpu (const char * str)
c19d1205 32623{
69133863 32624 const struct arm_option_fpu_value_table * opt;
b99bd4ef 32625
c19d1205
ZW
32626 for (opt = arm_fpus; opt->name != NULL; opt++)
32627 if (streq (opt->name, str))
32628 {
e74cfd16 32629 mfpu_opt = &opt->value;
5b7c81bd 32630 return true;
c19d1205 32631 }
b99bd4ef 32632
c19d1205 32633 as_bad (_("unknown floating point format `%s'\n"), str);
5b7c81bd 32634 return false;
c19d1205
ZW
32635}
32636
5b7c81bd 32637static bool
17b9d67d 32638arm_parse_float_abi (const char * str)
b99bd4ef 32639{
e74cfd16 32640 const struct arm_option_value_table * opt;
b99bd4ef 32641
c19d1205
ZW
32642 for (opt = arm_float_abis; opt->name != NULL; opt++)
32643 if (streq (opt->name, str))
32644 {
32645 mfloat_abi_opt = opt->value;
5b7c81bd 32646 return true;
c19d1205 32647 }
cc8a6dd0 32648
c19d1205 32649 as_bad (_("unknown floating point abi `%s'\n"), str);
5b7c81bd 32650 return false;
c19d1205 32651}
b99bd4ef 32652
c19d1205 32653#ifdef OBJ_ELF
5b7c81bd 32654static bool
17b9d67d 32655arm_parse_eabi (const char * str)
c19d1205 32656{
e74cfd16 32657 const struct arm_option_value_table *opt;
cc8a6dd0 32658
c19d1205
ZW
32659 for (opt = arm_eabis; opt->name != NULL; opt++)
32660 if (streq (opt->name, str))
32661 {
32662 meabi_flags = opt->value;
5b7c81bd 32663 return true;
c19d1205
ZW
32664 }
32665 as_bad (_("unknown EABI `%s'\n"), str);
5b7c81bd 32666 return false;
c19d1205
ZW
32667}
32668#endif
cc8a6dd0 32669
5b7c81bd 32670static bool
17b9d67d 32671arm_parse_it_mode (const char * str)
e07e6e58 32672{
5b7c81bd 32673 bool ret = true;
e07e6e58
NC
32674
32675 if (streq ("arm", str))
32676 implicit_it_mode = IMPLICIT_IT_MODE_ARM;
32677 else if (streq ("thumb", str))
32678 implicit_it_mode = IMPLICIT_IT_MODE_THUMB;
32679 else if (streq ("always", str))
32680 implicit_it_mode = IMPLICIT_IT_MODE_ALWAYS;
32681 else if (streq ("never", str))
32682 implicit_it_mode = IMPLICIT_IT_MODE_NEVER;
32683 else
32684 {
32685 as_bad (_("unknown implicit IT mode `%s', should be "\
477330fc 32686 "arm, thumb, always, or never."), str);
5b7c81bd 32687 ret = false;
e07e6e58
NC
32688 }
32689
32690 return ret;
32691}
32692
5b7c81bd 32693static bool
17b9d67d 32694arm_ccs_mode (const char * unused ATTRIBUTE_UNUSED)
2e6976a8 32695{
5b7c81bd 32696 codecomposer_syntax = true;
2e6976a8
DG
32697 arm_comment_chars[0] = ';';
32698 arm_line_separator_chars[0] = 0;
5b7c81bd 32699 return true;
2e6976a8
DG
32700}
32701
c19d1205
ZW
32702struct arm_long_option_table arm_long_opts[] =
32703{
32704 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
32705 arm_parse_cpu, NULL},
32706 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
32707 arm_parse_arch, NULL},
32708 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
32709 arm_parse_fpu, NULL},
32710 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
32711 arm_parse_float_abi, NULL},
32712#ifdef OBJ_ELF
7fac0536 32713 {"meabi=", N_("<ver>\t\t assemble for eabi version <ver>"),
c19d1205
ZW
32714 arm_parse_eabi, NULL},
32715#endif
e07e6e58
NC
32716 {"mimplicit-it=", N_("<mode>\t controls implicit insertion of IT instructions"),
32717 arm_parse_it_mode, NULL},
2e6976a8
DG
32718 {"mccs", N_("\t\t\t TI CodeComposer Studio syntax compatibility mode"),
32719 arm_ccs_mode, NULL},
5312fe52
BW
32720 {"mfp16-format=",
32721 N_("[ieee|alternative]\n\
32722 set the encoding for half precision floating point "
32723 "numbers to IEEE\n\
32724 or Arm alternative format."),
32725 arm_parse_fp16_opt, NULL },
c19d1205
ZW
32726 {NULL, NULL, 0, NULL}
32727};
cc8a6dd0 32728
c19d1205 32729int
17b9d67d 32730md_parse_option (int c, const char * arg)
c19d1205
ZW
32731{
32732 struct arm_option_table *opt;
e74cfd16 32733 const struct arm_legacy_option_table *fopt;
c19d1205 32734 struct arm_long_option_table *lopt;
b99bd4ef 32735
c19d1205 32736 switch (c)
b99bd4ef 32737 {
c19d1205
ZW
32738#ifdef OPTION_EB
32739 case OPTION_EB:
32740 target_big_endian = 1;
32741 break;
32742#endif
cc8a6dd0 32743
c19d1205
ZW
32744#ifdef OPTION_EL
32745 case OPTION_EL:
32746 target_big_endian = 0;
32747 break;
32748#endif
b99bd4ef 32749
845b51d6 32750 case OPTION_FIX_V4BX:
5b7c81bd 32751 fix_v4bx = true;
845b51d6
PB
32752 break;
32753
18a20338
CL
32754#ifdef OBJ_ELF
32755 case OPTION_FDPIC:
5b7c81bd 32756 arm_fdpic = true;
18a20338
CL
32757 break;
32758#endif /* OBJ_ELF */
32759
c19d1205
ZW
32760 case 'a':
32761 /* Listing option. Just ignore these, we don't support additional
32762 ones. */
32763 return 0;
b99bd4ef 32764
c19d1205
ZW
32765 default:
32766 for (opt = arm_opts; opt->option != NULL; opt++)
32767 {
32768 if (c == opt->option[0]
32769 && ((arg == NULL && opt->option[1] == 0)
32770 || streq (arg, opt->option + 1)))
32771 {
c19d1205 32772 /* If the option is deprecated, tell the user. */
278df34e 32773 if (warn_on_deprecated && opt->deprecated != NULL)
c19d1205
ZW
32774 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
32775 arg ? arg : "", _(opt->deprecated));
b99bd4ef 32776
c19d1205
ZW
32777 if (opt->var != NULL)
32778 *opt->var = opt->value;
cc8a6dd0 32779
c19d1205
ZW
32780 return 1;
32781 }
32782 }
b99bd4ef 32783
e74cfd16
PB
32784 for (fopt = arm_legacy_opts; fopt->option != NULL; fopt++)
32785 {
32786 if (c == fopt->option[0]
32787 && ((arg == NULL && fopt->option[1] == 0)
32788 || streq (arg, fopt->option + 1)))
32789 {
e74cfd16 32790 /* If the option is deprecated, tell the user. */
278df34e 32791 if (warn_on_deprecated && fopt->deprecated != NULL)
e74cfd16
PB
32792 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
32793 arg ? arg : "", _(fopt->deprecated));
e74cfd16
PB
32794
32795 if (fopt->var != NULL)
32796 *fopt->var = &fopt->value;
32797
32798 return 1;
32799 }
32800 }
32801
c19d1205
ZW
32802 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
32803 {
32804 /* These options are expected to have an argument. */
32805 if (c == lopt->option[0]
32806 && arg != NULL
32807 && strncmp (arg, lopt->option + 1,
32808 strlen (lopt->option + 1)) == 0)
32809 {
c19d1205 32810 /* If the option is deprecated, tell the user. */
278df34e 32811 if (warn_on_deprecated && lopt->deprecated != NULL)
c19d1205
ZW
32812 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
32813 _(lopt->deprecated));
b99bd4ef 32814
c19d1205
ZW
32815 /* Call the sup-option parser. */
32816 return lopt->func (arg + strlen (lopt->option) - 1);
32817 }
32818 }
a737bd4d 32819
c19d1205
ZW
32820 return 0;
32821 }
a394c00f 32822
c19d1205
ZW
32823 return 1;
32824}
a394c00f 32825
c19d1205
ZW
32826void
32827md_show_usage (FILE * fp)
a394c00f 32828{
c19d1205
ZW
32829 struct arm_option_table *opt;
32830 struct arm_long_option_table *lopt;
a394c00f 32831
c19d1205 32832 fprintf (fp, _(" ARM-specific assembler options:\n"));
a394c00f 32833
c19d1205
ZW
32834 for (opt = arm_opts; opt->option != NULL; opt++)
32835 if (opt->help != NULL)
32836 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
a394c00f 32837
c19d1205
ZW
32838 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
32839 if (lopt->help != NULL)
32840 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
a394c00f 32841
c19d1205
ZW
32842#ifdef OPTION_EB
32843 fprintf (fp, _("\
32844 -EB assemble code for a big-endian cpu\n"));
a394c00f
NC
32845#endif
32846
c19d1205
ZW
32847#ifdef OPTION_EL
32848 fprintf (fp, _("\
32849 -EL assemble code for a little-endian cpu\n"));
a737bd4d 32850#endif
845b51d6
PB
32851
32852 fprintf (fp, _("\
32853 --fix-v4bx Allow BX in ARMv4 code\n"));
18a20338
CL
32854
32855#ifdef OBJ_ELF
32856 fprintf (fp, _("\
32857 --fdpic generate an FDPIC object file\n"));
32858#endif /* OBJ_ELF */
c19d1205 32859}
ee065d83 32860
ee065d83 32861#ifdef OBJ_ELF
0198d5e6 32862
62b3e311
PB
32863typedef struct
32864{
32865 int val;
32866 arm_feature_set flags;
32867} cpu_arch_ver_table;
32868
2c6b98ea
TP
32869/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
32870 chronologically for architectures, with an exception for ARMv6-M and
32871 ARMv6S-M due to legacy reasons. No new architecture should have a
32872 special case. This allows for build attribute selection results to be
32873 stable when new architectures are added. */
62b3e311
PB
32874static const cpu_arch_ver_table cpu_arch_ver[] =
32875{
031254f2
AV
32876 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V1},
32877 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2},
32878 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2S},
32879 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3},
32880 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3M},
32881 {TAG_CPU_ARCH_V4, ARM_ARCH_V4xM},
32882 {TAG_CPU_ARCH_V4, ARM_ARCH_V4},
32883 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4TxM},
32884 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4T},
32885 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5xM},
32886 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5},
32887 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5TxM},
32888 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5T},
32889 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TExP},
32890 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TE},
32891 {TAG_CPU_ARCH_V5TEJ, ARM_ARCH_V5TEJ},
32892 {TAG_CPU_ARCH_V6, ARM_ARCH_V6},
32893 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6Z},
32894 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6KZ},
32895 {TAG_CPU_ARCH_V6K, ARM_ARCH_V6K},
32896 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6T2},
32897 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KT2},
32898 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6ZT2},
32899 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KZT2},
2c6b98ea
TP
32900
32901 /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
32902 always selected build attributes to match those of ARMv6-M
32903 (resp. ARMv6S-M). However, due to these architectures being a strict
32904 subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
32905 would be selected when fully respecting chronology of architectures.
32906 It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
32907 move them before ARMv7 architectures. */
031254f2
AV
32908 {TAG_CPU_ARCH_V6_M, ARM_ARCH_V6M},
32909 {TAG_CPU_ARCH_V6S_M, ARM_ARCH_V6SM},
32910
32911 {TAG_CPU_ARCH_V7, ARM_ARCH_V7},
32912 {TAG_CPU_ARCH_V7, ARM_ARCH_V7A},
32913 {TAG_CPU_ARCH_V7, ARM_ARCH_V7R},
32914 {TAG_CPU_ARCH_V7, ARM_ARCH_V7M},
32915 {TAG_CPU_ARCH_V7, ARM_ARCH_V7VE},
32916 {TAG_CPU_ARCH_V7E_M, ARM_ARCH_V7EM},
32917 {TAG_CPU_ARCH_V8, ARM_ARCH_V8A},
32918 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_1A},
32919 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_2A},
32920 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_3A},
32921 {TAG_CPU_ARCH_V8M_BASE, ARM_ARCH_V8M_BASE},
32922 {TAG_CPU_ARCH_V8M_MAIN, ARM_ARCH_V8M_MAIN},
32923 {TAG_CPU_ARCH_V8R, ARM_ARCH_V8R},
32924 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_4A},
32925 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_5A},
32926 {TAG_CPU_ARCH_V8_1M_MAIN, ARM_ARCH_V8_1M_MAIN},
aab2c27d 32927 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_6A},
b3e4d932
RS
32928 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_7A},
32929 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_8A},
3197e593 32930 {TAG_CPU_ARCH_V9, ARM_ARCH_V9A},
a2b1ea81
RS
32931 {TAG_CPU_ARCH_V9, ARM_ARCH_V9_1A},
32932 {TAG_CPU_ARCH_V9, ARM_ARCH_V9_2A},
32933 {TAG_CPU_ARCH_V9, ARM_ARCH_V9_3A},
aab2c27d 32934 {-1, ARM_ARCH_NONE}
62b3e311
PB
32935};
32936
ee3c0378 32937/* Set an attribute if it has not already been set by the user. */
0198d5e6 32938
ee3c0378
AS
32939static void
32940aeabi_set_attribute_int (int tag, int value)
32941{
32942 if (tag < 1
32943 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
32944 || !attributes_set_explicitly[tag])
32945 bfd_elf_add_proc_attr_int (stdoutput, tag, value);
32946}
32947
32948static void
32949aeabi_set_attribute_string (int tag, const char *value)
32950{
32951 if (tag < 1
32952 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
32953 || !attributes_set_explicitly[tag])
32954 bfd_elf_add_proc_attr_string (stdoutput, tag, value);
32955}
32956
2c6b98ea
TP
32957/* Return whether features in the *NEEDED feature set are available via
32958 extensions for the architecture whose feature set is *ARCH_FSET. */
0198d5e6 32959
5b7c81bd 32960static bool
2c6b98ea
TP
32961have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
32962 const arm_feature_set *needed)
32963{
32964 int i, nb_allowed_archs;
32965 arm_feature_set ext_fset;
32966 const struct arm_option_extension_value_table *opt;
32967
32968 ext_fset = arm_arch_none;
32969 for (opt = arm_extensions; opt->name != NULL; opt++)
32970 {
32971 /* Extension does not provide any feature we need. */
32972 if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
32973 continue;
32974
32975 nb_allowed_archs =
32976 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
32977 for (i = 0; i < nb_allowed_archs; i++)
32978 {
32979 /* Empty entry. */
32980 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
32981 break;
32982
32983 /* Extension is available, add it. */
32984 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
32985 ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
32986 }
32987 }
32988
32989 /* Can we enable all features in *needed? */
32990 return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
32991}
32992
32993/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
32994 a given architecture feature set *ARCH_EXT_FSET including extension feature
32995 set *EXT_FSET. Selection logic used depend on EXACT_MATCH:
32996 - if true, check for an exact match of the architecture modulo extensions;
32997 - otherwise, select build attribute value of the first superset
32998 architecture released so that results remains stable when new architectures
32999 are added.
33000 For -march/-mcpu=all the build attribute value of the most featureful
33001 architecture is returned. Tag_CPU_arch_profile result is returned in
33002 PROFILE. */
0198d5e6 33003
2c6b98ea
TP
33004static int
33005get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
33006 const arm_feature_set *ext_fset,
33007 char *profile, int exact_match)
33008{
33009 arm_feature_set arch_fset;
33010 const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
33011
33012 /* Select most featureful architecture with all its extensions if building
33013 for -march=all as the feature sets used to set build attributes. */
33014 if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
33015 {
33016 /* Force revisiting of decision for each new architecture. */
3197e593 33017 gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V9);
2c6b98ea 33018 *profile = 'A';
3197e593 33019 return TAG_CPU_ARCH_V9;
2c6b98ea
TP
33020 }
33021
33022 ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
33023
33024 for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
33025 {
33026 arm_feature_set known_arch_fset;
33027
33028 ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
33029 if (exact_match)
33030 {
33031 /* Base architecture match user-specified architecture and
33032 extensions, eg. ARMv6S-M matching -march=armv6-m+os. */
33033 if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
33034 {
33035 p_ver_ret = p_ver;
33036 goto found;
33037 }
33038 /* Base architecture match user-specified architecture only
33039 (eg. ARMv6-M in the same case as above). Record it in case we
33040 find a match with above condition. */
33041 else if (p_ver_ret == NULL
33042 && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
33043 p_ver_ret = p_ver;
33044 }
33045 else
33046 {
33047
33048 /* Architecture has all features wanted. */
33049 if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
33050 {
33051 arm_feature_set added_fset;
33052
33053 /* Compute features added by this architecture over the one
33054 recorded in p_ver_ret. */
33055 if (p_ver_ret != NULL)
33056 ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
33057 p_ver_ret->flags);
33058 /* First architecture that match incl. with extensions, or the
33059 only difference in features over the recorded match is
33060 features that were optional and are now mandatory. */
33061 if (p_ver_ret == NULL
33062 || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
33063 {
33064 p_ver_ret = p_ver;
33065 goto found;
33066 }
33067 }
33068 else if (p_ver_ret == NULL)
33069 {
33070 arm_feature_set needed_ext_fset;
33071
33072 ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
33073
33074 /* Architecture has all features needed when using some
33075 extensions. Record it and continue searching in case there
33076 exist an architecture providing all needed features without
33077 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
33078 OS extension). */
33079 if (have_ext_for_needed_feat_p (&known_arch_fset,
33080 &needed_ext_fset))
33081 p_ver_ret = p_ver;
33082 }
33083 }
33084 }
33085
33086 if (p_ver_ret == NULL)
33087 return -1;
33088
dc1e8a47 33089 found:
2c6b98ea 33090 /* Tag_CPU_arch_profile. */
164446e0
AF
33091 if (!ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8r)
33092 && (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
33093 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
33094 || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
33095 && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only))))
2c6b98ea 33096 *profile = 'A';
164446e0
AF
33097 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r)
33098 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8r))
2c6b98ea
TP
33099 *profile = 'R';
33100 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
33101 *profile = 'M';
33102 else
33103 *profile = '\0';
33104 return p_ver_ret->val;
33105}
33106
ee065d83 33107/* Set the public EABI object attributes. */
0198d5e6 33108
c168ce07 33109static void
ee065d83
PB
33110aeabi_set_public_attributes (void)
33111{
b90d5ba0 33112 char profile = '\0';
2c6b98ea 33113 int arch = -1;
90ec0d68 33114 int virt_sec = 0;
bca38921 33115 int fp16_optional = 0;
2c6b98ea
TP
33116 int skip_exact_match = 0;
33117 arm_feature_set flags, flags_arch, flags_ext;
ee065d83 33118
54bab281
TP
33119 /* Autodetection mode, choose the architecture based the instructions
33120 actually used. */
33121 if (no_cpu_selected ())
33122 {
33123 ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
ddd7f988 33124
54bab281
TP
33125 if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
33126 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
ddd7f988 33127
54bab281
TP
33128 if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
33129 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
ddd7f988 33130
54bab281 33131 /* Code run during relaxation relies on selected_cpu being set. */
4d354d8b
TP
33132 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
33133 flags_ext = arm_arch_none;
33134 ARM_CLEAR_FEATURE (selected_arch, flags_arch, flags_ext);
33135 selected_ext = flags_ext;
54bab281
TP
33136 selected_cpu = flags;
33137 }
33138 /* Otherwise, choose the architecture based on the capabilities of the
33139 requested cpu. */
33140 else
4d354d8b
TP
33141 {
33142 ARM_MERGE_FEATURE_SETS (flags_arch, selected_arch, selected_ext);
33143 ARM_CLEAR_FEATURE (flags_arch, flags_arch, fpu_any);
33144 flags_ext = selected_ext;
33145 flags = selected_cpu;
33146 }
33147 ARM_MERGE_FEATURE_SETS (flags, flags, selected_fpu);
7f78eb34 33148
ddd7f988 33149 /* Allow the user to override the reported architecture. */
4d354d8b 33150 if (!ARM_FEATURE_ZERO (selected_object_arch))
7a1d4c38 33151 {
4d354d8b 33152 ARM_CLEAR_FEATURE (flags_arch, selected_object_arch, fpu_any);
2c6b98ea 33153 flags_ext = arm_arch_none;
7a1d4c38 33154 }
2c6b98ea 33155 else
4d354d8b 33156 skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
2c6b98ea
TP
33157
33158 /* When this function is run again after relaxation has happened there is no
33159 way to determine whether an architecture or CPU was specified by the user:
33160 - selected_cpu is set above for relaxation to work;
33161 - march_cpu_opt is not set if only -mcpu or .cpu is used;
33162 - mcpu_cpu_opt is set to arm_arch_any for autodetection.
33163 Therefore, if not in -march=all case we first try an exact match and fall
33164 back to autodetection. */
33165 if (!skip_exact_match)
33166 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
33167 if (arch == -1)
33168 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
33169 if (arch == -1)
33170 as_bad (_("no architecture contains all the instructions used\n"));
9e3c6df6 33171
ee065d83
PB
33172 /* Tag_CPU_name. */
33173 if (selected_cpu_name[0])
33174 {
91d6fa6a 33175 char *q;
ee065d83 33176
91d6fa6a 33177 q = selected_cpu_name;
d34049e8 33178 if (startswith (q, "armv"))
ee065d83
PB
33179 {
33180 int i;
5f4273c7 33181
91d6fa6a
NC
33182 q += 4;
33183 for (i = 0; q[i]; i++)
33184 q[i] = TOUPPER (q[i]);
ee065d83 33185 }
91d6fa6a 33186 aeabi_set_attribute_string (Tag_CPU_name, q);
ee065d83 33187 }
62f3b8c8 33188
ee065d83 33189 /* Tag_CPU_arch. */
ee3c0378 33190 aeabi_set_attribute_int (Tag_CPU_arch, arch);
62f3b8c8 33191
62b3e311 33192 /* Tag_CPU_arch_profile. */
69239280
MGD
33193 if (profile != '\0')
33194 aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
62f3b8c8 33195
15afaa63 33196 /* Tag_DSP_extension. */
4d354d8b 33197 if (ARM_CPU_HAS_FEATURE (selected_ext, arm_ext_dsp))
6c290d53 33198 aeabi_set_attribute_int (Tag_DSP_extension, 1);
15afaa63 33199
2c6b98ea 33200 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
ee065d83 33201 /* Tag_ARM_ISA_use. */
ee3c0378 33202 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
2c6b98ea 33203 || ARM_FEATURE_ZERO (flags_arch))
ee3c0378 33204 aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
62f3b8c8 33205
ee065d83 33206 /* Tag_THUMB_ISA_use. */
ee3c0378 33207 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
2c6b98ea 33208 || ARM_FEATURE_ZERO (flags_arch))
4ed7ed8d
TP
33209 {
33210 int thumb_isa_use;
33211
33212 if (!ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
16a1fa25 33213 && ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only))
4ed7ed8d
TP
33214 thumb_isa_use = 3;
33215 else if (ARM_CPU_HAS_FEATURE (flags, arm_arch_t2))
33216 thumb_isa_use = 2;
33217 else
33218 thumb_isa_use = 1;
33219 aeabi_set_attribute_int (Tag_THUMB_ISA_use, thumb_isa_use);
33220 }
62f3b8c8 33221
ee065d83 33222 /* Tag_VFP_arch. */
a715796b
TG
33223 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_armv8xd))
33224 aeabi_set_attribute_int (Tag_VFP_arch,
33225 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
33226 ? 7 : 8);
bca38921 33227 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_fma))
62f3b8c8
PB
33228 aeabi_set_attribute_int (Tag_VFP_arch,
33229 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
33230 ? 5 : 6);
33231 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32))
bca38921
MGD
33232 {
33233 fp16_optional = 1;
33234 aeabi_set_attribute_int (Tag_VFP_arch, 3);
33235 }
ada65aa3 33236 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v3xd))
bca38921
MGD
33237 {
33238 aeabi_set_attribute_int (Tag_VFP_arch, 4);
33239 fp16_optional = 1;
33240 }
ee3c0378
AS
33241 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v2))
33242 aeabi_set_attribute_int (Tag_VFP_arch, 2);
33243 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1)
477330fc 33244 || ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd))
ee3c0378 33245 aeabi_set_attribute_int (Tag_VFP_arch, 1);
62f3b8c8 33246
4547cb56
NC
33247 /* Tag_ABI_HardFP_use. */
33248 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd)
33249 && !ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1))
33250 aeabi_set_attribute_int (Tag_ABI_HardFP_use, 1);
33251
ee065d83 33252 /* Tag_WMMX_arch. */
ee3c0378
AS
33253 if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt2))
33254 aeabi_set_attribute_int (Tag_WMMX_arch, 2);
33255 else if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt))
33256 aeabi_set_attribute_int (Tag_WMMX_arch, 1);
62f3b8c8 33257
ee3c0378 33258 /* Tag_Advanced_SIMD_arch (formerly Tag_NEON_arch). */
9411fd44
MW
33259 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v8_1))
33260 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 4);
33261 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_armv8))
bca38921
MGD
33262 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 3);
33263 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v1))
33264 {
33265 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_fma))
33266 {
33267 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 2);
33268 }
33269 else
33270 {
33271 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 1);
33272 fp16_optional = 1;
33273 }
33274 }
fa94de6b 33275
a7ad558c
AV
33276 if (ARM_CPU_HAS_FEATURE (flags, mve_fp_ext))
33277 aeabi_set_attribute_int (Tag_MVE_arch, 2);
33278 else if (ARM_CPU_HAS_FEATURE (flags, mve_ext))
33279 aeabi_set_attribute_int (Tag_MVE_arch, 1);
33280
ee3c0378 33281 /* Tag_VFP_HP_extension (formerly Tag_NEON_FP16_arch). */
bca38921 33282 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_fp16) && fp16_optional)
ee3c0378 33283 aeabi_set_attribute_int (Tag_VFP_HP_extension, 1);
4547cb56 33284
69239280
MGD
33285 /* Tag_DIV_use.
33286
33287 We set Tag_DIV_use to two when integer divide instructions have been used
33288 in ARM state, or when Thumb integer divide instructions have been used,
33289 but we have no architecture profile set, nor have we any ARM instructions.
33290
4ed7ed8d
TP
33291 For ARMv8-A and ARMv8-M we set the tag to 0 as integer divide is implied
33292 by the base architecture.
bca38921 33293
69239280 33294 For new architectures we will have to check these tests. */
3197e593 33295 gas_assert (arch <= TAG_CPU_ARCH_V9);
4ed7ed8d
TP
33296 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
33297 || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
bca38921
MGD
33298 aeabi_set_attribute_int (Tag_DIV_use, 0);
33299 else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_adiv)
33300 || (profile == '\0'
33301 && ARM_CPU_HAS_FEATURE (flags, arm_ext_div)
33302 && !ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any)))
eea54501 33303 aeabi_set_attribute_int (Tag_DIV_use, 2);
60e5ef9f
MGD
33304
33305 /* Tag_MP_extension_use. */
33306 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_mp))
33307 aeabi_set_attribute_int (Tag_MPextension_use, 1);
f4c65163
MGD
33308
33309 /* Tag Virtualization_use. */
33310 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_sec))
90ec0d68
MGD
33311 virt_sec |= 1;
33312 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_virt))
33313 virt_sec |= 2;
33314 if (virt_sec != 0)
33315 aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
5312fe52
BW
33316
33317 if (fp16_format != ARM_FP16_FORMAT_DEFAULT)
33318 aeabi_set_attribute_int (Tag_ABI_FP_16bit_format, fp16_format);
ee065d83
PB
33319}
33320
c168ce07
TP
33321/* Post relaxation hook. Recompute ARM attributes now that relaxation is
33322 finished and free extension feature bits which will not be used anymore. */
0198d5e6 33323
c168ce07
TP
33324void
33325arm_md_post_relax (void)
33326{
33327 aeabi_set_public_attributes ();
4d354d8b
TP
33328 XDELETE (mcpu_ext_opt);
33329 mcpu_ext_opt = NULL;
33330 XDELETE (march_ext_opt);
33331 march_ext_opt = NULL;
c168ce07
TP
33332}
33333
104d59d1 33334/* Add the default contents for the .ARM.attributes section. */
0198d5e6 33335
ee065d83
PB
33336void
33337arm_md_end (void)
33338{
ee065d83
PB
33339 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
33340 return;
33341
33342 aeabi_set_public_attributes ();
ee065d83 33343}
8463be01 33344#endif /* OBJ_ELF */
ee065d83 33345
ee065d83
PB
33346/* Parse a .cpu directive. */
33347
33348static void
33349s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
33350{
e74cfd16 33351 const struct arm_cpu_option_table *opt;
ee065d83
PB
33352 char *name;
33353 char saved_char;
33354
33355 name = input_line_pointer;
5f4273c7 33356 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
33357 input_line_pointer++;
33358 saved_char = *input_line_pointer;
33359 *input_line_pointer = 0;
33360
33361 /* Skip the first "all" entry. */
33362 for (opt = arm_cpus + 1; opt->name != NULL; opt++)
33363 if (streq (opt->name, name))
33364 {
4d354d8b
TP
33365 selected_arch = opt->value;
33366 selected_ext = opt->ext;
33367 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
ee065d83 33368 if (opt->canonical_name)
5f4273c7 33369 strcpy (selected_cpu_name, opt->canonical_name);
ee065d83
PB
33370 else
33371 {
33372 int i;
33373 for (i = 0; opt->name[i]; i++)
33374 selected_cpu_name[i] = TOUPPER (opt->name[i]);
f3bad469 33375
ee065d83
PB
33376 selected_cpu_name[i] = 0;
33377 }
4d354d8b
TP
33378 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
33379
ee065d83
PB
33380 *input_line_pointer = saved_char;
33381 demand_empty_rest_of_line ();
33382 return;
33383 }
33384 as_bad (_("unknown cpu `%s'"), name);
33385 *input_line_pointer = saved_char;
33386 ignore_rest_of_line ();
33387}
33388
ee065d83
PB
33389/* Parse a .arch directive. */
33390
33391static void
33392s_arm_arch (int ignored ATTRIBUTE_UNUSED)
33393{
e74cfd16 33394 const struct arm_arch_option_table *opt;
ee065d83
PB
33395 char saved_char;
33396 char *name;
33397
33398 name = input_line_pointer;
5f4273c7 33399 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
33400 input_line_pointer++;
33401 saved_char = *input_line_pointer;
33402 *input_line_pointer = 0;
33403
33404 /* Skip the first "all" entry. */
33405 for (opt = arm_archs + 1; opt->name != NULL; opt++)
33406 if (streq (opt->name, name))
33407 {
4d354d8b 33408 selected_arch = opt->value;
0e7aaa72 33409 selected_ctx_ext_table = opt->ext_table;
4d354d8b
TP
33410 selected_ext = arm_arch_none;
33411 selected_cpu = selected_arch;
5f4273c7 33412 strcpy (selected_cpu_name, opt->name);
4d354d8b 33413 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
33414 *input_line_pointer = saved_char;
33415 demand_empty_rest_of_line ();
33416 return;
33417 }
33418
33419 as_bad (_("unknown architecture `%s'\n"), name);
33420 *input_line_pointer = saved_char;
33421 ignore_rest_of_line ();
33422}
33423
7a1d4c38
PB
33424/* Parse a .object_arch directive. */
33425
33426static void
33427s_arm_object_arch (int ignored ATTRIBUTE_UNUSED)
33428{
33429 const struct arm_arch_option_table *opt;
33430 char saved_char;
33431 char *name;
33432
33433 name = input_line_pointer;
5f4273c7 33434 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
7a1d4c38
PB
33435 input_line_pointer++;
33436 saved_char = *input_line_pointer;
33437 *input_line_pointer = 0;
33438
33439 /* Skip the first "all" entry. */
33440 for (opt = arm_archs + 1; opt->name != NULL; opt++)
33441 if (streq (opt->name, name))
33442 {
4d354d8b 33443 selected_object_arch = opt->value;
7a1d4c38
PB
33444 *input_line_pointer = saved_char;
33445 demand_empty_rest_of_line ();
33446 return;
33447 }
33448
33449 as_bad (_("unknown architecture `%s'\n"), name);
33450 *input_line_pointer = saved_char;
33451 ignore_rest_of_line ();
33452}
33453
69133863
MGD
33454/* Parse a .arch_extension directive. */
33455
33456static void
33457s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
33458{
33459 const struct arm_option_extension_value_table *opt;
33460 char saved_char;
33461 char *name;
33462 int adding_value = 1;
33463
33464 name = input_line_pointer;
33465 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
33466 input_line_pointer++;
33467 saved_char = *input_line_pointer;
33468 *input_line_pointer = 0;
33469
33470 if (strlen (name) >= 2
d34049e8 33471 && startswith (name, "no"))
69133863
MGD
33472 {
33473 adding_value = 0;
33474 name += 2;
33475 }
33476
e20f9590
MI
33477 /* Check the context specific extension table */
33478 if (selected_ctx_ext_table)
33479 {
33480 const struct arm_ext_table * ext_opt;
33481 for (ext_opt = selected_ctx_ext_table; ext_opt->name != NULL; ext_opt++)
33482 {
33483 if (streq (ext_opt->name, name))
33484 {
33485 if (adding_value)
33486 {
33487 if (ARM_FEATURE_ZERO (ext_opt->merge))
33488 /* TODO: Option not supported. When we remove the
33489 legacy table this case should error out. */
33490 continue;
33491 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
33492 ext_opt->merge);
33493 }
33494 else
33495 ARM_CLEAR_FEATURE (selected_ext, selected_ext, ext_opt->clear);
33496
33497 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
33498 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
33499 *input_line_pointer = saved_char;
33500 demand_empty_rest_of_line ();
33501 return;
33502 }
33503 }
33504 }
33505
69133863
MGD
33506 for (opt = arm_extensions; opt->name != NULL; opt++)
33507 if (streq (opt->name, name))
33508 {
d942732e
TP
33509 int i, nb_allowed_archs =
33510 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[i]);
33511 for (i = 0; i < nb_allowed_archs; i++)
33512 {
33513 /* Empty entry. */
4d354d8b 33514 if (ARM_CPU_IS_ANY (opt->allowed_archs[i]))
d942732e 33515 continue;
4d354d8b 33516 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], selected_arch))
d942732e
TP
33517 break;
33518 }
33519
33520 if (i == nb_allowed_archs)
69133863
MGD
33521 {
33522 as_bad (_("architectural extension `%s' is not allowed for the "
33523 "current base architecture"), name);
33524 break;
33525 }
33526
33527 if (adding_value)
4d354d8b 33528 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
5a70a223 33529 opt->merge_value);
69133863 33530 else
4d354d8b 33531 ARM_CLEAR_FEATURE (selected_ext, selected_ext, opt->clear_value);
69133863 33532
4d354d8b
TP
33533 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
33534 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
69133863
MGD
33535 *input_line_pointer = saved_char;
33536 demand_empty_rest_of_line ();
3d030cdb
TP
33537 /* Allowing Thumb division instructions for ARMv7 in autodetection rely
33538 on this return so that duplicate extensions (extensions with the
33539 same name as a previous extension in the list) are not considered
33540 for command-line parsing. */
69133863
MGD
33541 return;
33542 }
33543
33544 if (opt->name == NULL)
e673710a 33545 as_bad (_("unknown architecture extension `%s'\n"), name);
69133863
MGD
33546
33547 *input_line_pointer = saved_char;
33548 ignore_rest_of_line ();
33549}
33550
ee065d83
PB
33551/* Parse a .fpu directive. */
33552
33553static void
33554s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
33555{
69133863 33556 const struct arm_option_fpu_value_table *opt;
ee065d83
PB
33557 char saved_char;
33558 char *name;
33559
33560 name = input_line_pointer;
5f4273c7 33561 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
33562 input_line_pointer++;
33563 saved_char = *input_line_pointer;
33564 *input_line_pointer = 0;
5f4273c7 33565
ee065d83
PB
33566 for (opt = arm_fpus; opt->name != NULL; opt++)
33567 if (streq (opt->name, name))
33568 {
4d354d8b 33569 selected_fpu = opt->value;
f4399880 33570 ARM_CLEAR_FEATURE (selected_cpu, selected_cpu, fpu_any);
4d354d8b
TP
33571#ifndef CPU_DEFAULT
33572 if (no_cpu_selected ())
33573 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
33574 else
33575#endif
33576 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
33577 *input_line_pointer = saved_char;
33578 demand_empty_rest_of_line ();
33579 return;
33580 }
33581
33582 as_bad (_("unknown floating point format `%s'\n"), name);
33583 *input_line_pointer = saved_char;
33584 ignore_rest_of_line ();
33585}
ee065d83 33586
794ba86a 33587/* Copy symbol information. */
f31fef98 33588
794ba86a
DJ
33589void
33590arm_copy_symbol_attributes (symbolS *dest, symbolS *src)
33591{
33592 ARM_GET_FLAG (dest) = ARM_GET_FLAG (src);
33593}
e04befd0 33594
f31fef98 33595#ifdef OBJ_ELF
e04befd0
AS
33596/* Given a symbolic attribute NAME, return the proper integer value.
33597 Returns -1 if the attribute is not known. */
f31fef98 33598
e04befd0
AS
33599int
33600arm_convert_symbolic_attribute (const char *name)
33601{
f31fef98
NC
33602 static const struct
33603 {
33604 const char * name;
33605 const int tag;
33606 }
33607 attribute_table[] =
33608 {
33609 /* When you modify this table you should
33610 also modify the list in doc/c-arm.texi. */
e04befd0 33611#define T(tag) {#tag, tag}
f31fef98
NC
33612 T (Tag_CPU_raw_name),
33613 T (Tag_CPU_name),
33614 T (Tag_CPU_arch),
33615 T (Tag_CPU_arch_profile),
33616 T (Tag_ARM_ISA_use),
33617 T (Tag_THUMB_ISA_use),
75375b3e 33618 T (Tag_FP_arch),
f31fef98
NC
33619 T (Tag_VFP_arch),
33620 T (Tag_WMMX_arch),
33621 T (Tag_Advanced_SIMD_arch),
33622 T (Tag_PCS_config),
33623 T (Tag_ABI_PCS_R9_use),
33624 T (Tag_ABI_PCS_RW_data),
33625 T (Tag_ABI_PCS_RO_data),
33626 T (Tag_ABI_PCS_GOT_use),
33627 T (Tag_ABI_PCS_wchar_t),
33628 T (Tag_ABI_FP_rounding),
33629 T (Tag_ABI_FP_denormal),
33630 T (Tag_ABI_FP_exceptions),
33631 T (Tag_ABI_FP_user_exceptions),
33632 T (Tag_ABI_FP_number_model),
75375b3e 33633 T (Tag_ABI_align_needed),
f31fef98 33634 T (Tag_ABI_align8_needed),
75375b3e 33635 T (Tag_ABI_align_preserved),
f31fef98
NC
33636 T (Tag_ABI_align8_preserved),
33637 T (Tag_ABI_enum_size),
33638 T (Tag_ABI_HardFP_use),
33639 T (Tag_ABI_VFP_args),
33640 T (Tag_ABI_WMMX_args),
33641 T (Tag_ABI_optimization_goals),
33642 T (Tag_ABI_FP_optimization_goals),
33643 T (Tag_compatibility),
33644 T (Tag_CPU_unaligned_access),
75375b3e 33645 T (Tag_FP_HP_extension),
f31fef98
NC
33646 T (Tag_VFP_HP_extension),
33647 T (Tag_ABI_FP_16bit_format),
cd21e546
MGD
33648 T (Tag_MPextension_use),
33649 T (Tag_DIV_use),
f31fef98
NC
33650 T (Tag_nodefaults),
33651 T (Tag_also_compatible_with),
33652 T (Tag_conformance),
33653 T (Tag_T2EE_use),
33654 T (Tag_Virtualization_use),
15afaa63 33655 T (Tag_DSP_extension),
a7ad558c 33656 T (Tag_MVE_arch),
99db83d0 33657 T (Tag_PAC_extension),
4b535030 33658 T (Tag_BTI_extension),
b81ee92f 33659 T (Tag_BTI_use),
c9fed665 33660 T (Tag_PACRET_use),
cd21e546 33661 /* We deliberately do not include Tag_MPextension_use_legacy. */
e04befd0 33662#undef T
f31fef98 33663 };
e04befd0
AS
33664 unsigned int i;
33665
33666 if (name == NULL)
33667 return -1;
33668
f31fef98 33669 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
c921be7d 33670 if (streq (name, attribute_table[i].name))
e04befd0
AS
33671 return attribute_table[i].tag;
33672
33673 return -1;
33674}
267bf995 33675
93ef582d
NC
33676/* Apply sym value for relocations only in the case that they are for
33677 local symbols in the same segment as the fixup and you have the
33678 respective architectural feature for blx and simple switches. */
0198d5e6 33679
267bf995 33680int
93ef582d 33681arm_apply_sym_value (struct fix * fixP, segT this_seg)
267bf995
RR
33682{
33683 if (fixP->fx_addsy
33684 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
93ef582d
NC
33685 /* PR 17444: If the local symbol is in a different section then a reloc
33686 will always be generated for it, so applying the symbol value now
33687 will result in a double offset being stored in the relocation. */
33688 && (S_GET_SEGMENT (fixP->fx_addsy) == this_seg)
5b7c81bd 33689 && !S_FORCE_RELOC (fixP->fx_addsy, true))
267bf995
RR
33690 {
33691 switch (fixP->fx_r_type)
33692 {
33693 case BFD_RELOC_ARM_PCREL_BLX:
33694 case BFD_RELOC_THUMB_PCREL_BRANCH23:
33695 if (ARM_IS_FUNC (fixP->fx_addsy))
33696 return 1;
33697 break;
33698
33699 case BFD_RELOC_ARM_PCREL_CALL:
33700 case BFD_RELOC_THUMB_PCREL_BLX:
33701 if (THUMB_IS_FUNC (fixP->fx_addsy))
93ef582d 33702 return 1;
267bf995
RR
33703 break;
33704
33705 default:
33706 break;
33707 }
33708
33709 }
33710 return 0;
33711}
f31fef98 33712#endif /* OBJ_ELF */