]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-arm.c
Fix whitespace snafu in tc-riscv.c
[thirdparty/binutils-gdb.git] / gas / config / tc-arm.c
CommitLineData
b99bd4ef 1/* tc-arm.c -- Assemble for the ARM
d87bef3a 2 Copyright (C) 1994-2023 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
3a368c4c 745#define REG_RA_AUTH_CODE 143
404ff6b5 746
b99bd4ef
NC
747/* ARM instructions take 4bytes in the object file, Thumb instructions
748 take 2: */
c19d1205 749#define INSN_SIZE 4
b99bd4ef
NC
750
751struct asm_opcode
752{
753 /* Basic string to match. */
d3ce72d0 754 const char * template_name;
c19d1205
ZW
755
756 /* Parameters to instruction. */
5be8be5d 757 unsigned int operands[8];
c19d1205
ZW
758
759 /* Conditional tag - see opcode_lookup. */
760 unsigned int tag : 4;
b99bd4ef
NC
761
762 /* Basic instruction code. */
a302e574 763 unsigned int avalue;
b99bd4ef 764
c19d1205
ZW
765 /* Thumb-format instruction code. */
766 unsigned int tvalue;
b99bd4ef 767
90e4755a 768 /* Which architecture variant provides this instruction. */
c921be7d
NC
769 const arm_feature_set * avariant;
770 const arm_feature_set * tvariant;
c19d1205
ZW
771
772 /* Function to call to encode instruction in ARM format. */
773 void (* aencode) (void);
b99bd4ef 774
c19d1205
ZW
775 /* Function to call to encode instruction in Thumb format. */
776 void (* tencode) (void);
5ee91343
AV
777
778 /* Indicates whether this instruction may be vector predicated. */
779 unsigned int mayBeVecPred : 1;
b99bd4ef
NC
780};
781
a737bd4d
NC
782/* Defines for various bits that we will want to toggle. */
783#define INST_IMMEDIATE 0x02000000
784#define OFFSET_REG 0x02000000
c19d1205 785#define HWOFFSET_IMM 0x00400000
a737bd4d
NC
786#define SHIFT_BY_REG 0x00000010
787#define PRE_INDEX 0x01000000
788#define INDEX_UP 0x00800000
789#define WRITE_BACK 0x00200000
790#define LDM_TYPE_2_OR_3 0x00400000
a028a6f5 791#define CPSI_MMOD 0x00020000
90e4755a 792
a737bd4d
NC
793#define LITERAL_MASK 0xf000f000
794#define OPCODE_MASK 0xfe1fffff
795#define V4_STR_BIT 0x00000020
8335d6aa 796#define VLDR_VMOV_SAME 0x0040f000
90e4755a 797
efd81785
PB
798#define T2_SUBS_PC_LR 0xf3de8f00
799
a737bd4d 800#define DATA_OP_SHIFT 21
bada4342 801#define SBIT_SHIFT 20
90e4755a 802
ef8d22e6
PB
803#define T2_OPCODE_MASK 0xfe1fffff
804#define T2_DATA_OP_SHIFT 21
bada4342 805#define T2_SBIT_SHIFT 20
ef8d22e6 806
6530b175
NC
807#define A_COND_MASK 0xf0000000
808#define A_PUSH_POP_OP_MASK 0x0fff0000
809
810/* Opcodes for pushing/poping registers to/from the stack. */
811#define A1_OPCODE_PUSH 0x092d0000
812#define A2_OPCODE_PUSH 0x052d0004
813#define A2_OPCODE_POP 0x049d0004
814
a737bd4d
NC
815/* Codes to distinguish the arithmetic instructions. */
816#define OPCODE_AND 0
817#define OPCODE_EOR 1
818#define OPCODE_SUB 2
819#define OPCODE_RSB 3
820#define OPCODE_ADD 4
821#define OPCODE_ADC 5
822#define OPCODE_SBC 6
823#define OPCODE_RSC 7
824#define OPCODE_TST 8
825#define OPCODE_TEQ 9
826#define OPCODE_CMP 10
827#define OPCODE_CMN 11
828#define OPCODE_ORR 12
829#define OPCODE_MOV 13
830#define OPCODE_BIC 14
831#define OPCODE_MVN 15
90e4755a 832
ef8d22e6
PB
833#define T2_OPCODE_AND 0
834#define T2_OPCODE_BIC 1
835#define T2_OPCODE_ORR 2
836#define T2_OPCODE_ORN 3
837#define T2_OPCODE_EOR 4
838#define T2_OPCODE_ADD 8
839#define T2_OPCODE_ADC 10
840#define T2_OPCODE_SBC 11
841#define T2_OPCODE_SUB 13
842#define T2_OPCODE_RSB 14
843
a737bd4d
NC
844#define T_OPCODE_MUL 0x4340
845#define T_OPCODE_TST 0x4200
846#define T_OPCODE_CMN 0x42c0
847#define T_OPCODE_NEG 0x4240
848#define T_OPCODE_MVN 0x43c0
90e4755a 849
a737bd4d
NC
850#define T_OPCODE_ADD_R3 0x1800
851#define T_OPCODE_SUB_R3 0x1a00
852#define T_OPCODE_ADD_HI 0x4400
853#define T_OPCODE_ADD_ST 0xb000
854#define T_OPCODE_SUB_ST 0xb080
855#define T_OPCODE_ADD_SP 0xa800
856#define T_OPCODE_ADD_PC 0xa000
857#define T_OPCODE_ADD_I8 0x3000
858#define T_OPCODE_SUB_I8 0x3800
859#define T_OPCODE_ADD_I3 0x1c00
860#define T_OPCODE_SUB_I3 0x1e00
b99bd4ef 861
a737bd4d
NC
862#define T_OPCODE_ASR_R 0x4100
863#define T_OPCODE_LSL_R 0x4080
c19d1205
ZW
864#define T_OPCODE_LSR_R 0x40c0
865#define T_OPCODE_ROR_R 0x41c0
a737bd4d
NC
866#define T_OPCODE_ASR_I 0x1000
867#define T_OPCODE_LSL_I 0x0000
868#define T_OPCODE_LSR_I 0x0800
b99bd4ef 869
a737bd4d
NC
870#define T_OPCODE_MOV_I8 0x2000
871#define T_OPCODE_CMP_I8 0x2800
872#define T_OPCODE_CMP_LR 0x4280
873#define T_OPCODE_MOV_HR 0x4600
874#define T_OPCODE_CMP_HR 0x4500
b99bd4ef 875
a737bd4d
NC
876#define T_OPCODE_LDR_PC 0x4800
877#define T_OPCODE_LDR_SP 0x9800
878#define T_OPCODE_STR_SP 0x9000
879#define T_OPCODE_LDR_IW 0x6800
880#define T_OPCODE_STR_IW 0x6000
881#define T_OPCODE_LDR_IH 0x8800
882#define T_OPCODE_STR_IH 0x8000
883#define T_OPCODE_LDR_IB 0x7800
884#define T_OPCODE_STR_IB 0x7000
885#define T_OPCODE_LDR_RW 0x5800
886#define T_OPCODE_STR_RW 0x5000
887#define T_OPCODE_LDR_RH 0x5a00
888#define T_OPCODE_STR_RH 0x5200
889#define T_OPCODE_LDR_RB 0x5c00
890#define T_OPCODE_STR_RB 0x5400
c9b604bd 891
a737bd4d
NC
892#define T_OPCODE_PUSH 0xb400
893#define T_OPCODE_POP 0xbc00
b99bd4ef 894
2fc8bdac 895#define T_OPCODE_BRANCH 0xe000
b99bd4ef 896
a737bd4d 897#define THUMB_SIZE 2 /* Size of thumb instruction. */
a737bd4d 898#define THUMB_PP_PC_LR 0x0100
c19d1205 899#define THUMB_LOAD_BIT 0x0800
53365c0d 900#define THUMB2_LOAD_BIT 0x00100000
c19d1205 901
5ee91343 902#define BAD_SYNTAX _("syntax error")
c19d1205 903#define BAD_ARGS _("bad arguments to instruction")
fdfde340 904#define BAD_SP _("r13 not allowed here")
c19d1205 905#define BAD_PC _("r15 not allowed here")
a302e574
AV
906#define BAD_ODD _("Odd register not allowed here")
907#define BAD_EVEN _("Even register not allowed here")
c19d1205
ZW
908#define BAD_COND _("instruction cannot be conditional")
909#define BAD_OVERLAP _("registers may not be the same")
910#define BAD_HIREG _("lo register required")
911#define BAD_THUMB32 _("instruction not supported in Thumb16 mode")
35c228db 912#define BAD_ADDR_MODE _("instruction does not accept this addressing mode")
dfa9f0d5 913#define BAD_BRANCH _("branch must be last instruction in IT block")
e12437dc 914#define BAD_BRANCH_OFF _("branch out of range or not a multiple of 2")
4934a27c 915#define BAD_NO_VPT _("instruction not allowed in VPT block")
dfa9f0d5 916#define BAD_NOT_IT _("instruction not allowed in IT block")
5ee91343 917#define BAD_NOT_VPT _("instruction missing MVE vector predication code")
037e8744 918#define BAD_FPU _("selected FPU does not support instruction")
e07e6e58 919#define BAD_OUT_IT _("thumb conditional instruction should be in IT block")
5ee91343
AV
920#define BAD_OUT_VPT \
921 _("vector predicated instruction should be in VPT/VPST block")
e07e6e58 922#define BAD_IT_COND _("incorrect condition in IT block")
5ee91343 923#define BAD_VPT_COND _("incorrect condition in VPT/VPST block")
e07e6e58 924#define BAD_IT_IT _("IT falling in the range of a previous IT block")
921e5f0a 925#define MISSING_FNSTART _("missing .fnstart before unwinding directive")
5be8be5d
DG
926#define BAD_PC_ADDRESSING \
927 _("cannot use register index with PC-relative addressing")
928#define BAD_PC_WRITEBACK \
929 _("cannot use writeback with PC-relative addressing")
9db2f6b4
RL
930#define BAD_RANGE _("branch out of range")
931#define BAD_FP16 _("selected processor does not support fp16 instruction")
aab2c27d 932#define BAD_BF16 _("selected processor does not support bf16 instruction")
4934a27c
MM
933#define BAD_CDE _("selected processor does not support cde instruction")
934#define BAD_CDE_COPROC _("coprocessor for insn is not enabled for cde")
dd5181d5 935#define UNPRED_REG(R) _("using " R " results in unpredictable behaviour")
a9f02af8 936#define THUMB1_RELOC_ONLY _("relocation valid in thumb1 code only")
5ee91343
AV
937#define MVE_NOT_IT _("Warning: instruction is UNPREDICTABLE in an IT " \
938 "block")
939#define MVE_NOT_VPT _("Warning: instruction is UNPREDICTABLE in a VPT " \
940 "block")
941#define MVE_BAD_PC _("Warning: instruction is UNPREDICTABLE with PC" \
942 " operand")
943#define MVE_BAD_SP _("Warning: instruction is UNPREDICTABLE with SP" \
944 " operand")
a302e574 945#define BAD_SIMD_TYPE _("bad type in SIMD instruction")
886e1c73
AV
946#define BAD_MVE_AUTO \
947 _("GAS auto-detection mode and -march=all is deprecated for MVE, please" \
948 " use a valid -march or -mcpu option.")
949#define BAD_MVE_SRCDEST _("Warning: 32-bit element size and same destination "\
950 "and source operands makes instruction UNPREDICTABLE")
35c228db 951#define BAD_EL_TYPE _("bad element type for instruction")
1b883319 952#define MVE_BAD_QREG _("MVE vector register Q[0..7] expected")
5a0c7a81 953#define BAD_PACBTI _("selected processor does not support PACBTI extention")
c19d1205 954
629310ab
ML
955static htab_t arm_ops_hsh;
956static htab_t arm_cond_hsh;
957static htab_t arm_vcond_hsh;
958static htab_t arm_shift_hsh;
959static htab_t arm_psr_hsh;
960static htab_t arm_v7m_psr_hsh;
961static htab_t arm_reg_hsh;
962static htab_t arm_reloc_hsh;
963static htab_t arm_barrier_opt_hsh;
b99bd4ef 964
b99bd4ef
NC
965/* Stuff needed to resolve the label ambiguity
966 As:
967 ...
968 label: <insn>
969 may differ from:
970 ...
971 label:
5f4273c7 972 <insn> */
b99bd4ef
NC
973
974symbolS * last_label_seen;
5b7c81bd 975static int label_is_thumb_function_name = false;
e07e6e58 976
3d0c9500
NC
977/* Literal pool structure. Held on a per-section
978 and per-sub-section basis. */
a737bd4d 979
c19d1205 980#define MAX_LITERAL_POOL_SIZE 1024
3d0c9500 981typedef struct literal_pool
b99bd4ef 982{
c921be7d
NC
983 expressionS literals [MAX_LITERAL_POOL_SIZE];
984 unsigned int next_free_entry;
985 unsigned int id;
986 symbolS * symbol;
987 segT section;
988 subsegT sub_section;
a8040cf2
NC
989#ifdef OBJ_ELF
990 struct dwarf2_line_info locs [MAX_LITERAL_POOL_SIZE];
991#endif
c921be7d 992 struct literal_pool * next;
8335d6aa 993 unsigned int alignment;
3d0c9500 994} literal_pool;
b99bd4ef 995
3d0c9500
NC
996/* Pointer to a linked list of literal pools. */
997literal_pool * list_of_pools = NULL;
e27ec89e 998
2e6976a8
DG
999typedef enum asmfunc_states
1000{
1001 OUTSIDE_ASMFUNC,
1002 WAITING_ASMFUNC_NAME,
1003 WAITING_ENDASMFUNC
1004} asmfunc_states;
1005
1006static asmfunc_states asmfunc_state = OUTSIDE_ASMFUNC;
1007
e07e6e58 1008#ifdef OBJ_ELF
5ee91343 1009# define now_pred seg_info (now_seg)->tc_segment_info_data.current_pred
e07e6e58 1010#else
5ee91343 1011static struct current_pred now_pred;
e07e6e58
NC
1012#endif
1013
1014static inline int
5ee91343 1015now_pred_compatible (int cond)
e07e6e58 1016{
5ee91343 1017 return (cond & ~1) == (now_pred.cc & ~1);
e07e6e58
NC
1018}
1019
1020static inline int
1021conditional_insn (void)
1022{
1023 return inst.cond != COND_ALWAYS;
1024}
1025
5ee91343 1026static int in_pred_block (void);
e07e6e58 1027
5ee91343 1028static int handle_pred_state (void);
e07e6e58
NC
1029
1030static void force_automatic_it_block_close (void);
1031
c921be7d
NC
1032static void it_fsm_post_encode (void);
1033
5ee91343 1034#define set_pred_insn_type(type) \
e07e6e58
NC
1035 do \
1036 { \
5ee91343
AV
1037 inst.pred_insn_type = type; \
1038 if (handle_pred_state () == FAIL) \
477330fc 1039 return; \
e07e6e58
NC
1040 } \
1041 while (0)
1042
5ee91343 1043#define set_pred_insn_type_nonvoid(type, failret) \
c921be7d
NC
1044 do \
1045 { \
5ee91343
AV
1046 inst.pred_insn_type = type; \
1047 if (handle_pred_state () == FAIL) \
477330fc 1048 return failret; \
c921be7d
NC
1049 } \
1050 while(0)
1051
5ee91343 1052#define set_pred_insn_type_last() \
e07e6e58
NC
1053 do \
1054 { \
1055 if (inst.cond == COND_ALWAYS) \
5ee91343 1056 set_pred_insn_type (IF_INSIDE_IT_LAST_INSN); \
e07e6e58 1057 else \
5ee91343 1058 set_pred_insn_type (INSIDE_IT_LAST_INSN); \
e07e6e58
NC
1059 } \
1060 while (0)
1061
e39c1607
SD
1062/* Toggle value[pos]. */
1063#define TOGGLE_BIT(value, pos) (value ^ (1 << pos))
1064
c19d1205 1065/* Pure syntax. */
b99bd4ef 1066
c19d1205
ZW
1067/* This array holds the chars that always start a comment. If the
1068 pre-processor is disabled, these aren't very useful. */
2e6976a8 1069char arm_comment_chars[] = "@";
3d0c9500 1070
c19d1205
ZW
1071/* This array holds the chars that only start a comment at the beginning of
1072 a line. If the line seems to have the form '# 123 filename'
1073 .line and .file directives will appear in the pre-processed output. */
1074/* Note that input_file.c hand checks for '#' at the beginning of the
1075 first line of the input file. This is because the compiler outputs
1076 #NO_APP at the beginning of its output. */
1077/* Also note that comments like this one will always work. */
1078const char line_comment_chars[] = "#";
3d0c9500 1079
2e6976a8 1080char arm_line_separator_chars[] = ";";
b99bd4ef 1081
c19d1205
ZW
1082/* Chars that can be used to separate mant
1083 from exp in floating point numbers. */
1084const char EXP_CHARS[] = "eE";
3d0c9500 1085
c19d1205
ZW
1086/* Chars that mean this number is a floating point constant. */
1087/* As in 0f12.456 */
1088/* or 0d1.2345e12 */
b99bd4ef 1089
5312fe52 1090const char FLT_CHARS[] = "rRsSfFdDxXeEpPHh";
3d0c9500 1091
c19d1205
ZW
1092/* Prefix characters that indicate the start of an immediate
1093 value. */
1094#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
3d0c9500 1095
c19d1205
ZW
1096/* Separator character handling. */
1097
1098#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
1099
5312fe52
BW
1100enum fp_16bit_format
1101{
1102 ARM_FP16_FORMAT_IEEE = 0x1,
1103 ARM_FP16_FORMAT_ALTERNATIVE = 0x2,
1104 ARM_FP16_FORMAT_DEFAULT = 0x3
1105};
1106
1107static enum fp_16bit_format fp16_format = ARM_FP16_FORMAT_DEFAULT;
1108
1109
c19d1205
ZW
1110static inline int
1111skip_past_char (char ** str, char c)
1112{
8ab8155f
NC
1113 /* PR gas/14987: Allow for whitespace before the expected character. */
1114 skip_whitespace (*str);
427d0db6 1115
c19d1205
ZW
1116 if (**str == c)
1117 {
1118 (*str)++;
1119 return SUCCESS;
3d0c9500 1120 }
c19d1205
ZW
1121 else
1122 return FAIL;
1123}
c921be7d 1124
c19d1205 1125#define skip_past_comma(str) skip_past_char (str, ',')
3d0c9500 1126
c19d1205
ZW
1127/* Arithmetic expressions (possibly involving symbols). */
1128
1129/* Return TRUE if anything in the expression is a bignum. */
1130
5b7c81bd 1131static bool
c19d1205
ZW
1132walk_no_bignums (symbolS * sp)
1133{
1134 if (symbol_get_value_expression (sp)->X_op == O_big)
5b7c81bd 1135 return true;
c19d1205
ZW
1136
1137 if (symbol_get_value_expression (sp)->X_add_symbol)
3d0c9500 1138 {
c19d1205
ZW
1139 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
1140 || (symbol_get_value_expression (sp)->X_op_symbol
1141 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
3d0c9500
NC
1142 }
1143
5b7c81bd 1144 return false;
3d0c9500
NC
1145}
1146
5b7c81bd 1147static bool in_my_get_expression = false;
c19d1205
ZW
1148
1149/* Third argument to my_get_expression. */
1150#define GE_NO_PREFIX 0
1151#define GE_IMM_PREFIX 1
1152#define GE_OPT_PREFIX 2
5287ad62
JB
1153/* This is a bit of a hack. Use an optional prefix, and also allow big (64-bit)
1154 immediates, as can be used in Neon VMVN and VMOV immediate instructions. */
1155#define GE_OPT_PREFIX_BIG 3
a737bd4d 1156
b99bd4ef 1157static int
c19d1205 1158my_get_expression (expressionS * ep, char ** str, int prefix_mode)
b99bd4ef 1159{
c19d1205 1160 char * save_in;
b99bd4ef 1161
c19d1205
ZW
1162 /* In unified syntax, all prefixes are optional. */
1163 if (unified_syntax)
5287ad62 1164 prefix_mode = (prefix_mode == GE_OPT_PREFIX_BIG) ? prefix_mode
477330fc 1165 : GE_OPT_PREFIX;
b99bd4ef 1166
c19d1205 1167 switch (prefix_mode)
b99bd4ef 1168 {
c19d1205
ZW
1169 case GE_NO_PREFIX: break;
1170 case GE_IMM_PREFIX:
1171 if (!is_immediate_prefix (**str))
1172 {
1173 inst.error = _("immediate expression requires a # prefix");
1174 return FAIL;
1175 }
1176 (*str)++;
1177 break;
1178 case GE_OPT_PREFIX:
5287ad62 1179 case GE_OPT_PREFIX_BIG:
c19d1205
ZW
1180 if (is_immediate_prefix (**str))
1181 (*str)++;
1182 break;
0198d5e6
TC
1183 default:
1184 abort ();
c19d1205 1185 }
b99bd4ef 1186
c19d1205 1187 memset (ep, 0, sizeof (expressionS));
b99bd4ef 1188
c19d1205
ZW
1189 save_in = input_line_pointer;
1190 input_line_pointer = *str;
5b7c81bd 1191 in_my_get_expression = true;
2ac93be7 1192 expression (ep);
5b7c81bd 1193 in_my_get_expression = false;
c19d1205 1194
f86adc07 1195 if (ep->X_op == O_illegal || ep->X_op == O_absent)
b99bd4ef 1196 {
f86adc07 1197 /* We found a bad or missing expression in md_operand(). */
c19d1205
ZW
1198 *str = input_line_pointer;
1199 input_line_pointer = save_in;
1200 if (inst.error == NULL)
f86adc07
NS
1201 inst.error = (ep->X_op == O_absent
1202 ? _("missing expression") :_("bad expression"));
c19d1205
ZW
1203 return 1;
1204 }
b99bd4ef 1205
c19d1205
ZW
1206 /* Get rid of any bignums now, so that we don't generate an error for which
1207 we can't establish a line number later on. Big numbers are never valid
1208 in instructions, which is where this routine is always called. */
5287ad62
JB
1209 if (prefix_mode != GE_OPT_PREFIX_BIG
1210 && (ep->X_op == O_big
477330fc 1211 || (ep->X_add_symbol
5287ad62 1212 && (walk_no_bignums (ep->X_add_symbol)
477330fc 1213 || (ep->X_op_symbol
5287ad62 1214 && walk_no_bignums (ep->X_op_symbol))))))
c19d1205
ZW
1215 {
1216 inst.error = _("invalid constant");
1217 *str = input_line_pointer;
1218 input_line_pointer = save_in;
1219 return 1;
1220 }
b99bd4ef 1221
c19d1205
ZW
1222 *str = input_line_pointer;
1223 input_line_pointer = save_in;
0198d5e6 1224 return SUCCESS;
b99bd4ef
NC
1225}
1226
c19d1205
ZW
1227/* Turn a string in input_line_pointer into a floating point constant
1228 of type TYPE, and store the appropriate bytes in *LITP. The number
1229 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1230 returned, or NULL on OK.
b99bd4ef 1231
c19d1205
ZW
1232 Note that fp constants aren't represent in the normal way on the ARM.
1233 In big endian mode, things are as expected. However, in little endian
1234 mode fp constants are big-endian word-wise, and little-endian byte-wise
1235 within the words. For example, (double) 1.1 in big endian mode is
1236 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
1237 the byte sequence 99 99 f1 3f 9a 99 99 99.
b99bd4ef 1238
c19d1205 1239 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
b99bd4ef 1240
6d4af3c2 1241const char *
c19d1205
ZW
1242md_atof (int type, char * litP, int * sizeP)
1243{
1244 int prec;
1245 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1246 char *t;
1247 int i;
b99bd4ef 1248
c19d1205
ZW
1249 switch (type)
1250 {
5312fe52
BW
1251 case 'H':
1252 case 'h':
2557e081
JB
1253 /* bfloat16, despite not being part of the IEEE specification, can also
1254 be handled by atof_ieee(). */
1255 case 'b':
5312fe52
BW
1256 prec = 1;
1257 break;
1258
c19d1205
ZW
1259 case 'f':
1260 case 'F':
1261 case 's':
1262 case 'S':
1263 prec = 2;
1264 break;
b99bd4ef 1265
c19d1205
ZW
1266 case 'd':
1267 case 'D':
1268 case 'r':
1269 case 'R':
1270 prec = 4;
1271 break;
b99bd4ef 1272
c19d1205
ZW
1273 case 'x':
1274 case 'X':
499ac353 1275 prec = 5;
c19d1205 1276 break;
b99bd4ef 1277
c19d1205
ZW
1278 case 'p':
1279 case 'P':
499ac353 1280 prec = 5;
c19d1205 1281 break;
a737bd4d 1282
c19d1205
ZW
1283 default:
1284 *sizeP = 0;
499ac353 1285 return _("Unrecognized or unsupported floating point constant");
c19d1205 1286 }
b99bd4ef 1287
c19d1205
ZW
1288 t = atof_ieee (input_line_pointer, type, words);
1289 if (t)
1290 input_line_pointer = t;
499ac353 1291 *sizeP = prec * sizeof (LITTLENUM_TYPE);
b99bd4ef 1292
72c03e30
BW
1293 if (target_big_endian || prec == 1)
1294 for (i = 0; i < prec; i++)
1295 {
1296 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1297 litP += sizeof (LITTLENUM_TYPE);
1298 }
1299 else if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
1300 for (i = prec - 1; i >= 0; i--)
1301 {
1302 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1303 litP += sizeof (LITTLENUM_TYPE);
1304 }
c19d1205 1305 else
72c03e30
BW
1306 /* For a 4 byte float the order of elements in `words' is 1 0.
1307 For an 8 byte float the order is 1 0 3 2. */
1308 for (i = 0; i < prec; i += 2)
1309 {
1310 md_number_to_chars (litP, (valueT) words[i + 1],
1311 sizeof (LITTLENUM_TYPE));
1312 md_number_to_chars (litP + sizeof (LITTLENUM_TYPE),
1313 (valueT) words[i], sizeof (LITTLENUM_TYPE));
1314 litP += 2 * sizeof (LITTLENUM_TYPE);
1315 }
b99bd4ef 1316
499ac353 1317 return NULL;
c19d1205 1318}
b99bd4ef 1319
c19d1205
ZW
1320/* We handle all bad expressions here, so that we can report the faulty
1321 instruction in the error message. */
0198d5e6 1322
c19d1205 1323void
91d6fa6a 1324md_operand (expressionS * exp)
c19d1205
ZW
1325{
1326 if (in_my_get_expression)
91d6fa6a 1327 exp->X_op = O_illegal;
b99bd4ef
NC
1328}
1329
c19d1205 1330/* Immediate values. */
b99bd4ef 1331
0198d5e6 1332#ifdef OBJ_ELF
c19d1205
ZW
1333/* Generic immediate-value read function for use in directives.
1334 Accepts anything that 'expression' can fold to a constant.
1335 *val receives the number. */
0198d5e6 1336
c19d1205
ZW
1337static int
1338immediate_for_directive (int *val)
b99bd4ef 1339{
c19d1205
ZW
1340 expressionS exp;
1341 exp.X_op = O_illegal;
b99bd4ef 1342
c19d1205
ZW
1343 if (is_immediate_prefix (*input_line_pointer))
1344 {
1345 input_line_pointer++;
1346 expression (&exp);
1347 }
b99bd4ef 1348
c19d1205
ZW
1349 if (exp.X_op != O_constant)
1350 {
1351 as_bad (_("expected #constant"));
1352 ignore_rest_of_line ();
1353 return FAIL;
1354 }
1355 *val = exp.X_add_number;
1356 return SUCCESS;
b99bd4ef 1357}
c19d1205 1358#endif
b99bd4ef 1359
c19d1205 1360/* Register parsing. */
b99bd4ef 1361
c19d1205
ZW
1362/* Generic register parser. CCP points to what should be the
1363 beginning of a register name. If it is indeed a valid register
1364 name, advance CCP over it and return the reg_entry structure;
1365 otherwise return NULL. Does not issue diagnostics. */
1366
1367static struct reg_entry *
1368arm_reg_parse_multi (char **ccp)
b99bd4ef 1369{
c19d1205
ZW
1370 char *start = *ccp;
1371 char *p;
1372 struct reg_entry *reg;
b99bd4ef 1373
477330fc
RM
1374 skip_whitespace (start);
1375
c19d1205
ZW
1376#ifdef REGISTER_PREFIX
1377 if (*start != REGISTER_PREFIX)
01cfc07f 1378 return NULL;
c19d1205
ZW
1379 start++;
1380#endif
1381#ifdef OPTIONAL_REGISTER_PREFIX
1382 if (*start == OPTIONAL_REGISTER_PREFIX)
1383 start++;
1384#endif
b99bd4ef 1385
c19d1205
ZW
1386 p = start;
1387 if (!ISALPHA (*p) || !is_name_beginner (*p))
1388 return NULL;
b99bd4ef 1389
c19d1205
ZW
1390 do
1391 p++;
1392 while (ISALPHA (*p) || ISDIGIT (*p) || *p == '_');
1393
629310ab 1394 reg = (struct reg_entry *) str_hash_find_n (arm_reg_hsh, start, p - start);
c19d1205
ZW
1395
1396 if (!reg)
1397 return NULL;
1398
1399 *ccp = p;
1400 return reg;
b99bd4ef
NC
1401}
1402
1403static int
dcbf9037 1404arm_reg_alt_syntax (char **ccp, char *start, struct reg_entry *reg,
477330fc 1405 enum arm_reg_type type)
b99bd4ef 1406{
c19d1205
ZW
1407 /* Alternative syntaxes are accepted for a few register classes. */
1408 switch (type)
1409 {
1410 case REG_TYPE_MVF:
1411 case REG_TYPE_MVD:
1412 case REG_TYPE_MVFX:
1413 case REG_TYPE_MVDX:
1414 /* Generic coprocessor register names are allowed for these. */
79134647 1415 if (reg && reg->type == REG_TYPE_CN)
c19d1205
ZW
1416 return reg->number;
1417 break;
69b97547 1418
c19d1205
ZW
1419 case REG_TYPE_CP:
1420 /* For backward compatibility, a bare number is valid here. */
1421 {
1422 unsigned long processor = strtoul (start, ccp, 10);
1423 if (*ccp != start && processor <= 15)
1424 return processor;
1425 }
1a0670f3 1426 /* Fall through. */
6057a28f 1427
c19d1205
ZW
1428 case REG_TYPE_MMXWC:
1429 /* WC includes WCG. ??? I'm not sure this is true for all
1430 instructions that take WC registers. */
79134647 1431 if (reg && reg->type == REG_TYPE_MMXWCG)
c19d1205 1432 return reg->number;
6057a28f 1433 break;
c19d1205 1434
6057a28f 1435 default:
c19d1205 1436 break;
6057a28f
NC
1437 }
1438
dcbf9037
JB
1439 return FAIL;
1440}
1441
1442/* As arm_reg_parse_multi, but the register must be of type TYPE, and the
1443 return value is the register number or FAIL. */
1444
1445static int
1446arm_reg_parse (char **ccp, enum arm_reg_type type)
1447{
1448 char *start = *ccp;
1449 struct reg_entry *reg = arm_reg_parse_multi (ccp);
1450 int ret;
1451
1452 /* Do not allow a scalar (reg+index) to parse as a register. */
1453 if (reg && reg->neon && (reg->neon->defined & NTA_HASINDEX))
1454 return FAIL;
1455
1456 if (reg && reg->type == type)
1457 return reg->number;
1458
1459 if ((ret = arm_reg_alt_syntax (ccp, start, reg, type)) != FAIL)
1460 return ret;
1461
c19d1205
ZW
1462 *ccp = start;
1463 return FAIL;
1464}
69b97547 1465
dcbf9037
JB
1466/* Parse a Neon type specifier. *STR should point at the leading '.'
1467 character. Does no verification at this stage that the type fits the opcode
1468 properly. E.g.,
1469
1470 .i32.i32.s16
1471 .s32.f32
1472 .u16
1473
1474 Can all be legally parsed by this function.
1475
1476 Fills in neon_type struct pointer with parsed information, and updates STR
1477 to point after the parsed type specifier. Returns SUCCESS if this was a legal
1478 type, FAIL if not. */
1479
1480static int
1481parse_neon_type (struct neon_type *type, char **str)
1482{
1483 char *ptr = *str;
1484
1485 if (type)
1486 type->elems = 0;
1487
1488 while (type->elems < NEON_MAX_TYPE_ELS)
1489 {
1490 enum neon_el_type thistype = NT_untyped;
1491 unsigned thissize = -1u;
1492
1493 if (*ptr != '.')
1494 break;
1495
1496 ptr++;
1497
1498 /* Just a size without an explicit type. */
1499 if (ISDIGIT (*ptr))
1500 goto parsesize;
1501
1502 switch (TOLOWER (*ptr))
1503 {
1504 case 'i': thistype = NT_integer; break;
1505 case 'f': thistype = NT_float; break;
1506 case 'p': thistype = NT_poly; break;
1507 case 's': thistype = NT_signed; break;
1508 case 'u': thistype = NT_unsigned; break;
477330fc
RM
1509 case 'd':
1510 thistype = NT_float;
1511 thissize = 64;
1512 ptr++;
1513 goto done;
aab2c27d
MM
1514 case 'b':
1515 thistype = NT_bfloat;
1516 switch (TOLOWER (*(++ptr)))
1517 {
1518 case 'f':
1519 ptr += 1;
1520 thissize = strtoul (ptr, &ptr, 10);
1521 if (thissize != 16)
1522 {
1523 as_bad (_("bad size %d in type specifier"), thissize);
1524 return FAIL;
1525 }
1526 goto done;
1527 case '0': case '1': case '2': case '3': case '4':
1528 case '5': case '6': case '7': case '8': case '9':
1529 case ' ': case '.':
1530 as_bad (_("unexpected type character `b' -- did you mean `bf'?"));
1531 return FAIL;
1532 default:
1533 break;
1534 }
1535 break;
dcbf9037
JB
1536 default:
1537 as_bad (_("unexpected character `%c' in type specifier"), *ptr);
1538 return FAIL;
1539 }
1540
1541 ptr++;
1542
1543 /* .f is an abbreviation for .f32. */
1544 if (thistype == NT_float && !ISDIGIT (*ptr))
1545 thissize = 32;
1546 else
1547 {
1548 parsesize:
1549 thissize = strtoul (ptr, &ptr, 10);
1550
1551 if (thissize != 8 && thissize != 16 && thissize != 32
477330fc
RM
1552 && thissize != 64)
1553 {
1554 as_bad (_("bad size %d in type specifier"), thissize);
dcbf9037
JB
1555 return FAIL;
1556 }
1557 }
1558
037e8744 1559 done:
dcbf9037 1560 if (type)
477330fc
RM
1561 {
1562 type->el[type->elems].type = thistype;
dcbf9037
JB
1563 type->el[type->elems].size = thissize;
1564 type->elems++;
1565 }
1566 }
1567
1568 /* Empty/missing type is not a successful parse. */
1569 if (type->elems == 0)
1570 return FAIL;
1571
1572 *str = ptr;
1573
1574 return SUCCESS;
1575}
1576
1577/* Errors may be set multiple times during parsing or bit encoding
1578 (particularly in the Neon bits), but usually the earliest error which is set
1579 will be the most meaningful. Avoid overwriting it with later (cascading)
1580 errors by calling this function. */
1581
1582static void
1583first_error (const char *err)
1584{
1585 if (!inst.error)
1586 inst.error = err;
1587}
1588
1589/* Parse a single type, e.g. ".s32", leading period included. */
1590static int
1591parse_neon_operand_type (struct neon_type_el *vectype, char **ccp)
1592{
1593 char *str = *ccp;
1594 struct neon_type optype;
1595
1596 if (*str == '.')
1597 {
1598 if (parse_neon_type (&optype, &str) == SUCCESS)
477330fc
RM
1599 {
1600 if (optype.elems == 1)
1601 *vectype = optype.el[0];
1602 else
1603 {
1604 first_error (_("only one type should be specified for operand"));
1605 return FAIL;
1606 }
1607 }
dcbf9037 1608 else
477330fc
RM
1609 {
1610 first_error (_("vector type expected"));
1611 return FAIL;
1612 }
dcbf9037
JB
1613 }
1614 else
1615 return FAIL;
5f4273c7 1616
dcbf9037 1617 *ccp = str;
5f4273c7 1618
dcbf9037
JB
1619 return SUCCESS;
1620}
1621
1622/* Special meanings for indices (which have a range of 0-7), which will fit into
1623 a 4-bit integer. */
1624
1625#define NEON_ALL_LANES 15
1626#define NEON_INTERLEAVE_LANES 14
1627
5ee91343
AV
1628/* Record a use of the given feature. */
1629static void
1630record_feature_use (const arm_feature_set *feature)
1631{
1632 if (thumb_mode)
1633 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, *feature);
1634 else
1635 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, *feature);
1636}
1637
1638/* If the given feature available in the selected CPU, mark it as used.
1639 Returns TRUE iff feature is available. */
5b7c81bd 1640static bool
5ee91343
AV
1641mark_feature_used (const arm_feature_set *feature)
1642{
886e1c73
AV
1643
1644 /* Do not support the use of MVE only instructions when in auto-detection or
1645 -march=all. */
1646 if (((feature == &mve_ext) || (feature == &mve_fp_ext))
1647 && ARM_CPU_IS_ANY (cpu_variant))
1648 {
1649 first_error (BAD_MVE_AUTO);
5b7c81bd 1650 return false;
886e1c73 1651 }
5ee91343
AV
1652 /* Ensure the option is valid on the current architecture. */
1653 if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
5b7c81bd 1654 return false;
5ee91343
AV
1655
1656 /* Add the appropriate architecture feature for the barrier option used.
1657 */
1658 record_feature_use (feature);
1659
5b7c81bd 1660 return true;
5ee91343
AV
1661}
1662
dcbf9037
JB
1663/* Parse either a register or a scalar, with an optional type. Return the
1664 register number, and optionally fill in the actual type of the register
1665 when multiple alternatives were given (NEON_TYPE_NDQ) in *RTYPE, and
1666 type/index information in *TYPEINFO. */
1667
1668static int
1669parse_typed_reg_or_scalar (char **ccp, enum arm_reg_type type,
477330fc
RM
1670 enum arm_reg_type *rtype,
1671 struct neon_typed_alias *typeinfo)
dcbf9037
JB
1672{
1673 char *str = *ccp;
1674 struct reg_entry *reg = arm_reg_parse_multi (&str);
1675 struct neon_typed_alias atype;
1676 struct neon_type_el parsetype;
1677
1678 atype.defined = 0;
1679 atype.index = -1;
1680 atype.eltype.type = NT_invtype;
1681 atype.eltype.size = -1;
1682
1683 /* Try alternate syntax for some types of register. Note these are mutually
1684 exclusive with the Neon syntax extensions. */
1685 if (reg == NULL)
1686 {
1687 int altreg = arm_reg_alt_syntax (&str, *ccp, reg, type);
1688 if (altreg != FAIL)
477330fc 1689 *ccp = str;
dcbf9037 1690 if (typeinfo)
477330fc 1691 *typeinfo = atype;
dcbf9037
JB
1692 return altreg;
1693 }
1694
037e8744
JB
1695 /* Undo polymorphism when a set of register types may be accepted. */
1696 if ((type == REG_TYPE_NDQ
1697 && (reg->type == REG_TYPE_NQ || reg->type == REG_TYPE_VFD))
1698 || (type == REG_TYPE_VFSD
477330fc 1699 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
037e8744 1700 || (type == REG_TYPE_NSDQ
477330fc
RM
1701 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD
1702 || reg->type == REG_TYPE_NQ))
dec41383
JW
1703 || (type == REG_TYPE_NSD
1704 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
f512f76f
NC
1705 || (type == REG_TYPE_MMXWC
1706 && (reg->type == REG_TYPE_MMXWCG)))
21d799b5 1707 type = (enum arm_reg_type) reg->type;
dcbf9037 1708
5ee91343
AV
1709 if (type == REG_TYPE_MQ)
1710 {
1711 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
1712 return FAIL;
1713
1714 if (!reg || reg->type != REG_TYPE_NQ)
1715 return FAIL;
1716
1717 if (reg->number > 14 && !mark_feature_used (&fpu_vfp_ext_d32))
1718 {
1719 first_error (_("expected MVE register [q0..q7]"));
1720 return FAIL;
1721 }
1722 type = REG_TYPE_NQ;
1723 }
1724 else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
1725 && (type == REG_TYPE_NQ))
1726 return FAIL;
1727
1728
dcbf9037
JB
1729 if (type != reg->type)
1730 return FAIL;
1731
1732 if (reg->neon)
1733 atype = *reg->neon;
5f4273c7 1734
dcbf9037
JB
1735 if (parse_neon_operand_type (&parsetype, &str) == SUCCESS)
1736 {
1737 if ((atype.defined & NTA_HASTYPE) != 0)
477330fc
RM
1738 {
1739 first_error (_("can't redefine type for operand"));
1740 return FAIL;
1741 }
dcbf9037
JB
1742 atype.defined |= NTA_HASTYPE;
1743 atype.eltype = parsetype;
1744 }
5f4273c7 1745
dcbf9037
JB
1746 if (skip_past_char (&str, '[') == SUCCESS)
1747 {
dec41383
JW
1748 if (type != REG_TYPE_VFD
1749 && !(type == REG_TYPE_VFS
57785aa2
AV
1750 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_2))
1751 && !(type == REG_TYPE_NQ
1752 && ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)))
477330fc 1753 {
57785aa2
AV
1754 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
1755 first_error (_("only D and Q registers may be indexed"));
1756 else
1757 first_error (_("only D registers may be indexed"));
477330fc
RM
1758 return FAIL;
1759 }
5f4273c7 1760
dcbf9037 1761 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
1762 {
1763 first_error (_("can't change index for operand"));
1764 return FAIL;
1765 }
dcbf9037
JB
1766
1767 atype.defined |= NTA_HASINDEX;
1768
1769 if (skip_past_char (&str, ']') == SUCCESS)
477330fc 1770 atype.index = NEON_ALL_LANES;
dcbf9037 1771 else
477330fc
RM
1772 {
1773 expressionS exp;
dcbf9037 1774
477330fc 1775 my_get_expression (&exp, &str, GE_NO_PREFIX);
dcbf9037 1776
477330fc
RM
1777 if (exp.X_op != O_constant)
1778 {
1779 first_error (_("constant expression required"));
1780 return FAIL;
1781 }
dcbf9037 1782
477330fc
RM
1783 if (skip_past_char (&str, ']') == FAIL)
1784 return FAIL;
dcbf9037 1785
477330fc
RM
1786 atype.index = exp.X_add_number;
1787 }
dcbf9037 1788 }
5f4273c7 1789
dcbf9037
JB
1790 if (typeinfo)
1791 *typeinfo = atype;
5f4273c7 1792
dcbf9037
JB
1793 if (rtype)
1794 *rtype = type;
5f4273c7 1795
dcbf9037 1796 *ccp = str;
5f4273c7 1797
dcbf9037
JB
1798 return reg->number;
1799}
1800
efd6b359 1801/* Like arm_reg_parse, but also allow the following extra features:
dcbf9037
JB
1802 - If RTYPE is non-zero, return the (possibly restricted) type of the
1803 register (e.g. Neon double or quad reg when either has been requested).
1804 - If this is a Neon vector type with additional type information, fill
1805 in the struct pointed to by VECTYPE (if non-NULL).
5f4273c7 1806 This function will fault on encountering a scalar. */
dcbf9037
JB
1807
1808static int
1809arm_typed_reg_parse (char **ccp, enum arm_reg_type type,
477330fc 1810 enum arm_reg_type *rtype, struct neon_type_el *vectype)
dcbf9037
JB
1811{
1812 struct neon_typed_alias atype;
1813 char *str = *ccp;
1814 int reg = parse_typed_reg_or_scalar (&str, type, rtype, &atype);
1815
1816 if (reg == FAIL)
1817 return FAIL;
1818
0855e32b
NS
1819 /* Do not allow regname(... to parse as a register. */
1820 if (*str == '(')
1821 return FAIL;
1822
dcbf9037
JB
1823 /* Do not allow a scalar (reg+index) to parse as a register. */
1824 if ((atype.defined & NTA_HASINDEX) != 0)
1825 {
1826 first_error (_("register operand expected, but got scalar"));
1827 return FAIL;
1828 }
1829
1830 if (vectype)
1831 *vectype = atype.eltype;
1832
1833 *ccp = str;
1834
1835 return reg;
1836}
1837
1838#define NEON_SCALAR_REG(X) ((X) >> 4)
1839#define NEON_SCALAR_INDEX(X) ((X) & 15)
1840
5287ad62
JB
1841/* Parse a Neon scalar. Most of the time when we're parsing a scalar, we don't
1842 have enough information to be able to do a good job bounds-checking. So, we
1843 just do easy checks here, and do further checks later. */
1844
1845static int
57785aa2
AV
1846parse_scalar (char **ccp, int elsize, struct neon_type_el *type, enum
1847 arm_reg_type reg_type)
5287ad62 1848{
dcbf9037 1849 int reg;
5287ad62 1850 char *str = *ccp;
dcbf9037 1851 struct neon_typed_alias atype;
57785aa2 1852 unsigned reg_size;
5f4273c7 1853
dec41383 1854 reg = parse_typed_reg_or_scalar (&str, reg_type, NULL, &atype);
5f4273c7 1855
57785aa2
AV
1856 switch (reg_type)
1857 {
1858 case REG_TYPE_VFS:
1859 reg_size = 32;
1860 break;
1861 case REG_TYPE_VFD:
1862 reg_size = 64;
1863 break;
1864 case REG_TYPE_MQ:
1865 reg_size = 128;
1866 break;
1867 default:
1868 gas_assert (0);
1869 return FAIL;
1870 }
1871
dcbf9037 1872 if (reg == FAIL || (atype.defined & NTA_HASINDEX) == 0)
5287ad62 1873 return FAIL;
5f4273c7 1874
57785aa2 1875 if (reg_type != REG_TYPE_MQ && atype.index == NEON_ALL_LANES)
5287ad62 1876 {
dcbf9037 1877 first_error (_("scalar must have an index"));
5287ad62
JB
1878 return FAIL;
1879 }
57785aa2 1880 else if (atype.index >= reg_size / elsize)
5287ad62 1881 {
dcbf9037 1882 first_error (_("scalar index out of range"));
5287ad62
JB
1883 return FAIL;
1884 }
5f4273c7 1885
dcbf9037
JB
1886 if (type)
1887 *type = atype.eltype;
5f4273c7 1888
5287ad62 1889 *ccp = str;
5f4273c7 1890
dcbf9037 1891 return reg * 16 + atype.index;
5287ad62
JB
1892}
1893
4b5a202f
AV
1894/* Types of registers in a list. */
1895
1896enum reg_list_els
1897{
1898 REGLIST_RN,
8c299995 1899 REGLIST_PSEUDO,
4b5a202f
AV
1900 REGLIST_CLRM,
1901 REGLIST_VFP_S,
efd6b359 1902 REGLIST_VFP_S_VPR,
4b5a202f 1903 REGLIST_VFP_D,
efd6b359 1904 REGLIST_VFP_D_VPR,
4b5a202f
AV
1905 REGLIST_NEON_D
1906};
1907
c19d1205 1908/* Parse an ARM register list. Returns the bitmask, or FAIL. */
e07e6e58 1909
c19d1205 1910static long
4b5a202f 1911parse_reg_list (char ** strp, enum reg_list_els etype)
c19d1205 1912{
4b5a202f
AV
1913 char *str = *strp;
1914 long range = 0;
1915 int another_range;
1916
8c299995
TB
1917 gas_assert (etype == REGLIST_RN || etype == REGLIST_CLRM
1918 || etype == REGLIST_PSEUDO);
a737bd4d 1919
c19d1205
ZW
1920 /* We come back here if we get ranges concatenated by '+' or '|'. */
1921 do
6057a28f 1922 {
477330fc
RM
1923 skip_whitespace (str);
1924
c19d1205 1925 another_range = 0;
a737bd4d 1926
c19d1205
ZW
1927 if (*str == '{')
1928 {
1929 int in_range = 0;
1930 int cur_reg = -1;
a737bd4d 1931
c19d1205
ZW
1932 str++;
1933 do
1934 {
1935 int reg;
4b5a202f
AV
1936 const char apsr_str[] = "apsr";
1937 int apsr_str_len = strlen (apsr_str);
8c299995 1938 enum arm_reg_type rt;
6057a28f 1939
8c299995
TB
1940 if (etype == REGLIST_RN || etype == REGLIST_CLRM)
1941 rt = REG_TYPE_RN;
1942 else
1943 rt = REG_TYPE_PSEUDO;
1944
1945 reg = arm_reg_parse (&str, rt);
3363d856 1946
4b5a202f 1947 if (etype == REGLIST_CLRM)
c19d1205 1948 {
4b5a202f
AV
1949 if (reg == REG_SP || reg == REG_PC)
1950 reg = FAIL;
1951 else if (reg == FAIL
1952 && !strncasecmp (str, apsr_str, apsr_str_len)
1953 && !ISALPHA (*(str + apsr_str_len)))
1954 {
1955 reg = 15;
1956 str += apsr_str_len;
1957 }
1958
1959 if (reg == FAIL)
1960 {
1961 first_error (_("r0-r12, lr or APSR expected"));
1962 return FAIL;
1963 }
1964 }
8c299995
TB
1965 else if (etype == REGLIST_PSEUDO)
1966 {
1967 if (reg == FAIL)
1968 {
1969 first_error (_(reg_expected_msgs[REG_TYPE_PSEUDO]));
1970 return FAIL;
1971 }
1972 }
4b5a202f
AV
1973 else /* etype == REGLIST_RN. */
1974 {
1975 if (reg == FAIL)
1976 {
1977 first_error (_(reg_expected_msgs[REGLIST_RN]));
1978 return FAIL;
1979 }
c19d1205 1980 }
a737bd4d 1981
c19d1205
ZW
1982 if (in_range)
1983 {
1984 int i;
a737bd4d 1985
c19d1205
ZW
1986 if (reg <= cur_reg)
1987 {
dcbf9037 1988 first_error (_("bad range in register list"));
c19d1205
ZW
1989 return FAIL;
1990 }
40a18ebd 1991
c19d1205
ZW
1992 for (i = cur_reg + 1; i < reg; i++)
1993 {
1994 if (range & (1 << i))
1995 as_tsktsk
1996 (_("Warning: duplicated register (r%d) in register list"),
1997 i);
1998 else
1999 range |= 1 << i;
2000 }
2001 in_range = 0;
2002 }
a737bd4d 2003
c19d1205
ZW
2004 if (range & (1 << reg))
2005 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
2006 reg);
2007 else if (reg <= cur_reg)
2008 as_tsktsk (_("Warning: register range not in ascending order"));
a737bd4d 2009
c19d1205
ZW
2010 range |= 1 << reg;
2011 cur_reg = reg;
2012 }
2013 while (skip_past_comma (&str) != FAIL
2014 || (in_range = 1, *str++ == '-'));
2015 str--;
a737bd4d 2016
d996d970 2017 if (skip_past_char (&str, '}') == FAIL)
c19d1205 2018 {
dcbf9037 2019 first_error (_("missing `}'"));
c19d1205
ZW
2020 return FAIL;
2021 }
2022 }
4b5a202f 2023 else if (etype == REGLIST_RN)
c19d1205 2024 {
91d6fa6a 2025 expressionS exp;
40a18ebd 2026
91d6fa6a 2027 if (my_get_expression (&exp, &str, GE_NO_PREFIX))
c19d1205 2028 return FAIL;
40a18ebd 2029
91d6fa6a 2030 if (exp.X_op == O_constant)
c19d1205 2031 {
91d6fa6a
NC
2032 if (exp.X_add_number
2033 != (exp.X_add_number & 0x0000ffff))
c19d1205
ZW
2034 {
2035 inst.error = _("invalid register mask");
2036 return FAIL;
2037 }
a737bd4d 2038
91d6fa6a 2039 if ((range & exp.X_add_number) != 0)
c19d1205 2040 {
91d6fa6a 2041 int regno = range & exp.X_add_number;
a737bd4d 2042
c19d1205
ZW
2043 regno &= -regno;
2044 regno = (1 << regno) - 1;
2045 as_tsktsk
2046 (_("Warning: duplicated register (r%d) in register list"),
2047 regno);
2048 }
a737bd4d 2049
91d6fa6a 2050 range |= exp.X_add_number;
c19d1205
ZW
2051 }
2052 else
2053 {
e2b0ab59 2054 if (inst.relocs[0].type != 0)
c19d1205
ZW
2055 {
2056 inst.error = _("expression too complex");
2057 return FAIL;
2058 }
a737bd4d 2059
e2b0ab59
AV
2060 memcpy (&inst.relocs[0].exp, &exp, sizeof (expressionS));
2061 inst.relocs[0].type = BFD_RELOC_ARM_MULTI;
2062 inst.relocs[0].pc_rel = 0;
c19d1205
ZW
2063 }
2064 }
a737bd4d 2065
c19d1205
ZW
2066 if (*str == '|' || *str == '+')
2067 {
2068 str++;
2069 another_range = 1;
2070 }
a737bd4d 2071 }
c19d1205 2072 while (another_range);
a737bd4d 2073
c19d1205
ZW
2074 *strp = str;
2075 return range;
a737bd4d
NC
2076}
2077
c19d1205
ZW
2078/* Parse a VFP register list. If the string is invalid return FAIL.
2079 Otherwise return the number of registers, and set PBASE to the first
5287ad62
JB
2080 register. Parses registers of type ETYPE.
2081 If REGLIST_NEON_D is used, several syntax enhancements are enabled:
2082 - Q registers can be used to specify pairs of D registers
2083 - { } can be omitted from around a singleton register list
477330fc
RM
2084 FIXME: This is not implemented, as it would require backtracking in
2085 some cases, e.g.:
2086 vtbl.8 d3,d4,d5
2087 This could be done (the meaning isn't really ambiguous), but doesn't
2088 fit in well with the current parsing framework.
dcbf9037
JB
2089 - 32 D registers may be used (also true for VFPv3).
2090 FIXME: Types are ignored in these register lists, which is probably a
2091 bug. */
6057a28f 2092
c19d1205 2093static int
efd6b359 2094parse_vfp_reg_list (char **ccp, unsigned int *pbase, enum reg_list_els etype,
5b7c81bd 2095 bool *partial_match)
6057a28f 2096{
037e8744 2097 char *str = *ccp;
c19d1205
ZW
2098 int base_reg;
2099 int new_base;
21d799b5 2100 enum arm_reg_type regtype = (enum arm_reg_type) 0;
5287ad62 2101 int max_regs = 0;
c19d1205
ZW
2102 int count = 0;
2103 int warned = 0;
2104 unsigned long mask = 0;
a737bd4d 2105 int i;
5b7c81bd
AM
2106 bool vpr_seen = false;
2107 bool expect_vpr =
efd6b359 2108 (etype == REGLIST_VFP_S_VPR) || (etype == REGLIST_VFP_D_VPR);
6057a28f 2109
477330fc 2110 if (skip_past_char (&str, '{') == FAIL)
5287ad62
JB
2111 {
2112 inst.error = _("expecting {");
2113 return FAIL;
2114 }
6057a28f 2115
5287ad62 2116 switch (etype)
c19d1205 2117 {
5287ad62 2118 case REGLIST_VFP_S:
efd6b359 2119 case REGLIST_VFP_S_VPR:
c19d1205
ZW
2120 regtype = REG_TYPE_VFS;
2121 max_regs = 32;
5287ad62 2122 break;
5f4273c7 2123
5287ad62 2124 case REGLIST_VFP_D:
efd6b359 2125 case REGLIST_VFP_D_VPR:
5287ad62 2126 regtype = REG_TYPE_VFD;
b7fc2769 2127 break;
5f4273c7 2128
b7fc2769
JB
2129 case REGLIST_NEON_D:
2130 regtype = REG_TYPE_NDQ;
2131 break;
4b5a202f
AV
2132
2133 default:
2134 gas_assert (0);
b7fc2769
JB
2135 }
2136
efd6b359 2137 if (etype != REGLIST_VFP_S && etype != REGLIST_VFP_S_VPR)
b7fc2769 2138 {
b1cc4aeb
PB
2139 /* VFPv3 allows 32 D registers, except for the VFPv3-D16 variant. */
2140 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
2141 {
2142 max_regs = 32;
2143 if (thumb_mode)
2144 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
2145 fpu_vfp_ext_d32);
2146 else
2147 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
2148 fpu_vfp_ext_d32);
2149 }
5287ad62 2150 else
477330fc 2151 max_regs = 16;
c19d1205 2152 }
6057a28f 2153
c19d1205 2154 base_reg = max_regs;
5b7c81bd 2155 *partial_match = false;
a737bd4d 2156
c19d1205
ZW
2157 do
2158 {
7af67752 2159 unsigned int setmask = 1, addregs = 1;
efd6b359 2160 const char vpr_str[] = "vpr";
7af67752 2161 size_t vpr_str_len = strlen (vpr_str);
dcbf9037 2162
037e8744 2163 new_base = arm_typed_reg_parse (&str, regtype, &regtype, NULL);
dcbf9037 2164
efd6b359
AV
2165 if (expect_vpr)
2166 {
2167 if (new_base == FAIL
2168 && !strncasecmp (str, vpr_str, vpr_str_len)
2169 && !ISALPHA (*(str + vpr_str_len))
2170 && !vpr_seen)
2171 {
5b7c81bd 2172 vpr_seen = true;
efd6b359
AV
2173 str += vpr_str_len;
2174 if (count == 0)
2175 base_reg = 0; /* Canonicalize VPR only on d0 with 0 regs. */
2176 }
2177 else if (vpr_seen)
2178 {
2179 first_error (_("VPR expected last"));
2180 return FAIL;
2181 }
2182 else if (new_base == FAIL)
2183 {
2184 if (regtype == REG_TYPE_VFS)
2185 first_error (_("VFP single precision register or VPR "
2186 "expected"));
2187 else /* regtype == REG_TYPE_VFD. */
2188 first_error (_("VFP/Neon double precision register or VPR "
2189 "expected"));
2190 return FAIL;
2191 }
2192 }
2193 else if (new_base == FAIL)
a737bd4d 2194 {
dcbf9037 2195 first_error (_(reg_expected_msgs[regtype]));
c19d1205
ZW
2196 return FAIL;
2197 }
5f4273c7 2198
5b7c81bd 2199 *partial_match = true;
efd6b359
AV
2200 if (vpr_seen)
2201 continue;
2202
b7fc2769 2203 if (new_base >= max_regs)
477330fc
RM
2204 {
2205 first_error (_("register out of range in list"));
2206 return FAIL;
2207 }
5f4273c7 2208
5287ad62
JB
2209 /* Note: a value of 2 * n is returned for the register Q<n>. */
2210 if (regtype == REG_TYPE_NQ)
477330fc
RM
2211 {
2212 setmask = 3;
2213 addregs = 2;
2214 }
5287ad62 2215
c19d1205
ZW
2216 if (new_base < base_reg)
2217 base_reg = new_base;
a737bd4d 2218
5287ad62 2219 if (mask & (setmask << new_base))
c19d1205 2220 {
dcbf9037 2221 first_error (_("invalid register list"));
c19d1205 2222 return FAIL;
a737bd4d 2223 }
a737bd4d 2224
efd6b359 2225 if ((mask >> new_base) != 0 && ! warned && !vpr_seen)
c19d1205
ZW
2226 {
2227 as_tsktsk (_("register list not in ascending order"));
2228 warned = 1;
2229 }
0bbf2aa4 2230
5287ad62
JB
2231 mask |= setmask << new_base;
2232 count += addregs;
0bbf2aa4 2233
037e8744 2234 if (*str == '-') /* We have the start of a range expression */
c19d1205
ZW
2235 {
2236 int high_range;
0bbf2aa4 2237
037e8744 2238 str++;
0bbf2aa4 2239
037e8744 2240 if ((high_range = arm_typed_reg_parse (&str, regtype, NULL, NULL))
477330fc 2241 == FAIL)
c19d1205
ZW
2242 {
2243 inst.error = gettext (reg_expected_msgs[regtype]);
2244 return FAIL;
2245 }
0bbf2aa4 2246
477330fc
RM
2247 if (high_range >= max_regs)
2248 {
2249 first_error (_("register out of range in list"));
2250 return FAIL;
2251 }
b7fc2769 2252
477330fc
RM
2253 if (regtype == REG_TYPE_NQ)
2254 high_range = high_range + 1;
5287ad62 2255
c19d1205
ZW
2256 if (high_range <= new_base)
2257 {
2258 inst.error = _("register range not in ascending order");
2259 return FAIL;
2260 }
0bbf2aa4 2261
5287ad62 2262 for (new_base += addregs; new_base <= high_range; new_base += addregs)
0bbf2aa4 2263 {
5287ad62 2264 if (mask & (setmask << new_base))
0bbf2aa4 2265 {
c19d1205
ZW
2266 inst.error = _("invalid register list");
2267 return FAIL;
0bbf2aa4 2268 }
c19d1205 2269
5287ad62
JB
2270 mask |= setmask << new_base;
2271 count += addregs;
0bbf2aa4 2272 }
0bbf2aa4 2273 }
0bbf2aa4 2274 }
037e8744 2275 while (skip_past_comma (&str) != FAIL);
0bbf2aa4 2276
037e8744 2277 str++;
0bbf2aa4 2278
c19d1205 2279 /* Sanity check -- should have raised a parse error above. */
efd6b359 2280 if ((!vpr_seen && count == 0) || count > max_regs)
c19d1205
ZW
2281 abort ();
2282
2283 *pbase = base_reg;
2284
efd6b359
AV
2285 if (expect_vpr && !vpr_seen)
2286 {
2287 first_error (_("VPR expected last"));
2288 return FAIL;
2289 }
2290
c19d1205
ZW
2291 /* Final test -- the registers must be consecutive. */
2292 mask >>= base_reg;
2293 for (i = 0; i < count; i++)
2294 {
2295 if ((mask & (1u << i)) == 0)
2296 {
2297 inst.error = _("non-contiguous register range");
2298 return FAIL;
2299 }
2300 }
2301
037e8744
JB
2302 *ccp = str;
2303
c19d1205 2304 return count;
b99bd4ef
NC
2305}
2306
dcbf9037
JB
2307/* True if two alias types are the same. */
2308
5b7c81bd 2309static bool
dcbf9037
JB
2310neon_alias_types_same (struct neon_typed_alias *a, struct neon_typed_alias *b)
2311{
2312 if (!a && !b)
5b7c81bd 2313 return true;
5f4273c7 2314
dcbf9037 2315 if (!a || !b)
5b7c81bd 2316 return false;
dcbf9037
JB
2317
2318 if (a->defined != b->defined)
5b7c81bd 2319 return false;
5f4273c7 2320
dcbf9037
JB
2321 if ((a->defined & NTA_HASTYPE) != 0
2322 && (a->eltype.type != b->eltype.type
477330fc 2323 || a->eltype.size != b->eltype.size))
5b7c81bd 2324 return false;
dcbf9037
JB
2325
2326 if ((a->defined & NTA_HASINDEX) != 0
2327 && (a->index != b->index))
5b7c81bd 2328 return false;
5f4273c7 2329
5b7c81bd 2330 return true;
dcbf9037
JB
2331}
2332
5287ad62
JB
2333/* Parse element/structure lists for Neon VLD<n> and VST<n> instructions.
2334 The base register is put in *PBASE.
dcbf9037 2335 The lane (or one of the NEON_*_LANES constants) is placed in bits [3:0] of
5287ad62
JB
2336 the return value.
2337 The register stride (minus one) is put in bit 4 of the return value.
dcbf9037
JB
2338 Bits [6:5] encode the list length (minus one).
2339 The type of the list elements is put in *ELTYPE, if non-NULL. */
5287ad62 2340
5287ad62 2341#define NEON_LANE(X) ((X) & 0xf)
dcbf9037 2342#define NEON_REG_STRIDE(X) ((((X) >> 4) & 1) + 1)
5287ad62
JB
2343#define NEON_REGLIST_LENGTH(X) ((((X) >> 5) & 3) + 1)
2344
2345static int
dcbf9037 2346parse_neon_el_struct_list (char **str, unsigned *pbase,
35c228db 2347 int mve,
477330fc 2348 struct neon_type_el *eltype)
5287ad62
JB
2349{
2350 char *ptr = *str;
2351 int base_reg = -1;
2352 int reg_incr = -1;
2353 int count = 0;
2354 int lane = -1;
2355 int leading_brace = 0;
2356 enum arm_reg_type rtype = REG_TYPE_NDQ;
35c228db
AV
2357 const char *const incr_error = mve ? _("register stride must be 1") :
2358 _("register stride must be 1 or 2");
20203fb9 2359 const char *const type_error = _("mismatched element/structure types in list");
dcbf9037 2360 struct neon_typed_alias firsttype;
f85d59c3
KT
2361 firsttype.defined = 0;
2362 firsttype.eltype.type = NT_invtype;
2363 firsttype.eltype.size = -1;
2364 firsttype.index = -1;
5f4273c7 2365
5287ad62
JB
2366 if (skip_past_char (&ptr, '{') == SUCCESS)
2367 leading_brace = 1;
5f4273c7 2368
5287ad62
JB
2369 do
2370 {
dcbf9037 2371 struct neon_typed_alias atype;
35c228db
AV
2372 if (mve)
2373 rtype = REG_TYPE_MQ;
dcbf9037
JB
2374 int getreg = parse_typed_reg_or_scalar (&ptr, rtype, &rtype, &atype);
2375
5287ad62 2376 if (getreg == FAIL)
477330fc
RM
2377 {
2378 first_error (_(reg_expected_msgs[rtype]));
2379 return FAIL;
2380 }
5f4273c7 2381
5287ad62 2382 if (base_reg == -1)
477330fc
RM
2383 {
2384 base_reg = getreg;
2385 if (rtype == REG_TYPE_NQ)
2386 {
2387 reg_incr = 1;
2388 }
2389 firsttype = atype;
2390 }
5287ad62 2391 else if (reg_incr == -1)
477330fc
RM
2392 {
2393 reg_incr = getreg - base_reg;
2394 if (reg_incr < 1 || reg_incr > 2)
2395 {
2396 first_error (_(incr_error));
2397 return FAIL;
2398 }
2399 }
5287ad62 2400 else if (getreg != base_reg + reg_incr * count)
477330fc
RM
2401 {
2402 first_error (_(incr_error));
2403 return FAIL;
2404 }
dcbf9037 2405
c921be7d 2406 if (! neon_alias_types_same (&atype, &firsttype))
477330fc
RM
2407 {
2408 first_error (_(type_error));
2409 return FAIL;
2410 }
5f4273c7 2411
5287ad62 2412 /* Handle Dn-Dm or Qn-Qm syntax. Can only be used with non-indexed list
477330fc 2413 modes. */
5287ad62 2414 if (ptr[0] == '-')
477330fc
RM
2415 {
2416 struct neon_typed_alias htype;
2417 int hireg, dregs = (rtype == REG_TYPE_NQ) ? 2 : 1;
2418 if (lane == -1)
2419 lane = NEON_INTERLEAVE_LANES;
2420 else if (lane != NEON_INTERLEAVE_LANES)
2421 {
2422 first_error (_(type_error));
2423 return FAIL;
2424 }
2425 if (reg_incr == -1)
2426 reg_incr = 1;
2427 else if (reg_incr != 1)
2428 {
2429 first_error (_("don't use Rn-Rm syntax with non-unit stride"));
2430 return FAIL;
2431 }
2432 ptr++;
2433 hireg = parse_typed_reg_or_scalar (&ptr, rtype, NULL, &htype);
2434 if (hireg == FAIL)
2435 {
2436 first_error (_(reg_expected_msgs[rtype]));
2437 return FAIL;
2438 }
2439 if (! neon_alias_types_same (&htype, &firsttype))
2440 {
2441 first_error (_(type_error));
2442 return FAIL;
2443 }
2444 count += hireg + dregs - getreg;
2445 continue;
2446 }
5f4273c7 2447
5287ad62
JB
2448 /* If we're using Q registers, we can't use [] or [n] syntax. */
2449 if (rtype == REG_TYPE_NQ)
477330fc
RM
2450 {
2451 count += 2;
2452 continue;
2453 }
5f4273c7 2454
dcbf9037 2455 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
2456 {
2457 if (lane == -1)
2458 lane = atype.index;
2459 else if (lane != atype.index)
2460 {
2461 first_error (_(type_error));
2462 return FAIL;
2463 }
2464 }
5287ad62 2465 else if (lane == -1)
477330fc 2466 lane = NEON_INTERLEAVE_LANES;
5287ad62 2467 else if (lane != NEON_INTERLEAVE_LANES)
477330fc
RM
2468 {
2469 first_error (_(type_error));
2470 return FAIL;
2471 }
5287ad62
JB
2472 count++;
2473 }
2474 while ((count != 1 || leading_brace) && skip_past_comma (&ptr) != FAIL);
5f4273c7 2475
5287ad62
JB
2476 /* No lane set by [x]. We must be interleaving structures. */
2477 if (lane == -1)
2478 lane = NEON_INTERLEAVE_LANES;
5f4273c7 2479
5287ad62 2480 /* Sanity check. */
35c228db 2481 if (lane == -1 || base_reg == -1 || count < 1 || (!mve && count > 4)
5287ad62
JB
2482 || (count > 1 && reg_incr == -1))
2483 {
dcbf9037 2484 first_error (_("error parsing element/structure list"));
5287ad62
JB
2485 return FAIL;
2486 }
2487
2488 if ((count > 1 || leading_brace) && skip_past_char (&ptr, '}') == FAIL)
2489 {
dcbf9037 2490 first_error (_("expected }"));
5287ad62
JB
2491 return FAIL;
2492 }
5f4273c7 2493
5287ad62
JB
2494 if (reg_incr == -1)
2495 reg_incr = 1;
2496
dcbf9037
JB
2497 if (eltype)
2498 *eltype = firsttype.eltype;
2499
5287ad62
JB
2500 *pbase = base_reg;
2501 *str = ptr;
5f4273c7 2502
5287ad62
JB
2503 return lane | ((reg_incr - 1) << 4) | ((count - 1) << 5);
2504}
2505
c19d1205
ZW
2506/* Parse an explicit relocation suffix on an expression. This is
2507 either nothing, or a word in parentheses. Note that if !OBJ_ELF,
2508 arm_reloc_hsh contains no entries, so this function can only
2509 succeed if there is no () after the word. Returns -1 on error,
2510 BFD_RELOC_UNUSED if there wasn't any suffix. */
3da1d841 2511
c19d1205
ZW
2512static int
2513parse_reloc (char **str)
b99bd4ef 2514{
c19d1205
ZW
2515 struct reloc_entry *r;
2516 char *p, *q;
b99bd4ef 2517
c19d1205
ZW
2518 if (**str != '(')
2519 return BFD_RELOC_UNUSED;
b99bd4ef 2520
c19d1205
ZW
2521 p = *str + 1;
2522 q = p;
2523
2524 while (*q && *q != ')' && *q != ',')
2525 q++;
2526 if (*q != ')')
2527 return -1;
2528
21d799b5 2529 if ((r = (struct reloc_entry *)
629310ab 2530 str_hash_find_n (arm_reloc_hsh, p, q - p)) == NULL)
c19d1205
ZW
2531 return -1;
2532
2533 *str = q + 1;
2534 return r->reloc;
b99bd4ef
NC
2535}
2536
c19d1205
ZW
2537/* Directives: register aliases. */
2538
dcbf9037 2539static struct reg_entry *
90ec0d68 2540insert_reg_alias (char *str, unsigned number, int type)
b99bd4ef 2541{
d3ce72d0 2542 struct reg_entry *new_reg;
c19d1205 2543 const char *name;
b99bd4ef 2544
629310ab 2545 if ((new_reg = (struct reg_entry *) str_hash_find (arm_reg_hsh, str)) != 0)
c19d1205 2546 {
d3ce72d0 2547 if (new_reg->builtin)
c19d1205 2548 as_warn (_("ignoring attempt to redefine built-in register '%s'"), str);
b99bd4ef 2549
c19d1205
ZW
2550 /* Only warn about a redefinition if it's not defined as the
2551 same register. */
d3ce72d0 2552 else if (new_reg->number != number || new_reg->type != type)
c19d1205 2553 as_warn (_("ignoring redefinition of register alias '%s'"), str);
69b97547 2554
d929913e 2555 return NULL;
c19d1205 2556 }
b99bd4ef 2557
c19d1205 2558 name = xstrdup (str);
325801bd 2559 new_reg = XNEW (struct reg_entry);
b99bd4ef 2560
d3ce72d0
NC
2561 new_reg->name = name;
2562 new_reg->number = number;
2563 new_reg->type = type;
5b7c81bd 2564 new_reg->builtin = false;
d3ce72d0 2565 new_reg->neon = NULL;
b99bd4ef 2566
fe0e921f 2567 str_hash_insert (arm_reg_hsh, name, new_reg, 0);
5f4273c7 2568
d3ce72d0 2569 return new_reg;
dcbf9037
JB
2570}
2571
2572static void
2573insert_neon_reg_alias (char *str, int number, int type,
477330fc 2574 struct neon_typed_alias *atype)
dcbf9037
JB
2575{
2576 struct reg_entry *reg = insert_reg_alias (str, number, type);
5f4273c7 2577
dcbf9037
JB
2578 if (!reg)
2579 {
2580 first_error (_("attempt to redefine typed alias"));
2581 return;
2582 }
5f4273c7 2583
dcbf9037
JB
2584 if (atype)
2585 {
325801bd 2586 reg->neon = XNEW (struct neon_typed_alias);
dcbf9037
JB
2587 *reg->neon = *atype;
2588 }
c19d1205 2589}
b99bd4ef 2590
c19d1205 2591/* Look for the .req directive. This is of the form:
b99bd4ef 2592
c19d1205 2593 new_register_name .req existing_register_name
b99bd4ef 2594
c19d1205 2595 If we find one, or if it looks sufficiently like one that we want to
d929913e 2596 handle any error here, return TRUE. Otherwise return FALSE. */
b99bd4ef 2597
5b7c81bd 2598static bool
c19d1205
ZW
2599create_register_alias (char * newname, char *p)
2600{
2601 struct reg_entry *old;
2602 char *oldname, *nbuf;
2603 size_t nlen;
b99bd4ef 2604
c19d1205
ZW
2605 /* The input scrubber ensures that whitespace after the mnemonic is
2606 collapsed to single spaces. */
2607 oldname = p;
d34049e8 2608 if (!startswith (oldname, " .req "))
5b7c81bd 2609 return false;
b99bd4ef 2610
c19d1205
ZW
2611 oldname += 6;
2612 if (*oldname == '\0')
5b7c81bd 2613 return false;
b99bd4ef 2614
629310ab 2615 old = (struct reg_entry *) str_hash_find (arm_reg_hsh, oldname);
c19d1205 2616 if (!old)
b99bd4ef 2617 {
c19d1205 2618 as_warn (_("unknown register '%s' -- .req ignored"), oldname);
5b7c81bd 2619 return true;
b99bd4ef
NC
2620 }
2621
c19d1205
ZW
2622 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2623 the desired alias name, and p points to its end. If not, then
2624 the desired alias name is in the global original_case_string. */
2625#ifdef TC_CASE_SENSITIVE
2626 nlen = p - newname;
2627#else
2628 newname = original_case_string;
2629 nlen = strlen (newname);
2630#endif
b99bd4ef 2631
29a2809e 2632 nbuf = xmemdup0 (newname, nlen);
b99bd4ef 2633
c19d1205
ZW
2634 /* Create aliases under the new name as stated; an all-lowercase
2635 version of the new name; and an all-uppercase version of the new
2636 name. */
d929913e
NC
2637 if (insert_reg_alias (nbuf, old->number, old->type) != NULL)
2638 {
2639 for (p = nbuf; *p; p++)
2640 *p = TOUPPER (*p);
c19d1205 2641
d929913e
NC
2642 if (strncmp (nbuf, newname, nlen))
2643 {
2644 /* If this attempt to create an additional alias fails, do not bother
2645 trying to create the all-lower case alias. We will fail and issue
2646 a second, duplicate error message. This situation arises when the
2647 programmer does something like:
2648 foo .req r0
2649 Foo .req r1
2650 The second .req creates the "Foo" alias but then fails to create
5f4273c7 2651 the artificial FOO alias because it has already been created by the
d929913e
NC
2652 first .req. */
2653 if (insert_reg_alias (nbuf, old->number, old->type) == NULL)
e1fa0163
NC
2654 {
2655 free (nbuf);
5b7c81bd 2656 return true;
e1fa0163 2657 }
d929913e 2658 }
c19d1205 2659
d929913e
NC
2660 for (p = nbuf; *p; p++)
2661 *p = TOLOWER (*p);
c19d1205 2662
d929913e
NC
2663 if (strncmp (nbuf, newname, nlen))
2664 insert_reg_alias (nbuf, old->number, old->type);
2665 }
c19d1205 2666
e1fa0163 2667 free (nbuf);
5b7c81bd 2668 return true;
b99bd4ef
NC
2669}
2670
dcbf9037
JB
2671/* Create a Neon typed/indexed register alias using directives, e.g.:
2672 X .dn d5.s32[1]
2673 Y .qn 6.s16
2674 Z .dn d7
2675 T .dn Z[0]
2676 These typed registers can be used instead of the types specified after the
2677 Neon mnemonic, so long as all operands given have types. Types can also be
2678 specified directly, e.g.:
5f4273c7 2679 vadd d0.s32, d1.s32, d2.s32 */
dcbf9037 2680
5b7c81bd 2681static bool
dcbf9037
JB
2682create_neon_reg_alias (char *newname, char *p)
2683{
2684 enum arm_reg_type basetype;
2685 struct reg_entry *basereg;
2686 struct reg_entry mybasereg;
2687 struct neon_type ntype;
2688 struct neon_typed_alias typeinfo;
12d6b0b7 2689 char *namebuf, *nameend ATTRIBUTE_UNUSED;
dcbf9037 2690 int namelen;
5f4273c7 2691
dcbf9037
JB
2692 typeinfo.defined = 0;
2693 typeinfo.eltype.type = NT_invtype;
2694 typeinfo.eltype.size = -1;
2695 typeinfo.index = -1;
5f4273c7 2696
dcbf9037 2697 nameend = p;
5f4273c7 2698
d34049e8 2699 if (startswith (p, " .dn "))
dcbf9037 2700 basetype = REG_TYPE_VFD;
d34049e8 2701 else if (startswith (p, " .qn "))
dcbf9037
JB
2702 basetype = REG_TYPE_NQ;
2703 else
5b7c81bd 2704 return false;
5f4273c7 2705
dcbf9037 2706 p += 5;
5f4273c7 2707
dcbf9037 2708 if (*p == '\0')
5b7c81bd 2709 return false;
5f4273c7 2710
dcbf9037
JB
2711 basereg = arm_reg_parse_multi (&p);
2712
2713 if (basereg && basereg->type != basetype)
2714 {
2715 as_bad (_("bad type for register"));
5b7c81bd 2716 return false;
dcbf9037
JB
2717 }
2718
2719 if (basereg == NULL)
2720 {
2721 expressionS exp;
2722 /* Try parsing as an integer. */
2723 my_get_expression (&exp, &p, GE_NO_PREFIX);
2724 if (exp.X_op != O_constant)
477330fc
RM
2725 {
2726 as_bad (_("expression must be constant"));
5b7c81bd 2727 return false;
477330fc 2728 }
dcbf9037
JB
2729 basereg = &mybasereg;
2730 basereg->number = (basetype == REG_TYPE_NQ) ? exp.X_add_number * 2
477330fc 2731 : exp.X_add_number;
dcbf9037
JB
2732 basereg->neon = 0;
2733 }
2734
2735 if (basereg->neon)
2736 typeinfo = *basereg->neon;
2737
2738 if (parse_neon_type (&ntype, &p) == SUCCESS)
2739 {
2740 /* We got a type. */
2741 if (typeinfo.defined & NTA_HASTYPE)
477330fc
RM
2742 {
2743 as_bad (_("can't redefine the type of a register alias"));
5b7c81bd 2744 return false;
477330fc 2745 }
5f4273c7 2746
dcbf9037
JB
2747 typeinfo.defined |= NTA_HASTYPE;
2748 if (ntype.elems != 1)
477330fc
RM
2749 {
2750 as_bad (_("you must specify a single type only"));
5b7c81bd 2751 return false;
477330fc 2752 }
dcbf9037
JB
2753 typeinfo.eltype = ntype.el[0];
2754 }
5f4273c7 2755
dcbf9037
JB
2756 if (skip_past_char (&p, '[') == SUCCESS)
2757 {
2758 expressionS exp;
2759 /* We got a scalar index. */
5f4273c7 2760
dcbf9037 2761 if (typeinfo.defined & NTA_HASINDEX)
477330fc
RM
2762 {
2763 as_bad (_("can't redefine the index of a scalar alias"));
5b7c81bd 2764 return false;
477330fc 2765 }
5f4273c7 2766
dcbf9037 2767 my_get_expression (&exp, &p, GE_NO_PREFIX);
5f4273c7 2768
dcbf9037 2769 if (exp.X_op != O_constant)
477330fc
RM
2770 {
2771 as_bad (_("scalar index must be constant"));
5b7c81bd 2772 return false;
477330fc 2773 }
5f4273c7 2774
dcbf9037
JB
2775 typeinfo.defined |= NTA_HASINDEX;
2776 typeinfo.index = exp.X_add_number;
5f4273c7 2777
dcbf9037 2778 if (skip_past_char (&p, ']') == FAIL)
477330fc
RM
2779 {
2780 as_bad (_("expecting ]"));
5b7c81bd 2781 return false;
477330fc 2782 }
dcbf9037
JB
2783 }
2784
15735687
NS
2785 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2786 the desired alias name, and p points to its end. If not, then
2787 the desired alias name is in the global original_case_string. */
2788#ifdef TC_CASE_SENSITIVE
dcbf9037 2789 namelen = nameend - newname;
15735687
NS
2790#else
2791 newname = original_case_string;
2792 namelen = strlen (newname);
2793#endif
2794
29a2809e 2795 namebuf = xmemdup0 (newname, namelen);
5f4273c7 2796
dcbf9037 2797 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2798 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2799
dcbf9037
JB
2800 /* Insert name in all uppercase. */
2801 for (p = namebuf; *p; p++)
2802 *p = TOUPPER (*p);
5f4273c7 2803
dcbf9037
JB
2804 if (strncmp (namebuf, newname, namelen))
2805 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2806 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2807
dcbf9037
JB
2808 /* Insert name in all lowercase. */
2809 for (p = namebuf; *p; p++)
2810 *p = TOLOWER (*p);
5f4273c7 2811
dcbf9037
JB
2812 if (strncmp (namebuf, newname, namelen))
2813 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2814 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2815
e1fa0163 2816 free (namebuf);
5b7c81bd 2817 return true;
dcbf9037
JB
2818}
2819
c19d1205
ZW
2820/* Should never be called, as .req goes between the alias and the
2821 register name, not at the beginning of the line. */
c921be7d 2822
b99bd4ef 2823static void
c19d1205 2824s_req (int a ATTRIBUTE_UNUSED)
b99bd4ef 2825{
c19d1205
ZW
2826 as_bad (_("invalid syntax for .req directive"));
2827}
b99bd4ef 2828
dcbf9037
JB
2829static void
2830s_dn (int a ATTRIBUTE_UNUSED)
2831{
2832 as_bad (_("invalid syntax for .dn directive"));
2833}
2834
2835static void
2836s_qn (int a ATTRIBUTE_UNUSED)
2837{
2838 as_bad (_("invalid syntax for .qn directive"));
2839}
2840
c19d1205
ZW
2841/* The .unreq directive deletes an alias which was previously defined
2842 by .req. For example:
b99bd4ef 2843
c19d1205
ZW
2844 my_alias .req r11
2845 .unreq my_alias */
b99bd4ef
NC
2846
2847static void
c19d1205 2848s_unreq (int a ATTRIBUTE_UNUSED)
b99bd4ef 2849{
c19d1205
ZW
2850 char * name;
2851 char saved_char;
b99bd4ef 2852
c19d1205 2853 name = input_line_pointer;
a37854f9 2854 input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
c19d1205
ZW
2855 saved_char = *input_line_pointer;
2856 *input_line_pointer = 0;
2857
2858 if (!*name)
2859 as_bad (_("invalid syntax for .unreq directive"));
2860 else
2861 {
fe0e921f
AM
2862 struct reg_entry *reg
2863 = (struct reg_entry *) str_hash_find (arm_reg_hsh, name);
c19d1205
ZW
2864
2865 if (!reg)
2866 as_bad (_("unknown register alias '%s'"), name);
2867 else if (reg->builtin)
a1727c1a 2868 as_warn (_("ignoring attempt to use .unreq on fixed register name: '%s'"),
c19d1205
ZW
2869 name);
2870 else
2871 {
d929913e
NC
2872 char * p;
2873 char * nbuf;
2874
629310ab 2875 str_hash_delete (arm_reg_hsh, name);
c19d1205 2876 free ((char *) reg->name);
9fbb53c7 2877 free (reg->neon);
c19d1205 2878 free (reg);
d929913e
NC
2879
2880 /* Also locate the all upper case and all lower case versions.
2881 Do not complain if we cannot find one or the other as it
2882 was probably deleted above. */
5f4273c7 2883
d929913e
NC
2884 nbuf = strdup (name);
2885 for (p = nbuf; *p; p++)
2886 *p = TOUPPER (*p);
629310ab 2887 reg = (struct reg_entry *) str_hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2888 if (reg)
2889 {
629310ab 2890 str_hash_delete (arm_reg_hsh, nbuf);
d929913e 2891 free ((char *) reg->name);
9fbb53c7 2892 free (reg->neon);
d929913e
NC
2893 free (reg);
2894 }
2895
2896 for (p = nbuf; *p; p++)
2897 *p = TOLOWER (*p);
629310ab 2898 reg = (struct reg_entry *) str_hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2899 if (reg)
2900 {
629310ab 2901 str_hash_delete (arm_reg_hsh, nbuf);
d929913e 2902 free ((char *) reg->name);
9fbb53c7 2903 free (reg->neon);
d929913e
NC
2904 free (reg);
2905 }
2906
2907 free (nbuf);
c19d1205
ZW
2908 }
2909 }
b99bd4ef 2910
c19d1205 2911 *input_line_pointer = saved_char;
b99bd4ef
NC
2912 demand_empty_rest_of_line ();
2913}
2914
c19d1205
ZW
2915/* Directives: Instruction set selection. */
2916
2917#ifdef OBJ_ELF
2918/* This code is to handle mapping symbols as defined in the ARM ELF spec.
2919 (See "Mapping symbols", section 4.5.5, ARM AAELF version 1.0).
2920 Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
2921 and $d has type STT_OBJECT (BSF_OBJECT flag). Now all three are untyped. */
2922
cd000bff
DJ
2923/* Create a new mapping symbol for the transition to STATE. */
2924
2925static void
2926make_mapping_symbol (enum mstate state, valueT value, fragS *frag)
b99bd4ef 2927{
a737bd4d 2928 symbolS * symbolP;
c19d1205
ZW
2929 const char * symname;
2930 int type;
b99bd4ef 2931
c19d1205 2932 switch (state)
b99bd4ef 2933 {
c19d1205
ZW
2934 case MAP_DATA:
2935 symname = "$d";
2936 type = BSF_NO_FLAGS;
2937 break;
2938 case MAP_ARM:
2939 symname = "$a";
2940 type = BSF_NO_FLAGS;
2941 break;
2942 case MAP_THUMB:
2943 symname = "$t";
2944 type = BSF_NO_FLAGS;
2945 break;
c19d1205
ZW
2946 default:
2947 abort ();
2948 }
2949
e01e1cee 2950 symbolP = symbol_new (symname, now_seg, frag, value);
c19d1205
ZW
2951 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2952
2953 switch (state)
2954 {
2955 case MAP_ARM:
2956 THUMB_SET_FUNC (symbolP, 0);
2957 ARM_SET_THUMB (symbolP, 0);
2958 ARM_SET_INTERWORK (symbolP, support_interwork);
2959 break;
2960
2961 case MAP_THUMB:
2962 THUMB_SET_FUNC (symbolP, 1);
2963 ARM_SET_THUMB (symbolP, 1);
2964 ARM_SET_INTERWORK (symbolP, support_interwork);
2965 break;
2966
2967 case MAP_DATA:
2968 default:
cd000bff
DJ
2969 break;
2970 }
2971
2972 /* Save the mapping symbols for future reference. Also check that
2973 we do not place two mapping symbols at the same offset within a
2974 frag. We'll handle overlap between frags in
2de7820f
JZ
2975 check_mapping_symbols.
2976
2977 If .fill or other data filling directive generates zero sized data,
2978 the mapping symbol for the following code will have the same value
2979 as the one generated for the data filling directive. In this case,
2980 we replace the old symbol with the new one at the same address. */
cd000bff
DJ
2981 if (value == 0)
2982 {
2de7820f
JZ
2983 if (frag->tc_frag_data.first_map != NULL)
2984 {
2985 know (S_GET_VALUE (frag->tc_frag_data.first_map) == 0);
2986 symbol_remove (frag->tc_frag_data.first_map, &symbol_rootP, &symbol_lastP);
2987 }
cd000bff
DJ
2988 frag->tc_frag_data.first_map = symbolP;
2989 }
2990 if (frag->tc_frag_data.last_map != NULL)
0f020cef
JZ
2991 {
2992 know (S_GET_VALUE (frag->tc_frag_data.last_map) <= S_GET_VALUE (symbolP));
0f020cef
JZ
2993 if (S_GET_VALUE (frag->tc_frag_data.last_map) == S_GET_VALUE (symbolP))
2994 symbol_remove (frag->tc_frag_data.last_map, &symbol_rootP, &symbol_lastP);
2995 }
cd000bff
DJ
2996 frag->tc_frag_data.last_map = symbolP;
2997}
2998
2999/* We must sometimes convert a region marked as code to data during
3000 code alignment, if an odd number of bytes have to be padded. The
3001 code mapping symbol is pushed to an aligned address. */
3002
3003static void
3004insert_data_mapping_symbol (enum mstate state,
3005 valueT value, fragS *frag, offsetT bytes)
3006{
3007 /* If there was already a mapping symbol, remove it. */
3008 if (frag->tc_frag_data.last_map != NULL
3009 && S_GET_VALUE (frag->tc_frag_data.last_map) == frag->fr_address + value)
3010 {
3011 symbolS *symp = frag->tc_frag_data.last_map;
3012
3013 if (value == 0)
3014 {
3015 know (frag->tc_frag_data.first_map == symp);
3016 frag->tc_frag_data.first_map = NULL;
3017 }
3018 frag->tc_frag_data.last_map = NULL;
3019 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
c19d1205 3020 }
cd000bff
DJ
3021
3022 make_mapping_symbol (MAP_DATA, value, frag);
3023 make_mapping_symbol (state, value + bytes, frag);
3024}
3025
3026static void mapping_state_2 (enum mstate state, int max_chars);
3027
3028/* Set the mapping state to STATE. Only call this when about to
3029 emit some STATE bytes to the file. */
3030
4e9aaefb 3031#define TRANSITION(from, to) (mapstate == (from) && state == (to))
cd000bff
DJ
3032void
3033mapping_state (enum mstate state)
3034{
940b5ce0
DJ
3035 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
3036
cd000bff
DJ
3037 if (mapstate == state)
3038 /* The mapping symbol has already been emitted.
3039 There is nothing else to do. */
3040 return;
49c62a33
NC
3041
3042 if (state == MAP_ARM || state == MAP_THUMB)
3043 /* PR gas/12931
3044 All ARM instructions require 4-byte alignment.
3045 (Almost) all Thumb instructions require 2-byte alignment.
3046
3047 When emitting instructions into any section, mark the section
3048 appropriately.
3049
3050 Some Thumb instructions are alignment-sensitive modulo 4 bytes,
3051 but themselves require 2-byte alignment; this applies to some
33eaf5de 3052 PC- relative forms. However, these cases will involve implicit
49c62a33
NC
3053 literal pool generation or an explicit .align >=2, both of
3054 which will cause the section to me marked with sufficient
3055 alignment. Thus, we don't handle those cases here. */
3056 record_alignment (now_seg, state == MAP_ARM ? 2 : 1);
3057
3058 if (TRANSITION (MAP_UNDEFINED, MAP_DATA))
4e9aaefb 3059 /* This case will be evaluated later. */
cd000bff 3060 return;
cd000bff
DJ
3061
3062 mapping_state_2 (state, 0);
cd000bff
DJ
3063}
3064
3065/* Same as mapping_state, but MAX_CHARS bytes have already been
3066 allocated. Put the mapping symbol that far back. */
3067
3068static void
3069mapping_state_2 (enum mstate state, int max_chars)
3070{
940b5ce0
DJ
3071 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
3072
3073 if (!SEG_NORMAL (now_seg))
3074 return;
3075
cd000bff
DJ
3076 if (mapstate == state)
3077 /* The mapping symbol has already been emitted.
3078 There is nothing else to do. */
3079 return;
3080
4e9aaefb
SA
3081 if (TRANSITION (MAP_UNDEFINED, MAP_ARM)
3082 || TRANSITION (MAP_UNDEFINED, MAP_THUMB))
3083 {
3084 struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
3085 const int add_symbol = (frag_now != frag_first) || (frag_now_fix () > 0);
3086
3087 if (add_symbol)
3088 make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
3089 }
3090
cd000bff
DJ
3091 seg_info (now_seg)->tc_segment_info_data.mapstate = state;
3092 make_mapping_symbol (state, (valueT) frag_now_fix () - max_chars, frag_now);
c19d1205 3093}
4e9aaefb 3094#undef TRANSITION
c19d1205 3095#else
d3106081
NS
3096#define mapping_state(x) ((void)0)
3097#define mapping_state_2(x, y) ((void)0)
c19d1205
ZW
3098#endif
3099
3100/* Find the real, Thumb encoded start of a Thumb function. */
3101
4343666d 3102#ifdef OBJ_COFF
c19d1205
ZW
3103static symbolS *
3104find_real_start (symbolS * symbolP)
3105{
3106 char * real_start;
3107 const char * name = S_GET_NAME (symbolP);
3108 symbolS * new_target;
3109
3110 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
3111#define STUB_NAME ".real_start_of"
3112
3113 if (name == NULL)
3114 abort ();
3115
37f6032b
ZW
3116 /* The compiler may generate BL instructions to local labels because
3117 it needs to perform a branch to a far away location. These labels
3118 do not have a corresponding ".real_start_of" label. We check
3119 both for S_IS_LOCAL and for a leading dot, to give a way to bypass
3120 the ".real_start_of" convention for nonlocal branches. */
3121 if (S_IS_LOCAL (symbolP) || name[0] == '.')
c19d1205
ZW
3122 return symbolP;
3123
e1fa0163 3124 real_start = concat (STUB_NAME, name, NULL);
c19d1205 3125 new_target = symbol_find (real_start);
e1fa0163 3126 free (real_start);
c19d1205
ZW
3127
3128 if (new_target == NULL)
3129 {
bd3ba5d1 3130 as_warn (_("Failed to find real start of function: %s\n"), name);
c19d1205
ZW
3131 new_target = symbolP;
3132 }
3133
c19d1205
ZW
3134 return new_target;
3135}
4343666d 3136#endif
c19d1205
ZW
3137
3138static void
3139opcode_select (int width)
3140{
3141 switch (width)
3142 {
3143 case 16:
3144 if (! thumb_mode)
3145 {
e74cfd16 3146 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
c19d1205
ZW
3147 as_bad (_("selected processor does not support THUMB opcodes"));
3148
3149 thumb_mode = 1;
3150 /* No need to force the alignment, since we will have been
3151 coming from ARM mode, which is word-aligned. */
3152 record_alignment (now_seg, 1);
3153 }
c19d1205
ZW
3154 break;
3155
3156 case 32:
3157 if (thumb_mode)
3158 {
e74cfd16 3159 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205
ZW
3160 as_bad (_("selected processor does not support ARM opcodes"));
3161
3162 thumb_mode = 0;
3163
3164 if (!need_pass_2)
3165 frag_align (2, 0, 0);
3166
3167 record_alignment (now_seg, 1);
3168 }
c19d1205
ZW
3169 break;
3170
3171 default:
3172 as_bad (_("invalid instruction size selected (%d)"), width);
3173 }
3174}
3175
3176static void
3177s_arm (int ignore ATTRIBUTE_UNUSED)
3178{
3179 opcode_select (32);
3180 demand_empty_rest_of_line ();
3181}
3182
3183static void
3184s_thumb (int ignore ATTRIBUTE_UNUSED)
3185{
3186 opcode_select (16);
3187 demand_empty_rest_of_line ();
3188}
3189
3190static void
3191s_code (int unused ATTRIBUTE_UNUSED)
3192{
3193 int temp;
3194
3195 temp = get_absolute_expression ();
3196 switch (temp)
3197 {
3198 case 16:
3199 case 32:
3200 opcode_select (temp);
3201 break;
3202
3203 default:
3204 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3205 }
a37854f9 3206 demand_empty_rest_of_line ();
c19d1205
ZW
3207}
3208
3209static void
3210s_force_thumb (int ignore ATTRIBUTE_UNUSED)
3211{
3212 /* If we are not already in thumb mode go into it, EVEN if
3213 the target processor does not support thumb instructions.
3214 This is used by gcc/config/arm/lib1funcs.asm for example
3215 to compile interworking support functions even if the
3216 target processor should not support interworking. */
3217 if (! thumb_mode)
3218 {
3219 thumb_mode = 2;
3220 record_alignment (now_seg, 1);
3221 }
3222
3223 demand_empty_rest_of_line ();
3224}
3225
3226static void
3227s_thumb_func (int ignore ATTRIBUTE_UNUSED)
3228{
a37854f9 3229 s_thumb (0); /* Will check for end-of-line. */
c19d1205
ZW
3230
3231 /* The following label is the name/address of the start of a Thumb function.
3232 We need to know this for the interworking support. */
5b7c81bd 3233 label_is_thumb_function_name = true;
c19d1205
ZW
3234}
3235
3236/* Perform a .set directive, but also mark the alias as
3237 being a thumb function. */
3238
3239static void
3240s_thumb_set (int equiv)
3241{
3242 /* XXX the following is a duplicate of the code for s_set() in read.c
3243 We cannot just call that code as we need to get at the symbol that
3244 is created. */
3245 char * name;
3246 char delim;
3247 char * end_name;
3248 symbolS * symbolP;
3249
3250 /* Especial apologies for the random logic:
3251 This just grew, and could be parsed much more simply!
3252 Dean - in haste. */
d02603dc 3253 delim = get_symbol_name (& name);
c19d1205 3254 end_name = input_line_pointer;
d02603dc 3255 (void) restore_line_pointer (delim);
c19d1205
ZW
3256
3257 if (*input_line_pointer != ',')
3258 {
3259 *end_name = 0;
3260 as_bad (_("expected comma after name \"%s\""), name);
b99bd4ef
NC
3261 *end_name = delim;
3262 ignore_rest_of_line ();
3263 return;
3264 }
3265
3266 input_line_pointer++;
3267 *end_name = 0;
3268
3269 if (name[0] == '.' && name[1] == '\0')
3270 {
3271 /* XXX - this should not happen to .thumb_set. */
3272 abort ();
3273 }
3274
3275 if ((symbolP = symbol_find (name)) == NULL
3276 && (symbolP = md_undefined_symbol (name)) == NULL)
3277 {
3278#ifndef NO_LISTING
3279 /* When doing symbol listings, play games with dummy fragments living
3280 outside the normal fragment chain to record the file and line info
c19d1205 3281 for this symbol. */
b99bd4ef
NC
3282 if (listing & LISTING_SYMBOLS)
3283 {
3284 extern struct list_info_struct * listing_tail;
21d799b5 3285 fragS * dummy_frag = (fragS * ) xmalloc (sizeof (fragS));
b99bd4ef
NC
3286
3287 memset (dummy_frag, 0, sizeof (fragS));
3288 dummy_frag->fr_type = rs_fill;
3289 dummy_frag->line = listing_tail;
e01e1cee 3290 symbolP = symbol_new (name, undefined_section, dummy_frag, 0);
b99bd4ef
NC
3291 dummy_frag->fr_symbol = symbolP;
3292 }
3293 else
3294#endif
e01e1cee 3295 symbolP = symbol_new (name, undefined_section, &zero_address_frag, 0);
b99bd4ef
NC
3296
3297#ifdef OBJ_COFF
3298 /* "set" symbols are local unless otherwise specified. */
3299 SF_SET_LOCAL (symbolP);
3300#endif /* OBJ_COFF */
3301 } /* Make a new symbol. */
3302
3303 symbol_table_insert (symbolP);
3304
3305 * end_name = delim;
3306
3307 if (equiv
3308 && S_IS_DEFINED (symbolP)
3309 && S_GET_SEGMENT (symbolP) != reg_section)
3310 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3311
3312 pseudo_set (symbolP);
3313
3314 demand_empty_rest_of_line ();
3315
c19d1205 3316 /* XXX Now we come to the Thumb specific bit of code. */
b99bd4ef
NC
3317
3318 THUMB_SET_FUNC (symbolP, 1);
3319 ARM_SET_THUMB (symbolP, 1);
3320#if defined OBJ_ELF || defined OBJ_COFF
3321 ARM_SET_INTERWORK (symbolP, support_interwork);
3322#endif
3323}
3324
c19d1205 3325/* Directives: Mode selection. */
b99bd4ef 3326
c19d1205
ZW
3327/* .syntax [unified|divided] - choose the new unified syntax
3328 (same for Arm and Thumb encoding, modulo slight differences in what
3329 can be represented) or the old divergent syntax for each mode. */
b99bd4ef 3330static void
c19d1205 3331s_syntax (int unused ATTRIBUTE_UNUSED)
b99bd4ef 3332{
c19d1205
ZW
3333 char *name, delim;
3334
d02603dc 3335 delim = get_symbol_name (& name);
c19d1205
ZW
3336
3337 if (!strcasecmp (name, "unified"))
5b7c81bd 3338 unified_syntax = true;
c19d1205 3339 else if (!strcasecmp (name, "divided"))
5b7c81bd 3340 unified_syntax = false;
c19d1205
ZW
3341 else
3342 {
3343 as_bad (_("unrecognized syntax mode \"%s\""), name);
3344 return;
3345 }
d02603dc 3346 (void) restore_line_pointer (delim);
b99bd4ef
NC
3347 demand_empty_rest_of_line ();
3348}
3349
c19d1205
ZW
3350/* Directives: sectioning and alignment. */
3351
c19d1205
ZW
3352static void
3353s_bss (int ignore ATTRIBUTE_UNUSED)
b99bd4ef 3354{
c19d1205
ZW
3355 /* We don't support putting frags in the BSS segment, we fake it by
3356 marking in_bss, then looking at s_skip for clues. */
3357 subseg_set (bss_section, 0);
3358 demand_empty_rest_of_line ();
cd000bff
DJ
3359
3360#ifdef md_elf_section_change_hook
3361 md_elf_section_change_hook ();
3362#endif
c19d1205 3363}
b99bd4ef 3364
c19d1205
ZW
3365static void
3366s_even (int ignore ATTRIBUTE_UNUSED)
3367{
3368 /* Never make frag if expect extra pass. */
3369 if (!need_pass_2)
3370 frag_align (1, 0, 0);
b99bd4ef 3371
c19d1205 3372 record_alignment (now_seg, 1);
b99bd4ef 3373
c19d1205 3374 demand_empty_rest_of_line ();
b99bd4ef
NC
3375}
3376
2e6976a8
DG
3377/* Directives: CodeComposer Studio. */
3378
3379/* .ref (for CodeComposer Studio syntax only). */
3380static void
3381s_ccs_ref (int unused ATTRIBUTE_UNUSED)
3382{
3383 if (codecomposer_syntax)
3384 ignore_rest_of_line ();
3385 else
3386 as_bad (_(".ref pseudo-op only available with -mccs flag."));
3387}
3388
3389/* If name is not NULL, then it is used for marking the beginning of a
2b0f3761 3390 function, whereas if it is NULL then it means the function end. */
2e6976a8
DG
3391static void
3392asmfunc_debug (const char * name)
3393{
3394 static const char * last_name = NULL;
3395
3396 if (name != NULL)
3397 {
3398 gas_assert (last_name == NULL);
3399 last_name = name;
3400
3401 if (debug_type == DEBUG_STABS)
3402 stabs_generate_asm_func (name, name);
3403 }
3404 else
3405 {
3406 gas_assert (last_name != NULL);
3407
3408 if (debug_type == DEBUG_STABS)
3409 stabs_generate_asm_endfunc (last_name, last_name);
3410
3411 last_name = NULL;
3412 }
3413}
3414
3415static void
3416s_ccs_asmfunc (int unused ATTRIBUTE_UNUSED)
3417{
3418 if (codecomposer_syntax)
3419 {
3420 switch (asmfunc_state)
3421 {
3422 case OUTSIDE_ASMFUNC:
3423 asmfunc_state = WAITING_ASMFUNC_NAME;
3424 break;
3425
3426 case WAITING_ASMFUNC_NAME:
3427 as_bad (_(".asmfunc repeated."));
3428 break;
3429
3430 case WAITING_ENDASMFUNC:
3431 as_bad (_(".asmfunc without function."));
3432 break;
3433 }
3434 demand_empty_rest_of_line ();
3435 }
3436 else
3437 as_bad (_(".asmfunc pseudo-op only available with -mccs flag."));
3438}
3439
3440static void
3441s_ccs_endasmfunc (int unused ATTRIBUTE_UNUSED)
3442{
3443 if (codecomposer_syntax)
3444 {
3445 switch (asmfunc_state)
3446 {
3447 case OUTSIDE_ASMFUNC:
3448 as_bad (_(".endasmfunc without a .asmfunc."));
3449 break;
3450
3451 case WAITING_ASMFUNC_NAME:
3452 as_bad (_(".endasmfunc without function."));
3453 break;
3454
3455 case WAITING_ENDASMFUNC:
3456 asmfunc_state = OUTSIDE_ASMFUNC;
3457 asmfunc_debug (NULL);
3458 break;
3459 }
3460 demand_empty_rest_of_line ();
3461 }
3462 else
3463 as_bad (_(".endasmfunc pseudo-op only available with -mccs flag."));
3464}
3465
3466static void
3467s_ccs_def (int name)
3468{
3469 if (codecomposer_syntax)
3470 s_globl (name);
3471 else
3472 as_bad (_(".def pseudo-op only available with -mccs flag."));
3473}
3474
c19d1205 3475/* Directives: Literal pools. */
a737bd4d 3476
c19d1205
ZW
3477static literal_pool *
3478find_literal_pool (void)
a737bd4d 3479{
c19d1205 3480 literal_pool * pool;
a737bd4d 3481
c19d1205 3482 for (pool = list_of_pools; pool != NULL; pool = pool->next)
a737bd4d 3483 {
c19d1205
ZW
3484 if (pool->section == now_seg
3485 && pool->sub_section == now_subseg)
3486 break;
a737bd4d
NC
3487 }
3488
c19d1205 3489 return pool;
a737bd4d
NC
3490}
3491
c19d1205
ZW
3492static literal_pool *
3493find_or_make_literal_pool (void)
a737bd4d 3494{
c19d1205
ZW
3495 /* Next literal pool ID number. */
3496 static unsigned int latest_pool_num = 1;
3497 literal_pool * pool;
a737bd4d 3498
c19d1205 3499 pool = find_literal_pool ();
a737bd4d 3500
c19d1205 3501 if (pool == NULL)
a737bd4d 3502 {
c19d1205 3503 /* Create a new pool. */
325801bd 3504 pool = XNEW (literal_pool);
c19d1205
ZW
3505 if (! pool)
3506 return NULL;
a737bd4d 3507
c19d1205
ZW
3508 pool->next_free_entry = 0;
3509 pool->section = now_seg;
3510 pool->sub_section = now_subseg;
3511 pool->next = list_of_pools;
3512 pool->symbol = NULL;
8335d6aa 3513 pool->alignment = 2;
c19d1205
ZW
3514
3515 /* Add it to the list. */
3516 list_of_pools = pool;
a737bd4d 3517 }
a737bd4d 3518
c19d1205
ZW
3519 /* New pools, and emptied pools, will have a NULL symbol. */
3520 if (pool->symbol == NULL)
a737bd4d 3521 {
c19d1205 3522 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
e01e1cee 3523 &zero_address_frag, 0);
c19d1205 3524 pool->id = latest_pool_num ++;
a737bd4d
NC
3525 }
3526
c19d1205
ZW
3527 /* Done. */
3528 return pool;
a737bd4d
NC
3529}
3530
c19d1205 3531/* Add the literal in the global 'inst'
5f4273c7 3532 structure to the relevant literal pool. */
b99bd4ef
NC
3533
3534static int
8335d6aa 3535add_to_lit_pool (unsigned int nbytes)
b99bd4ef 3536{
8335d6aa
JW
3537#define PADDING_SLOT 0x1
3538#define LIT_ENTRY_SIZE_MASK 0xFF
c19d1205 3539 literal_pool * pool;
8335d6aa 3540 unsigned int entry, pool_size = 0;
5b7c81bd 3541 bool padding_slot_p = false;
e56c722b 3542 unsigned imm1 = 0;
8335d6aa
JW
3543 unsigned imm2 = 0;
3544
3545 if (nbytes == 8)
3546 {
3547 imm1 = inst.operands[1].imm;
3548 imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
e2b0ab59 3549 : inst.relocs[0].exp.X_unsigned ? 0
0e3c1eeb 3550 : (int64_t) inst.operands[1].imm >> 32);
8335d6aa
JW
3551 if (target_big_endian)
3552 {
3553 imm1 = imm2;
3554 imm2 = inst.operands[1].imm;
3555 }
3556 }
b99bd4ef 3557
c19d1205
ZW
3558 pool = find_or_make_literal_pool ();
3559
3560 /* Check if this literal value is already in the pool. */
3561 for (entry = 0; entry < pool->next_free_entry; entry ++)
b99bd4ef 3562 {
8335d6aa
JW
3563 if (nbytes == 4)
3564 {
e2b0ab59
AV
3565 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3566 && (inst.relocs[0].exp.X_op == O_constant)
8335d6aa 3567 && (pool->literals[entry].X_add_number
e2b0ab59 3568 == inst.relocs[0].exp.X_add_number)
8335d6aa
JW
3569 && (pool->literals[entry].X_md == nbytes)
3570 && (pool->literals[entry].X_unsigned
e2b0ab59 3571 == inst.relocs[0].exp.X_unsigned))
8335d6aa
JW
3572 break;
3573
e2b0ab59
AV
3574 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3575 && (inst.relocs[0].exp.X_op == O_symbol)
8335d6aa 3576 && (pool->literals[entry].X_add_number
e2b0ab59 3577 == inst.relocs[0].exp.X_add_number)
8335d6aa 3578 && (pool->literals[entry].X_add_symbol
e2b0ab59 3579 == inst.relocs[0].exp.X_add_symbol)
8335d6aa 3580 && (pool->literals[entry].X_op_symbol
e2b0ab59 3581 == inst.relocs[0].exp.X_op_symbol)
8335d6aa
JW
3582 && (pool->literals[entry].X_md == nbytes))
3583 break;
3584 }
3585 else if ((nbytes == 8)
3586 && !(pool_size & 0x7)
3587 && ((entry + 1) != pool->next_free_entry)
3588 && (pool->literals[entry].X_op == O_constant)
19f2f6a9 3589 && (pool->literals[entry].X_add_number == (offsetT) imm1)
8335d6aa 3590 && (pool->literals[entry].X_unsigned
e2b0ab59 3591 == inst.relocs[0].exp.X_unsigned)
8335d6aa 3592 && (pool->literals[entry + 1].X_op == O_constant)
19f2f6a9 3593 && (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
8335d6aa 3594 && (pool->literals[entry + 1].X_unsigned
e2b0ab59 3595 == inst.relocs[0].exp.X_unsigned))
c19d1205
ZW
3596 break;
3597
8335d6aa
JW
3598 padding_slot_p = ((pool->literals[entry].X_md >> 8) == PADDING_SLOT);
3599 if (padding_slot_p && (nbytes == 4))
c19d1205 3600 break;
8335d6aa
JW
3601
3602 pool_size += 4;
b99bd4ef
NC
3603 }
3604
c19d1205
ZW
3605 /* Do we need to create a new entry? */
3606 if (entry == pool->next_free_entry)
3607 {
3608 if (entry >= MAX_LITERAL_POOL_SIZE)
3609 {
3610 inst.error = _("literal pool overflow");
3611 return FAIL;
3612 }
3613
8335d6aa
JW
3614 if (nbytes == 8)
3615 {
3616 /* For 8-byte entries, we align to an 8-byte boundary,
3617 and split it into two 4-byte entries, because on 32-bit
3618 host, 8-byte constants are treated as big num, thus
3619 saved in "generic_bignum" which will be overwritten
3620 by later assignments.
3621
3622 We also need to make sure there is enough space for
3623 the split.
3624
3625 We also check to make sure the literal operand is a
3626 constant number. */
e2b0ab59
AV
3627 if (!(inst.relocs[0].exp.X_op == O_constant
3628 || inst.relocs[0].exp.X_op == O_big))
8335d6aa
JW
3629 {
3630 inst.error = _("invalid type for literal pool");
3631 return FAIL;
3632 }
3633 else if (pool_size & 0x7)
3634 {
3635 if ((entry + 2) >= MAX_LITERAL_POOL_SIZE)
3636 {
3637 inst.error = _("literal pool overflow");
3638 return FAIL;
3639 }
3640
e2b0ab59 3641 pool->literals[entry] = inst.relocs[0].exp;
a6684f0d 3642 pool->literals[entry].X_op = O_constant;
8335d6aa
JW
3643 pool->literals[entry].X_add_number = 0;
3644 pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
3645 pool->next_free_entry += 1;
3646 pool_size += 4;
3647 }
3648 else if ((entry + 1) >= MAX_LITERAL_POOL_SIZE)
3649 {
3650 inst.error = _("literal pool overflow");
3651 return FAIL;
3652 }
3653
e2b0ab59 3654 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3655 pool->literals[entry].X_op = O_constant;
3656 pool->literals[entry].X_add_number = imm1;
e2b0ab59 3657 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa 3658 pool->literals[entry++].X_md = 4;
e2b0ab59 3659 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3660 pool->literals[entry].X_op = O_constant;
3661 pool->literals[entry].X_add_number = imm2;
e2b0ab59 3662 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa
JW
3663 pool->literals[entry].X_md = 4;
3664 pool->alignment = 3;
3665 pool->next_free_entry += 1;
3666 }
3667 else
3668 {
e2b0ab59 3669 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3670 pool->literals[entry].X_md = 4;
3671 }
3672
a8040cf2
NC
3673#ifdef OBJ_ELF
3674 /* PR ld/12974: Record the location of the first source line to reference
3675 this entry in the literal pool. If it turns out during linking that the
3676 symbol does not exist we will be able to give an accurate line number for
3677 the (first use of the) missing reference. */
3678 if (debug_type == DEBUG_DWARF2)
3679 dwarf2_where (pool->locs + entry);
3680#endif
c19d1205
ZW
3681 pool->next_free_entry += 1;
3682 }
8335d6aa
JW
3683 else if (padding_slot_p)
3684 {
e2b0ab59 3685 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3686 pool->literals[entry].X_md = nbytes;
3687 }
b99bd4ef 3688
e2b0ab59
AV
3689 inst.relocs[0].exp.X_op = O_symbol;
3690 inst.relocs[0].exp.X_add_number = pool_size;
3691 inst.relocs[0].exp.X_add_symbol = pool->symbol;
b99bd4ef 3692
c19d1205 3693 return SUCCESS;
b99bd4ef
NC
3694}
3695
5b7c81bd 3696bool
2e57ce7b 3697tc_start_label_without_colon (void)
2e6976a8 3698{
5b7c81bd 3699 bool ret = true;
2e6976a8
DG
3700
3701 if (codecomposer_syntax && asmfunc_state == WAITING_ASMFUNC_NAME)
3702 {
2e57ce7b 3703 const char *label = input_line_pointer;
2e6976a8
DG
3704
3705 while (!is_end_of_line[(int) label[-1]])
3706 --label;
3707
3708 if (*label == '.')
3709 {
3710 as_bad (_("Invalid label '%s'"), label);
5b7c81bd 3711 ret = false;
2e6976a8
DG
3712 }
3713
3714 asmfunc_debug (label);
3715
3716 asmfunc_state = WAITING_ENDASMFUNC;
3717 }
3718
3719 return ret;
3720}
3721
c19d1205 3722/* Can't use symbol_new here, so have to create a symbol and then at
33eaf5de 3723 a later date assign it a value. That's what these functions do. */
e16bb312 3724
c19d1205
ZW
3725static void
3726symbol_locate (symbolS * symbolP,
3727 const char * name, /* It is copied, the caller can modify. */
3728 segT segment, /* Segment identifier (SEG_<something>). */
3729 valueT valu, /* Symbol value. */
3730 fragS * frag) /* Associated fragment. */
3731{
e57e6ddc 3732 size_t name_length;
c19d1205 3733 char * preserved_copy_of_name;
e16bb312 3734
c19d1205
ZW
3735 name_length = strlen (name) + 1; /* +1 for \0. */
3736 obstack_grow (&notes, name, name_length);
21d799b5 3737 preserved_copy_of_name = (char *) obstack_finish (&notes);
e16bb312 3738
c19d1205
ZW
3739#ifdef tc_canonicalize_symbol_name
3740 preserved_copy_of_name =
3741 tc_canonicalize_symbol_name (preserved_copy_of_name);
3742#endif
b99bd4ef 3743
c19d1205 3744 S_SET_NAME (symbolP, preserved_copy_of_name);
b99bd4ef 3745
c19d1205
ZW
3746 S_SET_SEGMENT (symbolP, segment);
3747 S_SET_VALUE (symbolP, valu);
3748 symbol_clear_list_pointers (symbolP);
b99bd4ef 3749
c19d1205 3750 symbol_set_frag (symbolP, frag);
b99bd4ef 3751
c19d1205
ZW
3752 /* Link to end of symbol chain. */
3753 {
3754 extern int symbol_table_frozen;
b99bd4ef 3755
c19d1205
ZW
3756 if (symbol_table_frozen)
3757 abort ();
3758 }
b99bd4ef 3759
c19d1205 3760 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
b99bd4ef 3761
c19d1205 3762 obj_symbol_new_hook (symbolP);
b99bd4ef 3763
c19d1205
ZW
3764#ifdef tc_symbol_new_hook
3765 tc_symbol_new_hook (symbolP);
3766#endif
3767
3768#ifdef DEBUG_SYMS
3769 verify_symbol_chain (symbol_rootP, symbol_lastP);
3770#endif /* DEBUG_SYMS */
b99bd4ef
NC
3771}
3772
c19d1205
ZW
3773static void
3774s_ltorg (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 3775{
c19d1205
ZW
3776 unsigned int entry;
3777 literal_pool * pool;
3778 char sym_name[20];
b99bd4ef 3779
a37854f9 3780 demand_empty_rest_of_line ();
c19d1205
ZW
3781 pool = find_literal_pool ();
3782 if (pool == NULL
3783 || pool->symbol == NULL
3784 || pool->next_free_entry == 0)
3785 return;
b99bd4ef 3786
c19d1205
ZW
3787 /* Align pool as you have word accesses.
3788 Only make a frag if we have to. */
3789 if (!need_pass_2)
8335d6aa 3790 frag_align (pool->alignment, 0, 0);
b99bd4ef 3791
c19d1205 3792 record_alignment (now_seg, 2);
b99bd4ef 3793
aaca88ef 3794#ifdef OBJ_ELF
47fc6e36
WN
3795 seg_info (now_seg)->tc_segment_info_data.mapstate = MAP_DATA;
3796 make_mapping_symbol (MAP_DATA, (valueT) frag_now_fix (), frag_now);
aaca88ef 3797#endif
c19d1205 3798 sprintf (sym_name, "$$lit_\002%x", pool->id);
b99bd4ef 3799
c19d1205
ZW
3800 symbol_locate (pool->symbol, sym_name, now_seg,
3801 (valueT) frag_now_fix (), frag_now);
3802 symbol_table_insert (pool->symbol);
b99bd4ef 3803
c19d1205 3804 ARM_SET_THUMB (pool->symbol, thumb_mode);
b99bd4ef 3805
c19d1205
ZW
3806#if defined OBJ_COFF || defined OBJ_ELF
3807 ARM_SET_INTERWORK (pool->symbol, support_interwork);
3808#endif
6c43fab6 3809
c19d1205 3810 for (entry = 0; entry < pool->next_free_entry; entry ++)
a8040cf2
NC
3811 {
3812#ifdef OBJ_ELF
3813 if (debug_type == DEBUG_DWARF2)
3814 dwarf2_gen_line_info (frag_now_fix (), pool->locs + entry);
3815#endif
3816 /* First output the expression in the instruction to the pool. */
8335d6aa
JW
3817 emit_expr (&(pool->literals[entry]),
3818 pool->literals[entry].X_md & LIT_ENTRY_SIZE_MASK);
a8040cf2 3819 }
b99bd4ef 3820
c19d1205
ZW
3821 /* Mark the pool as empty. */
3822 pool->next_free_entry = 0;
3823 pool->symbol = NULL;
b99bd4ef
NC
3824}
3825
c19d1205
ZW
3826#ifdef OBJ_ELF
3827/* Forward declarations for functions below, in the MD interface
3828 section. */
3829static void fix_new_arm (fragS *, int, short, expressionS *, int, int);
3830static valueT create_unwind_entry (int);
3831static void start_unwind_section (const segT, int);
3832static void add_unwind_opcode (valueT, int);
3833static void flush_pending_unwind (void);
b99bd4ef 3834
c19d1205 3835/* Directives: Data. */
b99bd4ef 3836
c19d1205
ZW
3837static void
3838s_arm_elf_cons (int nbytes)
3839{
3840 expressionS exp;
b99bd4ef 3841
c19d1205
ZW
3842#ifdef md_flush_pending_output
3843 md_flush_pending_output ();
3844#endif
b99bd4ef 3845
c19d1205 3846 if (is_it_end_of_statement ())
b99bd4ef 3847 {
c19d1205
ZW
3848 demand_empty_rest_of_line ();
3849 return;
b99bd4ef
NC
3850 }
3851
c19d1205
ZW
3852#ifdef md_cons_align
3853 md_cons_align (nbytes);
3854#endif
b99bd4ef 3855
c19d1205
ZW
3856 mapping_state (MAP_DATA);
3857 do
b99bd4ef 3858 {
c19d1205
ZW
3859 int reloc;
3860 char *base = input_line_pointer;
b99bd4ef 3861
c19d1205 3862 expression (& exp);
b99bd4ef 3863
c19d1205
ZW
3864 if (exp.X_op != O_symbol)
3865 emit_expr (&exp, (unsigned int) nbytes);
3866 else
3867 {
3868 char *before_reloc = input_line_pointer;
3869 reloc = parse_reloc (&input_line_pointer);
3870 if (reloc == -1)
3871 {
3872 as_bad (_("unrecognized relocation suffix"));
3873 ignore_rest_of_line ();
3874 return;
3875 }
3876 else if (reloc == BFD_RELOC_UNUSED)
3877 emit_expr (&exp, (unsigned int) nbytes);
3878 else
3879 {
21d799b5 3880 reloc_howto_type *howto = (reloc_howto_type *)
477330fc
RM
3881 bfd_reloc_type_lookup (stdoutput,
3882 (bfd_reloc_code_real_type) reloc);
c19d1205 3883 int size = bfd_get_reloc_size (howto);
b99bd4ef 3884
2fc8bdac
ZW
3885 if (reloc == BFD_RELOC_ARM_PLT32)
3886 {
3887 as_bad (_("(plt) is only valid on branch targets"));
3888 reloc = BFD_RELOC_UNUSED;
3889 size = 0;
3890 }
3891
c19d1205 3892 if (size > nbytes)
992a06ee
AM
3893 as_bad (ngettext ("%s relocations do not fit in %d byte",
3894 "%s relocations do not fit in %d bytes",
3895 nbytes),
c19d1205
ZW
3896 howto->name, nbytes);
3897 else
3898 {
3899 /* We've parsed an expression stopping at O_symbol.
3900 But there may be more expression left now that we
3901 have parsed the relocation marker. Parse it again.
3902 XXX Surely there is a cleaner way to do this. */
3903 char *p = input_line_pointer;
3904 int offset;
325801bd 3905 char *save_buf = XNEWVEC (char, input_line_pointer - base);
e1fa0163 3906
c19d1205
ZW
3907 memcpy (save_buf, base, input_line_pointer - base);
3908 memmove (base + (input_line_pointer - before_reloc),
3909 base, before_reloc - base);
3910
3911 input_line_pointer = base + (input_line_pointer-before_reloc);
3912 expression (&exp);
3913 memcpy (base, save_buf, p - base);
3914
3915 offset = nbytes - size;
4b1a927e
AM
3916 p = frag_more (nbytes);
3917 memset (p, 0, nbytes);
c19d1205 3918 fix_new_exp (frag_now, p - frag_now->fr_literal + offset,
21d799b5 3919 size, &exp, 0, (enum bfd_reloc_code_real) reloc);
e1fa0163 3920 free (save_buf);
c19d1205
ZW
3921 }
3922 }
3923 }
b99bd4ef 3924 }
c19d1205 3925 while (*input_line_pointer++ == ',');
b99bd4ef 3926
c19d1205
ZW
3927 /* Put terminator back into stream. */
3928 input_line_pointer --;
3929 demand_empty_rest_of_line ();
b99bd4ef
NC
3930}
3931
c921be7d
NC
3932/* Emit an expression containing a 32-bit thumb instruction.
3933 Implementation based on put_thumb32_insn. */
3934
3935static void
3936emit_thumb32_expr (expressionS * exp)
3937{
3938 expressionS exp_high = *exp;
3939
3940 exp_high.X_add_number = (unsigned long)exp_high.X_add_number >> 16;
3941 emit_expr (& exp_high, (unsigned int) THUMB_SIZE);
3942 exp->X_add_number &= 0xffff;
3943 emit_expr (exp, (unsigned int) THUMB_SIZE);
3944}
3945
3946/* Guess the instruction size based on the opcode. */
3947
3948static int
3949thumb_insn_size (int opcode)
3950{
3951 if ((unsigned int) opcode < 0xe800u)
3952 return 2;
3953 else if ((unsigned int) opcode >= 0xe8000000u)
3954 return 4;
3955 else
3956 return 0;
3957}
3958
5b7c81bd 3959static bool
c921be7d
NC
3960emit_insn (expressionS *exp, int nbytes)
3961{
3962 int size = 0;
3963
3964 if (exp->X_op == O_constant)
3965 {
3966 size = nbytes;
3967
3968 if (size == 0)
3969 size = thumb_insn_size (exp->X_add_number);
3970
3971 if (size != 0)
3972 {
3973 if (size == 2 && (unsigned int)exp->X_add_number > 0xffffu)
3974 {
3975 as_bad (_(".inst.n operand too big. "\
3976 "Use .inst.w instead"));
3977 size = 0;
3978 }
3979 else
3980 {
5ee91343
AV
3981 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
3982 set_pred_insn_type_nonvoid (OUTSIDE_PRED_INSN, 0);
c921be7d 3983 else
5ee91343 3984 set_pred_insn_type_nonvoid (NEUTRAL_IT_INSN, 0);
c921be7d
NC
3985
3986 if (thumb_mode && (size > THUMB_SIZE) && !target_big_endian)
3987 emit_thumb32_expr (exp);
3988 else
3989 emit_expr (exp, (unsigned int) size);
3990
3991 it_fsm_post_encode ();
3992 }
3993 }
3994 else
3995 as_bad (_("cannot determine Thumb instruction size. " \
3996 "Use .inst.n/.inst.w instead"));
3997 }
3998 else
3999 as_bad (_("constant expression required"));
4000
4001 return (size != 0);
4002}
4003
4004/* Like s_arm_elf_cons but do not use md_cons_align and
4005 set the mapping state to MAP_ARM/MAP_THUMB. */
4006
4007static void
4008s_arm_elf_inst (int nbytes)
4009{
4010 if (is_it_end_of_statement ())
4011 {
4012 demand_empty_rest_of_line ();
4013 return;
4014 }
4015
4016 /* Calling mapping_state () here will not change ARM/THUMB,
4017 but will ensure not to be in DATA state. */
4018
4019 if (thumb_mode)
4020 mapping_state (MAP_THUMB);
4021 else
4022 {
4023 if (nbytes != 0)
4024 {
4025 as_bad (_("width suffixes are invalid in ARM mode"));
4026 ignore_rest_of_line ();
4027 return;
4028 }
4029
4030 nbytes = 4;
4031
4032 mapping_state (MAP_ARM);
4033 }
4034
13d414af
JB
4035 dwarf2_emit_insn (0);
4036
c921be7d
NC
4037 do
4038 {
4039 expressionS exp;
4040
4041 expression (& exp);
4042
4043 if (! emit_insn (& exp, nbytes))
4044 {
4045 ignore_rest_of_line ();
4046 return;
4047 }
4048 }
4049 while (*input_line_pointer++ == ',');
4050
4051 /* Put terminator back into stream. */
4052 input_line_pointer --;
4053 demand_empty_rest_of_line ();
4054}
b99bd4ef 4055
c19d1205 4056/* Parse a .rel31 directive. */
b99bd4ef 4057
c19d1205
ZW
4058static void
4059s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
4060{
4061 expressionS exp;
4062 char *p;
4063 valueT highbit;
b99bd4ef 4064
c19d1205
ZW
4065 highbit = 0;
4066 if (*input_line_pointer == '1')
4067 highbit = 0x80000000;
4068 else if (*input_line_pointer != '0')
4069 as_bad (_("expected 0 or 1"));
b99bd4ef 4070
c19d1205
ZW
4071 input_line_pointer++;
4072 if (*input_line_pointer != ',')
4073 as_bad (_("missing comma"));
4074 input_line_pointer++;
b99bd4ef 4075
c19d1205
ZW
4076#ifdef md_flush_pending_output
4077 md_flush_pending_output ();
4078#endif
b99bd4ef 4079
c19d1205
ZW
4080#ifdef md_cons_align
4081 md_cons_align (4);
4082#endif
b99bd4ef 4083
c19d1205 4084 mapping_state (MAP_DATA);
b99bd4ef 4085
c19d1205 4086 expression (&exp);
b99bd4ef 4087
c19d1205
ZW
4088 p = frag_more (4);
4089 md_number_to_chars (p, highbit, 4);
4090 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
4091 BFD_RELOC_ARM_PREL31);
b99bd4ef 4092
c19d1205 4093 demand_empty_rest_of_line ();
b99bd4ef
NC
4094}
4095
c19d1205 4096/* Directives: AEABI stack-unwind tables. */
b99bd4ef 4097
c19d1205 4098/* Parse an unwind_fnstart directive. Simply records the current location. */
b99bd4ef 4099
c19d1205
ZW
4100static void
4101s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
4102{
4103 demand_empty_rest_of_line ();
921e5f0a
PB
4104 if (unwind.proc_start)
4105 {
c921be7d 4106 as_bad (_("duplicate .fnstart directive"));
921e5f0a
PB
4107 return;
4108 }
4109
c19d1205
ZW
4110 /* Mark the start of the function. */
4111 unwind.proc_start = expr_build_dot ();
b99bd4ef 4112
c19d1205
ZW
4113 /* Reset the rest of the unwind info. */
4114 unwind.opcode_count = 0;
4115 unwind.table_entry = NULL;
4116 unwind.personality_routine = NULL;
4117 unwind.personality_index = -1;
4118 unwind.frame_size = 0;
4119 unwind.fp_offset = 0;
fdfde340 4120 unwind.fp_reg = REG_SP;
c19d1205
ZW
4121 unwind.fp_used = 0;
4122 unwind.sp_restored = 0;
4123}
b99bd4ef 4124
c19d1205
ZW
4125/* Parse a handlerdata directive. Creates the exception handling table entry
4126 for the function. */
b99bd4ef 4127
c19d1205
ZW
4128static void
4129s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
4130{
4131 demand_empty_rest_of_line ();
921e5f0a 4132 if (!unwind.proc_start)
c921be7d 4133 as_bad (MISSING_FNSTART);
921e5f0a 4134
c19d1205 4135 if (unwind.table_entry)
6decc662 4136 as_bad (_("duplicate .handlerdata directive"));
f02232aa 4137
c19d1205
ZW
4138 create_unwind_entry (1);
4139}
a737bd4d 4140
c19d1205 4141/* Parse an unwind_fnend directive. Generates the index table entry. */
b99bd4ef 4142
c19d1205
ZW
4143static void
4144s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
4145{
4146 long where;
4147 char *ptr;
4148 valueT val;
940b5ce0 4149 unsigned int marked_pr_dependency;
f02232aa 4150
c19d1205 4151 demand_empty_rest_of_line ();
f02232aa 4152
921e5f0a
PB
4153 if (!unwind.proc_start)
4154 {
c921be7d 4155 as_bad (_(".fnend directive without .fnstart"));
921e5f0a
PB
4156 return;
4157 }
4158
c19d1205
ZW
4159 /* Add eh table entry. */
4160 if (unwind.table_entry == NULL)
4161 val = create_unwind_entry (0);
4162 else
4163 val = 0;
f02232aa 4164
c19d1205
ZW
4165 /* Add index table entry. This is two words. */
4166 start_unwind_section (unwind.saved_seg, 1);
4167 frag_align (2, 0, 0);
4168 record_alignment (now_seg, 2);
b99bd4ef 4169
c19d1205 4170 ptr = frag_more (8);
5011093d 4171 memset (ptr, 0, 8);
c19d1205 4172 where = frag_now_fix () - 8;
f02232aa 4173
c19d1205
ZW
4174 /* Self relative offset of the function start. */
4175 fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
4176 BFD_RELOC_ARM_PREL31);
f02232aa 4177
c19d1205
ZW
4178 /* Indicate dependency on EHABI-defined personality routines to the
4179 linker, if it hasn't been done already. */
940b5ce0
DJ
4180 marked_pr_dependency
4181 = seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency;
c19d1205
ZW
4182 if (unwind.personality_index >= 0 && unwind.personality_index < 3
4183 && !(marked_pr_dependency & (1 << unwind.personality_index)))
4184 {
5f4273c7
NC
4185 static const char *const name[] =
4186 {
4187 "__aeabi_unwind_cpp_pr0",
4188 "__aeabi_unwind_cpp_pr1",
4189 "__aeabi_unwind_cpp_pr2"
4190 };
c19d1205
ZW
4191 symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
4192 fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
c19d1205 4193 seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
940b5ce0 4194 |= 1 << unwind.personality_index;
c19d1205 4195 }
f02232aa 4196
c19d1205
ZW
4197 if (val)
4198 /* Inline exception table entry. */
4199 md_number_to_chars (ptr + 4, val, 4);
4200 else
4201 /* Self relative offset of the table entry. */
4202 fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
4203 BFD_RELOC_ARM_PREL31);
f02232aa 4204
c19d1205
ZW
4205 /* Restore the original section. */
4206 subseg_set (unwind.saved_seg, unwind.saved_subseg);
921e5f0a
PB
4207
4208 unwind.proc_start = NULL;
c19d1205 4209}
f02232aa 4210
f02232aa 4211
c19d1205 4212/* Parse an unwind_cantunwind directive. */
b99bd4ef 4213
c19d1205
ZW
4214static void
4215s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
4216{
4217 demand_empty_rest_of_line ();
921e5f0a 4218 if (!unwind.proc_start)
c921be7d 4219 as_bad (MISSING_FNSTART);
921e5f0a 4220
c19d1205
ZW
4221 if (unwind.personality_routine || unwind.personality_index != -1)
4222 as_bad (_("personality routine specified for cantunwind frame"));
b99bd4ef 4223
c19d1205
ZW
4224 unwind.personality_index = -2;
4225}
b99bd4ef 4226
b99bd4ef 4227
c19d1205 4228/* Parse a personalityindex directive. */
b99bd4ef 4229
c19d1205
ZW
4230static void
4231s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
4232{
4233 expressionS exp;
b99bd4ef 4234
921e5f0a 4235 if (!unwind.proc_start)
c921be7d 4236 as_bad (MISSING_FNSTART);
921e5f0a 4237
c19d1205
ZW
4238 if (unwind.personality_routine || unwind.personality_index != -1)
4239 as_bad (_("duplicate .personalityindex directive"));
b99bd4ef 4240
c19d1205 4241 expression (&exp);
b99bd4ef 4242
c19d1205
ZW
4243 if (exp.X_op != O_constant
4244 || exp.X_add_number < 0 || exp.X_add_number > 15)
b99bd4ef 4245 {
c19d1205
ZW
4246 as_bad (_("bad personality routine number"));
4247 ignore_rest_of_line ();
4248 return;
b99bd4ef
NC
4249 }
4250
c19d1205 4251 unwind.personality_index = exp.X_add_number;
b99bd4ef 4252
c19d1205
ZW
4253 demand_empty_rest_of_line ();
4254}
e16bb312 4255
e16bb312 4256
c19d1205 4257/* Parse a personality directive. */
e16bb312 4258
c19d1205
ZW
4259static void
4260s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
4261{
4262 char *name, *p, c;
a737bd4d 4263
921e5f0a 4264 if (!unwind.proc_start)
c921be7d 4265 as_bad (MISSING_FNSTART);
921e5f0a 4266
c19d1205
ZW
4267 if (unwind.personality_routine || unwind.personality_index != -1)
4268 as_bad (_("duplicate .personality directive"));
a737bd4d 4269
d02603dc 4270 c = get_symbol_name (& name);
c19d1205 4271 p = input_line_pointer;
d02603dc
NC
4272 if (c == '"')
4273 ++ input_line_pointer;
c19d1205
ZW
4274 unwind.personality_routine = symbol_find_or_make (name);
4275 *p = c;
4276 demand_empty_rest_of_line ();
4277}
e16bb312 4278
8c299995
TB
4279/* Parse a directive saving pseudo registers. */
4280
4281static void
3a368c4c 4282s_arm_unwind_save_pseudo (int regno)
8c299995
TB
4283{
4284 valueT op;
8c299995 4285
3a368c4c 4286 switch (regno)
8c299995 4287 {
3a368c4c 4288 case REG_RA_AUTH_CODE:
8c299995
TB
4289 /* Opcode for restoring RA_AUTH_CODE. */
4290 op = 0xb4;
4291 add_unwind_opcode (op, 1);
3a368c4c
VDN
4292 break;
4293 default:
4294 as_bad (_("Unknown register no. encountered: %d\n"), regno);
8c299995
TB
4295 }
4296}
4297
e16bb312 4298
c19d1205 4299/* Parse a directive saving core registers. */
e16bb312 4300
c19d1205 4301static void
3363d856 4302s_arm_unwind_save_core (long range)
e16bb312 4303{
c19d1205 4304 valueT op;
c19d1205 4305 int n;
e16bb312 4306
c19d1205
ZW
4307 /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
4308 into .unwind_save {..., sp...}. We aren't bothered about the value of
4309 ip because it is clobbered by calls. */
4310 if (unwind.sp_restored && unwind.fp_reg == 12
4311 && (range & 0x3000) == 0x1000)
4312 {
4313 unwind.opcode_count--;
4314 unwind.sp_restored = 0;
4315 range = (range | 0x2000) & ~0x1000;
4316 unwind.pending_offset = 0;
4317 }
e16bb312 4318
01ae4198
DJ
4319 /* Pop r4-r15. */
4320 if (range & 0xfff0)
c19d1205 4321 {
01ae4198
DJ
4322 /* See if we can use the short opcodes. These pop a block of up to 8
4323 registers starting with r4, plus maybe r14. */
4324 for (n = 0; n < 8; n++)
4325 {
4326 /* Break at the first non-saved register. */
4327 if ((range & (1 << (n + 4))) == 0)
4328 break;
4329 }
4330 /* See if there are any other bits set. */
4331 if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
4332 {
4333 /* Use the long form. */
4334 op = 0x8000 | ((range >> 4) & 0xfff);
4335 add_unwind_opcode (op, 2);
4336 }
0dd132b6 4337 else
01ae4198
DJ
4338 {
4339 /* Use the short form. */
4340 if (range & 0x4000)
4341 op = 0xa8; /* Pop r14. */
4342 else
4343 op = 0xa0; /* Do not pop r14. */
4344 op |= (n - 1);
4345 add_unwind_opcode (op, 1);
4346 }
c19d1205 4347 }
0dd132b6 4348
c19d1205
ZW
4349 /* Pop r0-r3. */
4350 if (range & 0xf)
4351 {
4352 op = 0xb100 | (range & 0xf);
4353 add_unwind_opcode (op, 2);
0dd132b6
NC
4354 }
4355
c19d1205
ZW
4356 /* Record the number of bytes pushed. */
4357 for (n = 0; n < 16; n++)
4358 {
4359 if (range & (1 << n))
4360 unwind.frame_size += 4;
4361 }
0dd132b6
NC
4362}
4363
3a368c4c
VDN
4364/* Implement correct handling of .save lists enabling the split into
4365sublists where necessary, while preserving correct sublist ordering. */
4366
4367static void
4368parse_dot_save (char **str_p, int prev_reg)
4369{
4370 long core_regs = 0;
4371 int reg;
4372 int in_range = 0;
4373
4374 if (**str_p == ',')
4375 *str_p += 1;
4376 if (**str_p == '}')
4377 {
4378 *str_p += 1;
4379 return;
4380 }
4381
4382 while ((reg = arm_reg_parse (str_p, REG_TYPE_RN)) != FAIL)
4383 {
4384 if (!in_range)
4385 {
4386 if (core_regs & (1 << reg))
4387 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
4388 reg);
4389 else if (reg <= prev_reg)
4390 as_tsktsk (_("Warning: register list not in ascending order"));
4391
4392 core_regs |= (1 << reg);
4393 prev_reg = reg;
4394 if (skip_past_char(str_p, '-') != FAIL)
4395 in_range = 1;
4396 else if (skip_past_comma(str_p) == FAIL)
4397 first_error (_("bad register list"));
4398 }
4399 else
4400 {
4401 int i;
4402 if (reg <= prev_reg)
4403 first_error (_("bad range in register list"));
4404 for (i = prev_reg + 1; i <= reg; i++)
4405 {
4406 if (core_regs & (1 << i))
4407 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
4408 i);
4409 else
4410 core_regs |= 1 << i;
4411 }
4412 in_range = 0;
4413 }
4414 }
4415 if (core_regs)
4416 {
4417 /* Higher register numbers go in higher memory addresses. When splitting a list,
4418 right-most sublist should therefore be .saved first. Use recursion for this. */
4419 parse_dot_save (str_p, reg);
4420 /* We're back from recursion, so emit .save insn for sublist. */
4421 s_arm_unwind_save_core (core_regs);
4422 return;
4423 }
4424 /* Handle pseudo-regs, under assumption these are emitted singly. */
4425 else if ((reg = arm_reg_parse (str_p, REG_TYPE_PSEUDO)) != FAIL)
4426 {
4427 /* recurse for remainder of input. Note: No assumption is made regarding which
4428 register in core register set holds pseudo-register. It's not considered in
4429 ordering check beyond ensuring it's not sandwiched between 2 consecutive
4430 registers. */
4431 parse_dot_save (str_p, prev_reg + 1);
4432 s_arm_unwind_save_pseudo (reg);
4433 return;
4434 }
4435 else
4436 as_bad (BAD_SYNTAX);
4437}
c19d1205
ZW
4438
4439/* Parse a directive saving FPA registers. */
b99bd4ef
NC
4440
4441static void
c19d1205 4442s_arm_unwind_save_fpa (int reg)
b99bd4ef 4443{
c19d1205
ZW
4444 expressionS exp;
4445 int num_regs;
4446 valueT op;
b99bd4ef 4447
c19d1205
ZW
4448 /* Get Number of registers to transfer. */
4449 if (skip_past_comma (&input_line_pointer) != FAIL)
4450 expression (&exp);
4451 else
4452 exp.X_op = O_illegal;
b99bd4ef 4453
c19d1205 4454 if (exp.X_op != O_constant)
b99bd4ef 4455 {
c19d1205
ZW
4456 as_bad (_("expected , <constant>"));
4457 ignore_rest_of_line ();
b99bd4ef
NC
4458 return;
4459 }
4460
c19d1205
ZW
4461 num_regs = exp.X_add_number;
4462
4463 if (num_regs < 1 || num_regs > 4)
b99bd4ef 4464 {
c19d1205
ZW
4465 as_bad (_("number of registers must be in the range [1:4]"));
4466 ignore_rest_of_line ();
b99bd4ef
NC
4467 return;
4468 }
4469
c19d1205 4470 demand_empty_rest_of_line ();
b99bd4ef 4471
c19d1205
ZW
4472 if (reg == 4)
4473 {
4474 /* Short form. */
4475 op = 0xb4 | (num_regs - 1);
4476 add_unwind_opcode (op, 1);
4477 }
b99bd4ef
NC
4478 else
4479 {
c19d1205
ZW
4480 /* Long form. */
4481 op = 0xc800 | (reg << 4) | (num_regs - 1);
4482 add_unwind_opcode (op, 2);
b99bd4ef 4483 }
c19d1205 4484 unwind.frame_size += num_regs * 12;
b99bd4ef
NC
4485}
4486
c19d1205 4487
fa073d69
MS
4488/* Parse a directive saving VFP registers for ARMv6 and above. */
4489
4490static void
4491s_arm_unwind_save_vfp_armv6 (void)
4492{
4493 int count;
4494 unsigned int start;
4495 valueT op;
4496 int num_vfpv3_regs = 0;
4497 int num_regs_below_16;
5b7c81bd 4498 bool partial_match;
fa073d69 4499
efd6b359
AV
4500 count = parse_vfp_reg_list (&input_line_pointer, &start, REGLIST_VFP_D,
4501 &partial_match);
fa073d69
MS
4502 if (count == FAIL)
4503 {
4504 as_bad (_("expected register list"));
4505 ignore_rest_of_line ();
4506 return;
4507 }
4508
4509 demand_empty_rest_of_line ();
4510
4511 /* We always generate FSTMD/FLDMD-style unwinding opcodes (rather
4512 than FSTMX/FLDMX-style ones). */
4513
4514 /* Generate opcode for (VFPv3) registers numbered in the range 16 .. 31. */
4515 if (start >= 16)
4516 num_vfpv3_regs = count;
4517 else if (start + count > 16)
4518 num_vfpv3_regs = start + count - 16;
4519
4520 if (num_vfpv3_regs > 0)
4521 {
4522 int start_offset = start > 16 ? start - 16 : 0;
4523 op = 0xc800 | (start_offset << 4) | (num_vfpv3_regs - 1);
4524 add_unwind_opcode (op, 2);
4525 }
4526
4527 /* Generate opcode for registers numbered in the range 0 .. 15. */
4528 num_regs_below_16 = num_vfpv3_regs > 0 ? 16 - (int) start : count;
9c2799c2 4529 gas_assert (num_regs_below_16 + num_vfpv3_regs == count);
fa073d69
MS
4530 if (num_regs_below_16 > 0)
4531 {
4532 op = 0xc900 | (start << 4) | (num_regs_below_16 - 1);
4533 add_unwind_opcode (op, 2);
4534 }
4535
4536 unwind.frame_size += count * 8;
4537}
4538
4539
4540/* Parse a directive saving VFP registers for pre-ARMv6. */
b99bd4ef
NC
4541
4542static void
c19d1205 4543s_arm_unwind_save_vfp (void)
b99bd4ef 4544{
c19d1205 4545 int count;
ca3f61f7 4546 unsigned int reg;
c19d1205 4547 valueT op;
5b7c81bd 4548 bool partial_match;
b99bd4ef 4549
efd6b359
AV
4550 count = parse_vfp_reg_list (&input_line_pointer, &reg, REGLIST_VFP_D,
4551 &partial_match);
c19d1205 4552 if (count == FAIL)
b99bd4ef 4553 {
c19d1205
ZW
4554 as_bad (_("expected register list"));
4555 ignore_rest_of_line ();
b99bd4ef
NC
4556 return;
4557 }
4558
c19d1205 4559 demand_empty_rest_of_line ();
b99bd4ef 4560
c19d1205 4561 if (reg == 8)
b99bd4ef 4562 {
c19d1205
ZW
4563 /* Short form. */
4564 op = 0xb8 | (count - 1);
4565 add_unwind_opcode (op, 1);
b99bd4ef 4566 }
c19d1205 4567 else
b99bd4ef 4568 {
c19d1205
ZW
4569 /* Long form. */
4570 op = 0xb300 | (reg << 4) | (count - 1);
4571 add_unwind_opcode (op, 2);
b99bd4ef 4572 }
c19d1205
ZW
4573 unwind.frame_size += count * 8 + 4;
4574}
b99bd4ef 4575
b99bd4ef 4576
c19d1205
ZW
4577/* Parse a directive saving iWMMXt data registers. */
4578
4579static void
4580s_arm_unwind_save_mmxwr (void)
4581{
4582 int reg;
4583 int hi_reg;
4584 int i;
4585 unsigned mask = 0;
4586 valueT op;
b99bd4ef 4587
c19d1205
ZW
4588 if (*input_line_pointer == '{')
4589 input_line_pointer++;
b99bd4ef 4590
c19d1205 4591 do
b99bd4ef 4592 {
dcbf9037 4593 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
b99bd4ef 4594
c19d1205 4595 if (reg == FAIL)
b99bd4ef 4596 {
9b7132d3 4597 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205 4598 goto error;
b99bd4ef
NC
4599 }
4600
c19d1205
ZW
4601 if (mask >> reg)
4602 as_tsktsk (_("register list not in ascending order"));
4603 mask |= 1 << reg;
b99bd4ef 4604
c19d1205
ZW
4605 if (*input_line_pointer == '-')
4606 {
4607 input_line_pointer++;
dcbf9037 4608 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
c19d1205
ZW
4609 if (hi_reg == FAIL)
4610 {
9b7132d3 4611 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205
ZW
4612 goto error;
4613 }
4614 else if (reg >= hi_reg)
4615 {
4616 as_bad (_("bad register range"));
4617 goto error;
4618 }
4619 for (; reg < hi_reg; reg++)
4620 mask |= 1 << reg;
4621 }
4622 }
4623 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4624
d996d970 4625 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4626
c19d1205 4627 demand_empty_rest_of_line ();
b99bd4ef 4628
708587a4 4629 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4630 the list. */
4631 flush_pending_unwind ();
b99bd4ef 4632
c19d1205 4633 for (i = 0; i < 16; i++)
b99bd4ef 4634 {
c19d1205
ZW
4635 if (mask & (1 << i))
4636 unwind.frame_size += 8;
b99bd4ef
NC
4637 }
4638
c19d1205
ZW
4639 /* Attempt to combine with a previous opcode. We do this because gcc
4640 likes to output separate unwind directives for a single block of
4641 registers. */
4642 if (unwind.opcode_count > 0)
b99bd4ef 4643 {
c19d1205
ZW
4644 i = unwind.opcodes[unwind.opcode_count - 1];
4645 if ((i & 0xf8) == 0xc0)
4646 {
4647 i &= 7;
4648 /* Only merge if the blocks are contiguous. */
4649 if (i < 6)
4650 {
4651 if ((mask & 0xfe00) == (1 << 9))
4652 {
4653 mask |= ((1 << (i + 11)) - 1) & 0xfc00;
4654 unwind.opcode_count--;
4655 }
4656 }
4657 else if (i == 6 && unwind.opcode_count >= 2)
4658 {
4659 i = unwind.opcodes[unwind.opcode_count - 2];
4660 reg = i >> 4;
4661 i &= 0xf;
b99bd4ef 4662
c19d1205
ZW
4663 op = 0xffff << (reg - 1);
4664 if (reg > 0
87a1fd79 4665 && ((mask & op) == (1u << (reg - 1))))
c19d1205
ZW
4666 {
4667 op = (1 << (reg + i + 1)) - 1;
4668 op &= ~((1 << reg) - 1);
4669 mask |= op;
4670 unwind.opcode_count -= 2;
4671 }
4672 }
4673 }
b99bd4ef
NC
4674 }
4675
c19d1205
ZW
4676 hi_reg = 15;
4677 /* We want to generate opcodes in the order the registers have been
4678 saved, ie. descending order. */
4679 for (reg = 15; reg >= -1; reg--)
b99bd4ef 4680 {
c19d1205
ZW
4681 /* Save registers in blocks. */
4682 if (reg < 0
4683 || !(mask & (1 << reg)))
4684 {
4685 /* We found an unsaved reg. Generate opcodes to save the
5f4273c7 4686 preceding block. */
c19d1205
ZW
4687 if (reg != hi_reg)
4688 {
4689 if (reg == 9)
4690 {
4691 /* Short form. */
4692 op = 0xc0 | (hi_reg - 10);
4693 add_unwind_opcode (op, 1);
4694 }
4695 else
4696 {
4697 /* Long form. */
4698 op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
4699 add_unwind_opcode (op, 2);
4700 }
4701 }
4702 hi_reg = reg - 1;
4703 }
b99bd4ef
NC
4704 }
4705
c19d1205 4706 return;
dc1e8a47 4707 error:
c19d1205 4708 ignore_rest_of_line ();
b99bd4ef
NC
4709}
4710
4711static void
c19d1205 4712s_arm_unwind_save_mmxwcg (void)
b99bd4ef 4713{
c19d1205
ZW
4714 int reg;
4715 int hi_reg;
4716 unsigned mask = 0;
4717 valueT op;
b99bd4ef 4718
c19d1205
ZW
4719 if (*input_line_pointer == '{')
4720 input_line_pointer++;
b99bd4ef 4721
477330fc
RM
4722 skip_whitespace (input_line_pointer);
4723
c19d1205 4724 do
b99bd4ef 4725 {
dcbf9037 4726 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
b99bd4ef 4727
c19d1205
ZW
4728 if (reg == FAIL)
4729 {
9b7132d3 4730 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4731 goto error;
4732 }
b99bd4ef 4733
c19d1205
ZW
4734 reg -= 8;
4735 if (mask >> reg)
4736 as_tsktsk (_("register list not in ascending order"));
4737 mask |= 1 << reg;
b99bd4ef 4738
c19d1205
ZW
4739 if (*input_line_pointer == '-')
4740 {
4741 input_line_pointer++;
dcbf9037 4742 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
c19d1205
ZW
4743 if (hi_reg == FAIL)
4744 {
9b7132d3 4745 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4746 goto error;
4747 }
4748 else if (reg >= hi_reg)
4749 {
4750 as_bad (_("bad register range"));
4751 goto error;
4752 }
4753 for (; reg < hi_reg; reg++)
4754 mask |= 1 << reg;
4755 }
b99bd4ef 4756 }
c19d1205 4757 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4758
d996d970 4759 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4760
c19d1205
ZW
4761 demand_empty_rest_of_line ();
4762
708587a4 4763 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4764 the list. */
4765 flush_pending_unwind ();
b99bd4ef 4766
c19d1205 4767 for (reg = 0; reg < 16; reg++)
b99bd4ef 4768 {
c19d1205
ZW
4769 if (mask & (1 << reg))
4770 unwind.frame_size += 4;
b99bd4ef 4771 }
c19d1205
ZW
4772 op = 0xc700 | mask;
4773 add_unwind_opcode (op, 2);
4774 return;
dc1e8a47 4775 error:
c19d1205 4776 ignore_rest_of_line ();
b99bd4ef
NC
4777}
4778
fa073d69
MS
4779/* Parse an unwind_save directive.
4780 If the argument is non-zero, this is a .vsave directive. */
c19d1205 4781
b99bd4ef 4782static void
fa073d69 4783s_arm_unwind_save (int arch_v6)
b99bd4ef 4784{
3a368c4c 4785 char *peek;
c19d1205 4786 struct reg_entry *reg;
5b7c81bd 4787 bool had_brace = false;
b99bd4ef 4788
921e5f0a 4789 if (!unwind.proc_start)
c921be7d 4790 as_bad (MISSING_FNSTART);
921e5f0a 4791
c19d1205 4792 /* Figure out what sort of save we have. */
3a368c4c 4793 peek = input_line_pointer;
b99bd4ef 4794
c19d1205 4795 if (*peek == '{')
b99bd4ef 4796 {
5b7c81bd 4797 had_brace = true;
c19d1205 4798 peek++;
b99bd4ef
NC
4799 }
4800
c19d1205 4801 reg = arm_reg_parse_multi (&peek);
b99bd4ef 4802
c19d1205 4803 if (!reg)
b99bd4ef 4804 {
c19d1205
ZW
4805 as_bad (_("register expected"));
4806 ignore_rest_of_line ();
b99bd4ef
NC
4807 return;
4808 }
4809
c19d1205 4810 switch (reg->type)
b99bd4ef 4811 {
c19d1205
ZW
4812 case REG_TYPE_FN:
4813 if (had_brace)
4814 {
4815 as_bad (_("FPA .unwind_save does not take a register list"));
4816 ignore_rest_of_line ();
4817 return;
4818 }
93ac2687 4819 input_line_pointer = peek;
c19d1205 4820 s_arm_unwind_save_fpa (reg->number);
b99bd4ef 4821 return;
c19d1205 4822
3363d856 4823 case REG_TYPE_PSEUDO:
1f5afe1c 4824 case REG_TYPE_RN:
3a368c4c
VDN
4825 {
4826 if (had_brace)
4827 input_line_pointer++;
4828 parse_dot_save (&input_line_pointer, -1);
4829 demand_empty_rest_of_line ();
4830 return;
4831 }
8c299995 4832
fa073d69
MS
4833 case REG_TYPE_VFD:
4834 if (arch_v6)
477330fc 4835 s_arm_unwind_save_vfp_armv6 ();
fa073d69 4836 else
477330fc 4837 s_arm_unwind_save_vfp ();
fa073d69 4838 return;
1f5afe1c
NC
4839
4840 case REG_TYPE_MMXWR:
4841 s_arm_unwind_save_mmxwr ();
4842 return;
4843
4844 case REG_TYPE_MMXWCG:
4845 s_arm_unwind_save_mmxwcg ();
4846 return;
c19d1205
ZW
4847
4848 default:
4849 as_bad (_(".unwind_save does not support this kind of register"));
4850 ignore_rest_of_line ();
b99bd4ef 4851 }
c19d1205 4852}
b99bd4ef 4853
b99bd4ef 4854
c19d1205
ZW
4855/* Parse an unwind_movsp directive. */
4856
4857static void
4858s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
4859{
4860 int reg;
4861 valueT op;
4fa3602b 4862 int offset;
c19d1205 4863
921e5f0a 4864 if (!unwind.proc_start)
c921be7d 4865 as_bad (MISSING_FNSTART);
921e5f0a 4866
dcbf9037 4867 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205 4868 if (reg == FAIL)
b99bd4ef 4869 {
9b7132d3 4870 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_RN]));
c19d1205 4871 ignore_rest_of_line ();
b99bd4ef
NC
4872 return;
4873 }
4fa3602b
PB
4874
4875 /* Optional constant. */
4876 if (skip_past_comma (&input_line_pointer) != FAIL)
4877 {
4878 if (immediate_for_directive (&offset) == FAIL)
4879 return;
4880 }
4881 else
4882 offset = 0;
4883
c19d1205 4884 demand_empty_rest_of_line ();
b99bd4ef 4885
c19d1205 4886 if (reg == REG_SP || reg == REG_PC)
b99bd4ef 4887 {
c19d1205 4888 as_bad (_("SP and PC not permitted in .unwind_movsp directive"));
b99bd4ef
NC
4889 return;
4890 }
4891
c19d1205
ZW
4892 if (unwind.fp_reg != REG_SP)
4893 as_bad (_("unexpected .unwind_movsp directive"));
b99bd4ef 4894
c19d1205
ZW
4895 /* Generate opcode to restore the value. */
4896 op = 0x90 | reg;
4897 add_unwind_opcode (op, 1);
4898
4899 /* Record the information for later. */
4900 unwind.fp_reg = reg;
4fa3602b 4901 unwind.fp_offset = unwind.frame_size - offset;
c19d1205 4902 unwind.sp_restored = 1;
b05fe5cf
ZW
4903}
4904
c19d1205
ZW
4905/* Parse an unwind_pad directive. */
4906
b05fe5cf 4907static void
c19d1205 4908s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
b05fe5cf 4909{
c19d1205 4910 int offset;
b05fe5cf 4911
921e5f0a 4912 if (!unwind.proc_start)
c921be7d 4913 as_bad (MISSING_FNSTART);
921e5f0a 4914
c19d1205
ZW
4915 if (immediate_for_directive (&offset) == FAIL)
4916 return;
b99bd4ef 4917
c19d1205
ZW
4918 if (offset & 3)
4919 {
4920 as_bad (_("stack increment must be multiple of 4"));
4921 ignore_rest_of_line ();
4922 return;
4923 }
b99bd4ef 4924
c19d1205
ZW
4925 /* Don't generate any opcodes, just record the details for later. */
4926 unwind.frame_size += offset;
4927 unwind.pending_offset += offset;
4928
4929 demand_empty_rest_of_line ();
4930}
4931
9b1c7dc3
SP
4932/* Parse an unwind_pacspval directive. */
4933
4934static void
4935s_arm_unwind_pacspval (int ignored ATTRIBUTE_UNUSED)
4936{
4937 valueT op;
4938
4939 if (!unwind.proc_start)
4940 as_bad (MISSING_FNSTART);
4941
4942 demand_empty_rest_of_line ();
4943
4944 op = 0xb5;
4945 add_unwind_opcode (op, 1);
4946}
4947
c19d1205
ZW
4948/* Parse an unwind_setfp directive. */
4949
4950static void
4951s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 4952{
c19d1205
ZW
4953 int sp_reg;
4954 int fp_reg;
4955 int offset;
4956
921e5f0a 4957 if (!unwind.proc_start)
c921be7d 4958 as_bad (MISSING_FNSTART);
921e5f0a 4959
dcbf9037 4960 fp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205
ZW
4961 if (skip_past_comma (&input_line_pointer) == FAIL)
4962 sp_reg = FAIL;
4963 else
dcbf9037 4964 sp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
b99bd4ef 4965
c19d1205
ZW
4966 if (fp_reg == FAIL || sp_reg == FAIL)
4967 {
4968 as_bad (_("expected <reg>, <reg>"));
4969 ignore_rest_of_line ();
4970 return;
4971 }
b99bd4ef 4972
c19d1205
ZW
4973 /* Optional constant. */
4974 if (skip_past_comma (&input_line_pointer) != FAIL)
4975 {
4976 if (immediate_for_directive (&offset) == FAIL)
4977 return;
4978 }
4979 else
4980 offset = 0;
a737bd4d 4981
c19d1205 4982 demand_empty_rest_of_line ();
a737bd4d 4983
fdfde340 4984 if (sp_reg != REG_SP && sp_reg != unwind.fp_reg)
a737bd4d 4985 {
c19d1205
ZW
4986 as_bad (_("register must be either sp or set by a previous"
4987 "unwind_movsp directive"));
4988 return;
a737bd4d
NC
4989 }
4990
c19d1205
ZW
4991 /* Don't generate any opcodes, just record the information for later. */
4992 unwind.fp_reg = fp_reg;
4993 unwind.fp_used = 1;
fdfde340 4994 if (sp_reg == REG_SP)
c19d1205
ZW
4995 unwind.fp_offset = unwind.frame_size - offset;
4996 else
4997 unwind.fp_offset -= offset;
a737bd4d
NC
4998}
4999
c19d1205
ZW
5000/* Parse an unwind_raw directive. */
5001
5002static void
5003s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
a737bd4d 5004{
c19d1205 5005 expressionS exp;
708587a4 5006 /* This is an arbitrary limit. */
c19d1205
ZW
5007 unsigned char op[16];
5008 int count;
a737bd4d 5009
921e5f0a 5010 if (!unwind.proc_start)
c921be7d 5011 as_bad (MISSING_FNSTART);
921e5f0a 5012
c19d1205
ZW
5013 expression (&exp);
5014 if (exp.X_op == O_constant
5015 && skip_past_comma (&input_line_pointer) != FAIL)
a737bd4d 5016 {
c19d1205
ZW
5017 unwind.frame_size += exp.X_add_number;
5018 expression (&exp);
5019 }
5020 else
5021 exp.X_op = O_illegal;
a737bd4d 5022
c19d1205
ZW
5023 if (exp.X_op != O_constant)
5024 {
5025 as_bad (_("expected <offset>, <opcode>"));
5026 ignore_rest_of_line ();
5027 return;
5028 }
a737bd4d 5029
c19d1205 5030 count = 0;
a737bd4d 5031
c19d1205
ZW
5032 /* Parse the opcode. */
5033 for (;;)
5034 {
5035 if (count >= 16)
5036 {
5037 as_bad (_("unwind opcode too long"));
5038 ignore_rest_of_line ();
a737bd4d 5039 }
c19d1205 5040 if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
a737bd4d 5041 {
c19d1205
ZW
5042 as_bad (_("invalid unwind opcode"));
5043 ignore_rest_of_line ();
5044 return;
a737bd4d 5045 }
c19d1205 5046 op[count++] = exp.X_add_number;
a737bd4d 5047
c19d1205
ZW
5048 /* Parse the next byte. */
5049 if (skip_past_comma (&input_line_pointer) == FAIL)
5050 break;
a737bd4d 5051
c19d1205
ZW
5052 expression (&exp);
5053 }
b99bd4ef 5054
c19d1205
ZW
5055 /* Add the opcode bytes in reverse order. */
5056 while (count--)
5057 add_unwind_opcode (op[count], 1);
b99bd4ef 5058
c19d1205 5059 demand_empty_rest_of_line ();
b99bd4ef 5060}
ee065d83
PB
5061
5062
5063/* Parse a .eabi_attribute directive. */
5064
5065static void
5066s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
5067{
0420f52b 5068 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
ee3c0378 5069
3076e594 5070 if (tag >= 0 && tag < NUM_KNOWN_OBJ_ATTRIBUTES)
ee3c0378 5071 attributes_set_explicitly[tag] = 1;
ee065d83
PB
5072}
5073
0855e32b
NS
5074/* Emit a tls fix for the symbol. */
5075
5076static void
5077s_arm_tls_descseq (int ignored ATTRIBUTE_UNUSED)
5078{
5079 char *p;
5080 expressionS exp;
5081#ifdef md_flush_pending_output
5082 md_flush_pending_output ();
5083#endif
5084
5085#ifdef md_cons_align
5086 md_cons_align (4);
5087#endif
5088
5089 /* Since we're just labelling the code, there's no need to define a
5090 mapping symbol. */
5091 expression (&exp);
5092 p = obstack_next_free (&frchain_now->frch_obstack);
5093 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
5094 thumb_mode ? BFD_RELOC_ARM_THM_TLS_DESCSEQ
5095 : BFD_RELOC_ARM_TLS_DESCSEQ);
5096}
cdf9ccec 5097#endif /* OBJ_ELF */
0855e32b 5098
ee065d83 5099static void s_arm_arch (int);
7a1d4c38 5100static void s_arm_object_arch (int);
ee065d83
PB
5101static void s_arm_cpu (int);
5102static void s_arm_fpu (int);
69133863 5103static void s_arm_arch_extension (int);
b99bd4ef 5104
f0927246
NC
5105#ifdef TE_PE
5106
5107static void
5f4273c7 5108pe_directive_secrel (int dummy ATTRIBUTE_UNUSED)
f0927246
NC
5109{
5110 expressionS exp;
5111
5112 do
5113 {
5114 expression (&exp);
5115 if (exp.X_op == O_symbol)
5116 exp.X_op = O_secrel;
5117
5118 emit_expr (&exp, 4);
5119 }
5120 while (*input_line_pointer++ == ',');
5121
5122 input_line_pointer--;
5123 demand_empty_rest_of_line ();
5124}
5125#endif /* TE_PE */
5126
5312fe52
BW
5127int
5128arm_is_largest_exponent_ok (int precision)
5129{
5130 /* precision == 1 ensures that this will only return
5131 true for 16 bit floats. */
5132 return (precision == 1) && (fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
5133}
5134
5135static void
5136set_fp16_format (int dummy ATTRIBUTE_UNUSED)
5137{
5138 char saved_char;
5139 char* name;
5140 enum fp_16bit_format new_format;
5141
5142 new_format = ARM_FP16_FORMAT_DEFAULT;
5143
5144 name = input_line_pointer;
5145 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
5146 input_line_pointer++;
5147
5148 saved_char = *input_line_pointer;
5149 *input_line_pointer = 0;
5150
5151 if (strcasecmp (name, "ieee") == 0)
5152 new_format = ARM_FP16_FORMAT_IEEE;
5153 else if (strcasecmp (name, "alternative") == 0)
5154 new_format = ARM_FP16_FORMAT_ALTERNATIVE;
5155 else
5156 {
5157 as_bad (_("unrecognised float16 format \"%s\""), name);
5158 goto cleanup;
5159 }
5160
5161 /* Only set fp16_format if it is still the default (aka not already
5162 been set yet). */
5163 if (fp16_format == ARM_FP16_FORMAT_DEFAULT)
5164 fp16_format = new_format;
5165 else
5166 {
5167 if (new_format != fp16_format)
5168 as_warn (_("float16 format cannot be set more than once, ignoring."));
5169 }
5170
dc1e8a47 5171 cleanup:
5312fe52
BW
5172 *input_line_pointer = saved_char;
5173 ignore_rest_of_line ();
5174}
5175
c19d1205
ZW
5176/* This table describes all the machine specific pseudo-ops the assembler
5177 has to support. The fields are:
5178 pseudo-op name without dot
5179 function to call to execute this pseudo-op
5180 Integer arg to pass to the function. */
b99bd4ef 5181
c19d1205 5182const pseudo_typeS md_pseudo_table[] =
b99bd4ef 5183{
c19d1205
ZW
5184 /* Never called because '.req' does not start a line. */
5185 { "req", s_req, 0 },
dcbf9037
JB
5186 /* Following two are likewise never called. */
5187 { "dn", s_dn, 0 },
5188 { "qn", s_qn, 0 },
c19d1205
ZW
5189 { "unreq", s_unreq, 0 },
5190 { "bss", s_bss, 0 },
db2ed2e0 5191 { "align", s_align_ptwo, 2 },
c19d1205
ZW
5192 { "arm", s_arm, 0 },
5193 { "thumb", s_thumb, 0 },
5194 { "code", s_code, 0 },
5195 { "force_thumb", s_force_thumb, 0 },
5196 { "thumb_func", s_thumb_func, 0 },
5197 { "thumb_set", s_thumb_set, 0 },
5198 { "even", s_even, 0 },
5199 { "ltorg", s_ltorg, 0 },
5200 { "pool", s_ltorg, 0 },
5201 { "syntax", s_syntax, 0 },
8463be01
PB
5202 { "cpu", s_arm_cpu, 0 },
5203 { "arch", s_arm_arch, 0 },
7a1d4c38 5204 { "object_arch", s_arm_object_arch, 0 },
8463be01 5205 { "fpu", s_arm_fpu, 0 },
69133863 5206 { "arch_extension", s_arm_arch_extension, 0 },
c19d1205 5207#ifdef OBJ_ELF
c921be7d
NC
5208 { "word", s_arm_elf_cons, 4 },
5209 { "long", s_arm_elf_cons, 4 },
5210 { "inst.n", s_arm_elf_inst, 2 },
5211 { "inst.w", s_arm_elf_inst, 4 },
5212 { "inst", s_arm_elf_inst, 0 },
5213 { "rel31", s_arm_rel31, 0 },
c19d1205
ZW
5214 { "fnstart", s_arm_unwind_fnstart, 0 },
5215 { "fnend", s_arm_unwind_fnend, 0 },
5216 { "cantunwind", s_arm_unwind_cantunwind, 0 },
5217 { "personality", s_arm_unwind_personality, 0 },
5218 { "personalityindex", s_arm_unwind_personalityindex, 0 },
5219 { "handlerdata", s_arm_unwind_handlerdata, 0 },
5220 { "save", s_arm_unwind_save, 0 },
fa073d69 5221 { "vsave", s_arm_unwind_save, 1 },
c19d1205
ZW
5222 { "movsp", s_arm_unwind_movsp, 0 },
5223 { "pad", s_arm_unwind_pad, 0 },
9b1c7dc3 5224 { "pacspval", s_arm_unwind_pacspval, 0 },
c19d1205
ZW
5225 { "setfp", s_arm_unwind_setfp, 0 },
5226 { "unwind_raw", s_arm_unwind_raw, 0 },
ee065d83 5227 { "eabi_attribute", s_arm_eabi_attribute, 0 },
0855e32b 5228 { "tlsdescseq", s_arm_tls_descseq, 0 },
c19d1205
ZW
5229#else
5230 { "word", cons, 4},
f0927246
NC
5231
5232 /* These are used for dwarf. */
5233 {"2byte", cons, 2},
5234 {"4byte", cons, 4},
5235 {"8byte", cons, 8},
5236 /* These are used for dwarf2. */
68d20676 5237 { "file", dwarf2_directive_file, 0 },
f0927246
NC
5238 { "loc", dwarf2_directive_loc, 0 },
5239 { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
c19d1205
ZW
5240#endif
5241 { "extend", float_cons, 'x' },
5242 { "ldouble", float_cons, 'x' },
5243 { "packed", float_cons, 'p' },
27cce866 5244 { "bfloat16", float_cons, 'b' },
f0927246
NC
5245#ifdef TE_PE
5246 {"secrel32", pe_directive_secrel, 0},
5247#endif
2e6976a8
DG
5248
5249 /* These are for compatibility with CodeComposer Studio. */
5250 {"ref", s_ccs_ref, 0},
5251 {"def", s_ccs_def, 0},
5252 {"asmfunc", s_ccs_asmfunc, 0},
5253 {"endasmfunc", s_ccs_endasmfunc, 0},
5254
5312fe52
BW
5255 {"float16", float_cons, 'h' },
5256 {"float16_format", set_fp16_format, 0 },
5257
c19d1205
ZW
5258 { 0, 0, 0 }
5259};
5312fe52 5260
c19d1205 5261/* Parser functions used exclusively in instruction operands. */
b99bd4ef 5262
c19d1205
ZW
5263/* Generic immediate-value read function for use in insn parsing.
5264 STR points to the beginning of the immediate (the leading #);
5265 VAL receives the value; if the value is outside [MIN, MAX]
5266 issue an error. PREFIX_OPT is true if the immediate prefix is
5267 optional. */
b99bd4ef 5268
c19d1205
ZW
5269static int
5270parse_immediate (char **str, int *val, int min, int max,
5b7c81bd 5271 bool prefix_opt)
c19d1205
ZW
5272{
5273 expressionS exp;
0198d5e6 5274
c19d1205
ZW
5275 my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
5276 if (exp.X_op != O_constant)
b99bd4ef 5277 {
c19d1205
ZW
5278 inst.error = _("constant expression required");
5279 return FAIL;
5280 }
b99bd4ef 5281
c19d1205
ZW
5282 if (exp.X_add_number < min || exp.X_add_number > max)
5283 {
5284 inst.error = _("immediate value out of range");
5285 return FAIL;
5286 }
b99bd4ef 5287
c19d1205
ZW
5288 *val = exp.X_add_number;
5289 return SUCCESS;
5290}
b99bd4ef 5291
5287ad62 5292/* Less-generic immediate-value read function with the possibility of loading a
036dc3f7 5293 big (64-bit) immediate, as required by Neon VMOV, VMVN and logic immediate
5287ad62
JB
5294 instructions. Puts the result directly in inst.operands[i]. */
5295
5296static int
8335d6aa 5297parse_big_immediate (char **str, int i, expressionS *in_exp,
5b7c81bd 5298 bool allow_symbol_p)
5287ad62
JB
5299{
5300 expressionS exp;
8335d6aa 5301 expressionS *exp_p = in_exp ? in_exp : &exp;
5287ad62
JB
5302 char *ptr = *str;
5303
8335d6aa 5304 my_get_expression (exp_p, &ptr, GE_OPT_PREFIX_BIG);
5287ad62 5305
8335d6aa 5306 if (exp_p->X_op == O_constant)
036dc3f7 5307 {
8335d6aa 5308 inst.operands[i].imm = exp_p->X_add_number & 0xffffffff;
036dc3f7
PB
5309 /* If we're on a 64-bit host, then a 64-bit number can be returned using
5310 O_constant. We have to be careful not to break compilation for
5311 32-bit X_add_number, though. */
8335d6aa 5312 if ((exp_p->X_add_number & ~(offsetT)(0xffffffffU)) != 0)
036dc3f7 5313 {
8335d6aa
JW
5314 /* X >> 32 is illegal if sizeof (exp_p->X_add_number) == 4. */
5315 inst.operands[i].reg = (((exp_p->X_add_number >> 16) >> 16)
5316 & 0xffffffff);
036dc3f7
PB
5317 inst.operands[i].regisimm = 1;
5318 }
5319 }
8335d6aa
JW
5320 else if (exp_p->X_op == O_big
5321 && LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 32)
5287ad62
JB
5322 {
5323 unsigned parts = 32 / LITTLENUM_NUMBER_OF_BITS, j, idx = 0;
95b75c01 5324
5287ad62 5325 /* Bignums have their least significant bits in
477330fc
RM
5326 generic_bignum[0]. Make sure we put 32 bits in imm and
5327 32 bits in reg, in a (hopefully) portable way. */
9c2799c2 5328 gas_assert (parts != 0);
95b75c01
NC
5329
5330 /* Make sure that the number is not too big.
5331 PR 11972: Bignums can now be sign-extended to the
5332 size of a .octa so check that the out of range bits
5333 are all zero or all one. */
8335d6aa 5334 if (LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 64)
95b75c01
NC
5335 {
5336 LITTLENUM_TYPE m = -1;
5337
5338 if (generic_bignum[parts * 2] != 0
5339 && generic_bignum[parts * 2] != m)
5340 return FAIL;
5341
8335d6aa 5342 for (j = parts * 2 + 1; j < (unsigned) exp_p->X_add_number; j++)
95b75c01
NC
5343 if (generic_bignum[j] != generic_bignum[j-1])
5344 return FAIL;
5345 }
5346
5287ad62
JB
5347 inst.operands[i].imm = 0;
5348 for (j = 0; j < parts; j++, idx++)
7af67752
AM
5349 inst.operands[i].imm |= ((unsigned) generic_bignum[idx]
5350 << (LITTLENUM_NUMBER_OF_BITS * j));
5287ad62
JB
5351 inst.operands[i].reg = 0;
5352 for (j = 0; j < parts; j++, idx++)
7af67752
AM
5353 inst.operands[i].reg |= ((unsigned) generic_bignum[idx]
5354 << (LITTLENUM_NUMBER_OF_BITS * j));
5287ad62
JB
5355 inst.operands[i].regisimm = 1;
5356 }
8335d6aa 5357 else if (!(exp_p->X_op == O_symbol && allow_symbol_p))
5287ad62 5358 return FAIL;
5f4273c7 5359
5287ad62
JB
5360 *str = ptr;
5361
5362 return SUCCESS;
5363}
5364
c19d1205
ZW
5365/* Returns the pseudo-register number of an FPA immediate constant,
5366 or FAIL if there isn't a valid constant here. */
b99bd4ef 5367
c19d1205
ZW
5368static int
5369parse_fpa_immediate (char ** str)
5370{
5371 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5372 char * save_in;
5373 expressionS exp;
5374 int i;
5375 int j;
b99bd4ef 5376
c19d1205
ZW
5377 /* First try and match exact strings, this is to guarantee
5378 that some formats will work even for cross assembly. */
b99bd4ef 5379
c19d1205
ZW
5380 for (i = 0; fp_const[i]; i++)
5381 {
5382 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
b99bd4ef 5383 {
c19d1205 5384 char *start = *str;
b99bd4ef 5385
c19d1205
ZW
5386 *str += strlen (fp_const[i]);
5387 if (is_end_of_line[(unsigned char) **str])
5388 return i + 8;
5389 *str = start;
5390 }
5391 }
b99bd4ef 5392
c19d1205
ZW
5393 /* Just because we didn't get a match doesn't mean that the constant
5394 isn't valid, just that it is in a format that we don't
5395 automatically recognize. Try parsing it with the standard
5396 expression routines. */
b99bd4ef 5397
c19d1205 5398 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
b99bd4ef 5399
c19d1205
ZW
5400 /* Look for a raw floating point number. */
5401 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5402 && is_end_of_line[(unsigned char) *save_in])
5403 {
5404 for (i = 0; i < NUM_FLOAT_VALS; i++)
5405 {
5406 for (j = 0; j < MAX_LITTLENUMS; j++)
b99bd4ef 5407 {
c19d1205
ZW
5408 if (words[j] != fp_values[i][j])
5409 break;
b99bd4ef
NC
5410 }
5411
c19d1205 5412 if (j == MAX_LITTLENUMS)
b99bd4ef 5413 {
c19d1205
ZW
5414 *str = save_in;
5415 return i + 8;
b99bd4ef
NC
5416 }
5417 }
5418 }
b99bd4ef 5419
c19d1205
ZW
5420 /* Try and parse a more complex expression, this will probably fail
5421 unless the code uses a floating point prefix (eg "0f"). */
5422 save_in = input_line_pointer;
5423 input_line_pointer = *str;
5424 if (expression (&exp) == absolute_section
5425 && exp.X_op == O_big
5426 && exp.X_add_number < 0)
5427 {
5428 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5429 Ditto for 15. */
ba592044
AM
5430#define X_PRECISION 5
5431#define E_PRECISION 15L
5432 if (gen_to_words (words, X_PRECISION, E_PRECISION) == 0)
c19d1205
ZW
5433 {
5434 for (i = 0; i < NUM_FLOAT_VALS; i++)
5435 {
5436 for (j = 0; j < MAX_LITTLENUMS; j++)
5437 {
5438 if (words[j] != fp_values[i][j])
5439 break;
5440 }
b99bd4ef 5441
c19d1205
ZW
5442 if (j == MAX_LITTLENUMS)
5443 {
5444 *str = input_line_pointer;
5445 input_line_pointer = save_in;
5446 return i + 8;
5447 }
5448 }
5449 }
b99bd4ef
NC
5450 }
5451
c19d1205
ZW
5452 *str = input_line_pointer;
5453 input_line_pointer = save_in;
5454 inst.error = _("invalid FPA immediate expression");
5455 return FAIL;
b99bd4ef
NC
5456}
5457
136da414
JB
5458/* Returns 1 if a number has "quarter-precision" float format
5459 0baBbbbbbc defgh000 00000000 00000000. */
5460
5461static int
5462is_quarter_float (unsigned imm)
5463{
5464 int bs = (imm & 0x20000000) ? 0x3e000000 : 0x40000000;
5465 return (imm & 0x7ffff) == 0 && ((imm & 0x7e000000) ^ bs) == 0;
5466}
5467
aacf0b33
KT
5468
5469/* Detect the presence of a floating point or integer zero constant,
5470 i.e. #0.0 or #0. */
5471
5b7c81bd 5472static bool
aacf0b33
KT
5473parse_ifimm_zero (char **in)
5474{
5475 int error_code;
5476
5477 if (!is_immediate_prefix (**in))
3c6452ae
TP
5478 {
5479 /* In unified syntax, all prefixes are optional. */
5480 if (!unified_syntax)
5b7c81bd 5481 return false;
3c6452ae
TP
5482 }
5483 else
5484 ++*in;
0900a05b
JW
5485
5486 /* Accept #0x0 as a synonym for #0. */
d34049e8 5487 if (startswith (*in, "0x"))
0900a05b
JW
5488 {
5489 int val;
5b7c81bd
AM
5490 if (parse_immediate (in, &val, 0, 0, true) == FAIL)
5491 return false;
5492 return true;
0900a05b
JW
5493 }
5494
aacf0b33
KT
5495 error_code = atof_generic (in, ".", EXP_CHARS,
5496 &generic_floating_point_number);
5497
5498 if (!error_code
5499 && generic_floating_point_number.sign == '+'
5500 && (generic_floating_point_number.low
5501 > generic_floating_point_number.leader))
5b7c81bd 5502 return true;
aacf0b33 5503
5b7c81bd 5504 return false;
aacf0b33
KT
5505}
5506
136da414
JB
5507/* Parse an 8-bit "quarter-precision" floating point number of the form:
5508 0baBbbbbbc defgh000 00000000 00000000.
c96612cc
JB
5509 The zero and minus-zero cases need special handling, since they can't be
5510 encoded in the "quarter-precision" float format, but can nonetheless be
5511 loaded as integer constants. */
136da414
JB
5512
5513static unsigned
5514parse_qfloat_immediate (char **ccp, int *immed)
5515{
5516 char *str = *ccp;
c96612cc 5517 char *fpnum;
136da414 5518 LITTLENUM_TYPE words[MAX_LITTLENUMS];
c96612cc 5519 int found_fpchar = 0;
5f4273c7 5520
136da414 5521 skip_past_char (&str, '#');
5f4273c7 5522
c96612cc
JB
5523 /* We must not accidentally parse an integer as a floating-point number. Make
5524 sure that the value we parse is not an integer by checking for special
5525 characters '.' or 'e'.
5526 FIXME: This is a horrible hack, but doing better is tricky because type
5527 information isn't in a very usable state at parse time. */
5528 fpnum = str;
5529 skip_whitespace (fpnum);
5530
d34049e8 5531 if (startswith (fpnum, "0x"))
c96612cc
JB
5532 return FAIL;
5533 else
5534 {
5535 for (; *fpnum != '\0' && *fpnum != ' ' && *fpnum != '\n'; fpnum++)
477330fc
RM
5536 if (*fpnum == '.' || *fpnum == 'e' || *fpnum == 'E')
5537 {
5538 found_fpchar = 1;
5539 break;
5540 }
c96612cc
JB
5541
5542 if (!found_fpchar)
477330fc 5543 return FAIL;
c96612cc 5544 }
5f4273c7 5545
136da414
JB
5546 if ((str = atof_ieee (str, 's', words)) != NULL)
5547 {
5548 unsigned fpword = 0;
5549 int i;
5f4273c7 5550
136da414
JB
5551 /* Our FP word must be 32 bits (single-precision FP). */
5552 for (i = 0; i < 32 / LITTLENUM_NUMBER_OF_BITS; i++)
477330fc
RM
5553 {
5554 fpword <<= LITTLENUM_NUMBER_OF_BITS;
5555 fpword |= words[i];
5556 }
5f4273c7 5557
c96612cc 5558 if (is_quarter_float (fpword) || (fpword & 0x7fffffff) == 0)
477330fc 5559 *immed = fpword;
136da414 5560 else
477330fc 5561 return FAIL;
136da414
JB
5562
5563 *ccp = str;
5f4273c7 5564
136da414
JB
5565 return SUCCESS;
5566 }
5f4273c7 5567
136da414
JB
5568 return FAIL;
5569}
5570
c19d1205
ZW
5571/* Shift operands. */
5572enum shift_kind
b99bd4ef 5573{
f5f10c66 5574 SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX, SHIFT_UXTW
c19d1205 5575};
b99bd4ef 5576
c19d1205
ZW
5577struct asm_shift_name
5578{
5579 const char *name;
5580 enum shift_kind kind;
5581};
b99bd4ef 5582
c19d1205
ZW
5583/* Third argument to parse_shift. */
5584enum parse_shift_mode
5585{
5586 NO_SHIFT_RESTRICT, /* Any kind of shift is accepted. */
5587 SHIFT_IMMEDIATE, /* Shift operand must be an immediate. */
5588 SHIFT_LSL_OR_ASR_IMMEDIATE, /* Shift must be LSL or ASR immediate. */
5589 SHIFT_ASR_IMMEDIATE, /* Shift must be ASR immediate. */
5590 SHIFT_LSL_IMMEDIATE, /* Shift must be LSL immediate. */
f5f10c66 5591 SHIFT_UXTW_IMMEDIATE /* Shift must be UXTW immediate. */
c19d1205 5592};
b99bd4ef 5593
c19d1205
ZW
5594/* Parse a <shift> specifier on an ARM data processing instruction.
5595 This has three forms:
b99bd4ef 5596
c19d1205
ZW
5597 (LSL|LSR|ASL|ASR|ROR) Rs
5598 (LSL|LSR|ASL|ASR|ROR) #imm
5599 RRX
b99bd4ef 5600
c19d1205
ZW
5601 Note that ASL is assimilated to LSL in the instruction encoding, and
5602 RRX to ROR #0 (which cannot be written as such). */
b99bd4ef 5603
c19d1205
ZW
5604static int
5605parse_shift (char **str, int i, enum parse_shift_mode mode)
b99bd4ef 5606{
c19d1205
ZW
5607 const struct asm_shift_name *shift_name;
5608 enum shift_kind shift;
5609 char *s = *str;
5610 char *p = s;
5611 int reg;
b99bd4ef 5612
c19d1205
ZW
5613 for (p = *str; ISALPHA (*p); p++)
5614 ;
b99bd4ef 5615
c19d1205 5616 if (p == *str)
b99bd4ef 5617 {
c19d1205
ZW
5618 inst.error = _("shift expression expected");
5619 return FAIL;
b99bd4ef
NC
5620 }
5621
fe0e921f
AM
5622 shift_name
5623 = (const struct asm_shift_name *) str_hash_find_n (arm_shift_hsh, *str,
5624 p - *str);
c19d1205
ZW
5625
5626 if (shift_name == NULL)
b99bd4ef 5627 {
c19d1205
ZW
5628 inst.error = _("shift expression expected");
5629 return FAIL;
b99bd4ef
NC
5630 }
5631
c19d1205 5632 shift = shift_name->kind;
b99bd4ef 5633
c19d1205
ZW
5634 switch (mode)
5635 {
5636 case NO_SHIFT_RESTRICT:
f5f10c66
AV
5637 case SHIFT_IMMEDIATE:
5638 if (shift == SHIFT_UXTW)
5639 {
5640 inst.error = _("'UXTW' not allowed here");
5641 return FAIL;
5642 }
5643 break;
b99bd4ef 5644
c19d1205
ZW
5645 case SHIFT_LSL_OR_ASR_IMMEDIATE:
5646 if (shift != SHIFT_LSL && shift != SHIFT_ASR)
5647 {
5648 inst.error = _("'LSL' or 'ASR' required");
5649 return FAIL;
5650 }
5651 break;
b99bd4ef 5652
c19d1205
ZW
5653 case SHIFT_LSL_IMMEDIATE:
5654 if (shift != SHIFT_LSL)
5655 {
5656 inst.error = _("'LSL' required");
5657 return FAIL;
5658 }
5659 break;
b99bd4ef 5660
c19d1205
ZW
5661 case SHIFT_ASR_IMMEDIATE:
5662 if (shift != SHIFT_ASR)
5663 {
5664 inst.error = _("'ASR' required");
5665 return FAIL;
5666 }
5667 break;
f5f10c66
AV
5668 case SHIFT_UXTW_IMMEDIATE:
5669 if (shift != SHIFT_UXTW)
5670 {
5671 inst.error = _("'UXTW' required");
5672 return FAIL;
5673 }
5674 break;
b99bd4ef 5675
c19d1205
ZW
5676 default: abort ();
5677 }
b99bd4ef 5678
c19d1205
ZW
5679 if (shift != SHIFT_RRX)
5680 {
5681 /* Whitespace can appear here if the next thing is a bare digit. */
5682 skip_whitespace (p);
b99bd4ef 5683
c19d1205 5684 if (mode == NO_SHIFT_RESTRICT
dcbf9037 5685 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5686 {
5687 inst.operands[i].imm = reg;
5688 inst.operands[i].immisreg = 1;
5689 }
e2b0ab59 5690 else if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
c19d1205
ZW
5691 return FAIL;
5692 }
5693 inst.operands[i].shift_kind = shift;
5694 inst.operands[i].shifted = 1;
5695 *str = p;
5696 return SUCCESS;
b99bd4ef
NC
5697}
5698
c19d1205 5699/* Parse a <shifter_operand> for an ARM data processing instruction:
b99bd4ef 5700
c19d1205
ZW
5701 #<immediate>
5702 #<immediate>, <rotate>
5703 <Rm>
5704 <Rm>, <shift>
b99bd4ef 5705
c19d1205
ZW
5706 where <shift> is defined by parse_shift above, and <rotate> is a
5707 multiple of 2 between 0 and 30. Validation of immediate operands
55cf6793 5708 is deferred to md_apply_fix. */
b99bd4ef 5709
c19d1205
ZW
5710static int
5711parse_shifter_operand (char **str, int i)
5712{
5713 int value;
91d6fa6a 5714 expressionS exp;
b99bd4ef 5715
dcbf9037 5716 if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5717 {
5718 inst.operands[i].reg = value;
5719 inst.operands[i].isreg = 1;
b99bd4ef 5720
c19d1205 5721 /* parse_shift will override this if appropriate */
e2b0ab59
AV
5722 inst.relocs[0].exp.X_op = O_constant;
5723 inst.relocs[0].exp.X_add_number = 0;
b99bd4ef 5724
c19d1205
ZW
5725 if (skip_past_comma (str) == FAIL)
5726 return SUCCESS;
b99bd4ef 5727
c19d1205
ZW
5728 /* Shift operation on register. */
5729 return parse_shift (str, i, NO_SHIFT_RESTRICT);
b99bd4ef
NC
5730 }
5731
e2b0ab59 5732 if (my_get_expression (&inst.relocs[0].exp, str, GE_IMM_PREFIX))
c19d1205 5733 return FAIL;
b99bd4ef 5734
c19d1205 5735 if (skip_past_comma (str) == SUCCESS)
b99bd4ef 5736 {
c19d1205 5737 /* #x, y -- ie explicit rotation by Y. */
91d6fa6a 5738 if (my_get_expression (&exp, str, GE_NO_PREFIX))
c19d1205 5739 return FAIL;
b99bd4ef 5740
e2b0ab59 5741 if (exp.X_op != O_constant || inst.relocs[0].exp.X_op != O_constant)
c19d1205
ZW
5742 {
5743 inst.error = _("constant expression expected");
5744 return FAIL;
5745 }
b99bd4ef 5746
91d6fa6a 5747 value = exp.X_add_number;
c19d1205
ZW
5748 if (value < 0 || value > 30 || value % 2 != 0)
5749 {
5750 inst.error = _("invalid rotation");
5751 return FAIL;
5752 }
e2b0ab59
AV
5753 if (inst.relocs[0].exp.X_add_number < 0
5754 || inst.relocs[0].exp.X_add_number > 255)
c19d1205
ZW
5755 {
5756 inst.error = _("invalid constant");
5757 return FAIL;
5758 }
09d92015 5759
a415b1cd 5760 /* Encode as specified. */
e2b0ab59 5761 inst.operands[i].imm = inst.relocs[0].exp.X_add_number | value << 7;
a415b1cd 5762 return SUCCESS;
09d92015
MM
5763 }
5764
e2b0ab59
AV
5765 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
5766 inst.relocs[0].pc_rel = 0;
c19d1205 5767 return SUCCESS;
09d92015
MM
5768}
5769
4962c51a
MS
5770/* Group relocation information. Each entry in the table contains the
5771 textual name of the relocation as may appear in assembler source
5772 and must end with a colon.
5773 Along with this textual name are the relocation codes to be used if
5774 the corresponding instruction is an ALU instruction (ADD or SUB only),
5775 an LDR, an LDRS, or an LDC. */
5776
5777struct group_reloc_table_entry
5778{
5779 const char *name;
5780 int alu_code;
5781 int ldr_code;
5782 int ldrs_code;
5783 int ldc_code;
5784};
5785
5786typedef enum
5787{
5788 /* Varieties of non-ALU group relocation. */
5789
5790 GROUP_LDR,
5791 GROUP_LDRS,
35c228db
AV
5792 GROUP_LDC,
5793 GROUP_MVE
4962c51a
MS
5794} group_reloc_type;
5795
5796static struct group_reloc_table_entry group_reloc_table[] =
5797 { /* Program counter relative: */
5798 { "pc_g0_nc",
5799 BFD_RELOC_ARM_ALU_PC_G0_NC, /* ALU */
5800 0, /* LDR */
5801 0, /* LDRS */
5802 0 }, /* LDC */
5803 { "pc_g0",
5804 BFD_RELOC_ARM_ALU_PC_G0, /* ALU */
5805 BFD_RELOC_ARM_LDR_PC_G0, /* LDR */
5806 BFD_RELOC_ARM_LDRS_PC_G0, /* LDRS */
5807 BFD_RELOC_ARM_LDC_PC_G0 }, /* LDC */
5808 { "pc_g1_nc",
5809 BFD_RELOC_ARM_ALU_PC_G1_NC, /* ALU */
5810 0, /* LDR */
5811 0, /* LDRS */
5812 0 }, /* LDC */
5813 { "pc_g1",
5814 BFD_RELOC_ARM_ALU_PC_G1, /* ALU */
5815 BFD_RELOC_ARM_LDR_PC_G1, /* LDR */
5816 BFD_RELOC_ARM_LDRS_PC_G1, /* LDRS */
5817 BFD_RELOC_ARM_LDC_PC_G1 }, /* LDC */
5818 { "pc_g2",
5819 BFD_RELOC_ARM_ALU_PC_G2, /* ALU */
5820 BFD_RELOC_ARM_LDR_PC_G2, /* LDR */
5821 BFD_RELOC_ARM_LDRS_PC_G2, /* LDRS */
5822 BFD_RELOC_ARM_LDC_PC_G2 }, /* LDC */
5823 /* Section base relative */
5824 { "sb_g0_nc",
5825 BFD_RELOC_ARM_ALU_SB_G0_NC, /* ALU */
5826 0, /* LDR */
5827 0, /* LDRS */
5828 0 }, /* LDC */
5829 { "sb_g0",
5830 BFD_RELOC_ARM_ALU_SB_G0, /* ALU */
5831 BFD_RELOC_ARM_LDR_SB_G0, /* LDR */
5832 BFD_RELOC_ARM_LDRS_SB_G0, /* LDRS */
5833 BFD_RELOC_ARM_LDC_SB_G0 }, /* LDC */
5834 { "sb_g1_nc",
5835 BFD_RELOC_ARM_ALU_SB_G1_NC, /* ALU */
5836 0, /* LDR */
5837 0, /* LDRS */
5838 0 }, /* LDC */
5839 { "sb_g1",
5840 BFD_RELOC_ARM_ALU_SB_G1, /* ALU */
5841 BFD_RELOC_ARM_LDR_SB_G1, /* LDR */
5842 BFD_RELOC_ARM_LDRS_SB_G1, /* LDRS */
5843 BFD_RELOC_ARM_LDC_SB_G1 }, /* LDC */
5844 { "sb_g2",
5845 BFD_RELOC_ARM_ALU_SB_G2, /* ALU */
5846 BFD_RELOC_ARM_LDR_SB_G2, /* LDR */
5847 BFD_RELOC_ARM_LDRS_SB_G2, /* LDRS */
72d98d16
MG
5848 BFD_RELOC_ARM_LDC_SB_G2 }, /* LDC */
5849 /* Absolute thumb alu relocations. */
5850 { "lower0_7",
5851 BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,/* ALU. */
5852 0, /* LDR. */
5853 0, /* LDRS. */
5854 0 }, /* LDC. */
5855 { "lower8_15",
5856 BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,/* ALU. */
5857 0, /* LDR. */
5858 0, /* LDRS. */
5859 0 }, /* LDC. */
5860 { "upper0_7",
5861 BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,/* ALU. */
5862 0, /* LDR. */
5863 0, /* LDRS. */
5864 0 }, /* LDC. */
5865 { "upper8_15",
5866 BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,/* ALU. */
5867 0, /* LDR. */
5868 0, /* LDRS. */
5869 0 } }; /* LDC. */
4962c51a
MS
5870
5871/* Given the address of a pointer pointing to the textual name of a group
5872 relocation as may appear in assembler source, attempt to find its details
5873 in group_reloc_table. The pointer will be updated to the character after
5874 the trailing colon. On failure, FAIL will be returned; SUCCESS
5875 otherwise. On success, *entry will be updated to point at the relevant
5876 group_reloc_table entry. */
5877
5878static int
5879find_group_reloc_table_entry (char **str, struct group_reloc_table_entry **out)
5880{
5881 unsigned int i;
5882 for (i = 0; i < ARRAY_SIZE (group_reloc_table); i++)
5883 {
5884 int length = strlen (group_reloc_table[i].name);
5885
5f4273c7
NC
5886 if (strncasecmp (group_reloc_table[i].name, *str, length) == 0
5887 && (*str)[length] == ':')
477330fc
RM
5888 {
5889 *out = &group_reloc_table[i];
5890 *str += (length + 1);
5891 return SUCCESS;
5892 }
4962c51a
MS
5893 }
5894
5895 return FAIL;
5896}
5897
5898/* Parse a <shifter_operand> for an ARM data processing instruction
5899 (as for parse_shifter_operand) where group relocations are allowed:
5900
5901 #<immediate>
5902 #<immediate>, <rotate>
5903 #:<group_reloc>:<expression>
5904 <Rm>
5905 <Rm>, <shift>
5906
5907 where <group_reloc> is one of the strings defined in group_reloc_table.
5908 The hashes are optional.
5909
5910 Everything else is as for parse_shifter_operand. */
5911
5912static parse_operand_result
5913parse_shifter_operand_group_reloc (char **str, int i)
5914{
5915 /* Determine if we have the sequence of characters #: or just :
5916 coming next. If we do, then we check for a group relocation.
5917 If we don't, punt the whole lot to parse_shifter_operand. */
5918
5919 if (((*str)[0] == '#' && (*str)[1] == ':')
5920 || (*str)[0] == ':')
5921 {
5922 struct group_reloc_table_entry *entry;
5923
5924 if ((*str)[0] == '#')
477330fc 5925 (*str) += 2;
4962c51a 5926 else
477330fc 5927 (*str)++;
4962c51a
MS
5928
5929 /* Try to parse a group relocation. Anything else is an error. */
5930 if (find_group_reloc_table_entry (str, &entry) == FAIL)
477330fc
RM
5931 {
5932 inst.error = _("unknown group relocation");
5933 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5934 }
4962c51a
MS
5935
5936 /* We now have the group relocation table entry corresponding to
477330fc 5937 the name in the assembler source. Next, we parse the expression. */
e2b0ab59 5938 if (my_get_expression (&inst.relocs[0].exp, str, GE_NO_PREFIX))
477330fc 5939 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
4962c51a
MS
5940
5941 /* Record the relocation type (always the ALU variant here). */
e2b0ab59
AV
5942 inst.relocs[0].type = (bfd_reloc_code_real_type) entry->alu_code;
5943 gas_assert (inst.relocs[0].type != 0);
4962c51a
MS
5944
5945 return PARSE_OPERAND_SUCCESS;
5946 }
5947 else
5948 return parse_shifter_operand (str, i) == SUCCESS
477330fc 5949 ? PARSE_OPERAND_SUCCESS : PARSE_OPERAND_FAIL;
4962c51a
MS
5950
5951 /* Never reached. */
5952}
5953
8e560766
MGD
5954/* Parse a Neon alignment expression. Information is written to
5955 inst.operands[i]. We assume the initial ':' has been skipped.
fa94de6b 5956
8e560766
MGD
5957 align .imm = align << 8, .immisalign=1, .preind=0 */
5958static parse_operand_result
5959parse_neon_alignment (char **str, int i)
5960{
5961 char *p = *str;
5962 expressionS exp;
5963
5964 my_get_expression (&exp, &p, GE_NO_PREFIX);
5965
5966 if (exp.X_op != O_constant)
5967 {
5968 inst.error = _("alignment must be constant");
5969 return PARSE_OPERAND_FAIL;
5970 }
5971
5972 inst.operands[i].imm = exp.X_add_number << 8;
5973 inst.operands[i].immisalign = 1;
5974 /* Alignments are not pre-indexes. */
5975 inst.operands[i].preind = 0;
5976
5977 *str = p;
5978 return PARSE_OPERAND_SUCCESS;
5979}
5980
c19d1205 5981/* Parse all forms of an ARM address expression. Information is written
e2b0ab59 5982 to inst.operands[i] and/or inst.relocs[0].
09d92015 5983
c19d1205 5984 Preindexed addressing (.preind=1):
09d92015 5985
e2b0ab59 5986 [Rn, #offset] .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5987 [Rn, +/-Rm] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5988 [Rn, +/-Rm, shift] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5989 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5990
c19d1205 5991 These three may have a trailing ! which causes .writeback to be set also.
09d92015 5992
c19d1205 5993 Postindexed addressing (.postind=1, .writeback=1):
09d92015 5994
e2b0ab59 5995 [Rn], #offset .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5996 [Rn], +/-Rm .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5997 [Rn], +/-Rm, shift .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5998 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5999
c19d1205 6000 Unindexed addressing (.preind=0, .postind=0):
09d92015 6001
c19d1205 6002 [Rn], {option} .reg=Rn .imm=option .immisreg=0
09d92015 6003
c19d1205 6004 Other:
09d92015 6005
c19d1205 6006 [Rn]{!} shorthand for [Rn,#0]{!}
e2b0ab59
AV
6007 =immediate .isreg=0 .relocs[0].exp=immediate
6008 label .reg=PC .relocs[0].pc_rel=1 .relocs[0].exp=label
09d92015 6009
c19d1205 6010 It is the caller's responsibility to check for addressing modes not
e2b0ab59 6011 supported by the instruction, and to set inst.relocs[0].type. */
c19d1205 6012
4962c51a
MS
6013static parse_operand_result
6014parse_address_main (char **str, int i, int group_relocations,
477330fc 6015 group_reloc_type group_type)
09d92015 6016{
c19d1205
ZW
6017 char *p = *str;
6018 int reg;
09d92015 6019
c19d1205 6020 if (skip_past_char (&p, '[') == FAIL)
09d92015 6021 {
79248c83
SP
6022 if (group_type == GROUP_MVE
6023 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
6024 {
6025 /* [r0-r15] expected as argument but receiving r0-r15 without
6026 [] brackets. */
6027 inst.error = BAD_SYNTAX;
6028 return PARSE_OPERAND_FAIL;
6029 }
6030 else if (skip_past_char (&p, '=') == FAIL)
c19d1205 6031 {
974da60d 6032 /* Bare address - translate to PC-relative offset. */
e2b0ab59 6033 inst.relocs[0].pc_rel = 1;
c19d1205
ZW
6034 inst.operands[i].reg = REG_PC;
6035 inst.operands[i].isreg = 1;
6036 inst.operands[i].preind = 1;
09d92015 6037
e2b0ab59 6038 if (my_get_expression (&inst.relocs[0].exp, &p, GE_OPT_PREFIX_BIG))
8335d6aa
JW
6039 return PARSE_OPERAND_FAIL;
6040 }
e2b0ab59 6041 else if (parse_big_immediate (&p, i, &inst.relocs[0].exp,
5b7c81bd 6042 /*allow_symbol_p=*/true))
4962c51a 6043 return PARSE_OPERAND_FAIL;
09d92015 6044
c19d1205 6045 *str = p;
4962c51a 6046 return PARSE_OPERAND_SUCCESS;
09d92015
MM
6047 }
6048
8ab8155f
NC
6049 /* PR gas/14887: Allow for whitespace after the opening bracket. */
6050 skip_whitespace (p);
6051
f5f10c66
AV
6052 if (group_type == GROUP_MVE)
6053 {
6054 enum arm_reg_type rtype = REG_TYPE_MQ;
6055 struct neon_type_el et;
6056 if ((reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
6057 {
6058 inst.operands[i].isquad = 1;
6059 }
6060 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
6061 {
6062 inst.error = BAD_ADDR_MODE;
6063 return PARSE_OPERAND_FAIL;
6064 }
6065 }
6066 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
09d92015 6067 {
35c228db
AV
6068 if (group_type == GROUP_MVE)
6069 inst.error = BAD_ADDR_MODE;
6070 else
6071 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
4962c51a 6072 return PARSE_OPERAND_FAIL;
09d92015 6073 }
c19d1205
ZW
6074 inst.operands[i].reg = reg;
6075 inst.operands[i].isreg = 1;
09d92015 6076
c19d1205 6077 if (skip_past_comma (&p) == SUCCESS)
09d92015 6078 {
c19d1205 6079 inst.operands[i].preind = 1;
09d92015 6080
c19d1205
ZW
6081 if (*p == '+') p++;
6082 else if (*p == '-') p++, inst.operands[i].negative = 1;
6083
f5f10c66
AV
6084 enum arm_reg_type rtype = REG_TYPE_MQ;
6085 struct neon_type_el et;
6086 if (group_type == GROUP_MVE
6087 && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
6088 {
6089 inst.operands[i].immisreg = 2;
6090 inst.operands[i].imm = reg;
6091
6092 if (skip_past_comma (&p) == SUCCESS)
6093 {
6094 if (parse_shift (&p, i, SHIFT_UXTW_IMMEDIATE) == SUCCESS)
6095 {
6096 inst.operands[i].imm |= inst.relocs[0].exp.X_add_number << 5;
6097 inst.relocs[0].exp.X_add_number = 0;
6098 }
6099 else
6100 return PARSE_OPERAND_FAIL;
6101 }
6102 }
6103 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
09d92015 6104 {
c19d1205
ZW
6105 inst.operands[i].imm = reg;
6106 inst.operands[i].immisreg = 1;
6107
6108 if (skip_past_comma (&p) == SUCCESS)
6109 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 6110 return PARSE_OPERAND_FAIL;
c19d1205 6111 }
5287ad62 6112 else if (skip_past_char (&p, ':') == SUCCESS)
8e560766
MGD
6113 {
6114 /* FIXME: '@' should be used here, but it's filtered out by generic
6115 code before we get to see it here. This may be subject to
6116 change. */
6117 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 6118
8e560766
MGD
6119 if (result != PARSE_OPERAND_SUCCESS)
6120 return result;
6121 }
c19d1205
ZW
6122 else
6123 {
6124 if (inst.operands[i].negative)
6125 {
6126 inst.operands[i].negative = 0;
6127 p--;
6128 }
4962c51a 6129
5f4273c7
NC
6130 if (group_relocations
6131 && ((*p == '#' && *(p + 1) == ':') || *p == ':'))
4962c51a
MS
6132 {
6133 struct group_reloc_table_entry *entry;
6134
477330fc
RM
6135 /* Skip over the #: or : sequence. */
6136 if (*p == '#')
6137 p += 2;
6138 else
6139 p++;
4962c51a
MS
6140
6141 /* Try to parse a group relocation. Anything else is an
477330fc 6142 error. */
4962c51a
MS
6143 if (find_group_reloc_table_entry (&p, &entry) == FAIL)
6144 {
6145 inst.error = _("unknown group relocation");
6146 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6147 }
6148
6149 /* We now have the group relocation table entry corresponding to
6150 the name in the assembler source. Next, we parse the
477330fc 6151 expression. */
e2b0ab59 6152 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
4962c51a
MS
6153 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6154
6155 /* Record the relocation type. */
477330fc
RM
6156 switch (group_type)
6157 {
6158 case GROUP_LDR:
e2b0ab59
AV
6159 inst.relocs[0].type
6160 = (bfd_reloc_code_real_type) entry->ldr_code;
477330fc 6161 break;
4962c51a 6162
477330fc 6163 case GROUP_LDRS:
e2b0ab59
AV
6164 inst.relocs[0].type
6165 = (bfd_reloc_code_real_type) entry->ldrs_code;
477330fc 6166 break;
4962c51a 6167
477330fc 6168 case GROUP_LDC:
e2b0ab59
AV
6169 inst.relocs[0].type
6170 = (bfd_reloc_code_real_type) entry->ldc_code;
477330fc 6171 break;
4962c51a 6172
477330fc
RM
6173 default:
6174 gas_assert (0);
6175 }
4962c51a 6176
e2b0ab59 6177 if (inst.relocs[0].type == 0)
4962c51a
MS
6178 {
6179 inst.error = _("this group relocation is not allowed on this instruction");
6180 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6181 }
477330fc
RM
6182 }
6183 else
26d97720
NS
6184 {
6185 char *q = p;
0198d5e6 6186
e2b0ab59 6187 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
26d97720
NS
6188 return PARSE_OPERAND_FAIL;
6189 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
6190 if (inst.relocs[0].exp.X_op == O_constant
6191 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
6192 {
6193 skip_whitespace (q);
6194 if (*q == '#')
6195 {
6196 q++;
6197 skip_whitespace (q);
6198 }
6199 if (*q == '-')
6200 inst.operands[i].negative = 1;
6201 }
6202 }
09d92015
MM
6203 }
6204 }
8e560766
MGD
6205 else if (skip_past_char (&p, ':') == SUCCESS)
6206 {
6207 /* FIXME: '@' should be used here, but it's filtered out by generic code
6208 before we get to see it here. This may be subject to change. */
6209 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 6210
8e560766
MGD
6211 if (result != PARSE_OPERAND_SUCCESS)
6212 return result;
6213 }
09d92015 6214
c19d1205 6215 if (skip_past_char (&p, ']') == FAIL)
09d92015 6216 {
c19d1205 6217 inst.error = _("']' expected");
4962c51a 6218 return PARSE_OPERAND_FAIL;
09d92015
MM
6219 }
6220
c19d1205
ZW
6221 if (skip_past_char (&p, '!') == SUCCESS)
6222 inst.operands[i].writeback = 1;
09d92015 6223
c19d1205 6224 else if (skip_past_comma (&p) == SUCCESS)
09d92015 6225 {
c19d1205
ZW
6226 if (skip_past_char (&p, '{') == SUCCESS)
6227 {
6228 /* [Rn], {expr} - unindexed, with option */
6229 if (parse_immediate (&p, &inst.operands[i].imm,
5b7c81bd 6230 0, 255, true) == FAIL)
4962c51a 6231 return PARSE_OPERAND_FAIL;
09d92015 6232
c19d1205
ZW
6233 if (skip_past_char (&p, '}') == FAIL)
6234 {
6235 inst.error = _("'}' expected at end of 'option' field");
4962c51a 6236 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6237 }
6238 if (inst.operands[i].preind)
6239 {
6240 inst.error = _("cannot combine index with option");
4962c51a 6241 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6242 }
6243 *str = p;
4962c51a 6244 return PARSE_OPERAND_SUCCESS;
09d92015 6245 }
c19d1205
ZW
6246 else
6247 {
6248 inst.operands[i].postind = 1;
6249 inst.operands[i].writeback = 1;
09d92015 6250
c19d1205
ZW
6251 if (inst.operands[i].preind)
6252 {
6253 inst.error = _("cannot combine pre- and post-indexing");
4962c51a 6254 return PARSE_OPERAND_FAIL;
c19d1205 6255 }
09d92015 6256
c19d1205
ZW
6257 if (*p == '+') p++;
6258 else if (*p == '-') p++, inst.operands[i].negative = 1;
a737bd4d 6259
f5f10c66
AV
6260 enum arm_reg_type rtype = REG_TYPE_MQ;
6261 struct neon_type_el et;
6262 if (group_type == GROUP_MVE
6263 && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
6264 {
6265 inst.operands[i].immisreg = 2;
6266 inst.operands[i].imm = reg;
6267 }
6268 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205 6269 {
477330fc
RM
6270 /* We might be using the immediate for alignment already. If we
6271 are, OR the register number into the low-order bits. */
6272 if (inst.operands[i].immisalign)
6273 inst.operands[i].imm |= reg;
6274 else
6275 inst.operands[i].imm = reg;
c19d1205 6276 inst.operands[i].immisreg = 1;
a737bd4d 6277
c19d1205
ZW
6278 if (skip_past_comma (&p) == SUCCESS)
6279 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 6280 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6281 }
6282 else
6283 {
26d97720 6284 char *q = p;
0198d5e6 6285
c19d1205
ZW
6286 if (inst.operands[i].negative)
6287 {
6288 inst.operands[i].negative = 0;
6289 p--;
6290 }
e2b0ab59 6291 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
4962c51a 6292 return PARSE_OPERAND_FAIL;
26d97720 6293 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
6294 if (inst.relocs[0].exp.X_op == O_constant
6295 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
6296 {
6297 skip_whitespace (q);
6298 if (*q == '#')
6299 {
6300 q++;
6301 skip_whitespace (q);
6302 }
6303 if (*q == '-')
6304 inst.operands[i].negative = 1;
6305 }
c19d1205
ZW
6306 }
6307 }
a737bd4d
NC
6308 }
6309
c19d1205
ZW
6310 /* If at this point neither .preind nor .postind is set, we have a
6311 bare [Rn]{!}, which is shorthand for [Rn,#0]{!}. */
6312 if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
6313 {
6314 inst.operands[i].preind = 1;
e2b0ab59
AV
6315 inst.relocs[0].exp.X_op = O_constant;
6316 inst.relocs[0].exp.X_add_number = 0;
c19d1205
ZW
6317 }
6318 *str = p;
4962c51a
MS
6319 return PARSE_OPERAND_SUCCESS;
6320}
6321
6322static int
6323parse_address (char **str, int i)
6324{
21d799b5 6325 return parse_address_main (str, i, 0, GROUP_LDR) == PARSE_OPERAND_SUCCESS
477330fc 6326 ? SUCCESS : FAIL;
4962c51a
MS
6327}
6328
6329static parse_operand_result
6330parse_address_group_reloc (char **str, int i, group_reloc_type type)
6331{
6332 return parse_address_main (str, i, 1, type);
a737bd4d
NC
6333}
6334
b6895b4f
PB
6335/* Parse an operand for a MOVW or MOVT instruction. */
6336static int
6337parse_half (char **str)
6338{
6339 char * p;
5f4273c7 6340
b6895b4f
PB
6341 p = *str;
6342 skip_past_char (&p, '#');
5f4273c7 6343 if (strncasecmp (p, ":lower16:", 9) == 0)
e2b0ab59 6344 inst.relocs[0].type = BFD_RELOC_ARM_MOVW;
b6895b4f 6345 else if (strncasecmp (p, ":upper16:", 9) == 0)
e2b0ab59 6346 inst.relocs[0].type = BFD_RELOC_ARM_MOVT;
b6895b4f 6347
e2b0ab59 6348 if (inst.relocs[0].type != BFD_RELOC_UNUSED)
b6895b4f
PB
6349 {
6350 p += 9;
5f4273c7 6351 skip_whitespace (p);
b6895b4f
PB
6352 }
6353
e2b0ab59 6354 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
b6895b4f
PB
6355 return FAIL;
6356
e2b0ab59 6357 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 6358 {
e2b0ab59 6359 if (inst.relocs[0].exp.X_op != O_constant)
b6895b4f
PB
6360 {
6361 inst.error = _("constant expression expected");
6362 return FAIL;
6363 }
e2b0ab59
AV
6364 if (inst.relocs[0].exp.X_add_number < 0
6365 || inst.relocs[0].exp.X_add_number > 0xffff)
b6895b4f
PB
6366 {
6367 inst.error = _("immediate value out of range");
6368 return FAIL;
6369 }
6370 }
6371 *str = p;
6372 return SUCCESS;
6373}
6374
c19d1205 6375/* Miscellaneous. */
a737bd4d 6376
c19d1205
ZW
6377/* Parse a PSR flag operand. The value returned is FAIL on syntax error,
6378 or a bitmask suitable to be or-ed into the ARM msr instruction. */
6379static int
5b7c81bd 6380parse_psr (char **str, bool lhs)
09d92015 6381{
c19d1205
ZW
6382 char *p;
6383 unsigned long psr_field;
62b3e311
PB
6384 const struct asm_psr *psr;
6385 char *start;
5b7c81bd
AM
6386 bool is_apsr = false;
6387 bool m_profile = ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m);
09d92015 6388
a4482bb6
NC
6389 /* PR gas/12698: If the user has specified -march=all then m_profile will
6390 be TRUE, but we want to ignore it in this case as we are building for any
6391 CPU type, including non-m variants. */
823d2571 6392 if (ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
5b7c81bd 6393 m_profile = false;
a4482bb6 6394
c19d1205
ZW
6395 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
6396 feature for ease of use and backwards compatibility. */
6397 p = *str;
62b3e311 6398 if (strncasecmp (p, "SPSR", 4) == 0)
d2cd1205
JB
6399 {
6400 if (m_profile)
6401 goto unsupported_psr;
fa94de6b 6402
d2cd1205
JB
6403 psr_field = SPSR_BIT;
6404 }
6405 else if (strncasecmp (p, "CPSR", 4) == 0)
6406 {
6407 if (m_profile)
6408 goto unsupported_psr;
6409
6410 psr_field = 0;
6411 }
6412 else if (strncasecmp (p, "APSR", 4) == 0)
6413 {
6414 /* APSR[_<bits>] can be used as a synonym for CPSR[_<flags>] on ARMv7-A
6415 and ARMv7-R architecture CPUs. */
5b7c81bd 6416 is_apsr = true;
d2cd1205
JB
6417 psr_field = 0;
6418 }
6419 else if (m_profile)
62b3e311
PB
6420 {
6421 start = p;
6422 do
6423 p++;
6424 while (ISALNUM (*p) || *p == '_');
6425
d2cd1205
JB
6426 if (strncasecmp (start, "iapsr", 5) == 0
6427 || strncasecmp (start, "eapsr", 5) == 0
6428 || strncasecmp (start, "xpsr", 4) == 0
6429 || strncasecmp (start, "psr", 3) == 0)
6430 p = start + strcspn (start, "rR") + 1;
6431
629310ab 6432 psr = (const struct asm_psr *) str_hash_find_n (arm_v7m_psr_hsh, start,
fe0e921f 6433 p - start);
d2cd1205 6434
62b3e311
PB
6435 if (!psr)
6436 return FAIL;
09d92015 6437
d2cd1205
JB
6438 /* If APSR is being written, a bitfield may be specified. Note that
6439 APSR itself is handled above. */
6440 if (psr->field <= 3)
6441 {
6442 psr_field = psr->field;
5b7c81bd 6443 is_apsr = true;
d2cd1205
JB
6444 goto check_suffix;
6445 }
6446
62b3e311 6447 *str = p;
d2cd1205
JB
6448 /* M-profile MSR instructions have the mask field set to "10", except
6449 *PSR variants which modify APSR, which may use a different mask (and
6450 have been handled already). Do that by setting the PSR_f field
6451 here. */
6452 return psr->field | (lhs ? PSR_f : 0);
62b3e311 6453 }
d2cd1205
JB
6454 else
6455 goto unsupported_psr;
09d92015 6456
62b3e311 6457 p += 4;
dc1e8a47 6458 check_suffix:
c19d1205
ZW
6459 if (*p == '_')
6460 {
6461 /* A suffix follows. */
c19d1205
ZW
6462 p++;
6463 start = p;
a737bd4d 6464
c19d1205
ZW
6465 do
6466 p++;
6467 while (ISALNUM (*p) || *p == '_');
a737bd4d 6468
d2cd1205
JB
6469 if (is_apsr)
6470 {
6471 /* APSR uses a notation for bits, rather than fields. */
6472 unsigned int nzcvq_bits = 0;
6473 unsigned int g_bit = 0;
6474 char *bit;
fa94de6b 6475
d2cd1205
JB
6476 for (bit = start; bit != p; bit++)
6477 {
6478 switch (TOLOWER (*bit))
477330fc 6479 {
d2cd1205
JB
6480 case 'n':
6481 nzcvq_bits |= (nzcvq_bits & 0x01) ? 0x20 : 0x01;
6482 break;
6483
6484 case 'z':
6485 nzcvq_bits |= (nzcvq_bits & 0x02) ? 0x20 : 0x02;
6486 break;
6487
6488 case 'c':
6489 nzcvq_bits |= (nzcvq_bits & 0x04) ? 0x20 : 0x04;
6490 break;
6491
6492 case 'v':
6493 nzcvq_bits |= (nzcvq_bits & 0x08) ? 0x20 : 0x08;
6494 break;
fa94de6b 6495
d2cd1205
JB
6496 case 'q':
6497 nzcvq_bits |= (nzcvq_bits & 0x10) ? 0x20 : 0x10;
6498 break;
fa94de6b 6499
d2cd1205
JB
6500 case 'g':
6501 g_bit |= (g_bit & 0x1) ? 0x2 : 0x1;
6502 break;
fa94de6b 6503
d2cd1205
JB
6504 default:
6505 inst.error = _("unexpected bit specified after APSR");
6506 return FAIL;
6507 }
6508 }
fa94de6b 6509
d2cd1205
JB
6510 if (nzcvq_bits == 0x1f)
6511 psr_field |= PSR_f;
fa94de6b 6512
d2cd1205
JB
6513 if (g_bit == 0x1)
6514 {
6515 if (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp))
477330fc 6516 {
d2cd1205
JB
6517 inst.error = _("selected processor does not "
6518 "support DSP extension");
6519 return FAIL;
6520 }
6521
6522 psr_field |= PSR_s;
6523 }
fa94de6b 6524
d2cd1205
JB
6525 if ((nzcvq_bits & 0x20) != 0
6526 || (nzcvq_bits != 0x1f && nzcvq_bits != 0)
6527 || (g_bit & 0x2) != 0)
6528 {
6529 inst.error = _("bad bitmask specified after APSR");
6530 return FAIL;
6531 }
6532 }
6533 else
477330fc 6534 {
629310ab 6535 psr = (const struct asm_psr *) str_hash_find_n (arm_psr_hsh, start,
fe0e921f 6536 p - start);
d2cd1205 6537 if (!psr)
477330fc 6538 goto error;
a737bd4d 6539
d2cd1205
JB
6540 psr_field |= psr->field;
6541 }
a737bd4d 6542 }
c19d1205 6543 else
a737bd4d 6544 {
c19d1205
ZW
6545 if (ISALNUM (*p))
6546 goto error; /* Garbage after "[CS]PSR". */
6547
d2cd1205 6548 /* Unadorned APSR is equivalent to APSR_nzcvq/CPSR_f (for writes). This
477330fc 6549 is deprecated, but allow it anyway. */
d2cd1205
JB
6550 if (is_apsr && lhs)
6551 {
6552 psr_field |= PSR_f;
6553 as_tsktsk (_("writing to APSR without specifying a bitmask is "
6554 "deprecated"));
6555 }
6556 else if (!m_profile)
6557 /* These bits are never right for M-profile devices: don't set them
6558 (only code paths which read/write APSR reach here). */
6559 psr_field |= (PSR_c | PSR_f);
a737bd4d 6560 }
c19d1205
ZW
6561 *str = p;
6562 return psr_field;
a737bd4d 6563
d2cd1205
JB
6564 unsupported_psr:
6565 inst.error = _("selected processor does not support requested special "
6566 "purpose register");
6567 return FAIL;
6568
c19d1205
ZW
6569 error:
6570 inst.error = _("flag for {c}psr instruction expected");
6571 return FAIL;
a737bd4d
NC
6572}
6573
32c36c3c
AV
6574static int
6575parse_sys_vldr_vstr (char **str)
6576{
6577 unsigned i;
6578 int val = FAIL;
6579 struct {
6580 const char *name;
6581 int regl;
6582 int regh;
6583 } sysregs[] = {
6584 {"FPSCR", 0x1, 0x0},
6585 {"FPSCR_nzcvqc", 0x2, 0x0},
6586 {"VPR", 0x4, 0x1},
6587 {"P0", 0x5, 0x1},
6588 {"FPCXTNS", 0x6, 0x1},
ee3272d4
SP
6589 {"FPCXT_NS", 0x6, 0x1},
6590 {"fpcxtns", 0x6, 0x1},
6591 {"fpcxt_ns", 0x6, 0x1},
6592 {"FPCXTS", 0x7, 0x1},
6593 {"FPCXT_S", 0x7, 0x1},
6594 {"fpcxts", 0x7, 0x1},
6595 {"fpcxt_s", 0x7, 0x1}
32c36c3c
AV
6596 };
6597 char *op_end = strchr (*str, ',');
6598 size_t op_strlen = op_end - *str;
6599
6600 for (i = 0; i < sizeof (sysregs) / sizeof (sysregs[0]); i++)
6601 {
6602 if (!strncmp (*str, sysregs[i].name, op_strlen))
6603 {
6604 val = sysregs[i].regl | (sysregs[i].regh << 3);
6605 *str = op_end;
6606 break;
6607 }
6608 }
6609
6610 return val;
6611}
6612
c19d1205
ZW
6613/* Parse the flags argument to CPSI[ED]. Returns FAIL on error, or a
6614 value suitable for splatting into the AIF field of the instruction. */
a737bd4d 6615
c19d1205
ZW
6616static int
6617parse_cps_flags (char **str)
a737bd4d 6618{
c19d1205
ZW
6619 int val = 0;
6620 int saw_a_flag = 0;
6621 char *s = *str;
a737bd4d 6622
c19d1205
ZW
6623 for (;;)
6624 switch (*s++)
6625 {
6626 case '\0': case ',':
6627 goto done;
a737bd4d 6628
c19d1205
ZW
6629 case 'a': case 'A': saw_a_flag = 1; val |= 0x4; break;
6630 case 'i': case 'I': saw_a_flag = 1; val |= 0x2; break;
6631 case 'f': case 'F': saw_a_flag = 1; val |= 0x1; break;
a737bd4d 6632
c19d1205
ZW
6633 default:
6634 inst.error = _("unrecognized CPS flag");
6635 return FAIL;
6636 }
a737bd4d 6637
c19d1205
ZW
6638 done:
6639 if (saw_a_flag == 0)
a737bd4d 6640 {
c19d1205
ZW
6641 inst.error = _("missing CPS flags");
6642 return FAIL;
a737bd4d 6643 }
a737bd4d 6644
c19d1205
ZW
6645 *str = s - 1;
6646 return val;
a737bd4d
NC
6647}
6648
c19d1205
ZW
6649/* Parse an endian specifier ("BE" or "LE", case insensitive);
6650 returns 0 for big-endian, 1 for little-endian, FAIL for an error. */
a737bd4d
NC
6651
6652static int
c19d1205 6653parse_endian_specifier (char **str)
a737bd4d 6654{
c19d1205
ZW
6655 int little_endian;
6656 char *s = *str;
a737bd4d 6657
c19d1205
ZW
6658 if (strncasecmp (s, "BE", 2))
6659 little_endian = 0;
6660 else if (strncasecmp (s, "LE", 2))
6661 little_endian = 1;
6662 else
a737bd4d 6663 {
c19d1205 6664 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6665 return FAIL;
6666 }
6667
c19d1205 6668 if (ISALNUM (s[2]) || s[2] == '_')
a737bd4d 6669 {
c19d1205 6670 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6671 return FAIL;
6672 }
6673
c19d1205
ZW
6674 *str = s + 2;
6675 return little_endian;
6676}
a737bd4d 6677
c19d1205
ZW
6678/* Parse a rotation specifier: ROR #0, #8, #16, #24. *val receives a
6679 value suitable for poking into the rotate field of an sxt or sxta
6680 instruction, or FAIL on error. */
6681
6682static int
6683parse_ror (char **str)
6684{
6685 int rot;
6686 char *s = *str;
6687
6688 if (strncasecmp (s, "ROR", 3) == 0)
6689 s += 3;
6690 else
a737bd4d 6691 {
c19d1205 6692 inst.error = _("missing rotation field after comma");
a737bd4d
NC
6693 return FAIL;
6694 }
c19d1205 6695
5b7c81bd 6696 if (parse_immediate (&s, &rot, 0, 24, false) == FAIL)
c19d1205
ZW
6697 return FAIL;
6698
6699 switch (rot)
a737bd4d 6700 {
c19d1205
ZW
6701 case 0: *str = s; return 0x0;
6702 case 8: *str = s; return 0x1;
6703 case 16: *str = s; return 0x2;
6704 case 24: *str = s; return 0x3;
6705
6706 default:
6707 inst.error = _("rotation can only be 0, 8, 16, or 24");
a737bd4d
NC
6708 return FAIL;
6709 }
c19d1205 6710}
a737bd4d 6711
c19d1205
ZW
6712/* Parse a conditional code (from conds[] below). The value returned is in the
6713 range 0 .. 14, or FAIL. */
6714static int
6715parse_cond (char **str)
6716{
c462b453 6717 char *q;
c19d1205 6718 const struct asm_cond *c;
c462b453
PB
6719 int n;
6720 /* Condition codes are always 2 characters, so matching up to
6721 3 characters is sufficient. */
6722 char cond[3];
a737bd4d 6723
c462b453
PB
6724 q = *str;
6725 n = 0;
6726 while (ISALPHA (*q) && n < 3)
6727 {
e07e6e58 6728 cond[n] = TOLOWER (*q);
c462b453
PB
6729 q++;
6730 n++;
6731 }
a737bd4d 6732
629310ab 6733 c = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, cond, n);
c19d1205 6734 if (!c)
a737bd4d 6735 {
c19d1205 6736 inst.error = _("condition required");
a737bd4d
NC
6737 return FAIL;
6738 }
6739
c19d1205
ZW
6740 *str = q;
6741 return c->value;
6742}
6743
62b3e311
PB
6744/* Parse an option for a barrier instruction. Returns the encoding for the
6745 option, or FAIL. */
6746static int
6747parse_barrier (char **str)
6748{
6749 char *p, *q;
6750 const struct asm_barrier_opt *o;
6751
6752 p = q = *str;
6753 while (ISALPHA (*q))
6754 q++;
6755
629310ab 6756 o = (const struct asm_barrier_opt *) str_hash_find_n (arm_barrier_opt_hsh, p,
fe0e921f 6757 q - p);
62b3e311
PB
6758 if (!o)
6759 return FAIL;
6760
e797f7e0
MGD
6761 if (!mark_feature_used (&o->arch))
6762 return FAIL;
6763
62b3e311
PB
6764 *str = q;
6765 return o->value;
6766}
6767
92e90b6e
PB
6768/* Parse the operands of a table branch instruction. Similar to a memory
6769 operand. */
6770static int
6771parse_tb (char **str)
6772{
6773 char * p = *str;
6774 int reg;
6775
6776 if (skip_past_char (&p, '[') == FAIL)
ab1eb5fe
PB
6777 {
6778 inst.error = _("'[' expected");
6779 return FAIL;
6780 }
92e90b6e 6781
dcbf9037 6782 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6783 {
6784 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6785 return FAIL;
6786 }
6787 inst.operands[0].reg = reg;
6788
6789 if (skip_past_comma (&p) == FAIL)
ab1eb5fe
PB
6790 {
6791 inst.error = _("',' expected");
6792 return FAIL;
6793 }
5f4273c7 6794
dcbf9037 6795 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6796 {
6797 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6798 return FAIL;
6799 }
6800 inst.operands[0].imm = reg;
6801
6802 if (skip_past_comma (&p) == SUCCESS)
6803 {
6804 if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
6805 return FAIL;
e2b0ab59 6806 if (inst.relocs[0].exp.X_add_number != 1)
92e90b6e
PB
6807 {
6808 inst.error = _("invalid shift");
6809 return FAIL;
6810 }
6811 inst.operands[0].shifted = 1;
6812 }
6813
6814 if (skip_past_char (&p, ']') == FAIL)
6815 {
6816 inst.error = _("']' expected");
6817 return FAIL;
6818 }
6819 *str = p;
6820 return SUCCESS;
6821}
6822
5287ad62
JB
6823/* Parse the operands of a Neon VMOV instruction. See do_neon_mov for more
6824 information on the types the operands can take and how they are encoded.
037e8744
JB
6825 Up to four operands may be read; this function handles setting the
6826 ".present" field for each read operand itself.
5287ad62
JB
6827 Updates STR and WHICH_OPERAND if parsing is successful and returns SUCCESS,
6828 else returns FAIL. */
6829
6830static int
6831parse_neon_mov (char **str, int *which_operand)
6832{
6833 int i = *which_operand, val;
6834 enum arm_reg_type rtype;
6835 char *ptr = *str;
dcbf9037 6836 struct neon_type_el optype;
5f4273c7 6837
57785aa2
AV
6838 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6839 {
6840 /* Cases 17 or 19. */
6841 inst.operands[i].reg = val;
6842 inst.operands[i].isvec = 1;
6843 inst.operands[i].isscalar = 2;
6844 inst.operands[i].vectype = optype;
6845 inst.operands[i++].present = 1;
6846
6847 if (skip_past_comma (&ptr) == FAIL)
6848 goto wanted_comma;
6849
6850 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
6851 {
6852 /* Case 17: VMOV<c>.<dt> <Qd[idx]>, <Rt> */
6853 inst.operands[i].reg = val;
6854 inst.operands[i].isreg = 1;
6855 inst.operands[i].present = 1;
6856 }
6857 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6858 {
6859 /* Case 19: VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2> */
6860 inst.operands[i].reg = val;
6861 inst.operands[i].isvec = 1;
6862 inst.operands[i].isscalar = 2;
6863 inst.operands[i].vectype = optype;
6864 inst.operands[i++].present = 1;
6865
6866 if (skip_past_comma (&ptr) == FAIL)
6867 goto wanted_comma;
6868
6869 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6870 goto wanted_arm;
6871
6872 inst.operands[i].reg = val;
6873 inst.operands[i].isreg = 1;
6874 inst.operands[i++].present = 1;
6875
6876 if (skip_past_comma (&ptr) == FAIL)
6877 goto wanted_comma;
6878
6879 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6880 goto wanted_arm;
6881
6882 inst.operands[i].reg = val;
6883 inst.operands[i].isreg = 1;
6884 inst.operands[i].present = 1;
6885 }
6886 else
6887 {
6888 first_error (_("expected ARM or MVE vector register"));
6889 return FAIL;
6890 }
6891 }
6892 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
5287ad62
JB
6893 {
6894 /* Case 4: VMOV<c><q>.<size> <Dn[x]>, <Rd>. */
6895 inst.operands[i].reg = val;
6896 inst.operands[i].isscalar = 1;
dcbf9037 6897 inst.operands[i].vectype = optype;
5287ad62
JB
6898 inst.operands[i++].present = 1;
6899
6900 if (skip_past_comma (&ptr) == FAIL)
477330fc 6901 goto wanted_comma;
5f4273c7 6902
dcbf9037 6903 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
477330fc 6904 goto wanted_arm;
5f4273c7 6905
5287ad62
JB
6906 inst.operands[i].reg = val;
6907 inst.operands[i].isreg = 1;
6908 inst.operands[i].present = 1;
6909 }
57785aa2
AV
6910 else if (((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype, &optype))
6911 != FAIL)
6912 || ((val = arm_typed_reg_parse (&ptr, REG_TYPE_MQ, &rtype, &optype))
6913 != FAIL))
5287ad62
JB
6914 {
6915 /* Cases 0, 1, 2, 3, 5 (D only). */
6916 if (skip_past_comma (&ptr) == FAIL)
477330fc 6917 goto wanted_comma;
5f4273c7 6918
5287ad62
JB
6919 inst.operands[i].reg = val;
6920 inst.operands[i].isreg = 1;
6921 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
037e8744
JB
6922 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6923 inst.operands[i].isvec = 1;
dcbf9037 6924 inst.operands[i].vectype = optype;
5287ad62
JB
6925 inst.operands[i++].present = 1;
6926
dcbf9037 6927 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc
RM
6928 {
6929 /* Case 5: VMOV<c><q> <Dm>, <Rd>, <Rn>.
6930 Case 13: VMOV <Sd>, <Rm> */
6931 inst.operands[i].reg = val;
6932 inst.operands[i].isreg = 1;
6933 inst.operands[i].present = 1;
6934
6935 if (rtype == REG_TYPE_NQ)
6936 {
6937 first_error (_("can't use Neon quad register here"));
6938 return FAIL;
6939 }
6940 else if (rtype != REG_TYPE_VFS)
6941 {
6942 i++;
6943 if (skip_past_comma (&ptr) == FAIL)
6944 goto wanted_comma;
6945 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6946 goto wanted_arm;
6947 inst.operands[i].reg = val;
6948 inst.operands[i].isreg = 1;
6949 inst.operands[i].present = 1;
6950 }
6951 }
c4a23bf8
SP
6952 else if (((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype,
6953 &optype)) != FAIL)
6954 || ((val = arm_typed_reg_parse (&ptr, REG_TYPE_MQ, &rtype,
6955 &optype)) != FAIL))
477330fc
RM
6956 {
6957 /* Case 0: VMOV<c><q> <Qd>, <Qm>
6958 Case 1: VMOV<c><q> <Dd>, <Dm>
6959 Case 8: VMOV.F32 <Sd>, <Sm>
6960 Case 15: VMOV <Sd>, <Se>, <Rn>, <Rm> */
6961
6962 inst.operands[i].reg = val;
6963 inst.operands[i].isreg = 1;
6964 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
6965 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6966 inst.operands[i].isvec = 1;
6967 inst.operands[i].vectype = optype;
6968 inst.operands[i].present = 1;
6969
6970 if (skip_past_comma (&ptr) == SUCCESS)
6971 {
6972 /* Case 15. */
6973 i++;
6974
6975 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6976 goto wanted_arm;
6977
6978 inst.operands[i].reg = val;
6979 inst.operands[i].isreg = 1;
6980 inst.operands[i++].present = 1;
6981
6982 if (skip_past_comma (&ptr) == FAIL)
6983 goto wanted_comma;
6984
6985 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6986 goto wanted_arm;
6987
6988 inst.operands[i].reg = val;
6989 inst.operands[i].isreg = 1;
6990 inst.operands[i].present = 1;
6991 }
6992 }
4641781c 6993 else if (parse_qfloat_immediate (&ptr, &inst.operands[i].imm) == SUCCESS)
477330fc
RM
6994 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<float-imm>
6995 Case 3: VMOV<c><q>.<dt> <Dd>, #<float-imm>
6996 Case 10: VMOV.F32 <Sd>, #<imm>
6997 Case 11: VMOV.F64 <Dd>, #<imm> */
6998 inst.operands[i].immisfloat = 1;
5b7c81bd 6999 else if (parse_big_immediate (&ptr, i, NULL, /*allow_symbol_p=*/false)
8335d6aa 7000 == SUCCESS)
477330fc
RM
7001 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<imm>
7002 Case 3: VMOV<c><q>.<dt> <Dd>, #<imm> */
7003 ;
5287ad62 7004 else
477330fc
RM
7005 {
7006 first_error (_("expected <Rm> or <Dm> or <Qm> operand"));
7007 return FAIL;
7008 }
5287ad62 7009 }
dcbf9037 7010 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
5287ad62 7011 {
57785aa2 7012 /* Cases 6, 7, 16, 18. */
5287ad62
JB
7013 inst.operands[i].reg = val;
7014 inst.operands[i].isreg = 1;
7015 inst.operands[i++].present = 1;
5f4273c7 7016
5287ad62 7017 if (skip_past_comma (&ptr) == FAIL)
477330fc 7018 goto wanted_comma;
5f4273c7 7019
57785aa2
AV
7020 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
7021 {
7022 /* Case 18: VMOV<c>.<dt> <Rt>, <Qn[idx]> */
7023 inst.operands[i].reg = val;
7024 inst.operands[i].isscalar = 2;
7025 inst.operands[i].present = 1;
7026 inst.operands[i].vectype = optype;
7027 }
7028 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
477330fc
RM
7029 {
7030 /* Case 6: VMOV<c><q>.<dt> <Rd>, <Dn[x]> */
7031 inst.operands[i].reg = val;
7032 inst.operands[i].isscalar = 1;
7033 inst.operands[i].present = 1;
7034 inst.operands[i].vectype = optype;
7035 }
dcbf9037 7036 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc 7037 {
477330fc
RM
7038 inst.operands[i].reg = val;
7039 inst.operands[i].isreg = 1;
7040 inst.operands[i++].present = 1;
7041
7042 if (skip_past_comma (&ptr) == FAIL)
7043 goto wanted_comma;
7044
7045 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFSD, &rtype, &optype))
57785aa2 7046 != FAIL)
477330fc 7047 {
57785aa2 7048 /* Case 7: VMOV<c><q> <Rd>, <Rn>, <Dm> */
477330fc 7049
477330fc
RM
7050 inst.operands[i].reg = val;
7051 inst.operands[i].isreg = 1;
7052 inst.operands[i].isvec = 1;
57785aa2 7053 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
477330fc
RM
7054 inst.operands[i].vectype = optype;
7055 inst.operands[i].present = 1;
57785aa2
AV
7056
7057 if (rtype == REG_TYPE_VFS)
7058 {
7059 /* Case 14. */
7060 i++;
7061 if (skip_past_comma (&ptr) == FAIL)
7062 goto wanted_comma;
7063 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL,
7064 &optype)) == FAIL)
7065 {
7066 first_error (_(reg_expected_msgs[REG_TYPE_VFS]));
7067 return FAIL;
7068 }
7069 inst.operands[i].reg = val;
7070 inst.operands[i].isreg = 1;
7071 inst.operands[i].isvec = 1;
7072 inst.operands[i].issingle = 1;
7073 inst.operands[i].vectype = optype;
7074 inst.operands[i].present = 1;
7075 }
7076 }
7077 else
7078 {
7079 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
7080 != FAIL)
7081 {
7082 /* Case 16: VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]> */
7083 inst.operands[i].reg = val;
7084 inst.operands[i].isvec = 1;
7085 inst.operands[i].isscalar = 2;
7086 inst.operands[i].vectype = optype;
7087 inst.operands[i++].present = 1;
7088
7089 if (skip_past_comma (&ptr) == FAIL)
7090 goto wanted_comma;
7091
7092 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
7093 == FAIL)
7094 {
7095 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
7096 return FAIL;
7097 }
7098 inst.operands[i].reg = val;
7099 inst.operands[i].isvec = 1;
7100 inst.operands[i].isscalar = 2;
7101 inst.operands[i].vectype = optype;
7102 inst.operands[i].present = 1;
7103 }
7104 else
7105 {
7106 first_error (_("VFP single, double or MVE vector register"
7107 " expected"));
7108 return FAIL;
7109 }
477330fc
RM
7110 }
7111 }
037e8744 7112 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL, &optype))
477330fc
RM
7113 != FAIL)
7114 {
7115 /* Case 13. */
7116 inst.operands[i].reg = val;
7117 inst.operands[i].isreg = 1;
7118 inst.operands[i].isvec = 1;
7119 inst.operands[i].issingle = 1;
7120 inst.operands[i].vectype = optype;
7121 inst.operands[i].present = 1;
7122 }
5287ad62
JB
7123 }
7124 else
7125 {
dcbf9037 7126 first_error (_("parse error"));
5287ad62
JB
7127 return FAIL;
7128 }
7129
7130 /* Successfully parsed the operands. Update args. */
7131 *which_operand = i;
7132 *str = ptr;
7133 return SUCCESS;
7134
5f4273c7 7135 wanted_comma:
dcbf9037 7136 first_error (_("expected comma"));
5287ad62 7137 return FAIL;
5f4273c7
NC
7138
7139 wanted_arm:
dcbf9037 7140 first_error (_(reg_expected_msgs[REG_TYPE_RN]));
5287ad62 7141 return FAIL;
5287ad62
JB
7142}
7143
5be8be5d
DG
7144/* Use this macro when the operand constraints are different
7145 for ARM and THUMB (e.g. ldrd). */
7146#define MIX_ARM_THUMB_OPERANDS(arm_operand, thumb_operand) \
7147 ((arm_operand) | ((thumb_operand) << 16))
7148
c19d1205
ZW
7149/* Matcher codes for parse_operands. */
7150enum operand_parse_code
7151{
7152 OP_stop, /* end of line */
7153
7154 OP_RR, /* ARM register */
7155 OP_RRnpc, /* ARM register, not r15 */
5be8be5d 7156 OP_RRnpcsp, /* ARM register, neither r15 nor r13 (a.k.a. 'BadReg') */
c19d1205 7157 OP_RRnpcb, /* ARM register, not r15, in square brackets */
fa94de6b 7158 OP_RRnpctw, /* ARM register, not r15 in Thumb-state or with writeback,
55881a11 7159 optional trailing ! */
c19d1205
ZW
7160 OP_RRw, /* ARM register, not r15, optional trailing ! */
7161 OP_RCP, /* Coprocessor number */
7162 OP_RCN, /* Coprocessor register */
7163 OP_RF, /* FPA register */
7164 OP_RVS, /* VFP single precision register */
5287ad62
JB
7165 OP_RVD, /* VFP double precision register (0..15) */
7166 OP_RND, /* Neon double precision register (0..31) */
5ee91343
AV
7167 OP_RNDMQ, /* Neon double precision (0..31) or MVE vector register. */
7168 OP_RNDMQR, /* Neon double precision (0..31), MVE vector or ARM register.
7169 */
66d1f7cc
AV
7170 OP_RNSDMQR, /* Neon single or double precision, MVE vector or ARM register.
7171 */
5287ad62 7172 OP_RNQ, /* Neon quad precision register */
5ee91343 7173 OP_RNQMQ, /* Neon quad or MVE vector register. */
037e8744 7174 OP_RVSD, /* VFP single or double precision register */
1b883319 7175 OP_RVSD_COND, /* VFP single, double precision register or condition code. */
dd9634d9 7176 OP_RVSDMQ, /* VFP single, double precision or MVE vector register. */
dec41383 7177 OP_RNSD, /* Neon single or double precision register */
5287ad62 7178 OP_RNDQ, /* Neon double or quad precision register */
5ee91343 7179 OP_RNDQMQ, /* Neon double, quad or MVE vector register. */
7df54120 7180 OP_RNDQMQR, /* Neon double, quad, MVE vector or ARM register. */
037e8744 7181 OP_RNSDQ, /* Neon single, double or quad precision register */
5287ad62 7182 OP_RNSC, /* Neon scalar D[X] */
c19d1205
ZW
7183 OP_RVC, /* VFP control register */
7184 OP_RMF, /* Maverick F register */
7185 OP_RMD, /* Maverick D register */
7186 OP_RMFX, /* Maverick FX register */
7187 OP_RMDX, /* Maverick DX register */
7188 OP_RMAX, /* Maverick AX register */
7189 OP_RMDS, /* Maverick DSPSC register */
7190 OP_RIWR, /* iWMMXt wR register */
7191 OP_RIWC, /* iWMMXt wC register */
7192 OP_RIWG, /* iWMMXt wCG register */
7193 OP_RXA, /* XScale accumulator register */
7194
5aae9ae9 7195 OP_RNSDMQ, /* Neon single, double or MVE vector register */
5ee91343
AV
7196 OP_RNSDQMQ, /* Neon single, double or quad register or MVE vector register
7197 */
7198 OP_RNSDQMQR, /* Neon single, double or quad register, MVE vector register or
7199 GPR (no SP/SP) */
a302e574 7200 OP_RMQ, /* MVE vector register. */
1b883319 7201 OP_RMQRZ, /* MVE vector or ARM register including ZR. */
35d1cfc2 7202 OP_RMQRR, /* MVE vector or ARM register. */
a302e574 7203
60f993ce
AV
7204 /* New operands for Armv8.1-M Mainline. */
7205 OP_LR, /* ARM LR register */
f1e1d7f3
AC
7206 OP_SP, /* ARM SP register */
7207 OP_R12,
a302e574
AV
7208 OP_RRe, /* ARM register, only even numbered. */
7209 OP_RRo, /* ARM register, only odd numbered, not r13 or r15. */
60f993ce 7210 OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
e39c1607 7211 OP_RR_ZR, /* ARM register or ZR but no PC */
60f993ce 7212
c19d1205 7213 OP_REGLST, /* ARM register list */
4b5a202f 7214 OP_CLRMLST, /* CLRM register list */
c19d1205
ZW
7215 OP_VRSLST, /* VFP single-precision register list */
7216 OP_VRDLST, /* VFP double-precision register list */
037e8744 7217 OP_VRSDLST, /* VFP single or double-precision register list (& quad) */
5287ad62
JB
7218 OP_NRDLST, /* Neon double-precision register list (d0-d31, qN aliases) */
7219 OP_NSTRLST, /* Neon element/structure list */
efd6b359 7220 OP_VRSDVLST, /* VFP single or double-precision register list and VPR */
35c228db
AV
7221 OP_MSTRLST2, /* MVE vector list with two elements. */
7222 OP_MSTRLST4, /* MVE vector list with four elements. */
5287ad62 7223
5287ad62 7224 OP_RNDQ_I0, /* Neon D or Q reg, or immediate zero. */
037e8744 7225 OP_RVSD_I0, /* VFP S or D reg, or immediate zero. */
aacf0b33 7226 OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero. */
1b883319
AV
7227 OP_RSVDMQ_FI0, /* VFP S, D, MVE vector register or floating point immediate
7228 zero. */
5287ad62 7229 OP_RR_RNSC, /* ARM reg or Neon scalar. */
dec41383 7230 OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar. */
037e8744 7231 OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar. */
886e1c73
AV
7232 OP_RNSDQ_RNSC_MQ, /* Vector S, D or Q reg, Neon scalar or MVE vector register.
7233 */
a8465a06
AV
7234 OP_RNSDQ_RNSC_MQ_RR, /* Vector S, D or Q reg, or MVE vector reg , or Neon
7235 scalar, or ARM register. */
5287ad62 7236 OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar. */
42b16635
AV
7237 OP_RNDQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, or ARM register. */
7238 OP_RNDQMQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, MVE vector or ARM
7239 register. */
5d281bf0 7240 OP_RNDQMQ_RNSC, /* Neon D, Q or MVE vector reg, or Neon scalar. */
5287ad62
JB
7241 OP_RND_RNSC, /* Neon D reg, or Neon scalar. */
7242 OP_VMOV, /* Neon VMOV operands. */
4316f0d2 7243 OP_RNDQ_Ibig, /* Neon D or Q reg, or big immediate for logic and VMVN. */
f601a00c
AV
7244 /* Neon D, Q or MVE vector register, or big immediate for logic and VMVN. */
7245 OP_RNDQMQ_Ibig,
5287ad62 7246 OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift. */
5150f0d8
AV
7247 OP_RNDQMQ_I63b_RR, /* Neon D or Q reg, immediate for shift, MVE vector or
7248 ARM register. */
2d447fca 7249 OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2. */
32c36c3c 7250 OP_VLDR, /* VLDR operand. */
5287ad62
JB
7251
7252 OP_I0, /* immediate zero */
c19d1205
ZW
7253 OP_I7, /* immediate value 0 .. 7 */
7254 OP_I15, /* 0 .. 15 */
7255 OP_I16, /* 1 .. 16 */
5287ad62 7256 OP_I16z, /* 0 .. 16 */
c19d1205
ZW
7257 OP_I31, /* 0 .. 31 */
7258 OP_I31w, /* 0 .. 31, optional trailing ! */
7259 OP_I32, /* 1 .. 32 */
5287ad62 7260 OP_I32z, /* 0 .. 32 */
08132bdd 7261 OP_I48_I64, /* 48 or 64 */
5287ad62 7262 OP_I63, /* 0 .. 63 */
c19d1205 7263 OP_I63s, /* -64 .. 63 */
5287ad62
JB
7264 OP_I64, /* 1 .. 64 */
7265 OP_I64z, /* 0 .. 64 */
5aae9ae9 7266 OP_I127, /* 0 .. 127 */
c19d1205 7267 OP_I255, /* 0 .. 255 */
4934a27c 7268 OP_I511, /* 0 .. 511 */
5aae9ae9 7269 OP_I4095, /* 0 .. 4095 */
4934a27c 7270 OP_I8191, /* 0 .. 8191 */
c19d1205
ZW
7271 OP_I4b, /* immediate, prefix optional, 1 .. 4 */
7272 OP_I7b, /* 0 .. 7 */
7273 OP_I15b, /* 0 .. 15 */
7274 OP_I31b, /* 0 .. 31 */
7275
7276 OP_SH, /* shifter operand */
4962c51a 7277 OP_SHG, /* shifter operand with possible group relocation */
c19d1205 7278 OP_ADDR, /* Memory address expression (any mode) */
35c228db 7279 OP_ADDRMVE, /* Memory address expression for MVE's VSTR/VLDR. */
4962c51a
MS
7280 OP_ADDRGLDR, /* Mem addr expr (any mode) with possible LDR group reloc */
7281 OP_ADDRGLDRS, /* Mem addr expr (any mode) with possible LDRS group reloc */
7282 OP_ADDRGLDC, /* Mem addr expr (any mode) with possible LDC group reloc */
c19d1205
ZW
7283 OP_EXP, /* arbitrary expression */
7284 OP_EXPi, /* same, with optional immediate prefix */
7285 OP_EXPr, /* same, with optional relocation suffix */
e2b0ab59 7286 OP_EXPs, /* same, with optional non-first operand relocation suffix */
b6895b4f 7287 OP_HALF, /* 0 .. 65535 or low/high reloc. */
c28eeff2
SN
7288 OP_IROT1, /* VCADD rotate immediate: 90, 270. */
7289 OP_IROT2, /* VCMLA rotate immediate: 0, 90, 180, 270. */
c19d1205
ZW
7290
7291 OP_CPSF, /* CPS flags */
7292 OP_ENDI, /* Endianness specifier */
d2cd1205
JB
7293 OP_wPSR, /* CPSR/SPSR/APSR mask for msr (writing). */
7294 OP_rPSR, /* CPSR/SPSR/APSR mask for msr (reading). */
c19d1205 7295 OP_COND, /* conditional code */
92e90b6e 7296 OP_TB, /* Table branch. */
c19d1205 7297
037e8744
JB
7298 OP_APSR_RR, /* ARM register or "APSR_nzcv". */
7299
c19d1205 7300 OP_RRnpc_I0, /* ARM register or literal 0 */
33eaf5de 7301 OP_RR_EXr, /* ARM register or expression with opt. reloc stuff. */
c19d1205
ZW
7302 OP_RR_EXi, /* ARM register or expression with imm prefix */
7303 OP_RF_IF, /* FPA register or immediate */
7304 OP_RIWR_RIWC, /* iWMMXt R or C reg */
41adaa5c 7305 OP_RIWC_RIWG, /* iWMMXt wC or wCG reg */
c19d1205
ZW
7306
7307 /* Optional operands. */
7308 OP_oI7b, /* immediate, prefix optional, 0 .. 7 */
7309 OP_oI31b, /* 0 .. 31 */
5287ad62 7310 OP_oI32b, /* 1 .. 32 */
5f1af56b 7311 OP_oI32z, /* 0 .. 32 */
c19d1205
ZW
7312 OP_oIffffb, /* 0 .. 65535 */
7313 OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
7314
7315 OP_oRR, /* ARM register */
60f993ce 7316 OP_oLR, /* ARM LR register */
c19d1205 7317 OP_oRRnpc, /* ARM register, not the PC */
5be8be5d 7318 OP_oRRnpcsp, /* ARM register, neither the PC nor the SP (a.k.a. BadReg) */
b6702015 7319 OP_oRRw, /* ARM register, not r15, optional trailing ! */
5287ad62
JB
7320 OP_oRND, /* Optional Neon double precision register */
7321 OP_oRNQ, /* Optional Neon quad precision register */
5ee91343 7322 OP_oRNDQMQ, /* Optional Neon double, quad or MVE vector register. */
5287ad62 7323 OP_oRNDQ, /* Optional Neon double or quad precision register */
037e8744 7324 OP_oRNSDQ, /* Optional single, double or quad precision vector register */
5ee91343
AV
7325 OP_oRNSDQMQ, /* Optional single, double or quad register or MVE vector
7326 register. */
66d1f7cc
AV
7327 OP_oRNSDMQ, /* Optional single, double register or MVE vector
7328 register. */
c19d1205
ZW
7329 OP_oSHll, /* LSL immediate */
7330 OP_oSHar, /* ASR immediate */
7331 OP_oSHllar, /* LSL or ASR immediate */
7332 OP_oROR, /* ROR 0/8/16/24 */
52e7f43d 7333 OP_oBARRIER_I15, /* Option argument for a barrier instruction. */
c19d1205 7334
1b883319
AV
7335 OP_oRMQRZ, /* optional MVE vector or ARM register including ZR. */
7336
5be8be5d
DG
7337 /* Some pre-defined mixed (ARM/THUMB) operands. */
7338 OP_RR_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
7339 OP_RRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
7340 OP_oRRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_oRRnpc, OP_oRRnpcsp),
7341
c19d1205
ZW
7342 OP_FIRST_OPTIONAL = OP_oI7b
7343};
a737bd4d 7344
c19d1205
ZW
7345/* Generic instruction operand parser. This does no encoding and no
7346 semantic validation; it merely squirrels values away in the inst
7347 structure. Returns SUCCESS or FAIL depending on whether the
7348 specified grammar matched. */
7349static int
5b7c81bd 7350parse_operands (char *str, const unsigned int *pattern, bool thumb)
c19d1205 7351{
5be8be5d 7352 unsigned const int *upat = pattern;
c19d1205
ZW
7353 char *backtrack_pos = 0;
7354 const char *backtrack_error = 0;
99aad254 7355 int i, val = 0, backtrack_index = 0;
5287ad62 7356 enum arm_reg_type rtype;
4962c51a 7357 parse_operand_result result;
5be8be5d 7358 unsigned int op_parse_code;
5b7c81bd 7359 bool partial_match;
c19d1205 7360
e07e6e58
NC
7361#define po_char_or_fail(chr) \
7362 do \
7363 { \
7364 if (skip_past_char (&str, chr) == FAIL) \
477330fc 7365 goto bad_args; \
e07e6e58
NC
7366 } \
7367 while (0)
c19d1205 7368
e07e6e58
NC
7369#define po_reg_or_fail(regtype) \
7370 do \
dcbf9037 7371 { \
e07e6e58 7372 val = arm_typed_reg_parse (& str, regtype, & rtype, \
477330fc 7373 & inst.operands[i].vectype); \
e07e6e58 7374 if (val == FAIL) \
477330fc
RM
7375 { \
7376 first_error (_(reg_expected_msgs[regtype])); \
7377 goto failure; \
7378 } \
e07e6e58
NC
7379 inst.operands[i].reg = val; \
7380 inst.operands[i].isreg = 1; \
7381 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7382 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7383 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc
RM
7384 || rtype == REG_TYPE_VFD \
7385 || rtype == REG_TYPE_NQ); \
1b883319 7386 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
dcbf9037 7387 } \
e07e6e58
NC
7388 while (0)
7389
7390#define po_reg_or_goto(regtype, label) \
7391 do \
7392 { \
7393 val = arm_typed_reg_parse (& str, regtype, & rtype, \
7394 & inst.operands[i].vectype); \
7395 if (val == FAIL) \
7396 goto label; \
dcbf9037 7397 \
e07e6e58
NC
7398 inst.operands[i].reg = val; \
7399 inst.operands[i].isreg = 1; \
7400 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7401 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7402 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc 7403 || rtype == REG_TYPE_VFD \
e07e6e58 7404 || rtype == REG_TYPE_NQ); \
1b883319 7405 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
e07e6e58
NC
7406 } \
7407 while (0)
7408
7409#define po_imm_or_fail(min, max, popt) \
7410 do \
7411 { \
7412 if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
7413 goto failure; \
7414 inst.operands[i].imm = val; \
7415 } \
7416 while (0)
7417
08132bdd
SP
7418#define po_imm1_or_imm2_or_fail(imm1, imm2, popt) \
7419 do \
7420 { \
7421 expressionS exp; \
7422 my_get_expression (&exp, &str, popt); \
7423 if (exp.X_op != O_constant) \
7424 { \
7425 inst.error = _("constant expression required"); \
7426 goto failure; \
7427 } \
7428 if (exp.X_add_number != imm1 && exp.X_add_number != imm2) \
7429 { \
7430 inst.error = _("immediate value 48 or 64 expected"); \
7431 goto failure; \
7432 } \
7433 inst.operands[i].imm = exp.X_add_number; \
7434 } \
7435 while (0)
7436
57785aa2 7437#define po_scalar_or_goto(elsz, label, reg_type) \
e07e6e58
NC
7438 do \
7439 { \
57785aa2
AV
7440 val = parse_scalar (& str, elsz, & inst.operands[i].vectype, \
7441 reg_type); \
e07e6e58
NC
7442 if (val == FAIL) \
7443 goto label; \
7444 inst.operands[i].reg = val; \
7445 inst.operands[i].isscalar = 1; \
7446 } \
7447 while (0)
7448
7449#define po_misc_or_fail(expr) \
7450 do \
7451 { \
7452 if (expr) \
7453 goto failure; \
7454 } \
7455 while (0)
7456
7457#define po_misc_or_fail_no_backtrack(expr) \
7458 do \
7459 { \
7460 result = expr; \
7461 if (result == PARSE_OPERAND_FAIL_NO_BACKTRACK) \
7462 backtrack_pos = 0; \
7463 if (result != PARSE_OPERAND_SUCCESS) \
7464 goto failure; \
7465 } \
7466 while (0)
4962c51a 7467
52e7f43d
RE
7468#define po_barrier_or_imm(str) \
7469 do \
7470 { \
7471 val = parse_barrier (&str); \
ccb84d65
JB
7472 if (val == FAIL && ! ISALPHA (*str)) \
7473 goto immediate; \
7474 if (val == FAIL \
7475 /* ISB can only take SY as an option. */ \
7476 || ((inst.instruction & 0xf0) == 0x60 \
7477 && val != 0xf)) \
52e7f43d 7478 { \
ccb84d65
JB
7479 inst.error = _("invalid barrier type"); \
7480 backtrack_pos = 0; \
7481 goto failure; \
52e7f43d
RE
7482 } \
7483 } \
7484 while (0)
7485
c19d1205
ZW
7486 skip_whitespace (str);
7487
7488 for (i = 0; upat[i] != OP_stop; i++)
7489 {
5be8be5d
DG
7490 op_parse_code = upat[i];
7491 if (op_parse_code >= 1<<16)
7492 op_parse_code = thumb ? (op_parse_code >> 16)
7493 : (op_parse_code & ((1<<16)-1));
7494
7495 if (op_parse_code >= OP_FIRST_OPTIONAL)
c19d1205
ZW
7496 {
7497 /* Remember where we are in case we need to backtrack. */
c19d1205
ZW
7498 backtrack_pos = str;
7499 backtrack_error = inst.error;
7500 backtrack_index = i;
7501 }
7502
b6702015 7503 if (i > 0 && (i > 1 || inst.operands[0].present))
c19d1205
ZW
7504 po_char_or_fail (',');
7505
5be8be5d 7506 switch (op_parse_code)
c19d1205
ZW
7507 {
7508 /* Registers */
7509 case OP_oRRnpc:
5be8be5d 7510 case OP_oRRnpcsp:
c19d1205 7511 case OP_RRnpc:
5be8be5d 7512 case OP_RRnpcsp:
c19d1205 7513 case OP_oRR:
a302e574
AV
7514 case OP_RRe:
7515 case OP_RRo:
60f993ce
AV
7516 case OP_LR:
7517 case OP_oLR:
f1e1d7f3
AC
7518 case OP_SP:
7519 case OP_R12:
c19d1205
ZW
7520 case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
7521 case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
7522 case OP_RCN: po_reg_or_fail (REG_TYPE_CN); break;
7523 case OP_RF: po_reg_or_fail (REG_TYPE_FN); break;
7524 case OP_RVS: po_reg_or_fail (REG_TYPE_VFS); break;
7525 case OP_RVD: po_reg_or_fail (REG_TYPE_VFD); break;
477330fc 7526 case OP_oRND:
66d1f7cc
AV
7527 case OP_RNSDMQR:
7528 po_reg_or_goto (REG_TYPE_VFS, try_rndmqr);
7529 break;
7530 try_rndmqr:
5ee91343
AV
7531 case OP_RNDMQR:
7532 po_reg_or_goto (REG_TYPE_RN, try_rndmq);
7533 break;
7534 try_rndmq:
7535 case OP_RNDMQ:
7536 po_reg_or_goto (REG_TYPE_MQ, try_rnd);
7537 break;
7538 try_rnd:
5287ad62 7539 case OP_RND: po_reg_or_fail (REG_TYPE_VFD); break;
cd2cf30b
PB
7540 case OP_RVC:
7541 po_reg_or_goto (REG_TYPE_VFC, coproc_reg);
7542 break;
7543 /* Also accept generic coprocessor regs for unknown registers. */
7544 coproc_reg:
ba6cd17f
SD
7545 po_reg_or_goto (REG_TYPE_CN, vpr_po);
7546 break;
7547 /* Also accept P0 or p0 for VPR.P0. Since P0 is already an
7548 existing register with a value of 0, this seems like the
7549 best way to parse P0. */
7550 vpr_po:
7551 if (strncasecmp (str, "P0", 2) == 0)
7552 {
7553 str += 2;
7554 inst.operands[i].isreg = 1;
7555 inst.operands[i].reg = 13;
7556 }
7557 else
7558 goto failure;
cd2cf30b 7559 break;
c19d1205
ZW
7560 case OP_RMF: po_reg_or_fail (REG_TYPE_MVF); break;
7561 case OP_RMD: po_reg_or_fail (REG_TYPE_MVD); break;
7562 case OP_RMFX: po_reg_or_fail (REG_TYPE_MVFX); break;
7563 case OP_RMDX: po_reg_or_fail (REG_TYPE_MVDX); break;
7564 case OP_RMAX: po_reg_or_fail (REG_TYPE_MVAX); break;
7565 case OP_RMDS: po_reg_or_fail (REG_TYPE_DSPSC); break;
7566 case OP_RIWR: po_reg_or_fail (REG_TYPE_MMXWR); break;
7567 case OP_RIWC: po_reg_or_fail (REG_TYPE_MMXWC); break;
7568 case OP_RIWG: po_reg_or_fail (REG_TYPE_MMXWCG); break;
7569 case OP_RXA: po_reg_or_fail (REG_TYPE_XSCALE); break;
477330fc 7570 case OP_oRNQ:
5ee91343
AV
7571 case OP_RNQMQ:
7572 po_reg_or_goto (REG_TYPE_MQ, try_nq);
7573 break;
7574 try_nq:
5287ad62 7575 case OP_RNQ: po_reg_or_fail (REG_TYPE_NQ); break;
dec41383 7576 case OP_RNSD: po_reg_or_fail (REG_TYPE_NSD); break;
7df54120
AV
7577 case OP_RNDQMQR:
7578 po_reg_or_goto (REG_TYPE_RN, try_rndqmq);
7579 break;
7580 try_rndqmq:
5ee91343
AV
7581 case OP_oRNDQMQ:
7582 case OP_RNDQMQ:
7583 po_reg_or_goto (REG_TYPE_MQ, try_rndq);
7584 break;
7585 try_rndq:
477330fc 7586 case OP_oRNDQ:
5287ad62 7587 case OP_RNDQ: po_reg_or_fail (REG_TYPE_NDQ); break;
dd9634d9
AV
7588 case OP_RVSDMQ:
7589 po_reg_or_goto (REG_TYPE_MQ, try_rvsd);
7590 break;
7591 try_rvsd:
477330fc 7592 case OP_RVSD: po_reg_or_fail (REG_TYPE_VFSD); break;
1b883319
AV
7593 case OP_RVSD_COND:
7594 po_reg_or_goto (REG_TYPE_VFSD, try_cond);
7595 break;
66d1f7cc 7596 case OP_oRNSDMQ:
5aae9ae9
MM
7597 case OP_RNSDMQ:
7598 po_reg_or_goto (REG_TYPE_NSD, try_mq2);
7599 break;
7600 try_mq2:
7601 po_reg_or_fail (REG_TYPE_MQ);
7602 break;
477330fc
RM
7603 case OP_oRNSDQ:
7604 case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ); break;
5ee91343
AV
7605 case OP_RNSDQMQR:
7606 po_reg_or_goto (REG_TYPE_RN, try_mq);
7607 break;
7608 try_mq:
7609 case OP_oRNSDQMQ:
7610 case OP_RNSDQMQ:
7611 po_reg_or_goto (REG_TYPE_MQ, try_nsdq2);
7612 break;
7613 try_nsdq2:
7614 po_reg_or_fail (REG_TYPE_NSDQ);
7615 inst.error = 0;
7616 break;
35d1cfc2
AV
7617 case OP_RMQRR:
7618 po_reg_or_goto (REG_TYPE_RN, try_rmq);
7619 break;
7620 try_rmq:
a302e574
AV
7621 case OP_RMQ:
7622 po_reg_or_fail (REG_TYPE_MQ);
7623 break;
477330fc
RM
7624 /* Neon scalar. Using an element size of 8 means that some invalid
7625 scalars are accepted here, so deal with those in later code. */
57785aa2 7626 case OP_RNSC: po_scalar_or_goto (8, failure, REG_TYPE_VFD); break;
477330fc
RM
7627
7628 case OP_RNDQ_I0:
7629 {
7630 po_reg_or_goto (REG_TYPE_NDQ, try_imm0);
7631 break;
7632 try_imm0:
5b7c81bd 7633 po_imm_or_fail (0, 0, true);
477330fc
RM
7634 }
7635 break;
7636
7637 case OP_RVSD_I0:
7638 po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
7639 break;
7640
1b883319
AV
7641 case OP_RSVDMQ_FI0:
7642 po_reg_or_goto (REG_TYPE_MQ, try_rsvd_fi0);
7643 break;
7644 try_rsvd_fi0:
aacf0b33
KT
7645 case OP_RSVD_FI0:
7646 {
7647 po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
7648 break;
7649 try_ifimm0:
7650 if (parse_ifimm_zero (&str))
7651 inst.operands[i].imm = 0;
7652 else
7653 {
7654 inst.error
7655 = _("only floating point zero is allowed as immediate value");
7656 goto failure;
7657 }
7658 }
7659 break;
7660
477330fc
RM
7661 case OP_RR_RNSC:
7662 {
57785aa2 7663 po_scalar_or_goto (8, try_rr, REG_TYPE_VFD);
477330fc
RM
7664 break;
7665 try_rr:
7666 po_reg_or_fail (REG_TYPE_RN);
7667 }
7668 break;
7669
a8465a06
AV
7670 case OP_RNSDQ_RNSC_MQ_RR:
7671 po_reg_or_goto (REG_TYPE_RN, try_rnsdq_rnsc_mq);
7672 break;
7673 try_rnsdq_rnsc_mq:
886e1c73
AV
7674 case OP_RNSDQ_RNSC_MQ:
7675 po_reg_or_goto (REG_TYPE_MQ, try_rnsdq_rnsc);
7676 break;
7677 try_rnsdq_rnsc:
477330fc
RM
7678 case OP_RNSDQ_RNSC:
7679 {
57785aa2
AV
7680 po_scalar_or_goto (8, try_nsdq, REG_TYPE_VFD);
7681 inst.error = 0;
477330fc
RM
7682 break;
7683 try_nsdq:
7684 po_reg_or_fail (REG_TYPE_NSDQ);
57785aa2 7685 inst.error = 0;
477330fc
RM
7686 }
7687 break;
7688
dec41383
JW
7689 case OP_RNSD_RNSC:
7690 {
57785aa2 7691 po_scalar_or_goto (8, try_s_scalar, REG_TYPE_VFD);
dec41383
JW
7692 break;
7693 try_s_scalar:
57785aa2 7694 po_scalar_or_goto (4, try_nsd, REG_TYPE_VFS);
dec41383
JW
7695 break;
7696 try_nsd:
7697 po_reg_or_fail (REG_TYPE_NSD);
7698 }
7699 break;
7700
42b16635
AV
7701 case OP_RNDQMQ_RNSC_RR:
7702 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc_rr);
7703 break;
7704 try_rndq_rnsc_rr:
7705 case OP_RNDQ_RNSC_RR:
7706 po_reg_or_goto (REG_TYPE_RN, try_rndq_rnsc);
7707 break;
5d281bf0
AV
7708 case OP_RNDQMQ_RNSC:
7709 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc);
7710 break;
7711 try_rndq_rnsc:
477330fc
RM
7712 case OP_RNDQ_RNSC:
7713 {
57785aa2 7714 po_scalar_or_goto (8, try_ndq, REG_TYPE_VFD);
477330fc
RM
7715 break;
7716 try_ndq:
7717 po_reg_or_fail (REG_TYPE_NDQ);
7718 }
7719 break;
7720
7721 case OP_RND_RNSC:
7722 {
57785aa2 7723 po_scalar_or_goto (8, try_vfd, REG_TYPE_VFD);
477330fc
RM
7724 break;
7725 try_vfd:
7726 po_reg_or_fail (REG_TYPE_VFD);
7727 }
7728 break;
7729
7730 case OP_VMOV:
7731 /* WARNING: parse_neon_mov can move the operand counter, i. If we're
7732 not careful then bad things might happen. */
7733 po_misc_or_fail (parse_neon_mov (&str, &i) == FAIL);
7734 break;
7735
f601a00c
AV
7736 case OP_RNDQMQ_Ibig:
7737 po_reg_or_goto (REG_TYPE_MQ, try_rndq_ibig);
7738 break;
7739 try_rndq_ibig:
477330fc
RM
7740 case OP_RNDQ_Ibig:
7741 {
7742 po_reg_or_goto (REG_TYPE_NDQ, try_immbig);
7743 break;
7744 try_immbig:
7745 /* There's a possibility of getting a 64-bit immediate here, so
7746 we need special handling. */
5b7c81bd 7747 if (parse_big_immediate (&str, i, NULL, /*allow_symbol_p=*/false)
8335d6aa 7748 == FAIL)
477330fc
RM
7749 {
7750 inst.error = _("immediate value is out of range");
7751 goto failure;
7752 }
7753 }
7754 break;
7755
5150f0d8
AV
7756 case OP_RNDQMQ_I63b_RR:
7757 po_reg_or_goto (REG_TYPE_MQ, try_rndq_i63b_rr);
7758 break;
7759 try_rndq_i63b_rr:
7760 po_reg_or_goto (REG_TYPE_RN, try_rndq_i63b);
7761 break;
7762 try_rndq_i63b:
477330fc
RM
7763 case OP_RNDQ_I63b:
7764 {
7765 po_reg_or_goto (REG_TYPE_NDQ, try_shimm);
7766 break;
7767 try_shimm:
5b7c81bd 7768 po_imm_or_fail (0, 63, true);
477330fc
RM
7769 }
7770 break;
c19d1205
ZW
7771
7772 case OP_RRnpcb:
7773 po_char_or_fail ('[');
7774 po_reg_or_fail (REG_TYPE_RN);
7775 po_char_or_fail (']');
7776 break;
a737bd4d 7777
55881a11 7778 case OP_RRnpctw:
c19d1205 7779 case OP_RRw:
b6702015 7780 case OP_oRRw:
c19d1205
ZW
7781 po_reg_or_fail (REG_TYPE_RN);
7782 if (skip_past_char (&str, '!') == SUCCESS)
7783 inst.operands[i].writeback = 1;
7784 break;
7785
7786 /* Immediates */
5b7c81bd
AM
7787 case OP_I7: po_imm_or_fail ( 0, 7, false); break;
7788 case OP_I15: po_imm_or_fail ( 0, 15, false); break;
7789 case OP_I16: po_imm_or_fail ( 1, 16, false); break;
7790 case OP_I16z: po_imm_or_fail ( 0, 16, false); break;
7791 case OP_I31: po_imm_or_fail ( 0, 31, false); break;
7792 case OP_I32: po_imm_or_fail ( 1, 32, false); break;
7793 case OP_I32z: po_imm_or_fail ( 0, 32, false); break;
7794 case OP_I48_I64: po_imm1_or_imm2_or_fail (48, 64, false); break;
7795 case OP_I63s: po_imm_or_fail (-64, 63, false); break;
7796 case OP_I63: po_imm_or_fail ( 0, 63, false); break;
7797 case OP_I64: po_imm_or_fail ( 1, 64, false); break;
7798 case OP_I64z: po_imm_or_fail ( 0, 64, false); break;
7799 case OP_I127: po_imm_or_fail ( 0, 127, false); break;
7800 case OP_I255: po_imm_or_fail ( 0, 255, false); break;
7801 case OP_I511: po_imm_or_fail ( 0, 511, false); break;
7802 case OP_I4095: po_imm_or_fail ( 0, 4095, false); break;
7803 case OP_I8191: po_imm_or_fail ( 0, 8191, false); break;
7804 case OP_I4b: po_imm_or_fail ( 1, 4, true); break;
c19d1205 7805 case OP_oI7b:
5b7c81bd
AM
7806 case OP_I7b: po_imm_or_fail ( 0, 7, true); break;
7807 case OP_I15b: po_imm_or_fail ( 0, 15, true); break;
c19d1205 7808 case OP_oI31b:
5b7c81bd
AM
7809 case OP_I31b: po_imm_or_fail ( 0, 31, true); break;
7810 case OP_oI32b: po_imm_or_fail ( 1, 32, true); break;
7811 case OP_oI32z: po_imm_or_fail ( 0, 32, true); break;
7812 case OP_oIffffb: po_imm_or_fail ( 0, 0xffff, true); break;
c19d1205
ZW
7813
7814 /* Immediate variants */
7815 case OP_oI255c:
7816 po_char_or_fail ('{');
5b7c81bd 7817 po_imm_or_fail (0, 255, true);
c19d1205
ZW
7818 po_char_or_fail ('}');
7819 break;
7820
7821 case OP_I31w:
7822 /* The expression parser chokes on a trailing !, so we have
7823 to find it first and zap it. */
7824 {
7825 char *s = str;
7826 while (*s && *s != ',')
7827 s++;
7828 if (s[-1] == '!')
7829 {
7830 s[-1] = '\0';
7831 inst.operands[i].writeback = 1;
7832 }
5b7c81bd 7833 po_imm_or_fail (0, 31, true);
c19d1205
ZW
7834 if (str == s - 1)
7835 str = s;
7836 }
7837 break;
7838
7839 /* Expressions */
7840 case OP_EXPi: EXPi:
e2b0ab59 7841 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7842 GE_OPT_PREFIX));
7843 break;
7844
7845 case OP_EXP:
e2b0ab59 7846 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7847 GE_NO_PREFIX));
7848 break;
7849
7850 case OP_EXPr: EXPr:
e2b0ab59 7851 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205 7852 GE_NO_PREFIX));
e2b0ab59 7853 if (inst.relocs[0].exp.X_op == O_symbol)
a737bd4d 7854 {
c19d1205
ZW
7855 val = parse_reloc (&str);
7856 if (val == -1)
7857 {
7858 inst.error = _("unrecognized relocation suffix");
7859 goto failure;
7860 }
7861 else if (val != BFD_RELOC_UNUSED)
7862 {
7863 inst.operands[i].imm = val;
7864 inst.operands[i].hasreloc = 1;
7865 }
a737bd4d 7866 }
c19d1205 7867 break;
a737bd4d 7868
e2b0ab59
AV
7869 case OP_EXPs:
7870 po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
7871 GE_NO_PREFIX));
7872 if (inst.relocs[i].exp.X_op == O_symbol)
7873 {
7874 inst.operands[i].hasreloc = 1;
7875 }
7876 else if (inst.relocs[i].exp.X_op == O_constant)
7877 {
7878 inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
7879 inst.operands[i].hasreloc = 0;
7880 }
7881 break;
7882
b6895b4f
PB
7883 /* Operand for MOVW or MOVT. */
7884 case OP_HALF:
7885 po_misc_or_fail (parse_half (&str));
7886 break;
7887
e07e6e58 7888 /* Register or expression. */
c19d1205
ZW
7889 case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
7890 case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
a737bd4d 7891
e07e6e58 7892 /* Register or immediate. */
c19d1205 7893 case OP_RRnpc_I0: po_reg_or_goto (REG_TYPE_RN, I0); break;
5b7c81bd 7894 I0: po_imm_or_fail (0, 0, false); break;
a737bd4d 7895
23d00a41 7896 case OP_RRnpcsp_I32: po_reg_or_goto (REG_TYPE_RN, I32); break;
5b7c81bd 7897 I32: po_imm_or_fail (1, 32, false); break;
23d00a41 7898
c19d1205
ZW
7899 case OP_RF_IF: po_reg_or_goto (REG_TYPE_FN, IF); break;
7900 IF:
7901 if (!is_immediate_prefix (*str))
7902 goto bad_args;
7903 str++;
7904 val = parse_fpa_immediate (&str);
7905 if (val == FAIL)
7906 goto failure;
7907 /* FPA immediates are encoded as registers 8-15.
7908 parse_fpa_immediate has already applied the offset. */
7909 inst.operands[i].reg = val;
7910 inst.operands[i].isreg = 1;
7911 break;
09d92015 7912
2d447fca 7913 case OP_RIWR_I32z: po_reg_or_goto (REG_TYPE_MMXWR, I32z); break;
5b7c81bd 7914 I32z: po_imm_or_fail (0, 32, false); break;
2d447fca 7915
e07e6e58 7916 /* Two kinds of register. */
c19d1205
ZW
7917 case OP_RIWR_RIWC:
7918 {
7919 struct reg_entry *rege = arm_reg_parse_multi (&str);
97f87066
JM
7920 if (!rege
7921 || (rege->type != REG_TYPE_MMXWR
7922 && rege->type != REG_TYPE_MMXWC
7923 && rege->type != REG_TYPE_MMXWCG))
c19d1205
ZW
7924 {
7925 inst.error = _("iWMMXt data or control register expected");
7926 goto failure;
7927 }
7928 inst.operands[i].reg = rege->number;
7929 inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
7930 }
7931 break;
09d92015 7932
41adaa5c
JM
7933 case OP_RIWC_RIWG:
7934 {
7935 struct reg_entry *rege = arm_reg_parse_multi (&str);
7936 if (!rege
7937 || (rege->type != REG_TYPE_MMXWC
7938 && rege->type != REG_TYPE_MMXWCG))
7939 {
7940 inst.error = _("iWMMXt control register expected");
7941 goto failure;
7942 }
7943 inst.operands[i].reg = rege->number;
7944 inst.operands[i].isreg = 1;
7945 }
7946 break;
7947
c19d1205
ZW
7948 /* Misc */
7949 case OP_CPSF: val = parse_cps_flags (&str); break;
7950 case OP_ENDI: val = parse_endian_specifier (&str); break;
7951 case OP_oROR: val = parse_ror (&str); break;
1b883319 7952 try_cond:
c19d1205 7953 case OP_COND: val = parse_cond (&str); break;
52e7f43d
RE
7954 case OP_oBARRIER_I15:
7955 po_barrier_or_imm (str); break;
7956 immediate:
5b7c81bd 7957 if (parse_immediate (&str, &val, 0, 15, true) == FAIL)
477330fc 7958 goto failure;
52e7f43d 7959 break;
c19d1205 7960
fa94de6b 7961 case OP_wPSR:
d2cd1205 7962 case OP_rPSR:
90ec0d68
MGD
7963 po_reg_or_goto (REG_TYPE_RNB, try_psr);
7964 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_virt))
7965 {
7966 inst.error = _("Banked registers are not available with this "
7967 "architecture.");
7968 goto failure;
7969 }
7970 break;
d2cd1205
JB
7971 try_psr:
7972 val = parse_psr (&str, op_parse_code == OP_wPSR);
7973 break;
037e8744 7974
32c36c3c
AV
7975 case OP_VLDR:
7976 po_reg_or_goto (REG_TYPE_VFSD, try_sysreg);
7977 break;
7978 try_sysreg:
7979 val = parse_sys_vldr_vstr (&str);
7980 break;
7981
477330fc
RM
7982 case OP_APSR_RR:
7983 po_reg_or_goto (REG_TYPE_RN, try_apsr);
7984 break;
7985 try_apsr:
7986 /* Parse "APSR_nvzc" operand (for FMSTAT-equivalent MRS
7987 instruction). */
7988 if (strncasecmp (str, "APSR_", 5) == 0)
7989 {
7990 unsigned found = 0;
7991 str += 5;
7992 while (found < 15)
7993 switch (*str++)
7994 {
7995 case 'c': found = (found & 1) ? 16 : found | 1; break;
7996 case 'n': found = (found & 2) ? 16 : found | 2; break;
7997 case 'z': found = (found & 4) ? 16 : found | 4; break;
7998 case 'v': found = (found & 8) ? 16 : found | 8; break;
7999 default: found = 16;
8000 }
8001 if (found != 15)
8002 goto failure;
8003 inst.operands[i].isvec = 1;
f7c21dc7
NC
8004 /* APSR_nzcv is encoded in instructions as if it were the REG_PC. */
8005 inst.operands[i].reg = REG_PC;
477330fc
RM
8006 }
8007 else
8008 goto failure;
8009 break;
037e8744 8010
92e90b6e
PB
8011 case OP_TB:
8012 po_misc_or_fail (parse_tb (&str));
8013 break;
8014
e07e6e58 8015 /* Register lists. */
c19d1205 8016 case OP_REGLST:
4b5a202f 8017 val = parse_reg_list (&str, REGLIST_RN);
c19d1205
ZW
8018 if (*str == '^')
8019 {
5e0d7f77 8020 inst.operands[i].writeback = 1;
c19d1205
ZW
8021 str++;
8022 }
8023 break;
09d92015 8024
4b5a202f
AV
8025 case OP_CLRMLST:
8026 val = parse_reg_list (&str, REGLIST_CLRM);
8027 break;
8028
c19d1205 8029 case OP_VRSLST:
efd6b359
AV
8030 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_S,
8031 &partial_match);
c19d1205 8032 break;
09d92015 8033
c19d1205 8034 case OP_VRDLST:
efd6b359
AV
8035 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_D,
8036 &partial_match);
c19d1205 8037 break;
a737bd4d 8038
477330fc
RM
8039 case OP_VRSDLST:
8040 /* Allow Q registers too. */
8041 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 8042 REGLIST_NEON_D, &partial_match);
477330fc
RM
8043 if (val == FAIL)
8044 {
8045 inst.error = NULL;
8046 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359
AV
8047 REGLIST_VFP_S, &partial_match);
8048 inst.operands[i].issingle = 1;
8049 }
8050 break;
8051
8052 case OP_VRSDVLST:
8053 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
8054 REGLIST_VFP_D_VPR, &partial_match);
8055 if (val == FAIL && !partial_match)
8056 {
8057 inst.error = NULL;
8058 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
8059 REGLIST_VFP_S_VPR, &partial_match);
477330fc
RM
8060 inst.operands[i].issingle = 1;
8061 }
8062 break;
8063
8064 case OP_NRDLST:
8065 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 8066 REGLIST_NEON_D, &partial_match);
477330fc 8067 break;
5287ad62 8068
35c228db
AV
8069 case OP_MSTRLST4:
8070 case OP_MSTRLST2:
8071 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
8072 1, &inst.operands[i].vectype);
8073 if (val != (((op_parse_code == OP_MSTRLST2) ? 3 : 7) << 5 | 0xe))
8074 goto failure;
8075 break;
5287ad62 8076 case OP_NSTRLST:
477330fc 8077 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
35c228db 8078 0, &inst.operands[i].vectype);
477330fc 8079 break;
5287ad62 8080
c19d1205 8081 /* Addressing modes */
35c228db
AV
8082 case OP_ADDRMVE:
8083 po_misc_or_fail (parse_address_group_reloc (&str, i, GROUP_MVE));
8084 break;
8085
c19d1205
ZW
8086 case OP_ADDR:
8087 po_misc_or_fail (parse_address (&str, i));
8088 break;
09d92015 8089
4962c51a
MS
8090 case OP_ADDRGLDR:
8091 po_misc_or_fail_no_backtrack (
477330fc 8092 parse_address_group_reloc (&str, i, GROUP_LDR));
4962c51a
MS
8093 break;
8094
8095 case OP_ADDRGLDRS:
8096 po_misc_or_fail_no_backtrack (
477330fc 8097 parse_address_group_reloc (&str, i, GROUP_LDRS));
4962c51a
MS
8098 break;
8099
8100 case OP_ADDRGLDC:
8101 po_misc_or_fail_no_backtrack (
477330fc 8102 parse_address_group_reloc (&str, i, GROUP_LDC));
4962c51a
MS
8103 break;
8104
c19d1205
ZW
8105 case OP_SH:
8106 po_misc_or_fail (parse_shifter_operand (&str, i));
8107 break;
09d92015 8108
4962c51a
MS
8109 case OP_SHG:
8110 po_misc_or_fail_no_backtrack (
477330fc 8111 parse_shifter_operand_group_reloc (&str, i));
4962c51a
MS
8112 break;
8113
c19d1205
ZW
8114 case OP_oSHll:
8115 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_IMMEDIATE));
8116 break;
09d92015 8117
c19d1205
ZW
8118 case OP_oSHar:
8119 po_misc_or_fail (parse_shift (&str, i, SHIFT_ASR_IMMEDIATE));
8120 break;
09d92015 8121
c19d1205
ZW
8122 case OP_oSHllar:
8123 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
8124 break;
09d92015 8125
1b883319
AV
8126 case OP_RMQRZ:
8127 case OP_oRMQRZ:
8128 po_reg_or_goto (REG_TYPE_MQ, try_rr_zr);
8129 break;
e39c1607
SD
8130
8131 case OP_RR_ZR:
1b883319
AV
8132 try_rr_zr:
8133 po_reg_or_goto (REG_TYPE_RN, ZR);
8134 break;
8135 ZR:
8136 po_reg_or_fail (REG_TYPE_ZR);
8137 break;
8138
c19d1205 8139 default:
5be8be5d 8140 as_fatal (_("unhandled operand code %d"), op_parse_code);
c19d1205 8141 }
09d92015 8142
c19d1205
ZW
8143 /* Various value-based sanity checks and shared operations. We
8144 do not signal immediate failures for the register constraints;
8145 this allows a syntax error to take precedence. */
5be8be5d 8146 switch (op_parse_code)
c19d1205
ZW
8147 {
8148 case OP_oRRnpc:
8149 case OP_RRnpc:
8150 case OP_RRnpcb:
8151 case OP_RRw:
b6702015 8152 case OP_oRRw:
c19d1205
ZW
8153 case OP_RRnpc_I0:
8154 if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
8155 inst.error = BAD_PC;
8156 break;
09d92015 8157
5be8be5d
DG
8158 case OP_oRRnpcsp:
8159 case OP_RRnpcsp:
23d00a41 8160 case OP_RRnpcsp_I32:
5be8be5d
DG
8161 if (inst.operands[i].isreg)
8162 {
8163 if (inst.operands[i].reg == REG_PC)
8164 inst.error = BAD_PC;
5c8ed6a4
JW
8165 else if (inst.operands[i].reg == REG_SP
8166 /* The restriction on Rd/Rt/Rt2 on Thumb mode has been
8167 relaxed since ARMv8-A. */
8168 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
8169 {
8170 gas_assert (thumb);
8171 inst.error = BAD_SP;
8172 }
5be8be5d
DG
8173 }
8174 break;
8175
55881a11 8176 case OP_RRnpctw:
fa94de6b
RM
8177 if (inst.operands[i].isreg
8178 && inst.operands[i].reg == REG_PC
55881a11
MGD
8179 && (inst.operands[i].writeback || thumb))
8180 inst.error = BAD_PC;
8181 break;
8182
1b883319 8183 case OP_RVSD_COND:
32c36c3c
AV
8184 case OP_VLDR:
8185 if (inst.operands[i].isreg)
8186 break;
8187 /* fall through. */
1b883319 8188
c19d1205
ZW
8189 case OP_CPSF:
8190 case OP_ENDI:
8191 case OP_oROR:
d2cd1205
JB
8192 case OP_wPSR:
8193 case OP_rPSR:
c19d1205 8194 case OP_COND:
52e7f43d 8195 case OP_oBARRIER_I15:
c19d1205 8196 case OP_REGLST:
4b5a202f 8197 case OP_CLRMLST:
c19d1205
ZW
8198 case OP_VRSLST:
8199 case OP_VRDLST:
477330fc 8200 case OP_VRSDLST:
efd6b359 8201 case OP_VRSDVLST:
477330fc
RM
8202 case OP_NRDLST:
8203 case OP_NSTRLST:
35c228db
AV
8204 case OP_MSTRLST2:
8205 case OP_MSTRLST4:
c19d1205
ZW
8206 if (val == FAIL)
8207 goto failure;
8208 inst.operands[i].imm = val;
8209 break;
a737bd4d 8210
60f993ce
AV
8211 case OP_LR:
8212 case OP_oLR:
8213 if (inst.operands[i].reg != REG_LR)
8214 inst.error = _("operand must be LR register");
8215 break;
8216
f1e1d7f3
AC
8217 case OP_SP:
8218 if (inst.operands[i].reg != REG_SP)
8219 inst.error = _("operand must be SP register");
8220 break;
8221
8222 case OP_R12:
8223 if (inst.operands[i].reg != REG_R12)
8224 inst.error = _("operand must be r12");
8225 break;
8226
1b883319
AV
8227 case OP_RMQRZ:
8228 case OP_oRMQRZ:
e39c1607 8229 case OP_RR_ZR:
1b883319
AV
8230 if (!inst.operands[i].iszr && inst.operands[i].reg == REG_PC)
8231 inst.error = BAD_PC;
8232 break;
8233
a302e574
AV
8234 case OP_RRe:
8235 if (inst.operands[i].isreg
8236 && (inst.operands[i].reg & 0x00000001) != 0)
8237 inst.error = BAD_ODD;
8238 break;
8239
8240 case OP_RRo:
8241 if (inst.operands[i].isreg)
8242 {
8243 if ((inst.operands[i].reg & 0x00000001) != 1)
8244 inst.error = BAD_EVEN;
8245 else if (inst.operands[i].reg == REG_SP)
8246 as_tsktsk (MVE_BAD_SP);
8247 else if (inst.operands[i].reg == REG_PC)
8248 inst.error = BAD_PC;
8249 }
8250 break;
8251
c19d1205
ZW
8252 default:
8253 break;
8254 }
09d92015 8255
c19d1205
ZW
8256 /* If we get here, this operand was successfully parsed. */
8257 inst.operands[i].present = 1;
8258 continue;
09d92015 8259
c19d1205 8260 bad_args:
09d92015 8261 inst.error = BAD_ARGS;
c19d1205
ZW
8262
8263 failure:
8264 if (!backtrack_pos)
d252fdde
PB
8265 {
8266 /* The parse routine should already have set inst.error, but set a
5f4273c7 8267 default here just in case. */
d252fdde 8268 if (!inst.error)
5ee91343 8269 inst.error = BAD_SYNTAX;
d252fdde
PB
8270 return FAIL;
8271 }
c19d1205
ZW
8272
8273 /* Do not backtrack over a trailing optional argument that
8274 absorbed some text. We will only fail again, with the
8275 'garbage following instruction' error message, which is
8276 probably less helpful than the current one. */
8277 if (backtrack_index == i && backtrack_pos != str
8278 && upat[i+1] == OP_stop)
d252fdde
PB
8279 {
8280 if (!inst.error)
5ee91343 8281 inst.error = BAD_SYNTAX;
d252fdde
PB
8282 return FAIL;
8283 }
c19d1205
ZW
8284
8285 /* Try again, skipping the optional argument at backtrack_pos. */
8286 str = backtrack_pos;
8287 inst.error = backtrack_error;
8288 inst.operands[backtrack_index].present = 0;
8289 i = backtrack_index;
8290 backtrack_pos = 0;
09d92015 8291 }
09d92015 8292
c19d1205
ZW
8293 /* Check that we have parsed all the arguments. */
8294 if (*str != '\0' && !inst.error)
8295 inst.error = _("garbage following instruction");
09d92015 8296
c19d1205 8297 return inst.error ? FAIL : SUCCESS;
09d92015
MM
8298}
8299
c19d1205
ZW
8300#undef po_char_or_fail
8301#undef po_reg_or_fail
8302#undef po_reg_or_goto
8303#undef po_imm_or_fail
5287ad62 8304#undef po_scalar_or_fail
52e7f43d 8305#undef po_barrier_or_imm
e07e6e58 8306
c19d1205 8307/* Shorthand macro for instruction encoding functions issuing errors. */
e07e6e58
NC
8308#define constraint(expr, err) \
8309 do \
c19d1205 8310 { \
e07e6e58
NC
8311 if (expr) \
8312 { \
8313 inst.error = err; \
8314 return; \
8315 } \
c19d1205 8316 } \
e07e6e58 8317 while (0)
c19d1205 8318
fdfde340
JM
8319/* Reject "bad registers" for Thumb-2 instructions. Many Thumb-2
8320 instructions are unpredictable if these registers are used. This
5c8ed6a4
JW
8321 is the BadReg predicate in ARM's Thumb-2 documentation.
8322
8323 Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few
8324 places, while the restriction on REG_SP was relaxed since ARMv8-A. */
8325#define reject_bad_reg(reg) \
8326 do \
8327 if (reg == REG_PC) \
8328 { \
8329 inst.error = BAD_PC; \
8330 return; \
8331 } \
8332 else if (reg == REG_SP \
8333 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) \
8334 { \
8335 inst.error = BAD_SP; \
8336 return; \
8337 } \
fdfde340
JM
8338 while (0)
8339
94206790
MM
8340/* If REG is R13 (the stack pointer), warn that its use is
8341 deprecated. */
8342#define warn_deprecated_sp(reg) \
8343 do \
8344 if (warn_on_deprecated && reg == REG_SP) \
5c3696f8 8345 as_tsktsk (_("use of r13 is deprecated")); \
94206790
MM
8346 while (0)
8347
c19d1205
ZW
8348/* Functions for operand encoding. ARM, then Thumb. */
8349
d840c081 8350#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31))
c19d1205 8351
9db2f6b4
RL
8352/* If the current inst is scalar ARMv8.2 fp16 instruction, do special encoding.
8353
8354 The only binary encoding difference is the Coprocessor number. Coprocessor
8355 9 is used for half-precision calculations or conversions. The format of the
2b0f3761 8356 instruction is the same as the equivalent Coprocessor 10 instruction that
9db2f6b4
RL
8357 exists for Single-Precision operation. */
8358
8359static void
8360do_scalar_fp16_v82_encode (void)
8361{
5ee91343 8362 if (inst.cond < COND_ALWAYS)
55e0daa3 8363 as_warn (_("scalar fp16 instruction cannot be conditional,"
9db2f6b4
RL
8364 " the behaviour is UNPREDICTABLE"));
8365 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
8366 _(BAD_FP16));
8367
8368 inst.instruction = (inst.instruction & 0xfffff0ff) | 0x900;
8369 mark_feature_used (&arm_ext_fp16);
8370}
8371
c19d1205
ZW
8372/* If VAL can be encoded in the immediate field of an ARM instruction,
8373 return the encoded form. Otherwise, return FAIL. */
8374
8375static unsigned int
8376encode_arm_immediate (unsigned int val)
09d92015 8377{
c19d1205
ZW
8378 unsigned int a, i;
8379
4f1d6205
L
8380 if (val <= 0xff)
8381 return val;
8382
8383 for (i = 2; i < 32; i += 2)
c19d1205
ZW
8384 if ((a = rotate_left (val, i)) <= 0xff)
8385 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
8386
8387 return FAIL;
09d92015
MM
8388}
8389
c19d1205
ZW
8390/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
8391 return the encoded form. Otherwise, return FAIL. */
8392static unsigned int
8393encode_thumb32_immediate (unsigned int val)
09d92015 8394{
c19d1205 8395 unsigned int a, i;
09d92015 8396
9c3c69f2 8397 if (val <= 0xff)
c19d1205 8398 return val;
a737bd4d 8399
9c3c69f2 8400 for (i = 1; i <= 24; i++)
09d92015 8401 {
9c3c69f2 8402 a = val >> i;
7af67752 8403 if ((val & ~(0xffU << i)) == 0)
9c3c69f2 8404 return ((val >> i) & 0x7f) | ((32 - i) << 7);
09d92015 8405 }
a737bd4d 8406
c19d1205
ZW
8407 a = val & 0xff;
8408 if (val == ((a << 16) | a))
8409 return 0x100 | a;
8410 if (val == ((a << 24) | (a << 16) | (a << 8) | a))
8411 return 0x300 | a;
09d92015 8412
c19d1205
ZW
8413 a = val & 0xff00;
8414 if (val == ((a << 16) | a))
8415 return 0x200 | (a >> 8);
a737bd4d 8416
c19d1205 8417 return FAIL;
09d92015 8418}
5287ad62 8419/* Encode a VFP SP or DP register number into inst.instruction. */
09d92015
MM
8420
8421static void
5287ad62
JB
8422encode_arm_vfp_reg (int reg, enum vfp_reg_pos pos)
8423{
8424 if ((pos == VFP_REG_Dd || pos == VFP_REG_Dn || pos == VFP_REG_Dm)
8425 && reg > 15)
8426 {
b1cc4aeb 8427 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
8428 {
8429 if (thumb_mode)
8430 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
8431 fpu_vfp_ext_d32);
8432 else
8433 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
8434 fpu_vfp_ext_d32);
8435 }
5287ad62 8436 else
477330fc
RM
8437 {
8438 first_error (_("D register out of range for selected VFP version"));
8439 return;
8440 }
5287ad62
JB
8441 }
8442
c19d1205 8443 switch (pos)
09d92015 8444 {
c19d1205
ZW
8445 case VFP_REG_Sd:
8446 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8447 break;
8448
8449 case VFP_REG_Sn:
8450 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8451 break;
8452
8453 case VFP_REG_Sm:
8454 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8455 break;
8456
5287ad62
JB
8457 case VFP_REG_Dd:
8458 inst.instruction |= ((reg & 15) << 12) | ((reg >> 4) << 22);
8459 break;
5f4273c7 8460
5287ad62
JB
8461 case VFP_REG_Dn:
8462 inst.instruction |= ((reg & 15) << 16) | ((reg >> 4) << 7);
8463 break;
5f4273c7 8464
5287ad62
JB
8465 case VFP_REG_Dm:
8466 inst.instruction |= (reg & 15) | ((reg >> 4) << 5);
8467 break;
8468
c19d1205
ZW
8469 default:
8470 abort ();
09d92015 8471 }
09d92015
MM
8472}
8473
c19d1205 8474/* Encode a <shift> in an ARM-format instruction. The immediate,
55cf6793 8475 if any, is handled by md_apply_fix. */
09d92015 8476static void
c19d1205 8477encode_arm_shift (int i)
09d92015 8478{
008a97ef
RL
8479 /* register-shifted register. */
8480 if (inst.operands[i].immisreg)
8481 {
bf355b69
MR
8482 int op_index;
8483 for (op_index = 0; op_index <= i; ++op_index)
008a97ef 8484 {
5689c942
RL
8485 /* Check the operand only when it's presented. In pre-UAL syntax,
8486 if the destination register is the same as the first operand, two
8487 register form of the instruction can be used. */
bf355b69
MR
8488 if (inst.operands[op_index].present && inst.operands[op_index].isreg
8489 && inst.operands[op_index].reg == REG_PC)
008a97ef
RL
8490 as_warn (UNPRED_REG ("r15"));
8491 }
8492
8493 if (inst.operands[i].imm == REG_PC)
8494 as_warn (UNPRED_REG ("r15"));
8495 }
8496
c19d1205
ZW
8497 if (inst.operands[i].shift_kind == SHIFT_RRX)
8498 inst.instruction |= SHIFT_ROR << 5;
8499 else
09d92015 8500 {
c19d1205
ZW
8501 inst.instruction |= inst.operands[i].shift_kind << 5;
8502 if (inst.operands[i].immisreg)
8503 {
8504 inst.instruction |= SHIFT_BY_REG;
8505 inst.instruction |= inst.operands[i].imm << 8;
8506 }
8507 else
e2b0ab59 8508 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
09d92015 8509 }
c19d1205 8510}
09d92015 8511
c19d1205
ZW
8512static void
8513encode_arm_shifter_operand (int i)
8514{
8515 if (inst.operands[i].isreg)
09d92015 8516 {
c19d1205
ZW
8517 inst.instruction |= inst.operands[i].reg;
8518 encode_arm_shift (i);
09d92015 8519 }
c19d1205 8520 else
a415b1cd
JB
8521 {
8522 inst.instruction |= INST_IMMEDIATE;
e2b0ab59 8523 if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
a415b1cd
JB
8524 inst.instruction |= inst.operands[i].imm;
8525 }
09d92015
MM
8526}
8527
c19d1205 8528/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
09d92015 8529static void
5b7c81bd 8530encode_arm_addr_mode_common (int i, bool is_t)
09d92015 8531{
2b2f5df9
NC
8532 /* PR 14260:
8533 Generate an error if the operand is not a register. */
8534 constraint (!inst.operands[i].isreg,
8535 _("Instruction does not support =N addresses"));
8536
c19d1205 8537 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 8538
c19d1205 8539 if (inst.operands[i].preind)
09d92015 8540 {
c19d1205
ZW
8541 if (is_t)
8542 {
8543 inst.error = _("instruction does not accept preindexed addressing");
8544 return;
8545 }
8546 inst.instruction |= PRE_INDEX;
8547 if (inst.operands[i].writeback)
8548 inst.instruction |= WRITE_BACK;
09d92015 8549
c19d1205
ZW
8550 }
8551 else if (inst.operands[i].postind)
8552 {
9c2799c2 8553 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
8554 if (is_t)
8555 inst.instruction |= WRITE_BACK;
8556 }
8557 else /* unindexed - only for coprocessor */
09d92015 8558 {
c19d1205 8559 inst.error = _("instruction does not accept unindexed addressing");
09d92015
MM
8560 return;
8561 }
8562
c19d1205
ZW
8563 if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
8564 && (((inst.instruction & 0x000f0000) >> 16)
8565 == ((inst.instruction & 0x0000f000) >> 12)))
8566 as_warn ((inst.instruction & LOAD_BIT)
8567 ? _("destination register same as write-back base")
8568 : _("source register same as write-back base"));
09d92015
MM
8569}
8570
c19d1205
ZW
8571/* inst.operands[i] was set up by parse_address. Encode it into an
8572 ARM-format mode 2 load or store instruction. If is_t is true,
8573 reject forms that cannot be used with a T instruction (i.e. not
8574 post-indexed). */
a737bd4d 8575static void
5b7c81bd 8576encode_arm_addr_mode_2 (int i, bool is_t)
09d92015 8577{
5b7c81bd 8578 const bool is_pc = (inst.operands[i].reg == REG_PC);
5be8be5d 8579
c19d1205 8580 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8581
c19d1205 8582 if (inst.operands[i].immisreg)
09d92015 8583 {
5be8be5d
DG
8584 constraint ((inst.operands[i].imm == REG_PC
8585 || (is_pc && inst.operands[i].writeback)),
8586 BAD_PC_ADDRESSING);
c19d1205
ZW
8587 inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
8588 inst.instruction |= inst.operands[i].imm;
8589 if (!inst.operands[i].negative)
8590 inst.instruction |= INDEX_UP;
8591 if (inst.operands[i].shifted)
8592 {
8593 if (inst.operands[i].shift_kind == SHIFT_RRX)
8594 inst.instruction |= SHIFT_ROR << 5;
8595 else
8596 {
8597 inst.instruction |= inst.operands[i].shift_kind << 5;
e2b0ab59 8598 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
c19d1205
ZW
8599 }
8600 }
09d92015 8601 }
e2b0ab59 8602 else /* immediate offset in inst.relocs[0] */
09d92015 8603 {
e2b0ab59 8604 if (is_pc && !inst.relocs[0].pc_rel)
5be8be5d 8605 {
5b7c81bd 8606 const bool is_load = ((inst.instruction & LOAD_BIT) != 0);
23a10334
JZ
8607
8608 /* If is_t is TRUE, it's called from do_ldstt. ldrt/strt
8609 cannot use PC in addressing.
8610 PC cannot be used in writeback addressing, either. */
8611 constraint ((is_t || inst.operands[i].writeback),
5be8be5d 8612 BAD_PC_ADDRESSING);
23a10334 8613
dc5ec521 8614 /* Use of PC in str is deprecated for ARMv7. */
23a10334
JZ
8615 if (warn_on_deprecated
8616 && !is_load
8617 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
5c3696f8 8618 as_tsktsk (_("use of PC in this instruction is deprecated"));
5be8be5d
DG
8619 }
8620
e2b0ab59 8621 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8622 {
8623 /* Prefer + for zero encoded value. */
8624 if (!inst.operands[i].negative)
8625 inst.instruction |= INDEX_UP;
e2b0ab59 8626 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
26d97720 8627 }
09d92015 8628 }
09d92015
MM
8629}
8630
c19d1205
ZW
8631/* inst.operands[i] was set up by parse_address. Encode it into an
8632 ARM-format mode 3 load or store instruction. Reject forms that
8633 cannot be used with such instructions. If is_t is true, reject
8634 forms that cannot be used with a T instruction (i.e. not
8635 post-indexed). */
8636static void
5b7c81bd 8637encode_arm_addr_mode_3 (int i, bool is_t)
09d92015 8638{
c19d1205 8639 if (inst.operands[i].immisreg && inst.operands[i].shifted)
09d92015 8640 {
c19d1205
ZW
8641 inst.error = _("instruction does not accept scaled register index");
8642 return;
09d92015 8643 }
a737bd4d 8644
c19d1205 8645 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8646
c19d1205
ZW
8647 if (inst.operands[i].immisreg)
8648 {
5be8be5d 8649 constraint ((inst.operands[i].imm == REG_PC
eb9f3f00 8650 || (is_t && inst.operands[i].reg == REG_PC)),
5be8be5d 8651 BAD_PC_ADDRESSING);
eb9f3f00
JB
8652 constraint (inst.operands[i].reg == REG_PC && inst.operands[i].writeback,
8653 BAD_PC_WRITEBACK);
c19d1205
ZW
8654 inst.instruction |= inst.operands[i].imm;
8655 if (!inst.operands[i].negative)
8656 inst.instruction |= INDEX_UP;
8657 }
e2b0ab59 8658 else /* immediate offset in inst.relocs[0] */
c19d1205 8659 {
e2b0ab59 8660 constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
5be8be5d
DG
8661 && inst.operands[i].writeback),
8662 BAD_PC_WRITEBACK);
c19d1205 8663 inst.instruction |= HWOFFSET_IMM;
e2b0ab59 8664 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8665 {
8666 /* Prefer + for zero encoded value. */
8667 if (!inst.operands[i].negative)
8668 inst.instruction |= INDEX_UP;
8669
e2b0ab59 8670 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
26d97720 8671 }
c19d1205 8672 }
a737bd4d
NC
8673}
8674
8335d6aa
JW
8675/* Write immediate bits [7:0] to the following locations:
8676
8677 |28/24|23 19|18 16|15 4|3 0|
8678 | 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|
8679
8680 This function is used by VMOV/VMVN/VORR/VBIC. */
8681
8682static void
8683neon_write_immbits (unsigned immbits)
8684{
8685 inst.instruction |= immbits & 0xf;
8686 inst.instruction |= ((immbits >> 4) & 0x7) << 16;
8687 inst.instruction |= ((immbits >> 7) & 0x1) << (thumb_mode ? 28 : 24);
8688}
8689
8690/* Invert low-order SIZE bits of XHI:XLO. */
8691
8692static void
8693neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
8694{
8695 unsigned immlo = xlo ? *xlo : 0;
8696 unsigned immhi = xhi ? *xhi : 0;
8697
8698 switch (size)
8699 {
8700 case 8:
8701 immlo = (~immlo) & 0xff;
8702 break;
8703
8704 case 16:
8705 immlo = (~immlo) & 0xffff;
8706 break;
8707
8708 case 64:
8709 immhi = (~immhi) & 0xffffffff;
8710 /* fall through. */
8711
8712 case 32:
8713 immlo = (~immlo) & 0xffffffff;
8714 break;
8715
8716 default:
8717 abort ();
8718 }
8719
8720 if (xlo)
8721 *xlo = immlo;
8722
8723 if (xhi)
8724 *xhi = immhi;
8725}
8726
8727/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
8728 A, B, C, D. */
09d92015 8729
c19d1205 8730static int
8335d6aa 8731neon_bits_same_in_bytes (unsigned imm)
09d92015 8732{
8335d6aa
JW
8733 return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
8734 && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
8735 && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
8736 && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
8737}
a737bd4d 8738
8335d6aa 8739/* For immediate of above form, return 0bABCD. */
09d92015 8740
8335d6aa
JW
8741static unsigned
8742neon_squash_bits (unsigned imm)
8743{
8744 return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
8745 | ((imm & 0x01000000) >> 21);
8746}
8747
8748/* Compress quarter-float representation to 0b...000 abcdefgh. */
8749
8750static unsigned
8751neon_qfloat_bits (unsigned imm)
8752{
8753 return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
8754}
8755
8756/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
8757 the instruction. *OP is passed as the initial value of the op field, and
8758 may be set to a different value depending on the constant (i.e.
8759 "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
8760 MVN). If the immediate looks like a repeated pattern then also
8761 try smaller element sizes. */
8762
8763static int
8764neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
8765 unsigned *immbits, int *op, int size,
8766 enum neon_el_type type)
8767{
8768 /* Only permit float immediates (including 0.0/-0.0) if the operand type is
8769 float. */
8770 if (type == NT_float && !float_p)
8771 return FAIL;
8772
8773 if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
09d92015 8774 {
8335d6aa
JW
8775 if (size != 32 || *op == 1)
8776 return FAIL;
8777 *immbits = neon_qfloat_bits (immlo);
8778 return 0xf;
8779 }
8780
8781 if (size == 64)
8782 {
8783 if (neon_bits_same_in_bytes (immhi)
8784 && neon_bits_same_in_bytes (immlo))
c19d1205 8785 {
8335d6aa
JW
8786 if (*op == 1)
8787 return FAIL;
8788 *immbits = (neon_squash_bits (immhi) << 4)
8789 | neon_squash_bits (immlo);
8790 *op = 1;
8791 return 0xe;
c19d1205 8792 }
a737bd4d 8793
8335d6aa
JW
8794 if (immhi != immlo)
8795 return FAIL;
8796 }
a737bd4d 8797
8335d6aa 8798 if (size >= 32)
09d92015 8799 {
8335d6aa 8800 if (immlo == (immlo & 0x000000ff))
c19d1205 8801 {
8335d6aa
JW
8802 *immbits = immlo;
8803 return 0x0;
c19d1205 8804 }
8335d6aa 8805 else if (immlo == (immlo & 0x0000ff00))
c19d1205 8806 {
8335d6aa
JW
8807 *immbits = immlo >> 8;
8808 return 0x2;
c19d1205 8809 }
8335d6aa
JW
8810 else if (immlo == (immlo & 0x00ff0000))
8811 {
8812 *immbits = immlo >> 16;
8813 return 0x4;
8814 }
8815 else if (immlo == (immlo & 0xff000000))
8816 {
8817 *immbits = immlo >> 24;
8818 return 0x6;
8819 }
8820 else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
8821 {
8822 *immbits = (immlo >> 8) & 0xff;
8823 return 0xc;
8824 }
8825 else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
8826 {
8827 *immbits = (immlo >> 16) & 0xff;
8828 return 0xd;
8829 }
8830
8831 if ((immlo & 0xffff) != (immlo >> 16))
8832 return FAIL;
8833 immlo &= 0xffff;
09d92015 8834 }
a737bd4d 8835
8335d6aa 8836 if (size >= 16)
4962c51a 8837 {
8335d6aa
JW
8838 if (immlo == (immlo & 0x000000ff))
8839 {
8840 *immbits = immlo;
8841 return 0x8;
8842 }
8843 else if (immlo == (immlo & 0x0000ff00))
8844 {
8845 *immbits = immlo >> 8;
8846 return 0xa;
8847 }
8848
8849 if ((immlo & 0xff) != (immlo >> 8))
8850 return FAIL;
8851 immlo &= 0xff;
4962c51a
MS
8852 }
8853
8335d6aa
JW
8854 if (immlo == (immlo & 0x000000ff))
8855 {
8856 /* Don't allow MVN with 8-bit immediate. */
8857 if (*op == 1)
8858 return FAIL;
8859 *immbits = immlo;
8860 return 0xe;
8861 }
26d97720 8862
8335d6aa 8863 return FAIL;
c19d1205 8864}
a737bd4d 8865
ba592044
AM
8866/* Returns TRUE if double precision value V may be cast
8867 to single precision without loss of accuracy. */
8868
5b7c81bd 8869static bool
0e3c1eeb 8870is_double_a_single (uint64_t v)
ba592044 8871{
7e30b1eb 8872 int exp = (v >> 52) & 0x7FF;
0e3c1eeb 8873 uint64_t mantissa = v & 0xFFFFFFFFFFFFFULL;
ba592044 8874
7e30b1eb
AM
8875 return ((exp == 0 || exp == 0x7FF
8876 || (exp >= 1023 - 126 && exp <= 1023 + 127))
8877 && (mantissa & 0x1FFFFFFFL) == 0);
ba592044
AM
8878}
8879
3739860c 8880/* Returns a double precision value casted to single precision
ba592044
AM
8881 (ignoring the least significant bits in exponent and mantissa). */
8882
8883static int
0e3c1eeb 8884double_to_single (uint64_t v)
ba592044 8885{
7af67752
AM
8886 unsigned int sign = (v >> 63) & 1;
8887 int exp = (v >> 52) & 0x7FF;
0e3c1eeb 8888 uint64_t mantissa = v & 0xFFFFFFFFFFFFFULL;
ba592044
AM
8889
8890 if (exp == 0x7FF)
8891 exp = 0xFF;
8892 else
8893 {
8894 exp = exp - 1023 + 127;
8895 if (exp >= 0xFF)
8896 {
8897 /* Infinity. */
8898 exp = 0x7F;
8899 mantissa = 0;
8900 }
8901 else if (exp < 0)
8902 {
8903 /* No denormalized numbers. */
8904 exp = 0;
8905 mantissa = 0;
8906 }
8907 }
8908 mantissa >>= 29;
8909 return (sign << 31) | (exp << 23) | mantissa;
8910}
8911
8335d6aa
JW
8912enum lit_type
8913{
8914 CONST_THUMB,
8915 CONST_ARM,
8916 CONST_VEC
8917};
8918
ba592044
AM
8919static void do_vfp_nsyn_opcode (const char *);
8920
e2b0ab59 8921/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
c19d1205
ZW
8922 Determine whether it can be performed with a move instruction; if
8923 it can, convert inst.instruction to that move instruction and
5b7c81bd 8924 return true; if it can't, convert inst.instruction to a literal-pool
c921be7d
NC
8925 load and return FALSE. If this is not a valid thing to do in the
8926 current context, set inst.error and return TRUE.
a737bd4d 8927
c19d1205
ZW
8928 inst.operands[i] describes the destination register. */
8929
5b7c81bd
AM
8930static bool
8931move_or_literal_pool (int i, enum lit_type t, bool mode_3)
c19d1205 8932{
53365c0d 8933 unsigned long tbit;
5b7c81bd
AM
8934 bool thumb_p = (t == CONST_THUMB);
8935 bool arm_p = (t == CONST_ARM);
53365c0d
PB
8936
8937 if (thumb_p)
8938 tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
8939 else
8940 tbit = LOAD_BIT;
8941
8942 if ((inst.instruction & tbit) == 0)
09d92015 8943 {
c19d1205 8944 inst.error = _("invalid pseudo operation");
5b7c81bd 8945 return true;
09d92015 8946 }
ba592044 8947
e2b0ab59
AV
8948 if (inst.relocs[0].exp.X_op != O_constant
8949 && inst.relocs[0].exp.X_op != O_symbol
8950 && inst.relocs[0].exp.X_op != O_big)
09d92015
MM
8951 {
8952 inst.error = _("constant expression expected");
5b7c81bd 8953 return true;
09d92015 8954 }
ba592044 8955
e2b0ab59
AV
8956 if (inst.relocs[0].exp.X_op == O_constant
8957 || inst.relocs[0].exp.X_op == O_big)
8335d6aa 8958 {
0e3c1eeb 8959 uint64_t v;
e2b0ab59 8960 if (inst.relocs[0].exp.X_op == O_big)
8335d6aa 8961 {
ba592044
AM
8962 LITTLENUM_TYPE w[X_PRECISION];
8963 LITTLENUM_TYPE * l;
8964
e2b0ab59 8965 if (inst.relocs[0].exp.X_add_number == -1)
8335d6aa 8966 {
ba592044
AM
8967 gen_to_words (w, X_PRECISION, E_PRECISION);
8968 l = w;
8969 /* FIXME: Should we check words w[2..5] ? */
8335d6aa 8970 }
ba592044
AM
8971 else
8972 l = generic_bignum;
3739860c 8973
7e30b1eb
AM
8974 v = l[3] & LITTLENUM_MASK;
8975 v <<= LITTLENUM_NUMBER_OF_BITS;
8976 v |= l[2] & LITTLENUM_MASK;
8977 v <<= LITTLENUM_NUMBER_OF_BITS;
8978 v |= l[1] & LITTLENUM_MASK;
8979 v <<= LITTLENUM_NUMBER_OF_BITS;
8980 v |= l[0] & LITTLENUM_MASK;
8335d6aa 8981 }
ba592044 8982 else
e2b0ab59 8983 v = inst.relocs[0].exp.X_add_number;
ba592044
AM
8984
8985 if (!inst.operands[i].issingle)
8335d6aa 8986 {
12569877 8987 if (thumb_p)
8335d6aa 8988 {
53445554
TP
8989 /* LDR should not use lead in a flag-setting instruction being
8990 chosen so we do not check whether movs can be used. */
12569877 8991
53445554 8992 if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
ff8646ee 8993 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
53445554
TP
8994 && inst.operands[i].reg != 13
8995 && inst.operands[i].reg != 15)
12569877 8996 {
fc289b0a
TP
8997 /* Check if on thumb2 it can be done with a mov.w, mvn or
8998 movw instruction. */
12569877 8999 unsigned int newimm;
5b7c81bd 9000 bool isNegated = false;
12569877
AM
9001
9002 newimm = encode_thumb32_immediate (v);
f3da8a96 9003 if (newimm == (unsigned int) FAIL)
12569877 9004 {
582cfe03 9005 newimm = encode_thumb32_immediate (~v);
5b7c81bd 9006 isNegated = true;
12569877
AM
9007 }
9008
fc289b0a
TP
9009 /* The number can be loaded with a mov.w or mvn
9010 instruction. */
ff8646ee
TP
9011 if (newimm != (unsigned int) FAIL
9012 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
12569877 9013 {
fc289b0a 9014 inst.instruction = (0xf04f0000 /* MOV.W. */
582cfe03 9015 | (inst.operands[i].reg << 8));
fc289b0a 9016 /* Change to MOVN. */
582cfe03 9017 inst.instruction |= (isNegated ? 0x200000 : 0);
12569877
AM
9018 inst.instruction |= (newimm & 0x800) << 15;
9019 inst.instruction |= (newimm & 0x700) << 4;
9020 inst.instruction |= (newimm & 0x0ff);
5b7c81bd 9021 return true;
12569877 9022 }
fc289b0a 9023 /* The number can be loaded with a movw instruction. */
ff8646ee
TP
9024 else if ((v & ~0xFFFF) == 0
9025 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
3739860c 9026 {
582cfe03 9027 int imm = v & 0xFFFF;
12569877 9028
582cfe03 9029 inst.instruction = 0xf2400000; /* MOVW. */
12569877
AM
9030 inst.instruction |= (inst.operands[i].reg << 8);
9031 inst.instruction |= (imm & 0xf000) << 4;
9032 inst.instruction |= (imm & 0x0800) << 15;
9033 inst.instruction |= (imm & 0x0700) << 4;
9034 inst.instruction |= (imm & 0x00ff);
8fe9a076
AV
9035 /* In case this replacement is being done on Armv8-M
9036 Baseline we need to make sure to disable the
9037 instruction size check, as otherwise GAS will reject
9038 the use of this T32 instruction. */
9039 inst.size_req = 0;
5b7c81bd 9040 return true;
12569877
AM
9041 }
9042 }
8335d6aa 9043 }
12569877 9044 else if (arm_p)
ba592044
AM
9045 {
9046 int value = encode_arm_immediate (v);
12569877 9047
ba592044
AM
9048 if (value != FAIL)
9049 {
9050 /* This can be done with a mov instruction. */
9051 inst.instruction &= LITERAL_MASK;
9052 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
9053 inst.instruction |= value & 0xfff;
5b7c81bd 9054 return true;
ba592044 9055 }
8335d6aa 9056
ba592044
AM
9057 value = encode_arm_immediate (~ v);
9058 if (value != FAIL)
9059 {
9060 /* This can be done with a mvn instruction. */
9061 inst.instruction &= LITERAL_MASK;
9062 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
9063 inst.instruction |= value & 0xfff;
5b7c81bd 9064 return true;
ba592044
AM
9065 }
9066 }
934c2632 9067 else if (t == CONST_VEC && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
8335d6aa 9068 {
ba592044
AM
9069 int op = 0;
9070 unsigned immbits = 0;
9071 unsigned immlo = inst.operands[1].imm;
9072 unsigned immhi = inst.operands[1].regisimm
9073 ? inst.operands[1].reg
e2b0ab59 9074 : inst.relocs[0].exp.X_unsigned
ba592044 9075 ? 0
0e3c1eeb 9076 : (int64_t) (int) immlo >> 32;
5b7c81bd 9077 int cmode = neon_cmode_for_move_imm (immlo, immhi, false, &immbits,
ba592044
AM
9078 &op, 64, NT_invtype);
9079
9080 if (cmode == FAIL)
9081 {
9082 neon_invert_size (&immlo, &immhi, 64);
9083 op = !op;
5b7c81bd 9084 cmode = neon_cmode_for_move_imm (immlo, immhi, false, &immbits,
ba592044
AM
9085 &op, 64, NT_invtype);
9086 }
9087
9088 if (cmode != FAIL)
9089 {
9090 inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
9091 | (1 << 23)
9092 | (cmode << 8)
9093 | (op << 5)
9094 | (1 << 4);
9095
9096 /* Fill other bits in vmov encoding for both thumb and arm. */
9097 if (thumb_mode)
eff0bc54 9098 inst.instruction |= (0x7U << 29) | (0xF << 24);
ba592044 9099 else
eff0bc54 9100 inst.instruction |= (0xFU << 28) | (0x1 << 25);
ba592044 9101 neon_write_immbits (immbits);
5b7c81bd 9102 return true;
ba592044 9103 }
8335d6aa
JW
9104 }
9105 }
8335d6aa 9106
ba592044
AM
9107 if (t == CONST_VEC)
9108 {
9109 /* Check if vldr Rx, =constant could be optimized to vmov Rx, #constant. */
9110 if (inst.operands[i].issingle
9111 && is_quarter_float (inst.operands[1].imm)
9112 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3xd))
8335d6aa 9113 {
ba592044
AM
9114 inst.operands[1].imm =
9115 neon_qfloat_bits (v);
9116 do_vfp_nsyn_opcode ("fconsts");
5b7c81bd 9117 return true;
8335d6aa 9118 }
5fc177c8
NC
9119
9120 /* If our host does not support a 64-bit type then we cannot perform
9121 the following optimization. This mean that there will be a
9122 discrepancy between the output produced by an assembler built for
9123 a 32-bit-only host and the output produced from a 64-bit host, but
9124 this cannot be helped. */
ba592044
AM
9125 else if (!inst.operands[1].issingle
9126 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
8335d6aa 9127 {
ba592044
AM
9128 if (is_double_a_single (v)
9129 && is_quarter_float (double_to_single (v)))
9130 {
9131 inst.operands[1].imm =
9132 neon_qfloat_bits (double_to_single (v));
9133 do_vfp_nsyn_opcode ("fconstd");
5b7c81bd 9134 return true;
ba592044 9135 }
8335d6aa
JW
9136 }
9137 }
9138 }
9139
9140 if (add_to_lit_pool ((!inst.operands[i].isvec
9141 || inst.operands[i].issingle) ? 4 : 8) == FAIL)
5b7c81bd 9142 return true;
8335d6aa
JW
9143
9144 inst.operands[1].reg = REG_PC;
9145 inst.operands[1].isreg = 1;
9146 inst.operands[1].preind = 1;
e2b0ab59
AV
9147 inst.relocs[0].pc_rel = 1;
9148 inst.relocs[0].type = (thumb_p
8335d6aa
JW
9149 ? BFD_RELOC_ARM_THUMB_OFFSET
9150 : (mode_3
9151 ? BFD_RELOC_ARM_HWLITERAL
9152 : BFD_RELOC_ARM_LITERAL));
5b7c81bd 9153 return false;
8335d6aa
JW
9154}
9155
9156/* inst.operands[i] was set up by parse_address. Encode it into an
9157 ARM-format instruction. Reject all forms which cannot be encoded
9158 into a coprocessor load/store instruction. If wb_ok is false,
9159 reject use of writeback; if unind_ok is false, reject use of
9160 unindexed addressing. If reloc_override is not 0, use it instead
9161 of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
9162 (in which case it is preserved). */
9163
9164static int
9165encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
9166{
9167 if (!inst.operands[i].isreg)
9168 {
99b2a2dd
NC
9169 /* PR 18256 */
9170 if (! inst.operands[0].isvec)
9171 {
9172 inst.error = _("invalid co-processor operand");
9173 return FAIL;
9174 }
5b7c81bd 9175 if (move_or_literal_pool (0, CONST_VEC, /*mode_3=*/false))
8335d6aa
JW
9176 return SUCCESS;
9177 }
9178
9179 inst.instruction |= inst.operands[i].reg << 16;
9180
9181 gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
9182
9183 if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
9184 {
9185 gas_assert (!inst.operands[i].writeback);
9186 if (!unind_ok)
9187 {
9188 inst.error = _("instruction does not support unindexed addressing");
9189 return FAIL;
9190 }
9191 inst.instruction |= inst.operands[i].imm;
9192 inst.instruction |= INDEX_UP;
9193 return SUCCESS;
9194 }
9195
9196 if (inst.operands[i].preind)
9197 inst.instruction |= PRE_INDEX;
9198
9199 if (inst.operands[i].writeback)
09d92015 9200 {
8335d6aa 9201 if (inst.operands[i].reg == REG_PC)
c19d1205 9202 {
8335d6aa
JW
9203 inst.error = _("pc may not be used with write-back");
9204 return FAIL;
c19d1205 9205 }
8335d6aa 9206 if (!wb_ok)
c19d1205 9207 {
8335d6aa
JW
9208 inst.error = _("instruction does not support writeback");
9209 return FAIL;
c19d1205 9210 }
8335d6aa 9211 inst.instruction |= WRITE_BACK;
09d92015
MM
9212 }
9213
8335d6aa 9214 if (reloc_override)
e2b0ab59
AV
9215 inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
9216 else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
9217 || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
9218 && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
c19d1205 9219 {
8335d6aa 9220 if (thumb_mode)
e2b0ab59 9221 inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
8335d6aa 9222 else
e2b0ab59 9223 inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
c19d1205 9224 }
8335d6aa
JW
9225
9226 /* Prefer + for zero encoded value. */
9227 if (!inst.operands[i].negative)
9228 inst.instruction |= INDEX_UP;
9229
9230 return SUCCESS;
09d92015
MM
9231}
9232
5f4273c7 9233/* Functions for instruction encoding, sorted by sub-architecture.
c19d1205
ZW
9234 First some generics; their names are taken from the conventional
9235 bit positions for register arguments in ARM format instructions. */
09d92015 9236
a737bd4d 9237static void
c19d1205 9238do_noargs (void)
09d92015 9239{
c19d1205 9240}
a737bd4d 9241
c19d1205
ZW
9242static void
9243do_rd (void)
9244{
9245 inst.instruction |= inst.operands[0].reg << 12;
9246}
a737bd4d 9247
16a1fa25
TP
9248static void
9249do_rn (void)
9250{
9251 inst.instruction |= inst.operands[0].reg << 16;
9252}
9253
c19d1205
ZW
9254static void
9255do_rd_rm (void)
9256{
9257 inst.instruction |= inst.operands[0].reg << 12;
9258 inst.instruction |= inst.operands[1].reg;
9259}
09d92015 9260
9eb6c0f1
MGD
9261static void
9262do_rm_rn (void)
9263{
9264 inst.instruction |= inst.operands[0].reg;
9265 inst.instruction |= inst.operands[1].reg << 16;
9266}
9267
c19d1205
ZW
9268static void
9269do_rd_rn (void)
9270{
9271 inst.instruction |= inst.operands[0].reg << 12;
9272 inst.instruction |= inst.operands[1].reg << 16;
9273}
a737bd4d 9274
c19d1205
ZW
9275static void
9276do_rn_rd (void)
9277{
9278 inst.instruction |= inst.operands[0].reg << 16;
9279 inst.instruction |= inst.operands[1].reg << 12;
9280}
09d92015 9281
4ed7ed8d
TP
9282static void
9283do_tt (void)
9284{
9285 inst.instruction |= inst.operands[0].reg << 8;
9286 inst.instruction |= inst.operands[1].reg << 16;
9287}
9288
5b7c81bd 9289static bool
59d09be6
MGD
9290check_obsolete (const arm_feature_set *feature, const char *msg)
9291{
9292 if (ARM_CPU_IS_ANY (cpu_variant))
9293 {
5c3696f8 9294 as_tsktsk ("%s", msg);
5b7c81bd 9295 return true;
59d09be6
MGD
9296 }
9297 else if (ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
9298 {
9299 as_bad ("%s", msg);
5b7c81bd 9300 return true;
59d09be6
MGD
9301 }
9302
5b7c81bd 9303 return false;
59d09be6
MGD
9304}
9305
c19d1205
ZW
9306static void
9307do_rd_rm_rn (void)
9308{
9a64e435 9309 unsigned Rn = inst.operands[2].reg;
708587a4 9310 /* Enforce restrictions on SWP instruction. */
9a64e435 9311 if ((inst.instruction & 0x0fbfffff) == 0x01000090)
56adecf4
DG
9312 {
9313 constraint (Rn == inst.operands[0].reg || Rn == inst.operands[1].reg,
9314 _("Rn must not overlap other operands"));
9315
59d09be6
MGD
9316 /* SWP{b} is obsolete for ARMv8-A, and deprecated for ARMv6* and ARMv7.
9317 */
9318 if (!check_obsolete (&arm_ext_v8,
9319 _("swp{b} use is obsoleted for ARMv8 and later"))
9320 && warn_on_deprecated
9321 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6))
5c3696f8 9322 as_tsktsk (_("swp{b} use is deprecated for ARMv6 and ARMv7"));
56adecf4 9323 }
59d09be6 9324
c19d1205
ZW
9325 inst.instruction |= inst.operands[0].reg << 12;
9326 inst.instruction |= inst.operands[1].reg;
9a64e435 9327 inst.instruction |= Rn << 16;
c19d1205 9328}
09d92015 9329
c19d1205
ZW
9330static void
9331do_rd_rn_rm (void)
9332{
9333 inst.instruction |= inst.operands[0].reg << 12;
9334 inst.instruction |= inst.operands[1].reg << 16;
9335 inst.instruction |= inst.operands[2].reg;
9336}
a737bd4d 9337
c19d1205
ZW
9338static void
9339do_rm_rd_rn (void)
9340{
5be8be5d 9341 constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
e2b0ab59
AV
9342 constraint (((inst.relocs[0].exp.X_op != O_constant
9343 && inst.relocs[0].exp.X_op != O_illegal)
9344 || inst.relocs[0].exp.X_add_number != 0),
5be8be5d 9345 BAD_ADDR_MODE);
c19d1205
ZW
9346 inst.instruction |= inst.operands[0].reg;
9347 inst.instruction |= inst.operands[1].reg << 12;
9348 inst.instruction |= inst.operands[2].reg << 16;
9349}
09d92015 9350
c19d1205
ZW
9351static void
9352do_imm0 (void)
9353{
9354 inst.instruction |= inst.operands[0].imm;
9355}
09d92015 9356
c19d1205
ZW
9357static void
9358do_rd_cpaddr (void)
9359{
9360 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 9361 encode_arm_cp_address (1, true, true, 0);
09d92015 9362}
a737bd4d 9363
c19d1205
ZW
9364/* ARM instructions, in alphabetical order by function name (except
9365 that wrapper functions appear immediately after the function they
9366 wrap). */
09d92015 9367
c19d1205
ZW
9368/* This is a pseudo-op of the form "adr rd, label" to be converted
9369 into a relative address of the form "add rd, pc, #label-.-8". */
09d92015
MM
9370
9371static void
c19d1205 9372do_adr (void)
09d92015 9373{
c19d1205 9374 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9375
c19d1205
ZW
9376 /* Frag hacking will turn this into a sub instruction if the offset turns
9377 out to be negative. */
e2b0ab59
AV
9378 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9379 inst.relocs[0].pc_rel = 1;
9380 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9381
fc6141f0 9382 if (support_interwork
e2b0ab59
AV
9383 && inst.relocs[0].exp.X_op == O_symbol
9384 && inst.relocs[0].exp.X_add_symbol != NULL
9385 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9386 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9387 inst.relocs[0].exp.X_add_number |= 1;
c19d1205 9388}
b99bd4ef 9389
c19d1205
ZW
9390/* This is a pseudo-op of the form "adrl rd, label" to be converted
9391 into a relative address of the form:
9392 add rd, pc, #low(label-.-8)"
9393 add rd, rd, #high(label-.-8)" */
b99bd4ef 9394
c19d1205
ZW
9395static void
9396do_adrl (void)
9397{
9398 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9399
c19d1205
ZW
9400 /* Frag hacking will turn this into a sub instruction if the offset turns
9401 out to be negative. */
e2b0ab59
AV
9402 inst.relocs[0].type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
9403 inst.relocs[0].pc_rel = 1;
c19d1205 9404 inst.size = INSN_SIZE * 2;
e2b0ab59 9405 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9406
fc6141f0 9407 if (support_interwork
e2b0ab59
AV
9408 && inst.relocs[0].exp.X_op == O_symbol
9409 && inst.relocs[0].exp.X_add_symbol != NULL
9410 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9411 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9412 inst.relocs[0].exp.X_add_number |= 1;
b99bd4ef
NC
9413}
9414
b99bd4ef 9415static void
c19d1205 9416do_arit (void)
b99bd4ef 9417{
e2b0ab59
AV
9418 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9419 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9420 THUMB1_RELOC_ONLY);
c19d1205
ZW
9421 if (!inst.operands[1].present)
9422 inst.operands[1].reg = inst.operands[0].reg;
9423 inst.instruction |= inst.operands[0].reg << 12;
9424 inst.instruction |= inst.operands[1].reg << 16;
9425 encode_arm_shifter_operand (2);
9426}
b99bd4ef 9427
62b3e311
PB
9428static void
9429do_barrier (void)
9430{
9431 if (inst.operands[0].present)
ccb84d65 9432 inst.instruction |= inst.operands[0].imm;
62b3e311
PB
9433 else
9434 inst.instruction |= 0xf;
9435}
9436
c19d1205
ZW
9437static void
9438do_bfc (void)
9439{
9440 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
9441 constraint (msb > 32, _("bit-field extends past end of register"));
9442 /* The instruction encoding stores the LSB and MSB,
9443 not the LSB and width. */
9444 inst.instruction |= inst.operands[0].reg << 12;
9445 inst.instruction |= inst.operands[1].imm << 7;
9446 inst.instruction |= (msb - 1) << 16;
9447}
b99bd4ef 9448
c19d1205
ZW
9449static void
9450do_bfi (void)
9451{
9452 unsigned int msb;
b99bd4ef 9453
c19d1205
ZW
9454 /* #0 in second position is alternative syntax for bfc, which is
9455 the same instruction but with REG_PC in the Rm field. */
9456 if (!inst.operands[1].isreg)
9457 inst.operands[1].reg = REG_PC;
b99bd4ef 9458
c19d1205
ZW
9459 msb = inst.operands[2].imm + inst.operands[3].imm;
9460 constraint (msb > 32, _("bit-field extends past end of register"));
9461 /* The instruction encoding stores the LSB and MSB,
9462 not the LSB and width. */
9463 inst.instruction |= inst.operands[0].reg << 12;
9464 inst.instruction |= inst.operands[1].reg;
9465 inst.instruction |= inst.operands[2].imm << 7;
9466 inst.instruction |= (msb - 1) << 16;
b99bd4ef
NC
9467}
9468
b99bd4ef 9469static void
c19d1205 9470do_bfx (void)
b99bd4ef 9471{
c19d1205
ZW
9472 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
9473 _("bit-field extends past end of register"));
9474 inst.instruction |= inst.operands[0].reg << 12;
9475 inst.instruction |= inst.operands[1].reg;
9476 inst.instruction |= inst.operands[2].imm << 7;
9477 inst.instruction |= (inst.operands[3].imm - 1) << 16;
9478}
09d92015 9479
c19d1205
ZW
9480/* ARM V5 breakpoint instruction (argument parse)
9481 BKPT <16 bit unsigned immediate>
9482 Instruction is not conditional.
9483 The bit pattern given in insns[] has the COND_ALWAYS condition,
9484 and it is an error if the caller tried to override that. */
b99bd4ef 9485
c19d1205
ZW
9486static void
9487do_bkpt (void)
9488{
9489 /* Top 12 of 16 bits to bits 19:8. */
9490 inst.instruction |= (inst.operands[0].imm & 0xfff0) << 4;
09d92015 9491
c19d1205
ZW
9492 /* Bottom 4 of 16 bits to bits 3:0. */
9493 inst.instruction |= inst.operands[0].imm & 0xf;
9494}
09d92015 9495
c19d1205
ZW
9496static void
9497encode_branch (int default_reloc)
9498{
9499 if (inst.operands[0].hasreloc)
9500 {
0855e32b
NS
9501 constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
9502 && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
9503 _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
e2b0ab59 9504 inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
0855e32b
NS
9505 ? BFD_RELOC_ARM_PLT32
9506 : thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
c19d1205 9507 }
b99bd4ef 9508 else
e2b0ab59
AV
9509 inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
9510 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
9511}
9512
b99bd4ef 9513static void
c19d1205 9514do_branch (void)
b99bd4ef 9515{
39b41c9c
PB
9516#ifdef OBJ_ELF
9517 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9518 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9519 else
9520#endif
9521 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
9522}
9523
9524static void
9525do_bl (void)
9526{
9527#ifdef OBJ_ELF
9528 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9529 {
9530 if (inst.cond == COND_ALWAYS)
9531 encode_branch (BFD_RELOC_ARM_PCREL_CALL);
9532 else
9533 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9534 }
9535 else
9536#endif
9537 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
c19d1205 9538}
b99bd4ef 9539
c19d1205
ZW
9540/* ARM V5 branch-link-exchange instruction (argument parse)
9541 BLX <target_addr> ie BLX(1)
9542 BLX{<condition>} <Rm> ie BLX(2)
9543 Unfortunately, there are two different opcodes for this mnemonic.
9544 So, the insns[].value is not used, and the code here zaps values
9545 into inst.instruction.
9546 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
b99bd4ef 9547
c19d1205
ZW
9548static void
9549do_blx (void)
9550{
9551 if (inst.operands[0].isreg)
b99bd4ef 9552 {
c19d1205
ZW
9553 /* Arg is a register; the opcode provided by insns[] is correct.
9554 It is not illegal to do "blx pc", just useless. */
9555 if (inst.operands[0].reg == REG_PC)
9556 as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
b99bd4ef 9557
c19d1205
ZW
9558 inst.instruction |= inst.operands[0].reg;
9559 }
9560 else
b99bd4ef 9561 {
c19d1205 9562 /* Arg is an address; this instruction cannot be executed
267bf995
RR
9563 conditionally, and the opcode must be adjusted.
9564 We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
9565 where we generate out a BFD_RELOC_ARM_PCREL_CALL instead. */
c19d1205 9566 constraint (inst.cond != COND_ALWAYS, BAD_COND);
2fc8bdac 9567 inst.instruction = 0xfa000000;
267bf995 9568 encode_branch (BFD_RELOC_ARM_PCREL_BLX);
b99bd4ef 9569 }
c19d1205
ZW
9570}
9571
9572static void
9573do_bx (void)
9574{
5b7c81bd 9575 bool want_reloc;
845b51d6 9576
c19d1205
ZW
9577 if (inst.operands[0].reg == REG_PC)
9578 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
b99bd4ef 9579
c19d1205 9580 inst.instruction |= inst.operands[0].reg;
845b51d6
PB
9581 /* Output R_ARM_V4BX relocations if is an EABI object that looks like
9582 it is for ARMv4t or earlier. */
9583 want_reloc = !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5);
4d354d8b
TP
9584 if (!ARM_FEATURE_ZERO (selected_object_arch)
9585 && !ARM_CPU_HAS_FEATURE (selected_object_arch, arm_ext_v5))
5b7c81bd 9586 want_reloc = true;
845b51d6 9587
5ad34203 9588#ifdef OBJ_ELF
845b51d6 9589 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
5ad34203 9590#endif
5b7c81bd 9591 want_reloc = false;
845b51d6
PB
9592
9593 if (want_reloc)
e2b0ab59 9594 inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
09d92015
MM
9595}
9596
c19d1205
ZW
9597
9598/* ARM v5TEJ. Jump to Jazelle code. */
a737bd4d
NC
9599
9600static void
c19d1205 9601do_bxj (void)
a737bd4d 9602{
c19d1205
ZW
9603 if (inst.operands[0].reg == REG_PC)
9604 as_tsktsk (_("use of r15 in bxj is not really useful"));
9605
9606 inst.instruction |= inst.operands[0].reg;
a737bd4d
NC
9607}
9608
c19d1205
ZW
9609/* Co-processor data operation:
9610 CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
9611 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>} */
9612static void
9613do_cdp (void)
9614{
9615 inst.instruction |= inst.operands[0].reg << 8;
9616 inst.instruction |= inst.operands[1].imm << 20;
9617 inst.instruction |= inst.operands[2].reg << 12;
9618 inst.instruction |= inst.operands[3].reg << 16;
9619 inst.instruction |= inst.operands[4].reg;
9620 inst.instruction |= inst.operands[5].imm << 5;
9621}
a737bd4d
NC
9622
9623static void
c19d1205 9624do_cmp (void)
a737bd4d 9625{
c19d1205
ZW
9626 inst.instruction |= inst.operands[0].reg << 16;
9627 encode_arm_shifter_operand (1);
a737bd4d
NC
9628}
9629
c19d1205
ZW
9630/* Transfer between coprocessor and ARM registers.
9631 MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
9632 MRC2
9633 MCR{cond}
9634 MCR2
9635
9636 No special properties. */
09d92015 9637
dcbd0d71
MGD
9638struct deprecated_coproc_regs_s
9639{
9640 unsigned cp;
9641 int opc1;
9642 unsigned crn;
9643 unsigned crm;
9644 int opc2;
9645 arm_feature_set deprecated;
9646 arm_feature_set obsoleted;
9647 const char *dep_msg;
9648 const char *obs_msg;
9649};
9650
9651#define DEPR_ACCESS_V8 \
9652 N_("This coprocessor register access is deprecated in ARMv8")
9653
9654/* Table of all deprecated coprocessor registers. */
9655static struct deprecated_coproc_regs_s deprecated_coproc_regs[] =
9656{
9657 {15, 0, 7, 10, 5, /* CP15DMB. */
823d2571 9658 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9659 DEPR_ACCESS_V8, NULL},
9660 {15, 0, 7, 10, 4, /* CP15DSB. */
823d2571 9661 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9662 DEPR_ACCESS_V8, NULL},
9663 {15, 0, 7, 5, 4, /* CP15ISB. */
823d2571 9664 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9665 DEPR_ACCESS_V8, NULL},
9666 {14, 6, 1, 0, 0, /* TEEHBR. */
823d2571 9667 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9668 DEPR_ACCESS_V8, NULL},
9669 {14, 6, 0, 0, 0, /* TEECR. */
823d2571 9670 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9671 DEPR_ACCESS_V8, NULL},
9672};
9673
9674#undef DEPR_ACCESS_V8
9675
9676static const size_t deprecated_coproc_reg_count =
9677 sizeof (deprecated_coproc_regs) / sizeof (deprecated_coproc_regs[0]);
9678
09d92015 9679static void
c19d1205 9680do_co_reg (void)
09d92015 9681{
fdfde340 9682 unsigned Rd;
dcbd0d71 9683 size_t i;
fdfde340
JM
9684
9685 Rd = inst.operands[2].reg;
9686 if (thumb_mode)
9687 {
9688 if (inst.instruction == 0xee000010
9689 || inst.instruction == 0xfe000010)
9690 /* MCR, MCR2 */
9691 reject_bad_reg (Rd);
5c8ed6a4 9692 else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
fdfde340
JM
9693 /* MRC, MRC2 */
9694 constraint (Rd == REG_SP, BAD_SP);
9695 }
9696 else
9697 {
9698 /* MCR */
9699 if (inst.instruction == 0xe000010)
9700 constraint (Rd == REG_PC, BAD_PC);
9701 }
9702
dcbd0d71
MGD
9703 for (i = 0; i < deprecated_coproc_reg_count; ++i)
9704 {
9705 const struct deprecated_coproc_regs_s *r =
9706 deprecated_coproc_regs + i;
9707
9708 if (inst.operands[0].reg == r->cp
9709 && inst.operands[1].imm == r->opc1
9710 && inst.operands[3].reg == r->crn
9711 && inst.operands[4].reg == r->crm
9712 && inst.operands[5].imm == r->opc2)
9713 {
b10bf8c5 9714 if (! ARM_CPU_IS_ANY (cpu_variant)
477330fc 9715 && warn_on_deprecated
dcbd0d71 9716 && ARM_CPU_HAS_FEATURE (cpu_variant, r->deprecated))
5c3696f8 9717 as_tsktsk ("%s", r->dep_msg);
dcbd0d71
MGD
9718 }
9719 }
fdfde340 9720
c19d1205
ZW
9721 inst.instruction |= inst.operands[0].reg << 8;
9722 inst.instruction |= inst.operands[1].imm << 21;
fdfde340 9723 inst.instruction |= Rd << 12;
c19d1205
ZW
9724 inst.instruction |= inst.operands[3].reg << 16;
9725 inst.instruction |= inst.operands[4].reg;
9726 inst.instruction |= inst.operands[5].imm << 5;
9727}
09d92015 9728
c19d1205
ZW
9729/* Transfer between coprocessor register and pair of ARM registers.
9730 MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
9731 MCRR2
9732 MRRC{cond}
9733 MRRC2
b99bd4ef 9734
c19d1205 9735 Two XScale instructions are special cases of these:
09d92015 9736
c19d1205
ZW
9737 MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
9738 MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
b99bd4ef 9739
5f4273c7 9740 Result unpredictable if Rd or Rn is R15. */
a737bd4d 9741
c19d1205
ZW
9742static void
9743do_co_reg2c (void)
9744{
fdfde340
JM
9745 unsigned Rd, Rn;
9746
9747 Rd = inst.operands[2].reg;
9748 Rn = inst.operands[3].reg;
9749
9750 if (thumb_mode)
9751 {
9752 reject_bad_reg (Rd);
9753 reject_bad_reg (Rn);
9754 }
9755 else
9756 {
9757 constraint (Rd == REG_PC, BAD_PC);
9758 constraint (Rn == REG_PC, BAD_PC);
9759 }
9760
873f10f0
TC
9761 /* Only check the MRRC{2} variants. */
9762 if ((inst.instruction & 0x0FF00000) == 0x0C500000)
9763 {
9764 /* If Rd == Rn, error that the operation is
9765 unpredictable (example MRRC p3,#1,r1,r1,c4). */
9766 constraint (Rd == Rn, BAD_OVERLAP);
9767 }
9768
c19d1205
ZW
9769 inst.instruction |= inst.operands[0].reg << 8;
9770 inst.instruction |= inst.operands[1].imm << 4;
fdfde340
JM
9771 inst.instruction |= Rd << 12;
9772 inst.instruction |= Rn << 16;
c19d1205 9773 inst.instruction |= inst.operands[4].reg;
b99bd4ef
NC
9774}
9775
c19d1205
ZW
9776static void
9777do_cpsi (void)
9778{
9779 inst.instruction |= inst.operands[0].imm << 6;
a028a6f5
PB
9780 if (inst.operands[1].present)
9781 {
9782 inst.instruction |= CPSI_MMOD;
9783 inst.instruction |= inst.operands[1].imm;
9784 }
c19d1205 9785}
b99bd4ef 9786
62b3e311
PB
9787static void
9788do_dbg (void)
9789{
9790 inst.instruction |= inst.operands[0].imm;
9791}
9792
eea54501
MGD
9793static void
9794do_div (void)
9795{
9796 unsigned Rd, Rn, Rm;
9797
9798 Rd = inst.operands[0].reg;
9799 Rn = (inst.operands[1].present
9800 ? inst.operands[1].reg : Rd);
9801 Rm = inst.operands[2].reg;
9802
9803 constraint ((Rd == REG_PC), BAD_PC);
9804 constraint ((Rn == REG_PC), BAD_PC);
9805 constraint ((Rm == REG_PC), BAD_PC);
9806
9807 inst.instruction |= Rd << 16;
9808 inst.instruction |= Rn << 0;
9809 inst.instruction |= Rm << 8;
9810}
9811
b99bd4ef 9812static void
c19d1205 9813do_it (void)
b99bd4ef 9814{
c19d1205 9815 /* There is no IT instruction in ARM mode. We
e07e6e58
NC
9816 process it to do the validation as if in
9817 thumb mode, just in case the code gets
9818 assembled for thumb using the unified syntax. */
9819
c19d1205 9820 inst.size = 0;
e07e6e58
NC
9821 if (unified_syntax)
9822 {
5ee91343
AV
9823 set_pred_insn_type (IT_INSN);
9824 now_pred.mask = (inst.instruction & 0xf) | 0x10;
9825 now_pred.cc = inst.operands[0].imm;
e07e6e58 9826 }
09d92015 9827}
b99bd4ef 9828
6530b175
NC
9829/* If there is only one register in the register list,
9830 then return its register number. Otherwise return -1. */
9831static int
9832only_one_reg_in_list (int range)
9833{
9834 int i = ffs (range) - 1;
9835 return (i > 15 || range != (1 << i)) ? -1 : i;
9836}
9837
09d92015 9838static void
6530b175 9839encode_ldmstm(int from_push_pop_mnem)
ea6ef066 9840{
c19d1205
ZW
9841 int base_reg = inst.operands[0].reg;
9842 int range = inst.operands[1].imm;
6530b175 9843 int one_reg;
ea6ef066 9844
c19d1205
ZW
9845 inst.instruction |= base_reg << 16;
9846 inst.instruction |= range;
ea6ef066 9847
c19d1205
ZW
9848 if (inst.operands[1].writeback)
9849 inst.instruction |= LDM_TYPE_2_OR_3;
09d92015 9850
c19d1205 9851 if (inst.operands[0].writeback)
ea6ef066 9852 {
c19d1205
ZW
9853 inst.instruction |= WRITE_BACK;
9854 /* Check for unpredictable uses of writeback. */
9855 if (inst.instruction & LOAD_BIT)
09d92015 9856 {
c19d1205
ZW
9857 /* Not allowed in LDM type 2. */
9858 if ((inst.instruction & LDM_TYPE_2_OR_3)
9859 && ((range & (1 << REG_PC)) == 0))
9860 as_warn (_("writeback of base register is UNPREDICTABLE"));
9861 /* Only allowed if base reg not in list for other types. */
9862 else if (range & (1 << base_reg))
9863 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
9864 }
9865 else /* STM. */
9866 {
9867 /* Not allowed for type 2. */
9868 if (inst.instruction & LDM_TYPE_2_OR_3)
9869 as_warn (_("writeback of base register is UNPREDICTABLE"));
9870 /* Only allowed if base reg not in list, or first in list. */
9871 else if ((range & (1 << base_reg))
9872 && (range & ((1 << base_reg) - 1)))
9873 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
09d92015 9874 }
ea6ef066 9875 }
6530b175
NC
9876
9877 /* If PUSH/POP has only one register, then use the A2 encoding. */
9878 one_reg = only_one_reg_in_list (range);
9879 if (from_push_pop_mnem && one_reg >= 0)
9880 {
9881 int is_push = (inst.instruction & A_PUSH_POP_OP_MASK) == A1_OPCODE_PUSH;
9882
4f588891
NC
9883 if (is_push && one_reg == 13 /* SP */)
9884 /* PR 22483: The A2 encoding cannot be used when
9885 pushing the stack pointer as this is UNPREDICTABLE. */
9886 return;
9887
6530b175
NC
9888 inst.instruction &= A_COND_MASK;
9889 inst.instruction |= is_push ? A2_OPCODE_PUSH : A2_OPCODE_POP;
9890 inst.instruction |= one_reg << 12;
9891 }
9892}
9893
9894static void
9895do_ldmstm (void)
9896{
5b7c81bd 9897 encode_ldmstm (/*from_push_pop_mnem=*/false);
a737bd4d
NC
9898}
9899
c19d1205
ZW
9900/* ARMv5TE load-consecutive (argument parse)
9901 Mode is like LDRH.
9902
9903 LDRccD R, mode
9904 STRccD R, mode. */
9905
a737bd4d 9906static void
c19d1205 9907do_ldrd (void)
a737bd4d 9908{
c19d1205 9909 constraint (inst.operands[0].reg % 2 != 0,
c56791bb 9910 _("first transfer register must be even"));
c19d1205
ZW
9911 constraint (inst.operands[1].present
9912 && inst.operands[1].reg != inst.operands[0].reg + 1,
c56791bb 9913 _("can only transfer two consecutive registers"));
c19d1205
ZW
9914 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
9915 constraint (!inst.operands[2].isreg, _("'[' expected"));
a737bd4d 9916
c19d1205
ZW
9917 if (!inst.operands[1].present)
9918 inst.operands[1].reg = inst.operands[0].reg + 1;
5f4273c7 9919
c56791bb
RE
9920 /* encode_arm_addr_mode_3 will diagnose overlap between the base
9921 register and the first register written; we have to diagnose
9922 overlap between the base and the second register written here. */
ea6ef066 9923
c56791bb
RE
9924 if (inst.operands[2].reg == inst.operands[1].reg
9925 && (inst.operands[2].writeback || inst.operands[2].postind))
9926 as_warn (_("base register written back, and overlaps "
9927 "second transfer register"));
b05fe5cf 9928
c56791bb
RE
9929 if (!(inst.instruction & V4_STR_BIT))
9930 {
c19d1205 9931 /* For an index-register load, the index register must not overlap the
c56791bb
RE
9932 destination (even if not write-back). */
9933 if (inst.operands[2].immisreg
9934 && ((unsigned) inst.operands[2].imm == inst.operands[0].reg
9935 || (unsigned) inst.operands[2].imm == inst.operands[1].reg))
9936 as_warn (_("index register overlaps transfer register"));
b05fe5cf 9937 }
c19d1205 9938 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 9939 encode_arm_addr_mode_3 (2, /*is_t=*/false);
b05fe5cf
ZW
9940}
9941
9942static void
c19d1205 9943do_ldrex (void)
b05fe5cf 9944{
c19d1205
ZW
9945 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
9946 || inst.operands[1].postind || inst.operands[1].writeback
9947 || inst.operands[1].immisreg || inst.operands[1].shifted
01cfc07f
NC
9948 || inst.operands[1].negative
9949 /* This can arise if the programmer has written
9950 strex rN, rM, foo
9951 or if they have mistakenly used a register name as the last
9952 operand, eg:
9953 strex rN, rM, rX
9954 It is very difficult to distinguish between these two cases
9955 because "rX" might actually be a label. ie the register
9956 name has been occluded by a symbol of the same name. So we
9957 just generate a general 'bad addressing mode' type error
9958 message and leave it up to the programmer to discover the
9959 true cause and fix their mistake. */
9960 || (inst.operands[1].reg == REG_PC),
9961 BAD_ADDR_MODE);
b05fe5cf 9962
e2b0ab59
AV
9963 constraint (inst.relocs[0].exp.X_op != O_constant
9964 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9965 _("offset must be zero in ARM encoding"));
b05fe5cf 9966
5be8be5d
DG
9967 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
9968
c19d1205
ZW
9969 inst.instruction |= inst.operands[0].reg << 12;
9970 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 9971 inst.relocs[0].type = BFD_RELOC_UNUSED;
b05fe5cf
ZW
9972}
9973
9974static void
c19d1205 9975do_ldrexd (void)
b05fe5cf 9976{
c19d1205
ZW
9977 constraint (inst.operands[0].reg % 2 != 0,
9978 _("even register required"));
9979 constraint (inst.operands[1].present
9980 && inst.operands[1].reg != inst.operands[0].reg + 1,
9981 _("can only load two consecutive registers"));
9982 /* If op 1 were present and equal to PC, this function wouldn't
9983 have been called in the first place. */
9984 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
b05fe5cf 9985
c19d1205
ZW
9986 inst.instruction |= inst.operands[0].reg << 12;
9987 inst.instruction |= inst.operands[2].reg << 16;
b05fe5cf
ZW
9988}
9989
1be5fd2e
NC
9990/* In both ARM and thumb state 'ldr pc, #imm' with an immediate
9991 which is not a multiple of four is UNPREDICTABLE. */
9992static void
9993check_ldr_r15_aligned (void)
9994{
9995 constraint (!(inst.operands[1].immisreg)
9996 && (inst.operands[0].reg == REG_PC
9997 && inst.operands[1].reg == REG_PC
e2b0ab59 9998 && (inst.relocs[0].exp.X_add_number & 0x3)),
de194d85 9999 _("ldr to register 15 must be 4-byte aligned"));
1be5fd2e
NC
10000}
10001
b05fe5cf 10002static void
c19d1205 10003do_ldst (void)
b05fe5cf 10004{
c19d1205
ZW
10005 inst.instruction |= inst.operands[0].reg << 12;
10006 if (!inst.operands[1].isreg)
5b7c81bd 10007 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/false))
b05fe5cf 10008 return;
5b7c81bd 10009 encode_arm_addr_mode_2 (1, /*is_t=*/false);
1be5fd2e 10010 check_ldr_r15_aligned ();
b05fe5cf
ZW
10011}
10012
10013static void
c19d1205 10014do_ldstt (void)
b05fe5cf 10015{
c19d1205
ZW
10016 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
10017 reject [Rn,...]. */
10018 if (inst.operands[1].preind)
b05fe5cf 10019 {
e2b0ab59
AV
10020 constraint (inst.relocs[0].exp.X_op != O_constant
10021 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10022 _("this instruction requires a post-indexed address"));
b05fe5cf 10023
c19d1205
ZW
10024 inst.operands[1].preind = 0;
10025 inst.operands[1].postind = 1;
10026 inst.operands[1].writeback = 1;
b05fe5cf 10027 }
c19d1205 10028 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 10029 encode_arm_addr_mode_2 (1, /*is_t=*/true);
c19d1205 10030}
b05fe5cf 10031
c19d1205 10032/* Halfword and signed-byte load/store operations. */
b05fe5cf 10033
c19d1205
ZW
10034static void
10035do_ldstv4 (void)
10036{
ff4a8d2b 10037 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205
ZW
10038 inst.instruction |= inst.operands[0].reg << 12;
10039 if (!inst.operands[1].isreg)
5b7c81bd 10040 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/true))
b05fe5cf 10041 return;
5b7c81bd 10042 encode_arm_addr_mode_3 (1, /*is_t=*/false);
b05fe5cf
ZW
10043}
10044
10045static void
c19d1205 10046do_ldsttv4 (void)
b05fe5cf 10047{
c19d1205
ZW
10048 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
10049 reject [Rn,...]. */
10050 if (inst.operands[1].preind)
b05fe5cf 10051 {
e2b0ab59
AV
10052 constraint (inst.relocs[0].exp.X_op != O_constant
10053 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10054 _("this instruction requires a post-indexed address"));
b05fe5cf 10055
c19d1205
ZW
10056 inst.operands[1].preind = 0;
10057 inst.operands[1].postind = 1;
10058 inst.operands[1].writeback = 1;
b05fe5cf 10059 }
c19d1205 10060 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 10061 encode_arm_addr_mode_3 (1, /*is_t=*/true);
c19d1205 10062}
b05fe5cf 10063
c19d1205
ZW
10064/* Co-processor register load/store.
10065 Format: <LDC|STC>{cond}[L] CP#,CRd,<address> */
10066static void
10067do_lstc (void)
10068{
10069 inst.instruction |= inst.operands[0].reg << 8;
10070 inst.instruction |= inst.operands[1].reg << 12;
5b7c81bd 10071 encode_arm_cp_address (2, true, true, 0);
b05fe5cf
ZW
10072}
10073
b05fe5cf 10074static void
c19d1205 10075do_mlas (void)
b05fe5cf 10076{
8fb9d7b9 10077 /* This restriction does not apply to mls (nor to mla in v6 or later). */
c19d1205 10078 if (inst.operands[0].reg == inst.operands[1].reg
8fb9d7b9 10079 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6)
c19d1205 10080 && !(inst.instruction & 0x00400000))
8fb9d7b9 10081 as_tsktsk (_("Rd and Rm should be different in mla"));
b05fe5cf 10082
c19d1205
ZW
10083 inst.instruction |= inst.operands[0].reg << 16;
10084 inst.instruction |= inst.operands[1].reg;
10085 inst.instruction |= inst.operands[2].reg << 8;
10086 inst.instruction |= inst.operands[3].reg << 12;
c19d1205 10087}
b05fe5cf 10088
c19d1205
ZW
10089static void
10090do_mov (void)
10091{
e2b0ab59
AV
10092 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
10093 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 10094 THUMB1_RELOC_ONLY);
c19d1205
ZW
10095 inst.instruction |= inst.operands[0].reg << 12;
10096 encode_arm_shifter_operand (1);
10097}
b05fe5cf 10098
c19d1205
ZW
10099/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
10100static void
10101do_mov16 (void)
10102{
b6895b4f 10103 bfd_vma imm;
5b7c81bd 10104 bool top;
b6895b4f
PB
10105
10106 top = (inst.instruction & 0x00400000) != 0;
e2b0ab59 10107 constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
33eaf5de 10108 _(":lower16: not allowed in this instruction"));
e2b0ab59 10109 constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
33eaf5de 10110 _(":upper16: not allowed in this instruction"));
c19d1205 10111 inst.instruction |= inst.operands[0].reg << 12;
e2b0ab59 10112 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 10113 {
e2b0ab59 10114 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
10115 /* The value is in two pieces: 0:11, 16:19. */
10116 inst.instruction |= (imm & 0x00000fff);
10117 inst.instruction |= (imm & 0x0000f000) << 4;
10118 }
b05fe5cf 10119}
b99bd4ef 10120
037e8744
JB
10121static int
10122do_vfp_nsyn_mrs (void)
10123{
10124 if (inst.operands[0].isvec)
10125 {
10126 if (inst.operands[1].reg != 1)
477330fc 10127 first_error (_("operand 1 must be FPSCR"));
037e8744
JB
10128 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
10129 memset (&inst.operands[1], '\0', sizeof (inst.operands[1]));
10130 do_vfp_nsyn_opcode ("fmstat");
10131 }
10132 else if (inst.operands[1].isvec)
10133 do_vfp_nsyn_opcode ("fmrx");
10134 else
10135 return FAIL;
5f4273c7 10136
037e8744
JB
10137 return SUCCESS;
10138}
10139
10140static int
10141do_vfp_nsyn_msr (void)
10142{
10143 if (inst.operands[0].isvec)
10144 do_vfp_nsyn_opcode ("fmxr");
10145 else
10146 return FAIL;
10147
10148 return SUCCESS;
10149}
10150
f7c21dc7
NC
10151static void
10152do_vmrs (void)
10153{
10154 unsigned Rt = inst.operands[0].reg;
fa94de6b 10155
16d02dc9 10156 if (thumb_mode && Rt == REG_SP)
f7c21dc7
NC
10157 {
10158 inst.error = BAD_SP;
10159 return;
10160 }
10161
ba6cd17f
SD
10162 switch (inst.operands[1].reg)
10163 {
10164 /* MVFR2 is only valid for Armv8-A. */
10165 case 5:
10166 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
10167 _(BAD_FPU));
10168 break;
10169
10170 /* Check for new Armv8.1-M Mainline changes to <spec_reg>. */
10171 case 1: /* fpscr. */
10172 constraint (!(ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10173 || ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10174 _(BAD_FPU));
10175 break;
10176
ee3272d4
SP
10177 case 14: /* fpcxt_ns, fpcxtns, FPCXT_NS, FPCXTNS. */
10178 case 15: /* fpcxt_s, fpcxts, FPCXT_S, FPCXTS. */
ba6cd17f
SD
10179 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main),
10180 _("selected processor does not support instruction"));
10181 break;
10182
10183 case 2: /* fpscr_nzcvqc. */
10184 case 12: /* vpr. */
10185 case 13: /* p0. */
10186 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main)
10187 || (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10188 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10189 _("selected processor does not support instruction"));
10190 if (inst.operands[0].reg != 2
10191 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
10192 as_warn (_("accessing MVE system register without MVE is UNPREDICTABLE"));
10193 break;
10194
10195 default:
10196 break;
10197 }
40c7d507 10198
f7c21dc7 10199 /* APSR_ sets isvec. All other refs to PC are illegal. */
16d02dc9 10200 if (!inst.operands[0].isvec && Rt == REG_PC)
f7c21dc7
NC
10201 {
10202 inst.error = BAD_PC;
10203 return;
10204 }
10205
16d02dc9
JB
10206 /* If we get through parsing the register name, we just insert the number
10207 generated into the instruction without further validation. */
10208 inst.instruction |= (inst.operands[1].reg << 16);
f7c21dc7
NC
10209 inst.instruction |= (Rt << 12);
10210}
10211
10212static void
10213do_vmsr (void)
10214{
10215 unsigned Rt = inst.operands[1].reg;
fa94de6b 10216
f7c21dc7
NC
10217 if (thumb_mode)
10218 reject_bad_reg (Rt);
10219 else if (Rt == REG_PC)
10220 {
10221 inst.error = BAD_PC;
10222 return;
10223 }
10224
ba6cd17f
SD
10225 switch (inst.operands[0].reg)
10226 {
10227 /* MVFR2 is only valid for Armv8-A. */
10228 case 5:
10229 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
10230 _(BAD_FPU));
10231 break;
10232
10233 /* Check for new Armv8.1-M Mainline changes to <spec_reg>. */
10234 case 1: /* fpcr. */
10235 constraint (!(ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10236 || ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10237 _(BAD_FPU));
10238 break;
10239
10240 case 14: /* fpcxt_ns. */
10241 case 15: /* fpcxt_s. */
10242 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main),
10243 _("selected processor does not support instruction"));
10244 break;
10245
10246 case 2: /* fpscr_nzcvqc. */
10247 case 12: /* vpr. */
10248 case 13: /* p0. */
10249 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main)
10250 || (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10251 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10252 _("selected processor does not support instruction"));
10253 if (inst.operands[0].reg != 2
10254 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
10255 as_warn (_("accessing MVE system register without MVE is UNPREDICTABLE"));
10256 break;
10257
10258 default:
10259 break;
10260 }
40c7d507 10261
16d02dc9
JB
10262 /* If we get through parsing the register name, we just insert the number
10263 generated into the instruction without further validation. */
10264 inst.instruction |= (inst.operands[0].reg << 16);
f7c21dc7
NC
10265 inst.instruction |= (Rt << 12);
10266}
10267
b99bd4ef 10268static void
c19d1205 10269do_mrs (void)
b99bd4ef 10270{
90ec0d68
MGD
10271 unsigned br;
10272
037e8744
JB
10273 if (do_vfp_nsyn_mrs () == SUCCESS)
10274 return;
10275
ff4a8d2b 10276 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205 10277 inst.instruction |= inst.operands[0].reg << 12;
90ec0d68
MGD
10278
10279 if (inst.operands[1].isreg)
10280 {
10281 br = inst.operands[1].reg;
806ab1c0 10282 if (((br & 0x200) == 0) && ((br & 0xf0000) != 0xf0000))
90ec0d68
MGD
10283 as_bad (_("bad register for mrs"));
10284 }
10285 else
10286 {
10287 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
10288 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
10289 != (PSR_c|PSR_f),
d2cd1205 10290 _("'APSR', 'CPSR' or 'SPSR' expected"));
90ec0d68
MGD
10291 br = (15<<16) | (inst.operands[1].imm & SPSR_BIT);
10292 }
10293
10294 inst.instruction |= br;
c19d1205 10295}
b99bd4ef 10296
c19d1205
ZW
10297/* Two possible forms:
10298 "{C|S}PSR_<field>, Rm",
10299 "{C|S}PSR_f, #expression". */
b99bd4ef 10300
c19d1205
ZW
10301static void
10302do_msr (void)
10303{
037e8744
JB
10304 if (do_vfp_nsyn_msr () == SUCCESS)
10305 return;
10306
c19d1205
ZW
10307 inst.instruction |= inst.operands[0].imm;
10308 if (inst.operands[1].isreg)
10309 inst.instruction |= inst.operands[1].reg;
10310 else
b99bd4ef 10311 {
c19d1205 10312 inst.instruction |= INST_IMMEDIATE;
e2b0ab59
AV
10313 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
10314 inst.relocs[0].pc_rel = 0;
b99bd4ef 10315 }
b99bd4ef
NC
10316}
10317
c19d1205
ZW
10318static void
10319do_mul (void)
a737bd4d 10320{
ff4a8d2b
NC
10321 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
10322
c19d1205
ZW
10323 if (!inst.operands[2].present)
10324 inst.operands[2].reg = inst.operands[0].reg;
10325 inst.instruction |= inst.operands[0].reg << 16;
10326 inst.instruction |= inst.operands[1].reg;
10327 inst.instruction |= inst.operands[2].reg << 8;
a737bd4d 10328
8fb9d7b9
MS
10329 if (inst.operands[0].reg == inst.operands[1].reg
10330 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
10331 as_tsktsk (_("Rd and Rm should be different in mul"));
a737bd4d
NC
10332}
10333
c19d1205
ZW
10334/* Long Multiply Parser
10335 UMULL RdLo, RdHi, Rm, Rs
10336 SMULL RdLo, RdHi, Rm, Rs
10337 UMLAL RdLo, RdHi, Rm, Rs
10338 SMLAL RdLo, RdHi, Rm, Rs. */
b99bd4ef
NC
10339
10340static void
c19d1205 10341do_mull (void)
b99bd4ef 10342{
c19d1205
ZW
10343 inst.instruction |= inst.operands[0].reg << 12;
10344 inst.instruction |= inst.operands[1].reg << 16;
10345 inst.instruction |= inst.operands[2].reg;
10346 inst.instruction |= inst.operands[3].reg << 8;
b99bd4ef 10347
682b27ad
PB
10348 /* rdhi and rdlo must be different. */
10349 if (inst.operands[0].reg == inst.operands[1].reg)
10350 as_tsktsk (_("rdhi and rdlo must be different"));
10351
10352 /* rdhi, rdlo and rm must all be different before armv6. */
10353 if ((inst.operands[0].reg == inst.operands[2].reg
c19d1205 10354 || inst.operands[1].reg == inst.operands[2].reg)
682b27ad 10355 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
c19d1205
ZW
10356 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
10357}
b99bd4ef 10358
c19d1205
ZW
10359static void
10360do_nop (void)
10361{
e7495e45
NS
10362 if (inst.operands[0].present
10363 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k))
c19d1205
ZW
10364 {
10365 /* Architectural NOP hints are CPSR sets with no bits selected. */
10366 inst.instruction &= 0xf0000000;
e7495e45
NS
10367 inst.instruction |= 0x0320f000;
10368 if (inst.operands[0].present)
10369 inst.instruction |= inst.operands[0].imm;
c19d1205 10370 }
b99bd4ef
NC
10371}
10372
c19d1205
ZW
10373/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
10374 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
10375 Condition defaults to COND_ALWAYS.
10376 Error if Rd, Rn or Rm are R15. */
b99bd4ef
NC
10377
10378static void
c19d1205 10379do_pkhbt (void)
b99bd4ef 10380{
c19d1205
ZW
10381 inst.instruction |= inst.operands[0].reg << 12;
10382 inst.instruction |= inst.operands[1].reg << 16;
10383 inst.instruction |= inst.operands[2].reg;
10384 if (inst.operands[3].present)
10385 encode_arm_shift (3);
10386}
b99bd4ef 10387
c19d1205 10388/* ARM V6 PKHTB (Argument Parse). */
b99bd4ef 10389
c19d1205
ZW
10390static void
10391do_pkhtb (void)
10392{
10393 if (!inst.operands[3].present)
b99bd4ef 10394 {
c19d1205
ZW
10395 /* If the shift specifier is omitted, turn the instruction
10396 into pkhbt rd, rm, rn. */
10397 inst.instruction &= 0xfff00010;
10398 inst.instruction |= inst.operands[0].reg << 12;
10399 inst.instruction |= inst.operands[1].reg;
10400 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
10401 }
10402 else
10403 {
c19d1205
ZW
10404 inst.instruction |= inst.operands[0].reg << 12;
10405 inst.instruction |= inst.operands[1].reg << 16;
10406 inst.instruction |= inst.operands[2].reg;
10407 encode_arm_shift (3);
b99bd4ef
NC
10408 }
10409}
10410
c19d1205 10411/* ARMv5TE: Preload-Cache
60e5ef9f 10412 MP Extensions: Preload for write
c19d1205 10413
60e5ef9f 10414 PLD(W) <addr_mode>
c19d1205
ZW
10415
10416 Syntactically, like LDR with B=1, W=0, L=1. */
b99bd4ef
NC
10417
10418static void
c19d1205 10419do_pld (void)
b99bd4ef 10420{
c19d1205
ZW
10421 constraint (!inst.operands[0].isreg,
10422 _("'[' expected after PLD mnemonic"));
10423 constraint (inst.operands[0].postind,
10424 _("post-indexed expression used in preload instruction"));
10425 constraint (inst.operands[0].writeback,
10426 _("writeback used in preload instruction"));
10427 constraint (!inst.operands[0].preind,
10428 _("unindexed addressing used in preload instruction"));
5b7c81bd 10429 encode_arm_addr_mode_2 (0, /*is_t=*/false);
c19d1205 10430}
b99bd4ef 10431
62b3e311
PB
10432/* ARMv7: PLI <addr_mode> */
10433static void
10434do_pli (void)
10435{
10436 constraint (!inst.operands[0].isreg,
10437 _("'[' expected after PLI mnemonic"));
10438 constraint (inst.operands[0].postind,
10439 _("post-indexed expression used in preload instruction"));
10440 constraint (inst.operands[0].writeback,
10441 _("writeback used in preload instruction"));
10442 constraint (!inst.operands[0].preind,
10443 _("unindexed addressing used in preload instruction"));
5b7c81bd 10444 encode_arm_addr_mode_2 (0, /*is_t=*/false);
62b3e311
PB
10445 inst.instruction &= ~PRE_INDEX;
10446}
10447
c19d1205
ZW
10448static void
10449do_push_pop (void)
10450{
5e0d7f77
MP
10451 constraint (inst.operands[0].writeback,
10452 _("push/pop do not support {reglist}^"));
c19d1205
ZW
10453 inst.operands[1] = inst.operands[0];
10454 memset (&inst.operands[0], 0, sizeof inst.operands[0]);
10455 inst.operands[0].isreg = 1;
10456 inst.operands[0].writeback = 1;
10457 inst.operands[0].reg = REG_SP;
5b7c81bd 10458 encode_ldmstm (/*from_push_pop_mnem=*/true);
c19d1205 10459}
b99bd4ef 10460
c19d1205
ZW
10461/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
10462 word at the specified address and the following word
10463 respectively.
10464 Unconditionally executed.
10465 Error if Rn is R15. */
b99bd4ef 10466
c19d1205
ZW
10467static void
10468do_rfe (void)
10469{
10470 inst.instruction |= inst.operands[0].reg << 16;
10471 if (inst.operands[0].writeback)
10472 inst.instruction |= WRITE_BACK;
10473}
b99bd4ef 10474
c19d1205 10475/* ARM V6 ssat (argument parse). */
b99bd4ef 10476
c19d1205
ZW
10477static void
10478do_ssat (void)
10479{
10480 inst.instruction |= inst.operands[0].reg << 12;
10481 inst.instruction |= (inst.operands[1].imm - 1) << 16;
10482 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10483
c19d1205
ZW
10484 if (inst.operands[3].present)
10485 encode_arm_shift (3);
b99bd4ef
NC
10486}
10487
c19d1205 10488/* ARM V6 usat (argument parse). */
b99bd4ef
NC
10489
10490static void
c19d1205 10491do_usat (void)
b99bd4ef 10492{
c19d1205
ZW
10493 inst.instruction |= inst.operands[0].reg << 12;
10494 inst.instruction |= inst.operands[1].imm << 16;
10495 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10496
c19d1205
ZW
10497 if (inst.operands[3].present)
10498 encode_arm_shift (3);
b99bd4ef
NC
10499}
10500
c19d1205 10501/* ARM V6 ssat16 (argument parse). */
09d92015
MM
10502
10503static void
c19d1205 10504do_ssat16 (void)
09d92015 10505{
c19d1205
ZW
10506 inst.instruction |= inst.operands[0].reg << 12;
10507 inst.instruction |= ((inst.operands[1].imm - 1) << 16);
10508 inst.instruction |= inst.operands[2].reg;
09d92015
MM
10509}
10510
c19d1205
ZW
10511static void
10512do_usat16 (void)
a737bd4d 10513{
c19d1205
ZW
10514 inst.instruction |= inst.operands[0].reg << 12;
10515 inst.instruction |= inst.operands[1].imm << 16;
10516 inst.instruction |= inst.operands[2].reg;
10517}
a737bd4d 10518
c19d1205
ZW
10519/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
10520 preserving the other bits.
a737bd4d 10521
c19d1205
ZW
10522 setend <endian_specifier>, where <endian_specifier> is either
10523 BE or LE. */
a737bd4d 10524
c19d1205
ZW
10525static void
10526do_setend (void)
10527{
12e37cbc
MGD
10528 if (warn_on_deprecated
10529 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 10530 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 10531
c19d1205
ZW
10532 if (inst.operands[0].imm)
10533 inst.instruction |= 0x200;
a737bd4d
NC
10534}
10535
10536static void
c19d1205 10537do_shift (void)
a737bd4d 10538{
c19d1205
ZW
10539 unsigned int Rm = (inst.operands[1].present
10540 ? inst.operands[1].reg
10541 : inst.operands[0].reg);
a737bd4d 10542
c19d1205
ZW
10543 inst.instruction |= inst.operands[0].reg << 12;
10544 inst.instruction |= Rm;
10545 if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
a737bd4d 10546 {
c19d1205
ZW
10547 inst.instruction |= inst.operands[2].reg << 8;
10548 inst.instruction |= SHIFT_BY_REG;
94342ec3
NC
10549 /* PR 12854: Error on extraneous shifts. */
10550 constraint (inst.operands[2].shifted,
10551 _("extraneous shift as part of operand to shift insn"));
a737bd4d
NC
10552 }
10553 else
e2b0ab59 10554 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
a737bd4d
NC
10555}
10556
09d92015 10557static void
3eb17e6b 10558do_smc (void)
09d92015 10559{
ba85f98c
BW
10560 unsigned int value = inst.relocs[0].exp.X_add_number;
10561 constraint (value > 0xf, _("immediate too large (bigger than 0xF)"));
10562
e2b0ab59
AV
10563 inst.relocs[0].type = BFD_RELOC_ARM_SMC;
10564 inst.relocs[0].pc_rel = 0;
09d92015
MM
10565}
10566
90ec0d68
MGD
10567static void
10568do_hvc (void)
10569{
e2b0ab59
AV
10570 inst.relocs[0].type = BFD_RELOC_ARM_HVC;
10571 inst.relocs[0].pc_rel = 0;
90ec0d68
MGD
10572}
10573
09d92015 10574static void
c19d1205 10575do_swi (void)
09d92015 10576{
e2b0ab59
AV
10577 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
10578 inst.relocs[0].pc_rel = 0;
09d92015
MM
10579}
10580
ddfded2f
MW
10581static void
10582do_setpan (void)
10583{
10584 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10585 _("selected processor does not support SETPAN instruction"));
10586
10587 inst.instruction |= ((inst.operands[0].imm & 1) << 9);
10588}
10589
10590static void
10591do_t_setpan (void)
10592{
10593 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10594 _("selected processor does not support SETPAN instruction"));
10595
10596 inst.instruction |= (inst.operands[0].imm << 3);
10597}
10598
c19d1205
ZW
10599/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
10600 SMLAxy{cond} Rd,Rm,Rs,Rn
10601 SMLAWy{cond} Rd,Rm,Rs,Rn
10602 Error if any register is R15. */
e16bb312 10603
c19d1205
ZW
10604static void
10605do_smla (void)
e16bb312 10606{
c19d1205
ZW
10607 inst.instruction |= inst.operands[0].reg << 16;
10608 inst.instruction |= inst.operands[1].reg;
10609 inst.instruction |= inst.operands[2].reg << 8;
10610 inst.instruction |= inst.operands[3].reg << 12;
10611}
a737bd4d 10612
c19d1205
ZW
10613/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
10614 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
10615 Error if any register is R15.
10616 Warning if Rdlo == Rdhi. */
a737bd4d 10617
c19d1205
ZW
10618static void
10619do_smlal (void)
10620{
10621 inst.instruction |= inst.operands[0].reg << 12;
10622 inst.instruction |= inst.operands[1].reg << 16;
10623 inst.instruction |= inst.operands[2].reg;
10624 inst.instruction |= inst.operands[3].reg << 8;
a737bd4d 10625
c19d1205
ZW
10626 if (inst.operands[0].reg == inst.operands[1].reg)
10627 as_tsktsk (_("rdhi and rdlo must be different"));
10628}
a737bd4d 10629
c19d1205
ZW
10630/* ARM V5E (El Segundo) signed-multiply (argument parse)
10631 SMULxy{cond} Rd,Rm,Rs
10632 Error if any register is R15. */
a737bd4d 10633
c19d1205
ZW
10634static void
10635do_smul (void)
10636{
10637 inst.instruction |= inst.operands[0].reg << 16;
10638 inst.instruction |= inst.operands[1].reg;
10639 inst.instruction |= inst.operands[2].reg << 8;
10640}
a737bd4d 10641
b6702015
PB
10642/* ARM V6 srs (argument parse). The variable fields in the encoding are
10643 the same for both ARM and Thumb-2. */
a737bd4d 10644
c19d1205
ZW
10645static void
10646do_srs (void)
10647{
b6702015
PB
10648 int reg;
10649
10650 if (inst.operands[0].present)
10651 {
10652 reg = inst.operands[0].reg;
fdfde340 10653 constraint (reg != REG_SP, _("SRS base register must be r13"));
b6702015
PB
10654 }
10655 else
fdfde340 10656 reg = REG_SP;
b6702015
PB
10657
10658 inst.instruction |= reg << 16;
10659 inst.instruction |= inst.operands[1].imm;
10660 if (inst.operands[0].writeback || inst.operands[1].writeback)
c19d1205
ZW
10661 inst.instruction |= WRITE_BACK;
10662}
a737bd4d 10663
c19d1205 10664/* ARM V6 strex (argument parse). */
a737bd4d 10665
c19d1205
ZW
10666static void
10667do_strex (void)
10668{
10669 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10670 || inst.operands[2].postind || inst.operands[2].writeback
10671 || inst.operands[2].immisreg || inst.operands[2].shifted
01cfc07f
NC
10672 || inst.operands[2].negative
10673 /* See comment in do_ldrex(). */
10674 || (inst.operands[2].reg == REG_PC),
10675 BAD_ADDR_MODE);
a737bd4d 10676
c19d1205
ZW
10677 constraint (inst.operands[0].reg == inst.operands[1].reg
10678 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
a737bd4d 10679
e2b0ab59
AV
10680 constraint (inst.relocs[0].exp.X_op != O_constant
10681 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10682 _("offset must be zero in ARM encoding"));
a737bd4d 10683
c19d1205
ZW
10684 inst.instruction |= inst.operands[0].reg << 12;
10685 inst.instruction |= inst.operands[1].reg;
10686 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 10687 inst.relocs[0].type = BFD_RELOC_UNUSED;
e16bb312
NC
10688}
10689
877807f8
NC
10690static void
10691do_t_strexbh (void)
10692{
10693 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10694 || inst.operands[2].postind || inst.operands[2].writeback
10695 || inst.operands[2].immisreg || inst.operands[2].shifted
10696 || inst.operands[2].negative,
10697 BAD_ADDR_MODE);
10698
10699 constraint (inst.operands[0].reg == inst.operands[1].reg
10700 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10701
10702 do_rm_rd_rn ();
10703}
10704
e16bb312 10705static void
c19d1205 10706do_strexd (void)
e16bb312 10707{
c19d1205
ZW
10708 constraint (inst.operands[1].reg % 2 != 0,
10709 _("even register required"));
10710 constraint (inst.operands[2].present
10711 && inst.operands[2].reg != inst.operands[1].reg + 1,
10712 _("can only store two consecutive registers"));
10713 /* If op 2 were present and equal to PC, this function wouldn't
10714 have been called in the first place. */
10715 constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
e16bb312 10716
c19d1205
ZW
10717 constraint (inst.operands[0].reg == inst.operands[1].reg
10718 || inst.operands[0].reg == inst.operands[1].reg + 1
10719 || inst.operands[0].reg == inst.operands[3].reg,
10720 BAD_OVERLAP);
e16bb312 10721
c19d1205
ZW
10722 inst.instruction |= inst.operands[0].reg << 12;
10723 inst.instruction |= inst.operands[1].reg;
10724 inst.instruction |= inst.operands[3].reg << 16;
e16bb312
NC
10725}
10726
9eb6c0f1
MGD
10727/* ARM V8 STRL. */
10728static void
4b8c8c02 10729do_stlex (void)
9eb6c0f1
MGD
10730{
10731 constraint (inst.operands[0].reg == inst.operands[1].reg
10732 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10733
10734 do_rd_rm_rn ();
10735}
10736
10737static void
4b8c8c02 10738do_t_stlex (void)
9eb6c0f1
MGD
10739{
10740 constraint (inst.operands[0].reg == inst.operands[1].reg
10741 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10742
10743 do_rm_rd_rn ();
10744}
10745
c19d1205
ZW
10746/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
10747 extends it to 32-bits, and adds the result to a value in another
10748 register. You can specify a rotation by 0, 8, 16, or 24 bits
10749 before extracting the 16-bit value.
10750 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
10751 Condition defaults to COND_ALWAYS.
10752 Error if any register uses R15. */
10753
e16bb312 10754static void
c19d1205 10755do_sxtah (void)
e16bb312 10756{
c19d1205
ZW
10757 inst.instruction |= inst.operands[0].reg << 12;
10758 inst.instruction |= inst.operands[1].reg << 16;
10759 inst.instruction |= inst.operands[2].reg;
10760 inst.instruction |= inst.operands[3].imm << 10;
10761}
e16bb312 10762
c19d1205 10763/* ARM V6 SXTH.
e16bb312 10764
c19d1205
ZW
10765 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
10766 Condition defaults to COND_ALWAYS.
10767 Error if any register uses R15. */
e16bb312
NC
10768
10769static void
c19d1205 10770do_sxth (void)
e16bb312 10771{
c19d1205
ZW
10772 inst.instruction |= inst.operands[0].reg << 12;
10773 inst.instruction |= inst.operands[1].reg;
10774 inst.instruction |= inst.operands[2].imm << 10;
e16bb312 10775}
c19d1205
ZW
10776\f
10777/* VFP instructions. In a logical order: SP variant first, monad
10778 before dyad, arithmetic then move then load/store. */
e16bb312
NC
10779
10780static void
c19d1205 10781do_vfp_sp_monadic (void)
e16bb312 10782{
57785aa2
AV
10783 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10784 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10785 _(BAD_FPU));
10786
5287ad62
JB
10787 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10788 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10789}
10790
10791static void
c19d1205 10792do_vfp_sp_dyadic (void)
e16bb312 10793{
5287ad62
JB
10794 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10795 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
10796 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10797}
10798
10799static void
c19d1205 10800do_vfp_sp_compare_z (void)
e16bb312 10801{
5287ad62 10802 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
e16bb312
NC
10803}
10804
10805static void
c19d1205 10806do_vfp_dp_sp_cvt (void)
e16bb312 10807{
5287ad62
JB
10808 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10809 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10810}
10811
10812static void
c19d1205 10813do_vfp_sp_dp_cvt (void)
e16bb312 10814{
5287ad62
JB
10815 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10816 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
e16bb312
NC
10817}
10818
10819static void
c19d1205 10820do_vfp_reg_from_sp (void)
e16bb312 10821{
57785aa2
AV
10822 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10823 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10824 _(BAD_FPU));
10825
c19d1205 10826 inst.instruction |= inst.operands[0].reg << 12;
5287ad62 10827 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
e16bb312
NC
10828}
10829
10830static void
c19d1205 10831do_vfp_reg2_from_sp2 (void)
e16bb312 10832{
c19d1205
ZW
10833 constraint (inst.operands[2].imm != 2,
10834 _("only two consecutive VFP SP registers allowed here"));
10835 inst.instruction |= inst.operands[0].reg << 12;
10836 inst.instruction |= inst.operands[1].reg << 16;
5287ad62 10837 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10838}
10839
10840static void
c19d1205 10841do_vfp_sp_from_reg (void)
e16bb312 10842{
57785aa2
AV
10843 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10844 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10845 _(BAD_FPU));
10846
5287ad62 10847 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sn);
c19d1205 10848 inst.instruction |= inst.operands[1].reg << 12;
e16bb312
NC
10849}
10850
10851static void
c19d1205 10852do_vfp_sp2_from_reg2 (void)
e16bb312 10853{
c19d1205
ZW
10854 constraint (inst.operands[0].imm != 2,
10855 _("only two consecutive VFP SP registers allowed here"));
5287ad62 10856 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sm);
c19d1205
ZW
10857 inst.instruction |= inst.operands[1].reg << 12;
10858 inst.instruction |= inst.operands[2].reg << 16;
e16bb312
NC
10859}
10860
10861static void
c19d1205 10862do_vfp_sp_ldst (void)
e16bb312 10863{
5287ad62 10864 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
5b7c81bd 10865 encode_arm_cp_address (1, false, true, 0);
e16bb312
NC
10866}
10867
10868static void
c19d1205 10869do_vfp_dp_ldst (void)
e16bb312 10870{
5287ad62 10871 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
5b7c81bd 10872 encode_arm_cp_address (1, false, true, 0);
e16bb312
NC
10873}
10874
c19d1205 10875
e16bb312 10876static void
c19d1205 10877vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10878{
c19d1205
ZW
10879 if (inst.operands[0].writeback)
10880 inst.instruction |= WRITE_BACK;
10881 else
10882 constraint (ldstm_type != VFP_LDSTMIA,
10883 _("this addressing mode requires base-register writeback"));
10884 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10885 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sd);
c19d1205 10886 inst.instruction |= inst.operands[1].imm;
e16bb312
NC
10887}
10888
10889static void
c19d1205 10890vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10891{
c19d1205 10892 int count;
e16bb312 10893
c19d1205
ZW
10894 if (inst.operands[0].writeback)
10895 inst.instruction |= WRITE_BACK;
10896 else
10897 constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
10898 _("this addressing mode requires base-register writeback"));
e16bb312 10899
c19d1205 10900 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10901 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
e16bb312 10902
c19d1205
ZW
10903 count = inst.operands[1].imm << 1;
10904 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
10905 count += 1;
e16bb312 10906
c19d1205 10907 inst.instruction |= count;
e16bb312
NC
10908}
10909
10910static void
c19d1205 10911do_vfp_sp_ldstmia (void)
e16bb312 10912{
c19d1205 10913 vfp_sp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10914}
10915
10916static void
c19d1205 10917do_vfp_sp_ldstmdb (void)
e16bb312 10918{
c19d1205 10919 vfp_sp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10920}
10921
10922static void
c19d1205 10923do_vfp_dp_ldstmia (void)
e16bb312 10924{
c19d1205 10925 vfp_dp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10926}
10927
10928static void
c19d1205 10929do_vfp_dp_ldstmdb (void)
e16bb312 10930{
c19d1205 10931 vfp_dp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10932}
10933
10934static void
c19d1205 10935do_vfp_xp_ldstmia (void)
e16bb312 10936{
c19d1205
ZW
10937 vfp_dp_ldstm (VFP_LDSTMIAX);
10938}
e16bb312 10939
c19d1205
ZW
10940static void
10941do_vfp_xp_ldstmdb (void)
10942{
10943 vfp_dp_ldstm (VFP_LDSTMDBX);
e16bb312 10944}
5287ad62
JB
10945
10946static void
10947do_vfp_dp_rd_rm (void)
10948{
57785aa2
AV
10949 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
10950 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10951 _(BAD_FPU));
10952
5287ad62
JB
10953 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10954 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
10955}
10956
10957static void
10958do_vfp_dp_rn_rd (void)
10959{
10960 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dn);
10961 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10962}
10963
10964static void
10965do_vfp_dp_rd_rn (void)
10966{
10967 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10968 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10969}
10970
10971static void
10972do_vfp_dp_rd_rn_rm (void)
10973{
57785aa2
AV
10974 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10975 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10976 _(BAD_FPU));
10977
5287ad62
JB
10978 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10979 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10980 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dm);
10981}
10982
10983static void
10984do_vfp_dp_rd (void)
10985{
10986 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10987}
10988
10989static void
10990do_vfp_dp_rm_rd_rn (void)
10991{
57785aa2
AV
10992 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10993 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10994 _(BAD_FPU));
10995
5287ad62
JB
10996 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dm);
10997 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10998 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dn);
10999}
11000
11001/* VFPv3 instructions. */
11002static void
11003do_vfp_sp_const (void)
11004{
11005 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
00249aaa
PB
11006 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
11007 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
11008}
11009
11010static void
11011do_vfp_dp_const (void)
11012{
11013 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
00249aaa
PB
11014 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
11015 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
11016}
11017
11018static void
11019vfp_conv (int srcsize)
11020{
5f1af56b
MGD
11021 int immbits = srcsize - inst.operands[1].imm;
11022
fa94de6b
RM
11023 if (srcsize == 16 && !(immbits >= 0 && immbits <= srcsize))
11024 {
5f1af56b 11025 /* If srcsize is 16, inst.operands[1].imm must be in the range 0-16.
477330fc 11026 i.e. immbits must be in range 0 - 16. */
5f1af56b
MGD
11027 inst.error = _("immediate value out of range, expected range [0, 16]");
11028 return;
11029 }
fa94de6b 11030 else if (srcsize == 32 && !(immbits >= 0 && immbits < srcsize))
5f1af56b
MGD
11031 {
11032 /* If srcsize is 32, inst.operands[1].imm must be in the range 1-32.
477330fc 11033 i.e. immbits must be in range 0 - 31. */
5f1af56b
MGD
11034 inst.error = _("immediate value out of range, expected range [1, 32]");
11035 return;
11036 }
11037
5287ad62
JB
11038 inst.instruction |= (immbits & 1) << 5;
11039 inst.instruction |= (immbits >> 1);
11040}
11041
11042static void
11043do_vfp_sp_conv_16 (void)
11044{
11045 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
11046 vfp_conv (16);
11047}
11048
11049static void
11050do_vfp_dp_conv_16 (void)
11051{
11052 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
11053 vfp_conv (16);
11054}
11055
11056static void
11057do_vfp_sp_conv_32 (void)
11058{
11059 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
11060 vfp_conv (32);
11061}
11062
11063static void
11064do_vfp_dp_conv_32 (void)
11065{
11066 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
11067 vfp_conv (32);
11068}
c19d1205
ZW
11069\f
11070/* FPA instructions. Also in a logical order. */
e16bb312 11071
c19d1205
ZW
11072static void
11073do_fpa_cmp (void)
11074{
11075 inst.instruction |= inst.operands[0].reg << 16;
11076 inst.instruction |= inst.operands[1].reg;
11077}
b99bd4ef
NC
11078
11079static void
c19d1205 11080do_fpa_ldmstm (void)
b99bd4ef 11081{
c19d1205
ZW
11082 inst.instruction |= inst.operands[0].reg << 12;
11083 switch (inst.operands[1].imm)
11084 {
11085 case 1: inst.instruction |= CP_T_X; break;
11086 case 2: inst.instruction |= CP_T_Y; break;
11087 case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
11088 case 4: break;
11089 default: abort ();
11090 }
b99bd4ef 11091
c19d1205
ZW
11092 if (inst.instruction & (PRE_INDEX | INDEX_UP))
11093 {
11094 /* The instruction specified "ea" or "fd", so we can only accept
11095 [Rn]{!}. The instruction does not really support stacking or
11096 unstacking, so we have to emulate these by setting appropriate
11097 bits and offsets. */
e2b0ab59
AV
11098 constraint (inst.relocs[0].exp.X_op != O_constant
11099 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 11100 _("this instruction does not support indexing"));
b99bd4ef 11101
c19d1205 11102 if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
e2b0ab59 11103 inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
b99bd4ef 11104
c19d1205 11105 if (!(inst.instruction & INDEX_UP))
e2b0ab59 11106 inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
b99bd4ef 11107
c19d1205
ZW
11108 if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
11109 {
11110 inst.operands[2].preind = 0;
11111 inst.operands[2].postind = 1;
11112 }
11113 }
b99bd4ef 11114
5b7c81bd 11115 encode_arm_cp_address (2, true, true, 0);
b99bd4ef 11116}
c19d1205
ZW
11117\f
11118/* iWMMXt instructions: strictly in alphabetical order. */
b99bd4ef 11119
c19d1205
ZW
11120static void
11121do_iwmmxt_tandorc (void)
11122{
11123 constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
11124}
b99bd4ef 11125
c19d1205
ZW
11126static void
11127do_iwmmxt_textrc (void)
11128{
11129 inst.instruction |= inst.operands[0].reg << 12;
11130 inst.instruction |= inst.operands[1].imm;
11131}
b99bd4ef
NC
11132
11133static void
c19d1205 11134do_iwmmxt_textrm (void)
b99bd4ef 11135{
c19d1205
ZW
11136 inst.instruction |= inst.operands[0].reg << 12;
11137 inst.instruction |= inst.operands[1].reg << 16;
11138 inst.instruction |= inst.operands[2].imm;
11139}
b99bd4ef 11140
c19d1205
ZW
11141static void
11142do_iwmmxt_tinsr (void)
11143{
11144 inst.instruction |= inst.operands[0].reg << 16;
11145 inst.instruction |= inst.operands[1].reg << 12;
11146 inst.instruction |= inst.operands[2].imm;
11147}
b99bd4ef 11148
c19d1205
ZW
11149static void
11150do_iwmmxt_tmia (void)
11151{
11152 inst.instruction |= inst.operands[0].reg << 5;
11153 inst.instruction |= inst.operands[1].reg;
11154 inst.instruction |= inst.operands[2].reg << 12;
11155}
b99bd4ef 11156
c19d1205
ZW
11157static void
11158do_iwmmxt_waligni (void)
11159{
11160 inst.instruction |= inst.operands[0].reg << 12;
11161 inst.instruction |= inst.operands[1].reg << 16;
11162 inst.instruction |= inst.operands[2].reg;
11163 inst.instruction |= inst.operands[3].imm << 20;
11164}
b99bd4ef 11165
2d447fca
JM
11166static void
11167do_iwmmxt_wmerge (void)
11168{
11169 inst.instruction |= inst.operands[0].reg << 12;
11170 inst.instruction |= inst.operands[1].reg << 16;
11171 inst.instruction |= inst.operands[2].reg;
11172 inst.instruction |= inst.operands[3].imm << 21;
11173}
11174
c19d1205
ZW
11175static void
11176do_iwmmxt_wmov (void)
11177{
11178 /* WMOV rD, rN is an alias for WOR rD, rN, rN. */
11179 inst.instruction |= inst.operands[0].reg << 12;
11180 inst.instruction |= inst.operands[1].reg << 16;
11181 inst.instruction |= inst.operands[1].reg;
11182}
b99bd4ef 11183
c19d1205
ZW
11184static void
11185do_iwmmxt_wldstbh (void)
11186{
8f06b2d8 11187 int reloc;
c19d1205 11188 inst.instruction |= inst.operands[0].reg << 12;
8f06b2d8
PB
11189 if (thumb_mode)
11190 reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
11191 else
11192 reloc = BFD_RELOC_ARM_CP_OFF_IMM_S2;
5b7c81bd 11193 encode_arm_cp_address (1, true, false, reloc);
b99bd4ef
NC
11194}
11195
c19d1205
ZW
11196static void
11197do_iwmmxt_wldstw (void)
11198{
11199 /* RIWR_RIWC clears .isreg for a control register. */
11200 if (!inst.operands[0].isreg)
11201 {
11202 constraint (inst.cond != COND_ALWAYS, BAD_COND);
11203 inst.instruction |= 0xf0000000;
11204 }
b99bd4ef 11205
c19d1205 11206 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 11207 encode_arm_cp_address (1, true, true, 0);
c19d1205 11208}
b99bd4ef
NC
11209
11210static void
c19d1205 11211do_iwmmxt_wldstd (void)
b99bd4ef 11212{
c19d1205 11213 inst.instruction |= inst.operands[0].reg << 12;
2d447fca
JM
11214 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)
11215 && inst.operands[1].immisreg)
11216 {
11217 inst.instruction &= ~0x1a000ff;
eff0bc54 11218 inst.instruction |= (0xfU << 28);
2d447fca
JM
11219 if (inst.operands[1].preind)
11220 inst.instruction |= PRE_INDEX;
11221 if (!inst.operands[1].negative)
11222 inst.instruction |= INDEX_UP;
11223 if (inst.operands[1].writeback)
11224 inst.instruction |= WRITE_BACK;
11225 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 11226 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
2d447fca
JM
11227 inst.instruction |= inst.operands[1].imm;
11228 }
11229 else
5b7c81bd 11230 encode_arm_cp_address (1, true, false, 0);
c19d1205 11231}
b99bd4ef 11232
c19d1205
ZW
11233static void
11234do_iwmmxt_wshufh (void)
11235{
11236 inst.instruction |= inst.operands[0].reg << 12;
11237 inst.instruction |= inst.operands[1].reg << 16;
11238 inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
11239 inst.instruction |= (inst.operands[2].imm & 0x0f);
11240}
b99bd4ef 11241
c19d1205
ZW
11242static void
11243do_iwmmxt_wzero (void)
11244{
11245 /* WZERO reg is an alias for WANDN reg, reg, reg. */
11246 inst.instruction |= inst.operands[0].reg;
11247 inst.instruction |= inst.operands[0].reg << 12;
11248 inst.instruction |= inst.operands[0].reg << 16;
11249}
2d447fca
JM
11250
11251static void
11252do_iwmmxt_wrwrwr_or_imm5 (void)
11253{
11254 if (inst.operands[2].isreg)
11255 do_rd_rn_rm ();
11256 else {
11257 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2),
11258 _("immediate operand requires iWMMXt2"));
11259 do_rd_rn ();
11260 if (inst.operands[2].imm == 0)
11261 {
11262 switch ((inst.instruction >> 20) & 0xf)
11263 {
11264 case 4:
11265 case 5:
11266 case 6:
5f4273c7 11267 case 7:
2d447fca
JM
11268 /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16. */
11269 inst.operands[2].imm = 16;
11270 inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
11271 break;
11272 case 8:
11273 case 9:
11274 case 10:
11275 case 11:
11276 /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32. */
11277 inst.operands[2].imm = 32;
11278 inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
11279 break;
11280 case 12:
11281 case 13:
11282 case 14:
11283 case 15:
11284 {
11285 /* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn. */
11286 unsigned long wrn;
11287 wrn = (inst.instruction >> 16) & 0xf;
11288 inst.instruction &= 0xff0fff0f;
11289 inst.instruction |= wrn;
11290 /* Bail out here; the instruction is now assembled. */
11291 return;
11292 }
11293 }
11294 }
11295 /* Map 32 -> 0, etc. */
11296 inst.operands[2].imm &= 0x1f;
eff0bc54 11297 inst.instruction |= (0xfU << 28) | ((inst.operands[2].imm & 0x10) << 4) | (inst.operands[2].imm & 0xf);
2d447fca
JM
11298 }
11299}
c19d1205
ZW
11300\f
11301/* Cirrus Maverick instructions. Simple 2-, 3-, and 4-register
11302 operations first, then control, shift, and load/store. */
b99bd4ef 11303
c19d1205 11304/* Insns like "foo X,Y,Z". */
b99bd4ef 11305
c19d1205
ZW
11306static void
11307do_mav_triple (void)
11308{
11309 inst.instruction |= inst.operands[0].reg << 16;
11310 inst.instruction |= inst.operands[1].reg;
11311 inst.instruction |= inst.operands[2].reg << 12;
11312}
b99bd4ef 11313
c19d1205
ZW
11314/* Insns like "foo W,X,Y,Z".
11315 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
a737bd4d 11316
c19d1205
ZW
11317static void
11318do_mav_quad (void)
11319{
11320 inst.instruction |= inst.operands[0].reg << 5;
11321 inst.instruction |= inst.operands[1].reg << 12;
11322 inst.instruction |= inst.operands[2].reg << 16;
11323 inst.instruction |= inst.operands[3].reg;
a737bd4d
NC
11324}
11325
c19d1205
ZW
11326/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
11327static void
11328do_mav_dspsc (void)
a737bd4d 11329{
c19d1205
ZW
11330 inst.instruction |= inst.operands[1].reg << 12;
11331}
a737bd4d 11332
c19d1205
ZW
11333/* Maverick shift immediate instructions.
11334 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
11335 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
a737bd4d 11336
c19d1205
ZW
11337static void
11338do_mav_shift (void)
11339{
11340 int imm = inst.operands[2].imm;
a737bd4d 11341
c19d1205
ZW
11342 inst.instruction |= inst.operands[0].reg << 12;
11343 inst.instruction |= inst.operands[1].reg << 16;
a737bd4d 11344
c19d1205
ZW
11345 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
11346 Bits 5-7 of the insn should have bits 4-6 of the immediate.
11347 Bit 4 should be 0. */
11348 imm = (imm & 0xf) | ((imm & 0x70) << 1);
a737bd4d 11349
c19d1205
ZW
11350 inst.instruction |= imm;
11351}
11352\f
11353/* XScale instructions. Also sorted arithmetic before move. */
a737bd4d 11354
c19d1205
ZW
11355/* Xscale multiply-accumulate (argument parse)
11356 MIAcc acc0,Rm,Rs
11357 MIAPHcc acc0,Rm,Rs
11358 MIAxycc acc0,Rm,Rs. */
a737bd4d 11359
c19d1205
ZW
11360static void
11361do_xsc_mia (void)
11362{
11363 inst.instruction |= inst.operands[1].reg;
11364 inst.instruction |= inst.operands[2].reg << 12;
11365}
a737bd4d 11366
c19d1205 11367/* Xscale move-accumulator-register (argument parse)
a737bd4d 11368
c19d1205 11369 MARcc acc0,RdLo,RdHi. */
b99bd4ef 11370
c19d1205
ZW
11371static void
11372do_xsc_mar (void)
11373{
11374 inst.instruction |= inst.operands[1].reg << 12;
11375 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
11376}
11377
c19d1205 11378/* Xscale move-register-accumulator (argument parse)
b99bd4ef 11379
c19d1205 11380 MRAcc RdLo,RdHi,acc0. */
b99bd4ef
NC
11381
11382static void
c19d1205 11383do_xsc_mra (void)
b99bd4ef 11384{
c19d1205
ZW
11385 constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
11386 inst.instruction |= inst.operands[0].reg << 12;
11387 inst.instruction |= inst.operands[1].reg << 16;
11388}
11389\f
11390/* Encoding functions relevant only to Thumb. */
b99bd4ef 11391
c19d1205
ZW
11392/* inst.operands[i] is a shifted-register operand; encode
11393 it into inst.instruction in the format used by Thumb32. */
11394
11395static void
11396encode_thumb32_shifted_operand (int i)
11397{
e2b0ab59 11398 unsigned int value = inst.relocs[0].exp.X_add_number;
c19d1205 11399 unsigned int shift = inst.operands[i].shift_kind;
b99bd4ef 11400
9c3c69f2
PB
11401 constraint (inst.operands[i].immisreg,
11402 _("shift by register not allowed in thumb mode"));
c19d1205
ZW
11403 inst.instruction |= inst.operands[i].reg;
11404 if (shift == SHIFT_RRX)
11405 inst.instruction |= SHIFT_ROR << 4;
11406 else
b99bd4ef 11407 {
e2b0ab59 11408 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
11409 _("expression too complex"));
11410
11411 constraint (value > 32
11412 || (value == 32 && (shift == SHIFT_LSL
11413 || shift == SHIFT_ROR)),
11414 _("shift expression is too large"));
11415
11416 if (value == 0)
11417 shift = SHIFT_LSL;
11418 else if (value == 32)
11419 value = 0;
11420
11421 inst.instruction |= shift << 4;
11422 inst.instruction |= (value & 0x1c) << 10;
11423 inst.instruction |= (value & 0x03) << 6;
b99bd4ef 11424 }
c19d1205 11425}
b99bd4ef 11426
b99bd4ef 11427
c19d1205
ZW
11428/* inst.operands[i] was set up by parse_address. Encode it into a
11429 Thumb32 format load or store instruction. Reject forms that cannot
11430 be used with such instructions. If is_t is true, reject forms that
11431 cannot be used with a T instruction; if is_d is true, reject forms
5be8be5d
DG
11432 that cannot be used with a D instruction. If it is a store insn,
11433 reject PC in Rn. */
b99bd4ef 11434
c19d1205 11435static void
5b7c81bd 11436encode_thumb32_addr_mode (int i, bool is_t, bool is_d)
c19d1205 11437{
5b7c81bd 11438 const bool is_pc = (inst.operands[i].reg == REG_PC);
c19d1205
ZW
11439
11440 constraint (!inst.operands[i].isreg,
53365c0d 11441 _("Instruction does not support =N addresses"));
b99bd4ef 11442
c19d1205
ZW
11443 inst.instruction |= inst.operands[i].reg << 16;
11444 if (inst.operands[i].immisreg)
b99bd4ef 11445 {
5be8be5d 11446 constraint (is_pc, BAD_PC_ADDRESSING);
c19d1205
ZW
11447 constraint (is_t || is_d, _("cannot use register index with this instruction"));
11448 constraint (inst.operands[i].negative,
11449 _("Thumb does not support negative register indexing"));
11450 constraint (inst.operands[i].postind,
11451 _("Thumb does not support register post-indexing"));
11452 constraint (inst.operands[i].writeback,
11453 _("Thumb does not support register indexing with writeback"));
11454 constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
11455 _("Thumb supports only LSL in shifted register indexing"));
b99bd4ef 11456
f40d1643 11457 inst.instruction |= inst.operands[i].imm;
c19d1205 11458 if (inst.operands[i].shifted)
b99bd4ef 11459 {
e2b0ab59 11460 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 11461 _("expression too complex"));
e2b0ab59
AV
11462 constraint (inst.relocs[0].exp.X_add_number < 0
11463 || inst.relocs[0].exp.X_add_number > 3,
c19d1205 11464 _("shift out of range"));
e2b0ab59 11465 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
c19d1205 11466 }
e2b0ab59 11467 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
11468 }
11469 else if (inst.operands[i].preind)
11470 {
5be8be5d 11471 constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
f40d1643 11472 constraint (is_t && inst.operands[i].writeback,
c19d1205 11473 _("cannot use writeback with this instruction"));
4755303e
WN
11474 constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0),
11475 BAD_PC_ADDRESSING);
c19d1205
ZW
11476
11477 if (is_d)
11478 {
11479 inst.instruction |= 0x01000000;
11480 if (inst.operands[i].writeback)
11481 inst.instruction |= 0x00200000;
b99bd4ef 11482 }
c19d1205 11483 else
b99bd4ef 11484 {
c19d1205
ZW
11485 inst.instruction |= 0x00000c00;
11486 if (inst.operands[i].writeback)
11487 inst.instruction |= 0x00000100;
b99bd4ef 11488 }
e2b0ab59 11489 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
b99bd4ef 11490 }
c19d1205 11491 else if (inst.operands[i].postind)
b99bd4ef 11492 {
9c2799c2 11493 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
11494 constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
11495 constraint (is_t, _("cannot use post-indexing with this instruction"));
11496
11497 if (is_d)
11498 inst.instruction |= 0x00200000;
11499 else
11500 inst.instruction |= 0x00000900;
e2b0ab59 11501 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
c19d1205
ZW
11502 }
11503 else /* unindexed - only for coprocessor */
11504 inst.error = _("instruction does not accept unindexed addressing");
11505}
11506
e39c1607 11507/* Table of Thumb instructions which exist in 16- and/or 32-bit
c19d1205
ZW
11508 encodings (the latter only in post-V6T2 cores). The index is the
11509 value used in the insns table below. When there is more than one
11510 possible 16-bit encoding for the instruction, this table always
0110f2b8
PB
11511 holds variant (1).
11512 Also contains several pseudo-instructions used during relaxation. */
c19d1205 11513#define T16_32_TAB \
21d799b5
NC
11514 X(_adc, 4140, eb400000), \
11515 X(_adcs, 4140, eb500000), \
11516 X(_add, 1c00, eb000000), \
11517 X(_adds, 1c00, eb100000), \
11518 X(_addi, 0000, f1000000), \
11519 X(_addis, 0000, f1100000), \
11520 X(_add_pc,000f, f20f0000), \
11521 X(_add_sp,000d, f10d0000), \
11522 X(_adr, 000f, f20f0000), \
11523 X(_and, 4000, ea000000), \
11524 X(_ands, 4000, ea100000), \
11525 X(_asr, 1000, fa40f000), \
11526 X(_asrs, 1000, fa50f000), \
e43ca2cb 11527 X(_aut, 0000, f3af802d), \
be05908c 11528 X(_autg, 0000, fb500f00), \
21d799b5
NC
11529 X(_b, e000, f000b000), \
11530 X(_bcond, d000, f0008000), \
4389b29a 11531 X(_bf, 0000, f040e001), \
f6b2b12d 11532 X(_bfcsel,0000, f000e001), \
f1c7f421 11533 X(_bfx, 0000, f060e001), \
65d1bc05 11534 X(_bfl, 0000, f000c001), \
f1c7f421 11535 X(_bflx, 0000, f070e001), \
21d799b5
NC
11536 X(_bic, 4380, ea200000), \
11537 X(_bics, 4380, ea300000), \
e07352fa 11538 X(_bxaut, 0000, fb500f10), \
e39c1607
SD
11539 X(_cinc, 0000, ea509000), \
11540 X(_cinv, 0000, ea50a000), \
21d799b5
NC
11541 X(_cmn, 42c0, eb100f00), \
11542 X(_cmp, 2800, ebb00f00), \
e39c1607 11543 X(_cneg, 0000, ea50b000), \
21d799b5
NC
11544 X(_cpsie, b660, f3af8400), \
11545 X(_cpsid, b670, f3af8600), \
11546 X(_cpy, 4600, ea4f0000), \
e39c1607
SD
11547 X(_csel, 0000, ea508000), \
11548 X(_cset, 0000, ea5f900f), \
11549 X(_csetm, 0000, ea5fa00f), \
11550 X(_csinc, 0000, ea509000), \
11551 X(_csinv, 0000, ea50a000), \
11552 X(_csneg, 0000, ea50b000), \
21d799b5 11553 X(_dec_sp,80dd, f1ad0d00), \
60f993ce 11554 X(_dls, 0000, f040e001), \
1f6234a3 11555 X(_dlstp, 0000, f000e001), \
21d799b5
NC
11556 X(_eor, 4040, ea800000), \
11557 X(_eors, 4040, ea900000), \
11558 X(_inc_sp,00dd, f10d0d00), \
1f6234a3 11559 X(_lctp, 0000, f00fe001), \
21d799b5
NC
11560 X(_ldmia, c800, e8900000), \
11561 X(_ldr, 6800, f8500000), \
11562 X(_ldrb, 7800, f8100000), \
11563 X(_ldrh, 8800, f8300000), \
11564 X(_ldrsb, 5600, f9100000), \
11565 X(_ldrsh, 5e00, f9300000), \
11566 X(_ldr_pc,4800, f85f0000), \
11567 X(_ldr_pc2,4800, f85f0000), \
11568 X(_ldr_sp,9800, f85d0000), \
60f993ce 11569 X(_le, 0000, f00fc001), \
1f6234a3 11570 X(_letp, 0000, f01fc001), \
21d799b5
NC
11571 X(_lsl, 0000, fa00f000), \
11572 X(_lsls, 0000, fa10f000), \
11573 X(_lsr, 0800, fa20f000), \
11574 X(_lsrs, 0800, fa30f000), \
11575 X(_mov, 2000, ea4f0000), \
11576 X(_movs, 2000, ea5f0000), \
11577 X(_mul, 4340, fb00f000), \
11578 X(_muls, 4340, ffffffff), /* no 32b muls */ \
11579 X(_mvn, 43c0, ea6f0000), \
11580 X(_mvns, 43c0, ea7f0000), \
11581 X(_neg, 4240, f1c00000), /* rsb #0 */ \
11582 X(_negs, 4240, f1d00000), /* rsbs #0 */ \
11583 X(_orr, 4300, ea400000), \
11584 X(_orrs, 4300, ea500000), \
ce537a7d 11585 X(_pac, 0000, f3af801d), \
f1e1d7f3 11586 X(_pacbti, 0000, f3af800d), \
5c43020d 11587 X(_pacg, 0000, fb60f000), \
21d799b5
NC
11588 X(_pop, bc00, e8bd0000), /* ldmia sp!,... */ \
11589 X(_push, b400, e92d0000), /* stmdb sp!,... */ \
11590 X(_rev, ba00, fa90f080), \
11591 X(_rev16, ba40, fa90f090), \
11592 X(_revsh, bac0, fa90f0b0), \
11593 X(_ror, 41c0, fa60f000), \
11594 X(_rors, 41c0, fa70f000), \
11595 X(_sbc, 4180, eb600000), \
11596 X(_sbcs, 4180, eb700000), \
11597 X(_stmia, c000, e8800000), \
11598 X(_str, 6000, f8400000), \
11599 X(_strb, 7000, f8000000), \
11600 X(_strh, 8000, f8200000), \
11601 X(_str_sp,9000, f84d0000), \
11602 X(_sub, 1e00, eba00000), \
11603 X(_subs, 1e00, ebb00000), \
11604 X(_subi, 8000, f1a00000), \
11605 X(_subis, 8000, f1b00000), \
11606 X(_sxtb, b240, fa4ff080), \
11607 X(_sxth, b200, fa0ff080), \
11608 X(_tst, 4200, ea100f00), \
11609 X(_uxtb, b2c0, fa5ff080), \
11610 X(_uxth, b280, fa1ff080), \
11611 X(_nop, bf00, f3af8000), \
11612 X(_yield, bf10, f3af8001), \
11613 X(_wfe, bf20, f3af8002), \
11614 X(_wfi, bf30, f3af8003), \
60f993ce 11615 X(_wls, 0000, f040c001), \
1f6234a3 11616 X(_wlstp, 0000, f000c001), \
53c4b28b 11617 X(_sev, bf40, f3af8004), \
74db7efb
NC
11618 X(_sevl, bf50, f3af8005), \
11619 X(_udf, de00, f7f0a000)
c19d1205
ZW
11620
11621/* To catch errors in encoding functions, the codes are all offset by
11622 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
11623 as 16-bit instructions. */
21d799b5 11624#define X(a,b,c) T_MNEM##a
c19d1205
ZW
11625enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
11626#undef X
11627
11628#define X(a,b,c) 0x##b
11629static const unsigned short thumb_op16[] = { T16_32_TAB };
11630#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
11631#undef X
11632
11633#define X(a,b,c) 0x##c
11634static const unsigned int thumb_op32[] = { T16_32_TAB };
c921be7d
NC
11635#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
11636#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
c19d1205
ZW
11637#undef X
11638#undef T16_32_TAB
11639
11640/* Thumb instruction encoders, in alphabetical order. */
11641
92e90b6e 11642/* ADDW or SUBW. */
c921be7d 11643
92e90b6e
PB
11644static void
11645do_t_add_sub_w (void)
11646{
11647 int Rd, Rn;
11648
11649 Rd = inst.operands[0].reg;
11650 Rn = inst.operands[1].reg;
11651
539d4391
NC
11652 /* If Rn is REG_PC, this is ADR; if Rn is REG_SP, then this
11653 is the SP-{plus,minus}-immediate form of the instruction. */
11654 if (Rn == REG_SP)
11655 constraint (Rd == REG_PC, BAD_PC);
11656 else
11657 reject_bad_reg (Rd);
fdfde340 11658
92e90b6e 11659 inst.instruction |= (Rn << 16) | (Rd << 8);
e2b0ab59 11660 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
92e90b6e
PB
11661}
11662
c19d1205 11663/* Parse an add or subtract instruction. We get here with inst.instruction
33eaf5de 11664 equaling any of THUMB_OPCODE_add, adds, sub, or subs. */
c19d1205
ZW
11665
11666static void
11667do_t_add_sub (void)
11668{
11669 int Rd, Rs, Rn;
11670
11671 Rd = inst.operands[0].reg;
11672 Rs = (inst.operands[1].present
11673 ? inst.operands[1].reg /* Rd, Rs, foo */
11674 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11675
e07e6e58 11676 if (Rd == REG_PC)
5ee91343 11677 set_pred_insn_type_last ();
e07e6e58 11678
c19d1205
ZW
11679 if (unified_syntax)
11680 {
5b7c81bd
AM
11681 bool flags;
11682 bool narrow;
0110f2b8
PB
11683 int opcode;
11684
11685 flags = (inst.instruction == T_MNEM_adds
11686 || inst.instruction == T_MNEM_subs);
11687 if (flags)
5ee91343 11688 narrow = !in_pred_block ();
0110f2b8 11689 else
5ee91343 11690 narrow = in_pred_block ();
c19d1205 11691 if (!inst.operands[2].isreg)
b99bd4ef 11692 {
16805f35
PB
11693 int add;
11694
5c8ed6a4
JW
11695 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11696 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340 11697
16805f35
PB
11698 add = (inst.instruction == T_MNEM_add
11699 || inst.instruction == T_MNEM_adds);
0110f2b8
PB
11700 opcode = 0;
11701 if (inst.size_req != 4)
11702 {
0110f2b8 11703 /* Attempt to use a narrow opcode, with relaxation if
477330fc 11704 appropriate. */
0110f2b8
PB
11705 if (Rd == REG_SP && Rs == REG_SP && !flags)
11706 opcode = add ? T_MNEM_inc_sp : T_MNEM_dec_sp;
11707 else if (Rd <= 7 && Rs == REG_SP && add && !flags)
11708 opcode = T_MNEM_add_sp;
11709 else if (Rd <= 7 && Rs == REG_PC && add && !flags)
11710 opcode = T_MNEM_add_pc;
11711 else if (Rd <= 7 && Rs <= 7 && narrow)
11712 {
11713 if (flags)
11714 opcode = add ? T_MNEM_addis : T_MNEM_subis;
11715 else
11716 opcode = add ? T_MNEM_addi : T_MNEM_subi;
11717 }
11718 if (opcode)
11719 {
11720 inst.instruction = THUMB_OP16(opcode);
11721 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59
AV
11722 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
11723 || (inst.relocs[0].type
11724 > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
a9f02af8
MG
11725 {
11726 if (inst.size_req == 2)
e2b0ab59 11727 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
a9f02af8
MG
11728 else
11729 inst.relax = opcode;
11730 }
0110f2b8
PB
11731 }
11732 else
fe0171d2 11733 constraint (inst.size_req == 2, _("cannot honor width suffix"));
0110f2b8
PB
11734 }
11735 if (inst.size_req == 4
11736 || (inst.size_req != 2 && !opcode))
11737 {
e2b0ab59
AV
11738 constraint ((inst.relocs[0].type
11739 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
11740 && (inst.relocs[0].type
11741 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8 11742 THUMB1_RELOC_ONLY);
efd81785
PB
11743 if (Rd == REG_PC)
11744 {
fdfde340 11745 constraint (add, BAD_PC);
efd81785
PB
11746 constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
11747 _("only SUBS PC, LR, #const allowed"));
e2b0ab59 11748 constraint (inst.relocs[0].exp.X_op != O_constant,
efd81785 11749 _("expression too complex"));
e2b0ab59
AV
11750 constraint (inst.relocs[0].exp.X_add_number < 0
11751 || inst.relocs[0].exp.X_add_number > 0xff,
efd81785
PB
11752 _("immediate value out of range"));
11753 inst.instruction = T2_SUBS_PC_LR
e2b0ab59
AV
11754 | inst.relocs[0].exp.X_add_number;
11755 inst.relocs[0].type = BFD_RELOC_UNUSED;
efd81785
PB
11756 return;
11757 }
11758 else if (Rs == REG_PC)
16805f35
PB
11759 {
11760 /* Always use addw/subw. */
11761 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
e2b0ab59 11762 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
16805f35
PB
11763 }
11764 else
11765 {
11766 inst.instruction = THUMB_OP32 (inst.instruction);
11767 inst.instruction = (inst.instruction & 0xe1ffffff)
11768 | 0x10000000;
11769 if (flags)
e2b0ab59 11770 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
16805f35 11771 else
e2b0ab59 11772 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
16805f35 11773 }
dc4503c6
PB
11774 inst.instruction |= Rd << 8;
11775 inst.instruction |= Rs << 16;
0110f2b8 11776 }
b99bd4ef 11777 }
c19d1205
ZW
11778 else
11779 {
e2b0ab59 11780 unsigned int value = inst.relocs[0].exp.X_add_number;
5f4cb198
NC
11781 unsigned int shift = inst.operands[2].shift_kind;
11782
c19d1205
ZW
11783 Rn = inst.operands[2].reg;
11784 /* See if we can do this with a 16-bit instruction. */
11785 if (!inst.operands[2].shifted && inst.size_req != 4)
11786 {
e27ec89e 11787 if (Rd > 7 || Rs > 7 || Rn > 7)
5b7c81bd 11788 narrow = false;
e27ec89e
PB
11789
11790 if (narrow)
c19d1205 11791 {
e27ec89e
PB
11792 inst.instruction = ((inst.instruction == T_MNEM_adds
11793 || inst.instruction == T_MNEM_add)
c19d1205
ZW
11794 ? T_OPCODE_ADD_R3
11795 : T_OPCODE_SUB_R3);
11796 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
11797 return;
11798 }
b99bd4ef 11799
7e806470 11800 if (inst.instruction == T_MNEM_add && (Rd == Rs || Rd == Rn))
c19d1205 11801 {
7e806470
PB
11802 /* Thumb-1 cores (except v6-M) require at least one high
11803 register in a narrow non flag setting add. */
11804 if (Rd > 7 || Rn > 7
11805 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2)
11806 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_msr))
c19d1205 11807 {
7e806470
PB
11808 if (Rd == Rn)
11809 {
11810 Rn = Rs;
11811 Rs = Rd;
11812 }
c19d1205
ZW
11813 inst.instruction = T_OPCODE_ADD_HI;
11814 inst.instruction |= (Rd & 8) << 4;
11815 inst.instruction |= (Rd & 7);
11816 inst.instruction |= Rn << 3;
11817 return;
11818 }
c19d1205
ZW
11819 }
11820 }
c921be7d 11821
fdfde340 11822 constraint (Rd == REG_PC, BAD_PC);
5c8ed6a4
JW
11823 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11824 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340
JM
11825 constraint (Rs == REG_PC, BAD_PC);
11826 reject_bad_reg (Rn);
11827
c19d1205
ZW
11828 /* If we get here, it can't be done in 16 bits. */
11829 constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
11830 _("shift must be constant"));
11831 inst.instruction = THUMB_OP32 (inst.instruction);
11832 inst.instruction |= Rd << 8;
11833 inst.instruction |= Rs << 16;
5f4cb198
NC
11834 constraint (Rd == REG_SP && Rs == REG_SP && value > 3,
11835 _("shift value over 3 not allowed in thumb mode"));
11836 constraint (Rd == REG_SP && Rs == REG_SP && shift != SHIFT_LSL,
11837 _("only LSL shift allowed in thumb mode"));
c19d1205
ZW
11838 encode_thumb32_shifted_operand (2);
11839 }
11840 }
11841 else
11842 {
11843 constraint (inst.instruction == T_MNEM_adds
11844 || inst.instruction == T_MNEM_subs,
11845 BAD_THUMB32);
b99bd4ef 11846
c19d1205 11847 if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
b99bd4ef 11848 {
c19d1205
ZW
11849 constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
11850 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
11851 BAD_HIREG);
11852
11853 inst.instruction = (inst.instruction == T_MNEM_add
11854 ? 0x0000 : 0x8000);
11855 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59 11856 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
b99bd4ef
NC
11857 return;
11858 }
11859
c19d1205
ZW
11860 Rn = inst.operands[2].reg;
11861 constraint (inst.operands[2].shifted, _("unshifted register required"));
b99bd4ef 11862
c19d1205
ZW
11863 /* We now have Rd, Rs, and Rn set to registers. */
11864 if (Rd > 7 || Rs > 7 || Rn > 7)
b99bd4ef 11865 {
c19d1205
ZW
11866 /* Can't do this for SUB. */
11867 constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
11868 inst.instruction = T_OPCODE_ADD_HI;
11869 inst.instruction |= (Rd & 8) << 4;
11870 inst.instruction |= (Rd & 7);
11871 if (Rs == Rd)
11872 inst.instruction |= Rn << 3;
11873 else if (Rn == Rd)
11874 inst.instruction |= Rs << 3;
11875 else
11876 constraint (1, _("dest must overlap one source register"));
11877 }
11878 else
11879 {
11880 inst.instruction = (inst.instruction == T_MNEM_add
11881 ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
11882 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
b99bd4ef 11883 }
b99bd4ef 11884 }
b99bd4ef
NC
11885}
11886
c19d1205
ZW
11887static void
11888do_t_adr (void)
11889{
fdfde340
JM
11890 unsigned Rd;
11891
11892 Rd = inst.operands[0].reg;
11893 reject_bad_reg (Rd);
11894
11895 if (unified_syntax && inst.size_req == 0 && Rd <= 7)
0110f2b8
PB
11896 {
11897 /* Defer to section relaxation. */
11898 inst.relax = inst.instruction;
11899 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 11900 inst.instruction |= Rd << 4;
0110f2b8
PB
11901 }
11902 else if (unified_syntax && inst.size_req != 2)
e9f89963 11903 {
0110f2b8 11904 /* Generate a 32-bit opcode. */
e9f89963 11905 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 11906 inst.instruction |= Rd << 8;
e2b0ab59
AV
11907 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
11908 inst.relocs[0].pc_rel = 1;
e9f89963
PB
11909 }
11910 else
11911 {
0110f2b8 11912 /* Generate a 16-bit opcode. */
e9f89963 11913 inst.instruction = THUMB_OP16 (inst.instruction);
e2b0ab59
AV
11914 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
11915 inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust. */
11916 inst.relocs[0].pc_rel = 1;
fdfde340 11917 inst.instruction |= Rd << 4;
e9f89963 11918 }
52a86f84 11919
e2b0ab59
AV
11920 if (inst.relocs[0].exp.X_op == O_symbol
11921 && inst.relocs[0].exp.X_add_symbol != NULL
11922 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11923 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11924 inst.relocs[0].exp.X_add_number += 1;
c19d1205 11925}
b99bd4ef 11926
c19d1205
ZW
11927/* Arithmetic instructions for which there is just one 16-bit
11928 instruction encoding, and it allows only two low registers.
11929 For maximal compatibility with ARM syntax, we allow three register
11930 operands even when Thumb-32 instructions are not available, as long
11931 as the first two are identical. For instance, both "sbc r0,r1" and
11932 "sbc r0,r0,r1" are allowed. */
b99bd4ef 11933static void
c19d1205 11934do_t_arit3 (void)
b99bd4ef 11935{
c19d1205 11936 int Rd, Rs, Rn;
b99bd4ef 11937
c19d1205
ZW
11938 Rd = inst.operands[0].reg;
11939 Rs = (inst.operands[1].present
11940 ? inst.operands[1].reg /* Rd, Rs, foo */
11941 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11942 Rn = inst.operands[2].reg;
b99bd4ef 11943
fdfde340
JM
11944 reject_bad_reg (Rd);
11945 reject_bad_reg (Rs);
11946 if (inst.operands[2].isreg)
11947 reject_bad_reg (Rn);
11948
c19d1205 11949 if (unified_syntax)
b99bd4ef 11950 {
c19d1205
ZW
11951 if (!inst.operands[2].isreg)
11952 {
11953 /* For an immediate, we always generate a 32-bit opcode;
11954 section relaxation will shrink it later if possible. */
11955 inst.instruction = THUMB_OP32 (inst.instruction);
11956 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11957 inst.instruction |= Rd << 8;
11958 inst.instruction |= Rs << 16;
e2b0ab59 11959 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
c19d1205
ZW
11960 }
11961 else
11962 {
5b7c81bd 11963 bool narrow;
e27ec89e 11964
c19d1205 11965 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11966 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 11967 narrow = !in_pred_block ();
e27ec89e 11968 else
5ee91343 11969 narrow = in_pred_block ();
e27ec89e
PB
11970
11971 if (Rd > 7 || Rn > 7 || Rs > 7)
5b7c81bd 11972 narrow = false;
e27ec89e 11973 if (inst.operands[2].shifted)
5b7c81bd 11974 narrow = false;
e27ec89e 11975 if (inst.size_req == 4)
5b7c81bd 11976 narrow = false;
e27ec89e
PB
11977
11978 if (narrow
c19d1205
ZW
11979 && Rd == Rs)
11980 {
11981 inst.instruction = THUMB_OP16 (inst.instruction);
11982 inst.instruction |= Rd;
11983 inst.instruction |= Rn << 3;
11984 return;
11985 }
b99bd4ef 11986
c19d1205
ZW
11987 /* If we get here, it can't be done in 16 bits. */
11988 constraint (inst.operands[2].shifted
11989 && inst.operands[2].immisreg,
11990 _("shift must be constant"));
11991 inst.instruction = THUMB_OP32 (inst.instruction);
11992 inst.instruction |= Rd << 8;
11993 inst.instruction |= Rs << 16;
11994 encode_thumb32_shifted_operand (2);
11995 }
a737bd4d 11996 }
c19d1205 11997 else
b99bd4ef 11998 {
c19d1205
ZW
11999 /* On its face this is a lie - the instruction does set the
12000 flags. However, the only supported mnemonic in this mode
12001 says it doesn't. */
12002 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 12003
c19d1205
ZW
12004 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
12005 _("unshifted register required"));
12006 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
12007 constraint (Rd != Rs,
12008 _("dest and source1 must be the same register"));
a737bd4d 12009
c19d1205
ZW
12010 inst.instruction = THUMB_OP16 (inst.instruction);
12011 inst.instruction |= Rd;
12012 inst.instruction |= Rn << 3;
b99bd4ef 12013 }
a737bd4d 12014}
b99bd4ef 12015
c19d1205
ZW
12016/* Similarly, but for instructions where the arithmetic operation is
12017 commutative, so we can allow either of them to be different from
12018 the destination operand in a 16-bit instruction. For instance, all
12019 three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
12020 accepted. */
12021static void
12022do_t_arit3c (void)
a737bd4d 12023{
c19d1205 12024 int Rd, Rs, Rn;
b99bd4ef 12025
c19d1205
ZW
12026 Rd = inst.operands[0].reg;
12027 Rs = (inst.operands[1].present
12028 ? inst.operands[1].reg /* Rd, Rs, foo */
12029 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
12030 Rn = inst.operands[2].reg;
c921be7d 12031
fdfde340
JM
12032 reject_bad_reg (Rd);
12033 reject_bad_reg (Rs);
12034 if (inst.operands[2].isreg)
12035 reject_bad_reg (Rn);
a737bd4d 12036
c19d1205 12037 if (unified_syntax)
a737bd4d 12038 {
c19d1205 12039 if (!inst.operands[2].isreg)
b99bd4ef 12040 {
c19d1205
ZW
12041 /* For an immediate, we always generate a 32-bit opcode;
12042 section relaxation will shrink it later if possible. */
12043 inst.instruction = THUMB_OP32 (inst.instruction);
12044 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
12045 inst.instruction |= Rd << 8;
12046 inst.instruction |= Rs << 16;
e2b0ab59 12047 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 12048 }
c19d1205 12049 else
a737bd4d 12050 {
5b7c81bd 12051 bool narrow;
e27ec89e 12052
c19d1205 12053 /* See if we can do this with a 16-bit instruction. */
e27ec89e 12054 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 12055 narrow = !in_pred_block ();
e27ec89e 12056 else
5ee91343 12057 narrow = in_pred_block ();
e27ec89e
PB
12058
12059 if (Rd > 7 || Rn > 7 || Rs > 7)
5b7c81bd 12060 narrow = false;
e27ec89e 12061 if (inst.operands[2].shifted)
5b7c81bd 12062 narrow = false;
e27ec89e 12063 if (inst.size_req == 4)
5b7c81bd 12064 narrow = false;
e27ec89e
PB
12065
12066 if (narrow)
a737bd4d 12067 {
c19d1205 12068 if (Rd == Rs)
a737bd4d 12069 {
c19d1205
ZW
12070 inst.instruction = THUMB_OP16 (inst.instruction);
12071 inst.instruction |= Rd;
12072 inst.instruction |= Rn << 3;
12073 return;
a737bd4d 12074 }
c19d1205 12075 if (Rd == Rn)
a737bd4d 12076 {
c19d1205
ZW
12077 inst.instruction = THUMB_OP16 (inst.instruction);
12078 inst.instruction |= Rd;
12079 inst.instruction |= Rs << 3;
12080 return;
a737bd4d
NC
12081 }
12082 }
c19d1205
ZW
12083
12084 /* If we get here, it can't be done in 16 bits. */
12085 constraint (inst.operands[2].shifted
12086 && inst.operands[2].immisreg,
12087 _("shift must be constant"));
12088 inst.instruction = THUMB_OP32 (inst.instruction);
12089 inst.instruction |= Rd << 8;
12090 inst.instruction |= Rs << 16;
12091 encode_thumb32_shifted_operand (2);
a737bd4d 12092 }
b99bd4ef 12093 }
c19d1205
ZW
12094 else
12095 {
12096 /* On its face this is a lie - the instruction does set the
12097 flags. However, the only supported mnemonic in this mode
12098 says it doesn't. */
12099 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 12100
c19d1205
ZW
12101 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
12102 _("unshifted register required"));
12103 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
12104
12105 inst.instruction = THUMB_OP16 (inst.instruction);
12106 inst.instruction |= Rd;
12107
12108 if (Rd == Rs)
12109 inst.instruction |= Rn << 3;
12110 else if (Rd == Rn)
12111 inst.instruction |= Rs << 3;
12112 else
12113 constraint (1, _("dest must overlap one source register"));
12114 }
a737bd4d
NC
12115}
12116
c19d1205
ZW
12117static void
12118do_t_bfc (void)
a737bd4d 12119{
fdfde340 12120 unsigned Rd;
c19d1205
ZW
12121 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
12122 constraint (msb > 32, _("bit-field extends past end of register"));
12123 /* The instruction encoding stores the LSB and MSB,
12124 not the LSB and width. */
fdfde340
JM
12125 Rd = inst.operands[0].reg;
12126 reject_bad_reg (Rd);
12127 inst.instruction |= Rd << 8;
c19d1205
ZW
12128 inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
12129 inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
12130 inst.instruction |= msb - 1;
b99bd4ef
NC
12131}
12132
c19d1205
ZW
12133static void
12134do_t_bfi (void)
b99bd4ef 12135{
fdfde340 12136 int Rd, Rn;
c19d1205 12137 unsigned int msb;
b99bd4ef 12138
fdfde340
JM
12139 Rd = inst.operands[0].reg;
12140 reject_bad_reg (Rd);
12141
c19d1205
ZW
12142 /* #0 in second position is alternative syntax for bfc, which is
12143 the same instruction but with REG_PC in the Rm field. */
12144 if (!inst.operands[1].isreg)
fdfde340
JM
12145 Rn = REG_PC;
12146 else
12147 {
12148 Rn = inst.operands[1].reg;
12149 reject_bad_reg (Rn);
12150 }
b99bd4ef 12151
c19d1205
ZW
12152 msb = inst.operands[2].imm + inst.operands[3].imm;
12153 constraint (msb > 32, _("bit-field extends past end of register"));
12154 /* The instruction encoding stores the LSB and MSB,
12155 not the LSB and width. */
fdfde340
JM
12156 inst.instruction |= Rd << 8;
12157 inst.instruction |= Rn << 16;
c19d1205
ZW
12158 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
12159 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
12160 inst.instruction |= msb - 1;
b99bd4ef
NC
12161}
12162
c19d1205
ZW
12163static void
12164do_t_bfx (void)
b99bd4ef 12165{
fdfde340
JM
12166 unsigned Rd, Rn;
12167
12168 Rd = inst.operands[0].reg;
12169 Rn = inst.operands[1].reg;
12170
12171 reject_bad_reg (Rd);
12172 reject_bad_reg (Rn);
12173
c19d1205
ZW
12174 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
12175 _("bit-field extends past end of register"));
fdfde340
JM
12176 inst.instruction |= Rd << 8;
12177 inst.instruction |= Rn << 16;
c19d1205
ZW
12178 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
12179 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
12180 inst.instruction |= inst.operands[3].imm - 1;
12181}
b99bd4ef 12182
c19d1205
ZW
12183/* ARM V5 Thumb BLX (argument parse)
12184 BLX <target_addr> which is BLX(1)
12185 BLX <Rm> which is BLX(2)
12186 Unfortunately, there are two different opcodes for this mnemonic.
12187 So, the insns[].value is not used, and the code here zaps values
12188 into inst.instruction.
b99bd4ef 12189
c19d1205
ZW
12190 ??? How to take advantage of the additional two bits of displacement
12191 available in Thumb32 mode? Need new relocation? */
b99bd4ef 12192
c19d1205
ZW
12193static void
12194do_t_blx (void)
12195{
5ee91343 12196 set_pred_insn_type_last ();
e07e6e58 12197
c19d1205 12198 if (inst.operands[0].isreg)
fdfde340
JM
12199 {
12200 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
12201 /* We have a register, so this is BLX(2). */
12202 inst.instruction |= inst.operands[0].reg << 3;
12203 }
b99bd4ef
NC
12204 else
12205 {
c19d1205 12206 /* No register. This must be BLX(1). */
2fc8bdac 12207 inst.instruction = 0xf000e800;
0855e32b 12208 encode_branch (BFD_RELOC_THUMB_PCREL_BLX);
b99bd4ef
NC
12209 }
12210}
12211
c19d1205
ZW
12212static void
12213do_t_branch (void)
b99bd4ef 12214{
0110f2b8 12215 int opcode;
dfa9f0d5 12216 int cond;
2fe88214 12217 bfd_reloc_code_real_type reloc;
dfa9f0d5 12218
e07e6e58 12219 cond = inst.cond;
5ee91343 12220 set_pred_insn_type (IF_INSIDE_IT_LAST_INSN);
e07e6e58 12221
5ee91343 12222 if (in_pred_block ())
dfa9f0d5
PB
12223 {
12224 /* Conditional branches inside IT blocks are encoded as unconditional
477330fc 12225 branches. */
dfa9f0d5 12226 cond = COND_ALWAYS;
dfa9f0d5
PB
12227 }
12228 else
12229 cond = inst.cond;
12230
12231 if (cond != COND_ALWAYS)
0110f2b8
PB
12232 opcode = T_MNEM_bcond;
12233 else
12234 opcode = inst.instruction;
12235
12d6b0b7
RS
12236 if (unified_syntax
12237 && (inst.size_req == 4
10960bfb
PB
12238 || (inst.size_req != 2
12239 && (inst.operands[0].hasreloc
e2b0ab59 12240 || inst.relocs[0].exp.X_op == O_constant))))
c19d1205 12241 {
0110f2b8 12242 inst.instruction = THUMB_OP32(opcode);
dfa9f0d5 12243 if (cond == COND_ALWAYS)
9ae92b05 12244 reloc = BFD_RELOC_THUMB_PCREL_BRANCH25;
c19d1205
ZW
12245 else
12246 {
ff8646ee
TP
12247 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2),
12248 _("selected architecture does not support "
12249 "wide conditional branch instruction"));
12250
9c2799c2 12251 gas_assert (cond != 0xF);
dfa9f0d5 12252 inst.instruction |= cond << 22;
9ae92b05 12253 reloc = BFD_RELOC_THUMB_PCREL_BRANCH20;
c19d1205
ZW
12254 }
12255 }
b99bd4ef
NC
12256 else
12257 {
0110f2b8 12258 inst.instruction = THUMB_OP16(opcode);
dfa9f0d5 12259 if (cond == COND_ALWAYS)
9ae92b05 12260 reloc = BFD_RELOC_THUMB_PCREL_BRANCH12;
c19d1205 12261 else
b99bd4ef 12262 {
dfa9f0d5 12263 inst.instruction |= cond << 8;
9ae92b05 12264 reloc = BFD_RELOC_THUMB_PCREL_BRANCH9;
b99bd4ef 12265 }
0110f2b8
PB
12266 /* Allow section relaxation. */
12267 if (unified_syntax && inst.size_req != 2)
12268 inst.relax = opcode;
b99bd4ef 12269 }
e2b0ab59
AV
12270 inst.relocs[0].type = reloc;
12271 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
12272}
12273
8884b720 12274/* Actually do the work for Thumb state bkpt and hlt. The only difference
bacebabc 12275 between the two is the maximum immediate allowed - which is passed in
8884b720 12276 RANGE. */
b99bd4ef 12277static void
8884b720 12278do_t_bkpt_hlt1 (int range)
b99bd4ef 12279{
dfa9f0d5
PB
12280 constraint (inst.cond != COND_ALWAYS,
12281 _("instruction is always unconditional"));
c19d1205 12282 if (inst.operands[0].present)
b99bd4ef 12283 {
8884b720 12284 constraint (inst.operands[0].imm > range,
c19d1205
ZW
12285 _("immediate value out of range"));
12286 inst.instruction |= inst.operands[0].imm;
b99bd4ef 12287 }
8884b720 12288
5ee91343 12289 set_pred_insn_type (NEUTRAL_IT_INSN);
8884b720
MGD
12290}
12291
12292static void
12293do_t_hlt (void)
12294{
12295 do_t_bkpt_hlt1 (63);
12296}
12297
12298static void
12299do_t_bkpt (void)
12300{
12301 do_t_bkpt_hlt1 (255);
b99bd4ef
NC
12302}
12303
12304static void
c19d1205 12305do_t_branch23 (void)
b99bd4ef 12306{
5ee91343 12307 set_pred_insn_type_last ();
0855e32b 12308 encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
fa94de6b 12309
0855e32b
NS
12310 /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
12311 this file. We used to simply ignore the PLT reloc type here --
12312 the branch encoding is now needed to deal with TLSCALL relocs.
12313 So if we see a PLT reloc now, put it back to how it used to be to
12314 keep the preexisting behaviour. */
e2b0ab59
AV
12315 if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
12316 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
90e4755a 12317
4343666d 12318#if defined(OBJ_COFF)
c19d1205
ZW
12319 /* If the destination of the branch is a defined symbol which does not have
12320 the THUMB_FUNC attribute, then we must be calling a function which has
12321 the (interfacearm) attribute. We look for the Thumb entry point to that
12322 function and change the branch to refer to that function instead. */
e2b0ab59
AV
12323 if ( inst.relocs[0].exp.X_op == O_symbol
12324 && inst.relocs[0].exp.X_add_symbol != NULL
12325 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
12326 && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
12327 inst.relocs[0].exp.X_add_symbol
12328 = find_real_start (inst.relocs[0].exp.X_add_symbol);
4343666d 12329#endif
90e4755a
RE
12330}
12331
12332static void
c19d1205 12333do_t_bx (void)
90e4755a 12334{
5ee91343 12335 set_pred_insn_type_last ();
c19d1205
ZW
12336 inst.instruction |= inst.operands[0].reg << 3;
12337 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
12338 should cause the alignment to be checked once it is known. This is
12339 because BX PC only works if the instruction is word aligned. */
12340}
90e4755a 12341
c19d1205
ZW
12342static void
12343do_t_bxj (void)
12344{
fdfde340 12345 int Rm;
90e4755a 12346
5ee91343 12347 set_pred_insn_type_last ();
fdfde340
JM
12348 Rm = inst.operands[0].reg;
12349 reject_bad_reg (Rm);
12350 inst.instruction |= Rm << 16;
90e4755a
RE
12351}
12352
12353static void
c19d1205 12354do_t_clz (void)
90e4755a 12355{
fdfde340
JM
12356 unsigned Rd;
12357 unsigned Rm;
12358
12359 Rd = inst.operands[0].reg;
12360 Rm = inst.operands[1].reg;
12361
12362 reject_bad_reg (Rd);
12363 reject_bad_reg (Rm);
12364
12365 inst.instruction |= Rd << 8;
12366 inst.instruction |= Rm << 16;
12367 inst.instruction |= Rm;
c19d1205 12368}
90e4755a 12369
e39c1607
SD
12370/* For the Armv8.1-M conditional instructions. */
12371static void
12372do_t_cond (void)
12373{
12374 unsigned Rd, Rn, Rm;
12375 signed int cond;
12376
12377 constraint (inst.cond != COND_ALWAYS, BAD_COND);
12378
12379 Rd = inst.operands[0].reg;
12380 switch (inst.instruction)
12381 {
12382 case T_MNEM_csinc:
12383 case T_MNEM_csinv:
12384 case T_MNEM_csneg:
12385 case T_MNEM_csel:
12386 Rn = inst.operands[1].reg;
12387 Rm = inst.operands[2].reg;
12388 cond = inst.operands[3].imm;
12389 constraint (Rn == REG_SP, BAD_SP);
12390 constraint (Rm == REG_SP, BAD_SP);
12391 break;
12392
12393 case T_MNEM_cinc:
12394 case T_MNEM_cinv:
12395 case T_MNEM_cneg:
12396 Rn = inst.operands[1].reg;
12397 cond = inst.operands[2].imm;
12398 /* Invert the last bit to invert the cond. */
12399 cond = TOGGLE_BIT (cond, 0);
12400 constraint (Rn == REG_SP, BAD_SP);
12401 Rm = Rn;
12402 break;
12403
12404 case T_MNEM_csetm:
12405 case T_MNEM_cset:
12406 cond = inst.operands[1].imm;
12407 /* Invert the last bit to invert the cond. */
12408 cond = TOGGLE_BIT (cond, 0);
12409 Rn = REG_PC;
12410 Rm = REG_PC;
12411 break;
12412
12413 default: abort ();
12414 }
12415
12416 set_pred_insn_type (OUTSIDE_PRED_INSN);
12417 inst.instruction = THUMB_OP32 (inst.instruction);
12418 inst.instruction |= Rd << 8;
12419 inst.instruction |= Rn << 16;
12420 inst.instruction |= Rm;
12421 inst.instruction |= cond << 4;
12422}
12423
91d8b670
JG
12424static void
12425do_t_csdb (void)
12426{
5ee91343 12427 set_pred_insn_type (OUTSIDE_PRED_INSN);
91d8b670
JG
12428}
12429
dfa9f0d5
PB
12430static void
12431do_t_cps (void)
12432{
5ee91343 12433 set_pred_insn_type (OUTSIDE_PRED_INSN);
dfa9f0d5
PB
12434 inst.instruction |= inst.operands[0].imm;
12435}
12436
c19d1205
ZW
12437static void
12438do_t_cpsi (void)
12439{
5ee91343 12440 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205 12441 if (unified_syntax
62b3e311
PB
12442 && (inst.operands[1].present || inst.size_req == 4)
12443 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
90e4755a 12444 {
c19d1205
ZW
12445 unsigned int imod = (inst.instruction & 0x0030) >> 4;
12446 inst.instruction = 0xf3af8000;
12447 inst.instruction |= imod << 9;
12448 inst.instruction |= inst.operands[0].imm << 5;
12449 if (inst.operands[1].present)
12450 inst.instruction |= 0x100 | inst.operands[1].imm;
90e4755a 12451 }
c19d1205 12452 else
90e4755a 12453 {
62b3e311
PB
12454 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)
12455 && (inst.operands[0].imm & 4),
12456 _("selected processor does not support 'A' form "
12457 "of this instruction"));
12458 constraint (inst.operands[1].present || inst.size_req == 4,
c19d1205
ZW
12459 _("Thumb does not support the 2-argument "
12460 "form of this instruction"));
12461 inst.instruction |= inst.operands[0].imm;
90e4755a 12462 }
90e4755a
RE
12463}
12464
c19d1205
ZW
12465/* THUMB CPY instruction (argument parse). */
12466
90e4755a 12467static void
c19d1205 12468do_t_cpy (void)
90e4755a 12469{
c19d1205 12470 if (inst.size_req == 4)
90e4755a 12471 {
c19d1205
ZW
12472 inst.instruction = THUMB_OP32 (T_MNEM_mov);
12473 inst.instruction |= inst.operands[0].reg << 8;
12474 inst.instruction |= inst.operands[1].reg;
90e4755a 12475 }
c19d1205 12476 else
90e4755a 12477 {
c19d1205
ZW
12478 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
12479 inst.instruction |= (inst.operands[0].reg & 0x7);
12480 inst.instruction |= inst.operands[1].reg << 3;
90e4755a 12481 }
90e4755a
RE
12482}
12483
90e4755a 12484static void
25fe350b 12485do_t_cbz (void)
90e4755a 12486{
5ee91343 12487 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
12488 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12489 inst.instruction |= inst.operands[0].reg;
e2b0ab59
AV
12490 inst.relocs[0].pc_rel = 1;
12491 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
c19d1205 12492}
90e4755a 12493
62b3e311
PB
12494static void
12495do_t_dbg (void)
12496{
12497 inst.instruction |= inst.operands[0].imm;
12498}
12499
12500static void
12501do_t_div (void)
12502{
fdfde340
JM
12503 unsigned Rd, Rn, Rm;
12504
12505 Rd = inst.operands[0].reg;
12506 Rn = (inst.operands[1].present
12507 ? inst.operands[1].reg : Rd);
12508 Rm = inst.operands[2].reg;
12509
12510 reject_bad_reg (Rd);
12511 reject_bad_reg (Rn);
12512 reject_bad_reg (Rm);
12513
12514 inst.instruction |= Rd << 8;
12515 inst.instruction |= Rn << 16;
12516 inst.instruction |= Rm;
62b3e311
PB
12517}
12518
c19d1205
ZW
12519static void
12520do_t_hint (void)
12521{
12522 if (unified_syntax && inst.size_req == 4)
12523 inst.instruction = THUMB_OP32 (inst.instruction);
12524 else
12525 inst.instruction = THUMB_OP16 (inst.instruction);
12526}
90e4755a 12527
c19d1205
ZW
12528static void
12529do_t_it (void)
12530{
12531 unsigned int cond = inst.operands[0].imm;
e27ec89e 12532
5ee91343
AV
12533 set_pred_insn_type (IT_INSN);
12534 now_pred.mask = (inst.instruction & 0xf) | 0x10;
12535 now_pred.cc = cond;
5b7c81bd 12536 now_pred.warn_deprecated = false;
5ee91343 12537 now_pred.type = SCALAR_PRED;
e27ec89e
PB
12538
12539 /* If the condition is a negative condition, invert the mask. */
c19d1205 12540 if ((cond & 0x1) == 0x0)
90e4755a 12541 {
c19d1205 12542 unsigned int mask = inst.instruction & 0x000f;
90e4755a 12543
c19d1205 12544 if ((mask & 0x7) == 0)
5a01bb1d
MGD
12545 {
12546 /* No conversion needed. */
5ee91343 12547 now_pred.block_length = 1;
5a01bb1d 12548 }
c19d1205 12549 else if ((mask & 0x3) == 0)
5a01bb1d
MGD
12550 {
12551 mask ^= 0x8;
5ee91343 12552 now_pred.block_length = 2;
5a01bb1d 12553 }
e27ec89e 12554 else if ((mask & 0x1) == 0)
5a01bb1d
MGD
12555 {
12556 mask ^= 0xC;
5ee91343 12557 now_pred.block_length = 3;
5a01bb1d 12558 }
c19d1205 12559 else
5a01bb1d
MGD
12560 {
12561 mask ^= 0xE;
5ee91343 12562 now_pred.block_length = 4;
5a01bb1d 12563 }
90e4755a 12564
e27ec89e
PB
12565 inst.instruction &= 0xfff0;
12566 inst.instruction |= mask;
c19d1205 12567 }
90e4755a 12568
c19d1205
ZW
12569 inst.instruction |= cond << 4;
12570}
90e4755a 12571
3c707909
PB
12572/* Helper function used for both push/pop and ldm/stm. */
12573static void
5b7c81bd
AM
12574encode_thumb2_multi (bool do_io, int base, unsigned mask,
12575 bool writeback)
3c707909 12576{
5b7c81bd 12577 bool load, store;
3c707909 12578
4b5a202f
AV
12579 gas_assert (base != -1 || !do_io);
12580 load = do_io && ((inst.instruction & (1 << 20)) != 0);
12581 store = do_io && !load;
3c707909
PB
12582
12583 if (mask & (1 << 13))
12584 inst.error = _("SP not allowed in register list");
1e5b0379 12585
4b5a202f 12586 if (do_io && (mask & (1 << base)) != 0
1e5b0379
NC
12587 && writeback)
12588 inst.error = _("having the base register in the register list when "
12589 "using write back is UNPREDICTABLE");
12590
3c707909
PB
12591 if (load)
12592 {
e07e6e58 12593 if (mask & (1 << 15))
477330fc
RM
12594 {
12595 if (mask & (1 << 14))
12596 inst.error = _("LR and PC should not both be in register list");
12597 else
5ee91343 12598 set_pred_insn_type_last ();
477330fc 12599 }
3c707909 12600 }
4b5a202f 12601 else if (store)
3c707909
PB
12602 {
12603 if (mask & (1 << 15))
12604 inst.error = _("PC not allowed in register list");
3c707909
PB
12605 }
12606
4b5a202f 12607 if (do_io && ((mask & (mask - 1)) == 0))
3c707909
PB
12608 {
12609 /* Single register transfers implemented as str/ldr. */
12610 if (writeback)
12611 {
12612 if (inst.instruction & (1 << 23))
12613 inst.instruction = 0x00000b04; /* ia! -> [base], #4 */
12614 else
12615 inst.instruction = 0x00000d04; /* db! -> [base, #-4]! */
12616 }
12617 else
12618 {
12619 if (inst.instruction & (1 << 23))
12620 inst.instruction = 0x00800000; /* ia -> [base] */
12621 else
12622 inst.instruction = 0x00000c04; /* db -> [base, #-4] */
12623 }
12624
12625 inst.instruction |= 0xf8400000;
12626 if (load)
12627 inst.instruction |= 0x00100000;
12628
5f4273c7 12629 mask = ffs (mask) - 1;
3c707909
PB
12630 mask <<= 12;
12631 }
12632 else if (writeback)
12633 inst.instruction |= WRITE_BACK;
12634
12635 inst.instruction |= mask;
4b5a202f
AV
12636 if (do_io)
12637 inst.instruction |= base << 16;
3c707909
PB
12638}
12639
c19d1205
ZW
12640static void
12641do_t_ldmstm (void)
12642{
12643 /* This really doesn't seem worth it. */
e2b0ab59 12644 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205
ZW
12645 _("expression too complex"));
12646 constraint (inst.operands[1].writeback,
12647 _("Thumb load/store multiple does not support {reglist}^"));
90e4755a 12648
c19d1205
ZW
12649 if (unified_syntax)
12650 {
5b7c81bd 12651 bool narrow;
3c707909
PB
12652 unsigned mask;
12653
5b7c81bd 12654 narrow = false;
c19d1205
ZW
12655 /* See if we can use a 16-bit instruction. */
12656 if (inst.instruction < 0xffff /* not ldmdb/stmdb */
12657 && inst.size_req != 4
3c707909 12658 && !(inst.operands[1].imm & ~0xff))
90e4755a 12659 {
3c707909 12660 mask = 1 << inst.operands[0].reg;
90e4755a 12661
eab4f823 12662 if (inst.operands[0].reg <= 7)
90e4755a 12663 {
3c707909 12664 if (inst.instruction == T_MNEM_stmia
eab4f823
MGD
12665 ? inst.operands[0].writeback
12666 : (inst.operands[0].writeback
12667 == !(inst.operands[1].imm & mask)))
477330fc 12668 {
eab4f823
MGD
12669 if (inst.instruction == T_MNEM_stmia
12670 && (inst.operands[1].imm & mask)
12671 && (inst.operands[1].imm & (mask - 1)))
12672 as_warn (_("value stored for r%d is UNKNOWN"),
12673 inst.operands[0].reg);
3c707909 12674
eab4f823
MGD
12675 inst.instruction = THUMB_OP16 (inst.instruction);
12676 inst.instruction |= inst.operands[0].reg << 8;
12677 inst.instruction |= inst.operands[1].imm;
5b7c81bd 12678 narrow = true;
eab4f823
MGD
12679 }
12680 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12681 {
12682 /* This means 1 register in reg list one of 3 situations:
12683 1. Instruction is stmia, but without writeback.
12684 2. lmdia without writeback, but with Rn not in
477330fc 12685 reglist.
eab4f823
MGD
12686 3. ldmia with writeback, but with Rn in reglist.
12687 Case 3 is UNPREDICTABLE behaviour, so we handle
12688 case 1 and 2 which can be converted into a 16-bit
12689 str or ldr. The SP cases are handled below. */
12690 unsigned long opcode;
12691 /* First, record an error for Case 3. */
12692 if (inst.operands[1].imm & mask
12693 && inst.operands[0].writeback)
fa94de6b 12694 inst.error =
eab4f823
MGD
12695 _("having the base register in the register list when "
12696 "using write back is UNPREDICTABLE");
fa94de6b
RM
12697
12698 opcode = (inst.instruction == T_MNEM_stmia ? T_MNEM_str
eab4f823
MGD
12699 : T_MNEM_ldr);
12700 inst.instruction = THUMB_OP16 (opcode);
12701 inst.instruction |= inst.operands[0].reg << 3;
12702 inst.instruction |= (ffs (inst.operands[1].imm)-1);
5b7c81bd 12703 narrow = true;
eab4f823 12704 }
90e4755a 12705 }
eab4f823 12706 else if (inst.operands[0] .reg == REG_SP)
90e4755a 12707 {
eab4f823
MGD
12708 if (inst.operands[0].writeback)
12709 {
fa94de6b 12710 inst.instruction =
eab4f823 12711 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12712 ? T_MNEM_push : T_MNEM_pop);
eab4f823 12713 inst.instruction |= inst.operands[1].imm;
5b7c81bd 12714 narrow = true;
eab4f823
MGD
12715 }
12716 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12717 {
fa94de6b 12718 inst.instruction =
eab4f823 12719 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12720 ? T_MNEM_str_sp : T_MNEM_ldr_sp);
eab4f823 12721 inst.instruction |= ((ffs (inst.operands[1].imm)-1) << 8);
5b7c81bd 12722 narrow = true;
eab4f823 12723 }
90e4755a 12724 }
3c707909
PB
12725 }
12726
12727 if (!narrow)
12728 {
c19d1205
ZW
12729 if (inst.instruction < 0xffff)
12730 inst.instruction = THUMB_OP32 (inst.instruction);
3c707909 12731
5b7c81bd 12732 encode_thumb2_multi (true /* do_io */, inst.operands[0].reg,
4b5a202f
AV
12733 inst.operands[1].imm,
12734 inst.operands[0].writeback);
90e4755a
RE
12735 }
12736 }
c19d1205 12737 else
90e4755a 12738 {
c19d1205
ZW
12739 constraint (inst.operands[0].reg > 7
12740 || (inst.operands[1].imm & ~0xff), BAD_HIREG);
1198ca51
PB
12741 constraint (inst.instruction != T_MNEM_ldmia
12742 && inst.instruction != T_MNEM_stmia,
12743 _("Thumb-2 instruction only valid in unified syntax"));
c19d1205 12744 if (inst.instruction == T_MNEM_stmia)
f03698e6 12745 {
c19d1205
ZW
12746 if (!inst.operands[0].writeback)
12747 as_warn (_("this instruction will write back the base register"));
12748 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
12749 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
1e5b0379 12750 as_warn (_("value stored for r%d is UNKNOWN"),
c19d1205 12751 inst.operands[0].reg);
f03698e6 12752 }
c19d1205 12753 else
90e4755a 12754 {
c19d1205
ZW
12755 if (!inst.operands[0].writeback
12756 && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
12757 as_warn (_("this instruction will write back the base register"));
12758 else if (inst.operands[0].writeback
12759 && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
12760 as_warn (_("this instruction will not write back the base register"));
90e4755a
RE
12761 }
12762
c19d1205
ZW
12763 inst.instruction = THUMB_OP16 (inst.instruction);
12764 inst.instruction |= inst.operands[0].reg << 8;
12765 inst.instruction |= inst.operands[1].imm;
12766 }
12767}
e28cd48c 12768
c19d1205
ZW
12769static void
12770do_t_ldrex (void)
12771{
12772 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
12773 || inst.operands[1].postind || inst.operands[1].writeback
12774 || inst.operands[1].immisreg || inst.operands[1].shifted
12775 || inst.operands[1].negative,
01cfc07f 12776 BAD_ADDR_MODE);
e28cd48c 12777
5be8be5d
DG
12778 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
12779
c19d1205
ZW
12780 inst.instruction |= inst.operands[0].reg << 12;
12781 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 12782 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
c19d1205 12783}
e28cd48c 12784
c19d1205
ZW
12785static void
12786do_t_ldrexd (void)
12787{
12788 if (!inst.operands[1].present)
1cac9012 12789 {
c19d1205
ZW
12790 constraint (inst.operands[0].reg == REG_LR,
12791 _("r14 not allowed as first register "
12792 "when second register is omitted"));
12793 inst.operands[1].reg = inst.operands[0].reg + 1;
b99bd4ef 12794 }
c19d1205
ZW
12795 constraint (inst.operands[0].reg == inst.operands[1].reg,
12796 BAD_OVERLAP);
b99bd4ef 12797
c19d1205
ZW
12798 inst.instruction |= inst.operands[0].reg << 12;
12799 inst.instruction |= inst.operands[1].reg << 8;
12800 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
12801}
12802
12803static void
c19d1205 12804do_t_ldst (void)
b99bd4ef 12805{
0110f2b8
PB
12806 unsigned long opcode;
12807 int Rn;
12808
e07e6e58
NC
12809 if (inst.operands[0].isreg
12810 && !inst.operands[0].preind
12811 && inst.operands[0].reg == REG_PC)
5ee91343 12812 set_pred_insn_type_last ();
e07e6e58 12813
0110f2b8 12814 opcode = inst.instruction;
c19d1205 12815 if (unified_syntax)
b99bd4ef 12816 {
53365c0d
PB
12817 if (!inst.operands[1].isreg)
12818 {
12819 if (opcode <= 0xffff)
12820 inst.instruction = THUMB_OP32 (opcode);
5b7c81bd 12821 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/false))
53365c0d
PB
12822 return;
12823 }
0110f2b8
PB
12824 if (inst.operands[1].isreg
12825 && !inst.operands[1].writeback
c19d1205
ZW
12826 && !inst.operands[1].shifted && !inst.operands[1].postind
12827 && !inst.operands[1].negative && inst.operands[0].reg <= 7
0110f2b8
PB
12828 && opcode <= 0xffff
12829 && inst.size_req != 4)
c19d1205 12830 {
0110f2b8
PB
12831 /* Insn may have a 16-bit form. */
12832 Rn = inst.operands[1].reg;
12833 if (inst.operands[1].immisreg)
12834 {
12835 inst.instruction = THUMB_OP16 (opcode);
5f4273c7 12836 /* [Rn, Rik] */
0110f2b8
PB
12837 if (Rn <= 7 && inst.operands[1].imm <= 7)
12838 goto op16;
5be8be5d
DG
12839 else if (opcode != T_MNEM_ldr && opcode != T_MNEM_str)
12840 reject_bad_reg (inst.operands[1].imm);
0110f2b8
PB
12841 }
12842 else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
12843 && opcode != T_MNEM_ldrsb)
12844 || ((Rn == REG_PC || Rn == REG_SP) && opcode == T_MNEM_ldr)
12845 || (Rn == REG_SP && opcode == T_MNEM_str))
12846 {
12847 /* [Rn, #const] */
12848 if (Rn > 7)
12849 {
12850 if (Rn == REG_PC)
12851 {
e2b0ab59 12852 if (inst.relocs[0].pc_rel)
0110f2b8
PB
12853 opcode = T_MNEM_ldr_pc2;
12854 else
12855 opcode = T_MNEM_ldr_pc;
12856 }
12857 else
12858 {
12859 if (opcode == T_MNEM_ldr)
12860 opcode = T_MNEM_ldr_sp;
12861 else
12862 opcode = T_MNEM_str_sp;
12863 }
12864 inst.instruction = inst.operands[0].reg << 8;
12865 }
12866 else
12867 {
12868 inst.instruction = inst.operands[0].reg;
12869 inst.instruction |= inst.operands[1].reg << 3;
12870 }
12871 inst.instruction |= THUMB_OP16 (opcode);
12872 if (inst.size_req == 2)
e2b0ab59 12873 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
0110f2b8
PB
12874 else
12875 inst.relax = opcode;
12876 return;
12877 }
c19d1205 12878 }
0110f2b8 12879 /* Definitely a 32-bit variant. */
5be8be5d 12880
8d67f500
NC
12881 /* Warning for Erratum 752419. */
12882 if (opcode == T_MNEM_ldr
12883 && inst.operands[0].reg == REG_SP
12884 && inst.operands[1].writeback == 1
12885 && !inst.operands[1].immisreg)
12886 {
12887 if (no_cpu_selected ()
12888 || (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7)
477330fc
RM
12889 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a)
12890 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7r)))
8d67f500
NC
12891 as_warn (_("This instruction may be unpredictable "
12892 "if executed on M-profile cores "
12893 "with interrupts enabled."));
12894 }
12895
5be8be5d 12896 /* Do some validations regarding addressing modes. */
1be5fd2e 12897 if (inst.operands[1].immisreg)
5be8be5d
DG
12898 reject_bad_reg (inst.operands[1].imm);
12899
1be5fd2e
NC
12900 constraint (inst.operands[1].writeback == 1
12901 && inst.operands[0].reg == inst.operands[1].reg,
12902 BAD_OVERLAP);
12903
0110f2b8 12904 inst.instruction = THUMB_OP32 (opcode);
c19d1205 12905 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 12906 encode_thumb32_addr_mode (1, /*is_t=*/false, /*is_d=*/false);
1be5fd2e 12907 check_ldr_r15_aligned ();
b99bd4ef
NC
12908 return;
12909 }
12910
c19d1205
ZW
12911 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12912
12913 if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
b99bd4ef 12914 {
c19d1205
ZW
12915 /* Only [Rn,Rm] is acceptable. */
12916 constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
12917 constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
12918 || inst.operands[1].postind || inst.operands[1].shifted
12919 || inst.operands[1].negative,
12920 _("Thumb does not support this addressing mode"));
12921 inst.instruction = THUMB_OP16 (inst.instruction);
12922 goto op16;
b99bd4ef 12923 }
5f4273c7 12924
c19d1205
ZW
12925 inst.instruction = THUMB_OP16 (inst.instruction);
12926 if (!inst.operands[1].isreg)
5b7c81bd 12927 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/false))
c19d1205 12928 return;
b99bd4ef 12929
c19d1205
ZW
12930 constraint (!inst.operands[1].preind
12931 || inst.operands[1].shifted
12932 || inst.operands[1].writeback,
12933 _("Thumb does not support this addressing mode"));
12934 if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
90e4755a 12935 {
c19d1205
ZW
12936 constraint (inst.instruction & 0x0600,
12937 _("byte or halfword not valid for base register"));
12938 constraint (inst.operands[1].reg == REG_PC
12939 && !(inst.instruction & THUMB_LOAD_BIT),
12940 _("r15 based store not allowed"));
12941 constraint (inst.operands[1].immisreg,
12942 _("invalid base register for register offset"));
b99bd4ef 12943
c19d1205
ZW
12944 if (inst.operands[1].reg == REG_PC)
12945 inst.instruction = T_OPCODE_LDR_PC;
12946 else if (inst.instruction & THUMB_LOAD_BIT)
12947 inst.instruction = T_OPCODE_LDR_SP;
12948 else
12949 inst.instruction = T_OPCODE_STR_SP;
b99bd4ef 12950
c19d1205 12951 inst.instruction |= inst.operands[0].reg << 8;
e2b0ab59 12952 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12953 return;
12954 }
90e4755a 12955
c19d1205
ZW
12956 constraint (inst.operands[1].reg > 7, BAD_HIREG);
12957 if (!inst.operands[1].immisreg)
12958 {
12959 /* Immediate offset. */
12960 inst.instruction |= inst.operands[0].reg;
12961 inst.instruction |= inst.operands[1].reg << 3;
e2b0ab59 12962 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12963 return;
12964 }
90e4755a 12965
c19d1205
ZW
12966 /* Register offset. */
12967 constraint (inst.operands[1].imm > 7, BAD_HIREG);
12968 constraint (inst.operands[1].negative,
12969 _("Thumb does not support this addressing mode"));
90e4755a 12970
c19d1205
ZW
12971 op16:
12972 switch (inst.instruction)
12973 {
12974 case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
12975 case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
12976 case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
12977 case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
12978 case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
12979 case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
12980 case 0x5600 /* ldrsb */:
12981 case 0x5e00 /* ldrsh */: break;
12982 default: abort ();
12983 }
90e4755a 12984
c19d1205
ZW
12985 inst.instruction |= inst.operands[0].reg;
12986 inst.instruction |= inst.operands[1].reg << 3;
12987 inst.instruction |= inst.operands[1].imm << 6;
12988}
90e4755a 12989
c19d1205
ZW
12990static void
12991do_t_ldstd (void)
12992{
12993 if (!inst.operands[1].present)
b99bd4ef 12994 {
c19d1205
ZW
12995 inst.operands[1].reg = inst.operands[0].reg + 1;
12996 constraint (inst.operands[0].reg == REG_LR,
12997 _("r14 not allowed here"));
bd340a04 12998 constraint (inst.operands[0].reg == REG_R12,
477330fc 12999 _("r12 not allowed here"));
b99bd4ef 13000 }
bd340a04
MGD
13001
13002 if (inst.operands[2].writeback
13003 && (inst.operands[0].reg == inst.operands[2].reg
13004 || inst.operands[1].reg == inst.operands[2].reg))
13005 as_warn (_("base register written back, and overlaps "
477330fc 13006 "one of transfer registers"));
bd340a04 13007
c19d1205
ZW
13008 inst.instruction |= inst.operands[0].reg << 12;
13009 inst.instruction |= inst.operands[1].reg << 8;
5b7c81bd 13010 encode_thumb32_addr_mode (2, /*is_t=*/false, /*is_d=*/true);
b99bd4ef
NC
13011}
13012
c19d1205
ZW
13013static void
13014do_t_ldstt (void)
13015{
13016 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 13017 encode_thumb32_addr_mode (1, /*is_t=*/true, /*is_d=*/false);
c19d1205 13018}
a737bd4d 13019
b99bd4ef 13020static void
c19d1205 13021do_t_mla (void)
b99bd4ef 13022{
fdfde340 13023 unsigned Rd, Rn, Rm, Ra;
c921be7d 13024
fdfde340
JM
13025 Rd = inst.operands[0].reg;
13026 Rn = inst.operands[1].reg;
13027 Rm = inst.operands[2].reg;
13028 Ra = inst.operands[3].reg;
13029
13030 reject_bad_reg (Rd);
13031 reject_bad_reg (Rn);
13032 reject_bad_reg (Rm);
13033 reject_bad_reg (Ra);
13034
13035 inst.instruction |= Rd << 8;
13036 inst.instruction |= Rn << 16;
13037 inst.instruction |= Rm;
13038 inst.instruction |= Ra << 12;
c19d1205 13039}
b99bd4ef 13040
c19d1205
ZW
13041static void
13042do_t_mlal (void)
13043{
fdfde340
JM
13044 unsigned RdLo, RdHi, Rn, Rm;
13045
13046 RdLo = inst.operands[0].reg;
13047 RdHi = inst.operands[1].reg;
13048 Rn = inst.operands[2].reg;
13049 Rm = inst.operands[3].reg;
13050
13051 reject_bad_reg (RdLo);
13052 reject_bad_reg (RdHi);
13053 reject_bad_reg (Rn);
13054 reject_bad_reg (Rm);
13055
13056 inst.instruction |= RdLo << 12;
13057 inst.instruction |= RdHi << 8;
13058 inst.instruction |= Rn << 16;
13059 inst.instruction |= Rm;
c19d1205 13060}
b99bd4ef 13061
c19d1205
ZW
13062static void
13063do_t_mov_cmp (void)
13064{
fdfde340
JM
13065 unsigned Rn, Rm;
13066
13067 Rn = inst.operands[0].reg;
13068 Rm = inst.operands[1].reg;
13069
e07e6e58 13070 if (Rn == REG_PC)
5ee91343 13071 set_pred_insn_type_last ();
e07e6e58 13072
c19d1205 13073 if (unified_syntax)
b99bd4ef 13074 {
c19d1205
ZW
13075 int r0off = (inst.instruction == T_MNEM_mov
13076 || inst.instruction == T_MNEM_movs) ? 8 : 16;
0110f2b8 13077 unsigned long opcode;
5b7c81bd
AM
13078 bool narrow;
13079 bool low_regs;
3d388997 13080
fdfde340 13081 low_regs = (Rn <= 7 && Rm <= 7);
0110f2b8 13082 opcode = inst.instruction;
5ee91343 13083 if (in_pred_block ())
0110f2b8 13084 narrow = opcode != T_MNEM_movs;
3d388997 13085 else
0110f2b8 13086 narrow = opcode != T_MNEM_movs || low_regs;
3d388997
PB
13087 if (inst.size_req == 4
13088 || inst.operands[1].shifted)
5b7c81bd 13089 narrow = false;
3d388997 13090
efd81785
PB
13091 /* MOVS PC, LR is encoded as SUBS PC, LR, #0. */
13092 if (opcode == T_MNEM_movs && inst.operands[1].isreg
13093 && !inst.operands[1].shifted
fdfde340
JM
13094 && Rn == REG_PC
13095 && Rm == REG_LR)
efd81785
PB
13096 {
13097 inst.instruction = T2_SUBS_PC_LR;
13098 return;
13099 }
13100
fdfde340
JM
13101 if (opcode == T_MNEM_cmp)
13102 {
13103 constraint (Rn == REG_PC, BAD_PC);
94206790
MM
13104 if (narrow)
13105 {
13106 /* In the Thumb-2 ISA, use of R13 as Rm is deprecated,
13107 but valid. */
13108 warn_deprecated_sp (Rm);
13109 /* R15 was documented as a valid choice for Rm in ARMv6,
13110 but as UNPREDICTABLE in ARMv7. ARM's proprietary
13111 tools reject R15, so we do too. */
13112 constraint (Rm == REG_PC, BAD_PC);
13113 }
13114 else
13115 reject_bad_reg (Rm);
fdfde340
JM
13116 }
13117 else if (opcode == T_MNEM_mov
13118 || opcode == T_MNEM_movs)
13119 {
13120 if (inst.operands[1].isreg)
13121 {
13122 if (opcode == T_MNEM_movs)
13123 {
13124 reject_bad_reg (Rn);
13125 reject_bad_reg (Rm);
13126 }
76fa04a4
MGD
13127 else if (narrow)
13128 {
13129 /* This is mov.n. */
13130 if ((Rn == REG_SP || Rn == REG_PC)
13131 && (Rm == REG_SP || Rm == REG_PC))
13132 {
5c3696f8 13133 as_tsktsk (_("Use of r%u as a source register is "
76fa04a4
MGD
13134 "deprecated when r%u is the destination "
13135 "register."), Rm, Rn);
13136 }
13137 }
13138 else
13139 {
13140 /* This is mov.w. */
13141 constraint (Rn == REG_PC, BAD_PC);
13142 constraint (Rm == REG_PC, BAD_PC);
5c8ed6a4
JW
13143 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
13144 constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
76fa04a4 13145 }
fdfde340
JM
13146 }
13147 else
13148 reject_bad_reg (Rn);
13149 }
13150
c19d1205
ZW
13151 if (!inst.operands[1].isreg)
13152 {
0110f2b8 13153 /* Immediate operand. */
5ee91343 13154 if (!in_pred_block () && opcode == T_MNEM_mov)
0110f2b8
PB
13155 narrow = 0;
13156 if (low_regs && narrow)
13157 {
13158 inst.instruction = THUMB_OP16 (opcode);
fdfde340 13159 inst.instruction |= Rn << 8;
e2b0ab59
AV
13160 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
13161 || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
72d98d16 13162 {
a9f02af8 13163 if (inst.size_req == 2)
e2b0ab59 13164 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
a9f02af8
MG
13165 else
13166 inst.relax = opcode;
72d98d16 13167 }
0110f2b8
PB
13168 }
13169 else
13170 {
e2b0ab59
AV
13171 constraint ((inst.relocs[0].type
13172 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
13173 && (inst.relocs[0].type
13174 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8
MG
13175 THUMB1_RELOC_ONLY);
13176
0110f2b8
PB
13177 inst.instruction = THUMB_OP32 (inst.instruction);
13178 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 13179 inst.instruction |= Rn << r0off;
e2b0ab59 13180 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8 13181 }
c19d1205 13182 }
728ca7c9
PB
13183 else if (inst.operands[1].shifted && inst.operands[1].immisreg
13184 && (inst.instruction == T_MNEM_mov
13185 || inst.instruction == T_MNEM_movs))
13186 {
13187 /* Register shifts are encoded as separate shift instructions. */
5b7c81bd 13188 bool flags = (inst.instruction == T_MNEM_movs);
728ca7c9 13189
5ee91343 13190 if (in_pred_block ())
728ca7c9
PB
13191 narrow = !flags;
13192 else
13193 narrow = flags;
13194
13195 if (inst.size_req == 4)
5b7c81bd 13196 narrow = false;
728ca7c9
PB
13197
13198 if (!low_regs || inst.operands[1].imm > 7)
5b7c81bd 13199 narrow = false;
728ca7c9 13200
fdfde340 13201 if (Rn != Rm)
5b7c81bd 13202 narrow = false;
728ca7c9
PB
13203
13204 switch (inst.operands[1].shift_kind)
13205 {
13206 case SHIFT_LSL:
13207 opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl);
13208 break;
13209 case SHIFT_ASR:
13210 opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr);
13211 break;
13212 case SHIFT_LSR:
13213 opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr);
13214 break;
13215 case SHIFT_ROR:
13216 opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror);
13217 break;
13218 default:
5f4273c7 13219 abort ();
728ca7c9
PB
13220 }
13221
13222 inst.instruction = opcode;
13223 if (narrow)
13224 {
fdfde340 13225 inst.instruction |= Rn;
728ca7c9
PB
13226 inst.instruction |= inst.operands[1].imm << 3;
13227 }
13228 else
13229 {
13230 if (flags)
13231 inst.instruction |= CONDS_BIT;
13232
fdfde340
JM
13233 inst.instruction |= Rn << 8;
13234 inst.instruction |= Rm << 16;
728ca7c9
PB
13235 inst.instruction |= inst.operands[1].imm;
13236 }
13237 }
3d388997 13238 else if (!narrow)
c19d1205 13239 {
728ca7c9
PB
13240 /* Some mov with immediate shift have narrow variants.
13241 Register shifts are handled above. */
13242 if (low_regs && inst.operands[1].shifted
13243 && (inst.instruction == T_MNEM_mov
13244 || inst.instruction == T_MNEM_movs))
13245 {
5ee91343 13246 if (in_pred_block ())
728ca7c9
PB
13247 narrow = (inst.instruction == T_MNEM_mov);
13248 else
13249 narrow = (inst.instruction == T_MNEM_movs);
13250 }
13251
13252 if (narrow)
13253 {
13254 switch (inst.operands[1].shift_kind)
13255 {
13256 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
13257 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
13258 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
5b7c81bd 13259 default: narrow = false; break;
728ca7c9
PB
13260 }
13261 }
13262
13263 if (narrow)
13264 {
fdfde340
JM
13265 inst.instruction |= Rn;
13266 inst.instruction |= Rm << 3;
e2b0ab59 13267 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
728ca7c9
PB
13268 }
13269 else
13270 {
13271 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 13272 inst.instruction |= Rn << r0off;
728ca7c9
PB
13273 encode_thumb32_shifted_operand (1);
13274 }
c19d1205
ZW
13275 }
13276 else
13277 switch (inst.instruction)
13278 {
13279 case T_MNEM_mov:
837b3435 13280 /* In v4t or v5t a move of two lowregs produces unpredictable
c6400f8a
MGD
13281 results. Don't allow this. */
13282 if (low_regs)
13283 {
13284 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
13285 "MOV Rd, Rs with two low registers is not "
13286 "permitted on this architecture");
fa94de6b 13287 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
c6400f8a
MGD
13288 arm_ext_v6);
13289 }
13290
c19d1205 13291 inst.instruction = T_OPCODE_MOV_HR;
fdfde340
JM
13292 inst.instruction |= (Rn & 0x8) << 4;
13293 inst.instruction |= (Rn & 0x7);
13294 inst.instruction |= Rm << 3;
c19d1205 13295 break;
b99bd4ef 13296
c19d1205
ZW
13297 case T_MNEM_movs:
13298 /* We know we have low registers at this point.
941a8a52
MGD
13299 Generate LSLS Rd, Rs, #0. */
13300 inst.instruction = T_OPCODE_LSL_I;
fdfde340
JM
13301 inst.instruction |= Rn;
13302 inst.instruction |= Rm << 3;
c19d1205
ZW
13303 break;
13304
13305 case T_MNEM_cmp:
3d388997 13306 if (low_regs)
c19d1205
ZW
13307 {
13308 inst.instruction = T_OPCODE_CMP_LR;
fdfde340
JM
13309 inst.instruction |= Rn;
13310 inst.instruction |= Rm << 3;
c19d1205
ZW
13311 }
13312 else
13313 {
13314 inst.instruction = T_OPCODE_CMP_HR;
fdfde340
JM
13315 inst.instruction |= (Rn & 0x8) << 4;
13316 inst.instruction |= (Rn & 0x7);
13317 inst.instruction |= Rm << 3;
c19d1205
ZW
13318 }
13319 break;
13320 }
b99bd4ef
NC
13321 return;
13322 }
13323
c19d1205 13324 inst.instruction = THUMB_OP16 (inst.instruction);
539d4391
NC
13325
13326 /* PR 10443: Do not silently ignore shifted operands. */
13327 constraint (inst.operands[1].shifted,
13328 _("shifts in CMP/MOV instructions are only supported in unified syntax"));
13329
c19d1205 13330 if (inst.operands[1].isreg)
b99bd4ef 13331 {
fdfde340 13332 if (Rn < 8 && Rm < 8)
b99bd4ef 13333 {
c19d1205
ZW
13334 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
13335 since a MOV instruction produces unpredictable results. */
13336 if (inst.instruction == T_OPCODE_MOV_I8)
13337 inst.instruction = T_OPCODE_ADD_I3;
b99bd4ef 13338 else
c19d1205 13339 inst.instruction = T_OPCODE_CMP_LR;
b99bd4ef 13340
fdfde340
JM
13341 inst.instruction |= Rn;
13342 inst.instruction |= Rm << 3;
b99bd4ef
NC
13343 }
13344 else
13345 {
c19d1205
ZW
13346 if (inst.instruction == T_OPCODE_MOV_I8)
13347 inst.instruction = T_OPCODE_MOV_HR;
13348 else
13349 inst.instruction = T_OPCODE_CMP_HR;
13350 do_t_cpy ();
b99bd4ef
NC
13351 }
13352 }
c19d1205 13353 else
b99bd4ef 13354 {
fdfde340 13355 constraint (Rn > 7,
c19d1205 13356 _("only lo regs allowed with immediate"));
fdfde340 13357 inst.instruction |= Rn << 8;
e2b0ab59 13358 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
c19d1205
ZW
13359 }
13360}
b99bd4ef 13361
c19d1205
ZW
13362static void
13363do_t_mov16 (void)
13364{
fdfde340 13365 unsigned Rd;
b6895b4f 13366 bfd_vma imm;
5b7c81bd 13367 bool top;
b6895b4f
PB
13368
13369 top = (inst.instruction & 0x00800000) != 0;
e2b0ab59 13370 if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
b6895b4f 13371 {
33eaf5de 13372 constraint (top, _(":lower16: not allowed in this instruction"));
e2b0ab59 13373 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
b6895b4f 13374 }
e2b0ab59 13375 else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
b6895b4f 13376 {
33eaf5de 13377 constraint (!top, _(":upper16: not allowed in this instruction"));
e2b0ab59 13378 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
b6895b4f
PB
13379 }
13380
fdfde340
JM
13381 Rd = inst.operands[0].reg;
13382 reject_bad_reg (Rd);
13383
13384 inst.instruction |= Rd << 8;
e2b0ab59 13385 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 13386 {
e2b0ab59 13387 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
13388 inst.instruction |= (imm & 0xf000) << 4;
13389 inst.instruction |= (imm & 0x0800) << 15;
13390 inst.instruction |= (imm & 0x0700) << 4;
13391 inst.instruction |= (imm & 0x00ff);
13392 }
c19d1205 13393}
b99bd4ef 13394
c19d1205
ZW
13395static void
13396do_t_mvn_tst (void)
13397{
fdfde340 13398 unsigned Rn, Rm;
c921be7d 13399
fdfde340
JM
13400 Rn = inst.operands[0].reg;
13401 Rm = inst.operands[1].reg;
13402
13403 if (inst.instruction == T_MNEM_cmp
13404 || inst.instruction == T_MNEM_cmn)
13405 constraint (Rn == REG_PC, BAD_PC);
13406 else
13407 reject_bad_reg (Rn);
13408 reject_bad_reg (Rm);
13409
c19d1205
ZW
13410 if (unified_syntax)
13411 {
13412 int r0off = (inst.instruction == T_MNEM_mvn
13413 || inst.instruction == T_MNEM_mvns) ? 8 : 16;
5b7c81bd 13414 bool narrow;
3d388997
PB
13415
13416 if (inst.size_req == 4
13417 || inst.instruction > 0xffff
13418 || inst.operands[1].shifted
fdfde340 13419 || Rn > 7 || Rm > 7)
5b7c81bd 13420 narrow = false;
fe8b4cc3
KT
13421 else if (inst.instruction == T_MNEM_cmn
13422 || inst.instruction == T_MNEM_tst)
5b7c81bd 13423 narrow = true;
3d388997 13424 else if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13425 narrow = !in_pred_block ();
3d388997 13426 else
5ee91343 13427 narrow = in_pred_block ();
3d388997 13428
c19d1205 13429 if (!inst.operands[1].isreg)
b99bd4ef 13430 {
c19d1205
ZW
13431 /* For an immediate, we always generate a 32-bit opcode;
13432 section relaxation will shrink it later if possible. */
13433 if (inst.instruction < 0xffff)
13434 inst.instruction = THUMB_OP32 (inst.instruction);
13435 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 13436 inst.instruction |= Rn << r0off;
e2b0ab59 13437 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 13438 }
c19d1205 13439 else
b99bd4ef 13440 {
c19d1205 13441 /* See if we can do this with a 16-bit instruction. */
3d388997 13442 if (narrow)
b99bd4ef 13443 {
c19d1205 13444 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13445 inst.instruction |= Rn;
13446 inst.instruction |= Rm << 3;
b99bd4ef 13447 }
c19d1205 13448 else
b99bd4ef 13449 {
c19d1205
ZW
13450 constraint (inst.operands[1].shifted
13451 && inst.operands[1].immisreg,
13452 _("shift must be constant"));
13453 if (inst.instruction < 0xffff)
13454 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 13455 inst.instruction |= Rn << r0off;
c19d1205 13456 encode_thumb32_shifted_operand (1);
b99bd4ef 13457 }
b99bd4ef
NC
13458 }
13459 }
13460 else
13461 {
c19d1205
ZW
13462 constraint (inst.instruction > 0xffff
13463 || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
13464 constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
13465 _("unshifted register required"));
fdfde340 13466 constraint (Rn > 7 || Rm > 7,
c19d1205 13467 BAD_HIREG);
b99bd4ef 13468
c19d1205 13469 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13470 inst.instruction |= Rn;
13471 inst.instruction |= Rm << 3;
b99bd4ef 13472 }
b99bd4ef
NC
13473}
13474
b05fe5cf 13475static void
c19d1205 13476do_t_mrs (void)
b05fe5cf 13477{
fdfde340 13478 unsigned Rd;
037e8744
JB
13479
13480 if (do_vfp_nsyn_mrs () == SUCCESS)
13481 return;
13482
90ec0d68
MGD
13483 Rd = inst.operands[0].reg;
13484 reject_bad_reg (Rd);
13485 inst.instruction |= Rd << 8;
13486
13487 if (inst.operands[1].isreg)
62b3e311 13488 {
90ec0d68
MGD
13489 unsigned br = inst.operands[1].reg;
13490 if (((br & 0x200) == 0) && ((br & 0xf000) != 0xf000))
13491 as_bad (_("bad register for mrs"));
13492
13493 inst.instruction |= br & (0xf << 16);
13494 inst.instruction |= (br & 0x300) >> 4;
13495 inst.instruction |= (br & SPSR_BIT) >> 2;
62b3e311
PB
13496 }
13497 else
13498 {
90ec0d68 13499 int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
5f4273c7 13500
d2cd1205 13501 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
1a43faaf
NC
13502 {
13503 /* PR gas/12698: The constraint is only applied for m_profile.
13504 If the user has specified -march=all, we want to ignore it as
13505 we are building for any CPU type, including non-m variants. */
5b7c81bd 13506 bool m_profile =
823d2571 13507 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf
NC
13508 constraint ((flags != 0) && m_profile, _("selected processor does "
13509 "not support requested special purpose register"));
13510 }
90ec0d68 13511 else
d2cd1205
JB
13512 /* mrs only accepts APSR/CPSR/SPSR/CPSR_all/SPSR_all (for non-M profile
13513 devices). */
13514 constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
13515 _("'APSR', 'CPSR' or 'SPSR' expected"));
fdfde340 13516
90ec0d68
MGD
13517 inst.instruction |= (flags & SPSR_BIT) >> 2;
13518 inst.instruction |= inst.operands[1].imm & 0xff;
13519 inst.instruction |= 0xf0000;
13520 }
c19d1205 13521}
b05fe5cf 13522
c19d1205
ZW
13523static void
13524do_t_msr (void)
13525{
62b3e311 13526 int flags;
fdfde340 13527 unsigned Rn;
62b3e311 13528
037e8744
JB
13529 if (do_vfp_nsyn_msr () == SUCCESS)
13530 return;
13531
c19d1205
ZW
13532 constraint (!inst.operands[1].isreg,
13533 _("Thumb encoding does not support an immediate here"));
90ec0d68
MGD
13534
13535 if (inst.operands[0].isreg)
13536 flags = (int)(inst.operands[0].reg);
13537 else
13538 flags = inst.operands[0].imm;
13539
d2cd1205 13540 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
62b3e311 13541 {
d2cd1205
JB
13542 int bits = inst.operands[0].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
13543
1a43faaf 13544 /* PR gas/12698: The constraint is only applied for m_profile.
477330fc
RM
13545 If the user has specified -march=all, we want to ignore it as
13546 we are building for any CPU type, including non-m variants. */
5b7c81bd 13547 bool m_profile =
823d2571 13548 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf 13549 constraint (((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
477330fc
RM
13550 && (bits & ~(PSR_s | PSR_f)) != 0)
13551 || (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
13552 && bits != PSR_f)) && m_profile,
13553 _("selected processor does not support requested special "
13554 "purpose register"));
62b3e311
PB
13555 }
13556 else
d2cd1205
JB
13557 constraint ((flags & 0xff) != 0, _("selected processor does not support "
13558 "requested special purpose register"));
c921be7d 13559
fdfde340
JM
13560 Rn = inst.operands[1].reg;
13561 reject_bad_reg (Rn);
13562
62b3e311 13563 inst.instruction |= (flags & SPSR_BIT) >> 2;
90ec0d68
MGD
13564 inst.instruction |= (flags & 0xf0000) >> 8;
13565 inst.instruction |= (flags & 0x300) >> 4;
62b3e311 13566 inst.instruction |= (flags & 0xff);
fdfde340 13567 inst.instruction |= Rn << 16;
c19d1205 13568}
b05fe5cf 13569
c19d1205
ZW
13570static void
13571do_t_mul (void)
13572{
5b7c81bd 13573 bool narrow;
fdfde340 13574 unsigned Rd, Rn, Rm;
17828f45 13575
c19d1205
ZW
13576 if (!inst.operands[2].present)
13577 inst.operands[2].reg = inst.operands[0].reg;
b05fe5cf 13578
fdfde340
JM
13579 Rd = inst.operands[0].reg;
13580 Rn = inst.operands[1].reg;
13581 Rm = inst.operands[2].reg;
13582
17828f45 13583 if (unified_syntax)
b05fe5cf 13584 {
17828f45 13585 if (inst.size_req == 4
fdfde340
JM
13586 || (Rd != Rn
13587 && Rd != Rm)
13588 || Rn > 7
13589 || Rm > 7)
5b7c81bd 13590 narrow = false;
17828f45 13591 else if (inst.instruction == T_MNEM_muls)
5ee91343 13592 narrow = !in_pred_block ();
17828f45 13593 else
5ee91343 13594 narrow = in_pred_block ();
b05fe5cf 13595 }
c19d1205 13596 else
b05fe5cf 13597 {
17828f45 13598 constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32);
fdfde340 13599 constraint (Rn > 7 || Rm > 7,
c19d1205 13600 BAD_HIREG);
5b7c81bd 13601 narrow = true;
17828f45 13602 }
b05fe5cf 13603
17828f45
JM
13604 if (narrow)
13605 {
13606 /* 16-bit MULS/Conditional MUL. */
c19d1205 13607 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 13608 inst.instruction |= Rd;
b05fe5cf 13609
fdfde340
JM
13610 if (Rd == Rn)
13611 inst.instruction |= Rm << 3;
13612 else if (Rd == Rm)
13613 inst.instruction |= Rn << 3;
c19d1205
ZW
13614 else
13615 constraint (1, _("dest must overlap one source register"));
13616 }
17828f45
JM
13617 else
13618 {
e07e6e58
NC
13619 constraint (inst.instruction != T_MNEM_mul,
13620 _("Thumb-2 MUL must not set flags"));
17828f45
JM
13621 /* 32-bit MUL. */
13622 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13623 inst.instruction |= Rd << 8;
13624 inst.instruction |= Rn << 16;
13625 inst.instruction |= Rm << 0;
13626
13627 reject_bad_reg (Rd);
13628 reject_bad_reg (Rn);
13629 reject_bad_reg (Rm);
17828f45 13630 }
c19d1205 13631}
b05fe5cf 13632
c19d1205
ZW
13633static void
13634do_t_mull (void)
13635{
fdfde340 13636 unsigned RdLo, RdHi, Rn, Rm;
b05fe5cf 13637
fdfde340
JM
13638 RdLo = inst.operands[0].reg;
13639 RdHi = inst.operands[1].reg;
13640 Rn = inst.operands[2].reg;
13641 Rm = inst.operands[3].reg;
13642
13643 reject_bad_reg (RdLo);
13644 reject_bad_reg (RdHi);
13645 reject_bad_reg (Rn);
13646 reject_bad_reg (Rm);
13647
13648 inst.instruction |= RdLo << 12;
13649 inst.instruction |= RdHi << 8;
13650 inst.instruction |= Rn << 16;
13651 inst.instruction |= Rm;
13652
13653 if (RdLo == RdHi)
c19d1205
ZW
13654 as_tsktsk (_("rdhi and rdlo must be different"));
13655}
b05fe5cf 13656
c19d1205
ZW
13657static void
13658do_t_nop (void)
13659{
5ee91343 13660 set_pred_insn_type (NEUTRAL_IT_INSN);
e07e6e58 13661
c19d1205
ZW
13662 if (unified_syntax)
13663 {
13664 if (inst.size_req == 4 || inst.operands[0].imm > 15)
b05fe5cf 13665 {
c19d1205
ZW
13666 inst.instruction = THUMB_OP32 (inst.instruction);
13667 inst.instruction |= inst.operands[0].imm;
13668 }
13669 else
13670 {
bc2d1808
NC
13671 /* PR9722: Check for Thumb2 availability before
13672 generating a thumb2 nop instruction. */
afa62d5e 13673 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
bc2d1808
NC
13674 {
13675 inst.instruction = THUMB_OP16 (inst.instruction);
13676 inst.instruction |= inst.operands[0].imm << 4;
13677 }
13678 else
13679 inst.instruction = 0x46c0;
c19d1205
ZW
13680 }
13681 }
13682 else
13683 {
13684 constraint (inst.operands[0].present,
13685 _("Thumb does not support NOP with hints"));
13686 inst.instruction = 0x46c0;
13687 }
13688}
b05fe5cf 13689
c19d1205
ZW
13690static void
13691do_t_neg (void)
13692{
13693 if (unified_syntax)
13694 {
5b7c81bd 13695 bool narrow;
3d388997
PB
13696
13697 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13698 narrow = !in_pred_block ();
3d388997 13699 else
5ee91343 13700 narrow = in_pred_block ();
3d388997 13701 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
5b7c81bd 13702 narrow = false;
3d388997 13703 if (inst.size_req == 4)
5b7c81bd 13704 narrow = false;
3d388997
PB
13705
13706 if (!narrow)
c19d1205
ZW
13707 {
13708 inst.instruction = THUMB_OP32 (inst.instruction);
13709 inst.instruction |= inst.operands[0].reg << 8;
13710 inst.instruction |= inst.operands[1].reg << 16;
b05fe5cf
ZW
13711 }
13712 else
13713 {
c19d1205
ZW
13714 inst.instruction = THUMB_OP16 (inst.instruction);
13715 inst.instruction |= inst.operands[0].reg;
13716 inst.instruction |= inst.operands[1].reg << 3;
b05fe5cf
ZW
13717 }
13718 }
13719 else
13720 {
c19d1205
ZW
13721 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
13722 BAD_HIREG);
13723 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
13724
13725 inst.instruction = THUMB_OP16 (inst.instruction);
13726 inst.instruction |= inst.operands[0].reg;
13727 inst.instruction |= inst.operands[1].reg << 3;
13728 }
13729}
13730
1c444d06
JM
13731static void
13732do_t_orn (void)
13733{
13734 unsigned Rd, Rn;
13735
13736 Rd = inst.operands[0].reg;
13737 Rn = inst.operands[1].present ? inst.operands[1].reg : Rd;
13738
fdfde340
JM
13739 reject_bad_reg (Rd);
13740 /* Rn == REG_SP is unpredictable; Rn == REG_PC is MVN. */
13741 reject_bad_reg (Rn);
13742
1c444d06
JM
13743 inst.instruction |= Rd << 8;
13744 inst.instruction |= Rn << 16;
13745
13746 if (!inst.operands[2].isreg)
13747 {
13748 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13749 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
1c444d06
JM
13750 }
13751 else
13752 {
13753 unsigned Rm;
13754
13755 Rm = inst.operands[2].reg;
fdfde340 13756 reject_bad_reg (Rm);
1c444d06
JM
13757
13758 constraint (inst.operands[2].shifted
13759 && inst.operands[2].immisreg,
13760 _("shift must be constant"));
13761 encode_thumb32_shifted_operand (2);
13762 }
13763}
13764
c19d1205
ZW
13765static void
13766do_t_pkhbt (void)
13767{
fdfde340
JM
13768 unsigned Rd, Rn, Rm;
13769
13770 Rd = inst.operands[0].reg;
13771 Rn = inst.operands[1].reg;
13772 Rm = inst.operands[2].reg;
13773
13774 reject_bad_reg (Rd);
13775 reject_bad_reg (Rn);
13776 reject_bad_reg (Rm);
13777
13778 inst.instruction |= Rd << 8;
13779 inst.instruction |= Rn << 16;
13780 inst.instruction |= Rm;
c19d1205
ZW
13781 if (inst.operands[3].present)
13782 {
e2b0ab59
AV
13783 unsigned int val = inst.relocs[0].exp.X_add_number;
13784 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
13785 _("expression too complex"));
13786 inst.instruction |= (val & 0x1c) << 10;
13787 inst.instruction |= (val & 0x03) << 6;
b05fe5cf 13788 }
c19d1205 13789}
b05fe5cf 13790
c19d1205
ZW
13791static void
13792do_t_pkhtb (void)
13793{
13794 if (!inst.operands[3].present)
1ef52f49
NC
13795 {
13796 unsigned Rtmp;
13797
13798 inst.instruction &= ~0x00000020;
13799
13800 /* PR 10168. Swap the Rm and Rn registers. */
13801 Rtmp = inst.operands[1].reg;
13802 inst.operands[1].reg = inst.operands[2].reg;
13803 inst.operands[2].reg = Rtmp;
13804 }
c19d1205 13805 do_t_pkhbt ();
b05fe5cf
ZW
13806}
13807
c19d1205
ZW
13808static void
13809do_t_pld (void)
13810{
fdfde340
JM
13811 if (inst.operands[0].immisreg)
13812 reject_bad_reg (inst.operands[0].imm);
13813
5b7c81bd 13814 encode_thumb32_addr_mode (0, /*is_t=*/false, /*is_d=*/false);
c19d1205 13815}
b05fe5cf 13816
c19d1205
ZW
13817static void
13818do_t_push_pop (void)
b99bd4ef 13819{
e9f89963 13820 unsigned mask;
5f4273c7 13821
c19d1205
ZW
13822 constraint (inst.operands[0].writeback,
13823 _("push/pop do not support {reglist}^"));
e2b0ab59 13824 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205 13825 _("expression too complex"));
b99bd4ef 13826
e9f89963 13827 mask = inst.operands[0].imm;
d3bfe16e 13828 if (inst.size_req != 4 && (mask & ~0xff) == 0)
3c707909 13829 inst.instruction = THUMB_OP16 (inst.instruction) | mask;
d3bfe16e 13830 else if (inst.size_req != 4
c6025a80 13831 && (mask & ~0xff) == (1U << (inst.instruction == T_MNEM_push
d3bfe16e 13832 ? REG_LR : REG_PC)))
b99bd4ef 13833 {
c19d1205
ZW
13834 inst.instruction = THUMB_OP16 (inst.instruction);
13835 inst.instruction |= THUMB_PP_PC_LR;
3c707909 13836 inst.instruction |= mask & 0xff;
c19d1205
ZW
13837 }
13838 else if (unified_syntax)
13839 {
3c707909 13840 inst.instruction = THUMB_OP32 (inst.instruction);
5b7c81bd 13841 encode_thumb2_multi (true /* do_io */, 13, mask, true);
4b5a202f
AV
13842 }
13843 else
13844 {
13845 inst.error = _("invalid register list to push/pop instruction");
13846 return;
c19d1205 13847 }
4b5a202f
AV
13848}
13849
13850static void
13851do_t_clrm (void)
13852{
13853 if (unified_syntax)
5b7c81bd 13854 encode_thumb2_multi (false /* do_io */, -1, inst.operands[0].imm, false);
c19d1205
ZW
13855 else
13856 {
13857 inst.error = _("invalid register list to push/pop instruction");
13858 return;
13859 }
c19d1205 13860}
b99bd4ef 13861
efd6b359
AV
13862static void
13863do_t_vscclrm (void)
13864{
13865 if (inst.operands[0].issingle)
13866 {
13867 inst.instruction |= (inst.operands[0].reg & 0x1) << 22;
13868 inst.instruction |= (inst.operands[0].reg & 0x1e) << 11;
13869 inst.instruction |= inst.operands[0].imm;
13870 }
13871 else
13872 {
13873 inst.instruction |= (inst.operands[0].reg & 0x10) << 18;
13874 inst.instruction |= (inst.operands[0].reg & 0xf) << 12;
13875 inst.instruction |= 1 << 8;
13876 inst.instruction |= inst.operands[0].imm << 1;
13877 }
13878}
13879
c19d1205
ZW
13880static void
13881do_t_rbit (void)
13882{
fdfde340
JM
13883 unsigned Rd, Rm;
13884
13885 Rd = inst.operands[0].reg;
13886 Rm = inst.operands[1].reg;
13887
13888 reject_bad_reg (Rd);
13889 reject_bad_reg (Rm);
13890
13891 inst.instruction |= Rd << 8;
13892 inst.instruction |= Rm << 16;
13893 inst.instruction |= Rm;
c19d1205 13894}
b99bd4ef 13895
c19d1205
ZW
13896static void
13897do_t_rev (void)
13898{
fdfde340
JM
13899 unsigned Rd, Rm;
13900
13901 Rd = inst.operands[0].reg;
13902 Rm = inst.operands[1].reg;
13903
13904 reject_bad_reg (Rd);
13905 reject_bad_reg (Rm);
13906
13907 if (Rd <= 7 && Rm <= 7
c19d1205
ZW
13908 && inst.size_req != 4)
13909 {
13910 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13911 inst.instruction |= Rd;
13912 inst.instruction |= Rm << 3;
c19d1205
ZW
13913 }
13914 else if (unified_syntax)
13915 {
13916 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13917 inst.instruction |= Rd << 8;
13918 inst.instruction |= Rm << 16;
13919 inst.instruction |= Rm;
c19d1205
ZW
13920 }
13921 else
13922 inst.error = BAD_HIREG;
13923}
b99bd4ef 13924
1c444d06
JM
13925static void
13926do_t_rrx (void)
13927{
13928 unsigned Rd, Rm;
13929
13930 Rd = inst.operands[0].reg;
13931 Rm = inst.operands[1].reg;
13932
fdfde340
JM
13933 reject_bad_reg (Rd);
13934 reject_bad_reg (Rm);
c921be7d 13935
1c444d06
JM
13936 inst.instruction |= Rd << 8;
13937 inst.instruction |= Rm;
13938}
13939
c19d1205
ZW
13940static void
13941do_t_rsb (void)
13942{
fdfde340 13943 unsigned Rd, Rs;
b99bd4ef 13944
c19d1205
ZW
13945 Rd = inst.operands[0].reg;
13946 Rs = (inst.operands[1].present
13947 ? inst.operands[1].reg /* Rd, Rs, foo */
13948 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
b99bd4ef 13949
fdfde340
JM
13950 reject_bad_reg (Rd);
13951 reject_bad_reg (Rs);
13952 if (inst.operands[2].isreg)
13953 reject_bad_reg (inst.operands[2].reg);
13954
c19d1205
ZW
13955 inst.instruction |= Rd << 8;
13956 inst.instruction |= Rs << 16;
13957 if (!inst.operands[2].isreg)
13958 {
5b7c81bd 13959 bool narrow;
026d3abb
PB
13960
13961 if ((inst.instruction & 0x00100000) != 0)
5ee91343 13962 narrow = !in_pred_block ();
026d3abb 13963 else
5ee91343 13964 narrow = in_pred_block ();
026d3abb
PB
13965
13966 if (Rd > 7 || Rs > 7)
5b7c81bd 13967 narrow = false;
026d3abb
PB
13968
13969 if (inst.size_req == 4 || !unified_syntax)
5b7c81bd 13970 narrow = false;
026d3abb 13971
e2b0ab59
AV
13972 if (inst.relocs[0].exp.X_op != O_constant
13973 || inst.relocs[0].exp.X_add_number != 0)
5b7c81bd 13974 narrow = false;
026d3abb
PB
13975
13976 /* Turn rsb #0 into 16-bit neg. We should probably do this via
477330fc 13977 relaxation, but it doesn't seem worth the hassle. */
026d3abb
PB
13978 if (narrow)
13979 {
e2b0ab59 13980 inst.relocs[0].type = BFD_RELOC_UNUSED;
026d3abb
PB
13981 inst.instruction = THUMB_OP16 (T_MNEM_negs);
13982 inst.instruction |= Rs << 3;
13983 inst.instruction |= Rd;
13984 }
13985 else
13986 {
13987 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13988 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
026d3abb 13989 }
c19d1205
ZW
13990 }
13991 else
13992 encode_thumb32_shifted_operand (2);
13993}
b99bd4ef 13994
c19d1205
ZW
13995static void
13996do_t_setend (void)
13997{
12e37cbc
MGD
13998 if (warn_on_deprecated
13999 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 14000 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 14001
5ee91343 14002 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
14003 if (inst.operands[0].imm)
14004 inst.instruction |= 0x8;
14005}
b99bd4ef 14006
c19d1205
ZW
14007static void
14008do_t_shift (void)
14009{
14010 if (!inst.operands[1].present)
14011 inst.operands[1].reg = inst.operands[0].reg;
14012
14013 if (unified_syntax)
14014 {
5b7c81bd 14015 bool narrow;
3d388997
PB
14016 int shift_kind;
14017
14018 switch (inst.instruction)
14019 {
14020 case T_MNEM_asr:
14021 case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
14022 case T_MNEM_lsl:
14023 case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
14024 case T_MNEM_lsr:
14025 case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
14026 case T_MNEM_ror:
14027 case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
14028 default: abort ();
14029 }
14030
14031 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 14032 narrow = !in_pred_block ();
3d388997 14033 else
5ee91343 14034 narrow = in_pred_block ();
3d388997 14035 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
5b7c81bd 14036 narrow = false;
3d388997 14037 if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
5b7c81bd 14038 narrow = false;
3d388997
PB
14039 if (inst.operands[2].isreg
14040 && (inst.operands[1].reg != inst.operands[0].reg
14041 || inst.operands[2].reg > 7))
5b7c81bd 14042 narrow = false;
3d388997 14043 if (inst.size_req == 4)
5b7c81bd 14044 narrow = false;
3d388997 14045
fdfde340
JM
14046 reject_bad_reg (inst.operands[0].reg);
14047 reject_bad_reg (inst.operands[1].reg);
c921be7d 14048
3d388997 14049 if (!narrow)
c19d1205
ZW
14050 {
14051 if (inst.operands[2].isreg)
b99bd4ef 14052 {
fdfde340 14053 reject_bad_reg (inst.operands[2].reg);
c19d1205
ZW
14054 inst.instruction = THUMB_OP32 (inst.instruction);
14055 inst.instruction |= inst.operands[0].reg << 8;
14056 inst.instruction |= inst.operands[1].reg << 16;
14057 inst.instruction |= inst.operands[2].reg;
94342ec3
NC
14058
14059 /* PR 12854: Error on extraneous shifts. */
14060 constraint (inst.operands[2].shifted,
14061 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
14062 }
14063 else
14064 {
14065 inst.operands[1].shifted = 1;
3d388997 14066 inst.operands[1].shift_kind = shift_kind;
c19d1205
ZW
14067 inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
14068 ? T_MNEM_movs : T_MNEM_mov);
14069 inst.instruction |= inst.operands[0].reg << 8;
14070 encode_thumb32_shifted_operand (1);
14071 /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
e2b0ab59 14072 inst.relocs[0].type = BFD_RELOC_UNUSED;
b99bd4ef
NC
14073 }
14074 }
14075 else
14076 {
c19d1205 14077 if (inst.operands[2].isreg)
b99bd4ef 14078 {
3d388997 14079 switch (shift_kind)
b99bd4ef 14080 {
3d388997
PB
14081 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
14082 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
14083 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
14084 case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
c19d1205 14085 default: abort ();
b99bd4ef 14086 }
5f4273c7 14087
c19d1205
ZW
14088 inst.instruction |= inst.operands[0].reg;
14089 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
14090
14091 /* PR 12854: Error on extraneous shifts. */
14092 constraint (inst.operands[2].shifted,
14093 _("extraneous shift as part of operand to shift insn"));
b99bd4ef
NC
14094 }
14095 else
14096 {
3d388997 14097 switch (shift_kind)
b99bd4ef 14098 {
3d388997
PB
14099 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
14100 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
14101 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
c19d1205 14102 default: abort ();
b99bd4ef 14103 }
e2b0ab59 14104 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
14105 inst.instruction |= inst.operands[0].reg;
14106 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
14107 }
14108 }
c19d1205
ZW
14109 }
14110 else
14111 {
14112 constraint (inst.operands[0].reg > 7
14113 || inst.operands[1].reg > 7, BAD_HIREG);
14114 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
b99bd4ef 14115
c19d1205
ZW
14116 if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
14117 {
14118 constraint (inst.operands[2].reg > 7, BAD_HIREG);
14119 constraint (inst.operands[0].reg != inst.operands[1].reg,
14120 _("source1 and dest must be same register"));
b99bd4ef 14121
c19d1205
ZW
14122 switch (inst.instruction)
14123 {
14124 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
14125 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
14126 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
14127 case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
14128 default: abort ();
14129 }
5f4273c7 14130
c19d1205
ZW
14131 inst.instruction |= inst.operands[0].reg;
14132 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
14133
14134 /* PR 12854: Error on extraneous shifts. */
14135 constraint (inst.operands[2].shifted,
14136 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
14137 }
14138 else
b99bd4ef 14139 {
c19d1205
ZW
14140 switch (inst.instruction)
14141 {
14142 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
14143 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
14144 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
14145 case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
14146 default: abort ();
14147 }
e2b0ab59 14148 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
14149 inst.instruction |= inst.operands[0].reg;
14150 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
14151 }
14152 }
b99bd4ef
NC
14153}
14154
14155static void
c19d1205 14156do_t_simd (void)
b99bd4ef 14157{
fdfde340
JM
14158 unsigned Rd, Rn, Rm;
14159
14160 Rd = inst.operands[0].reg;
14161 Rn = inst.operands[1].reg;
14162 Rm = inst.operands[2].reg;
14163
14164 reject_bad_reg (Rd);
14165 reject_bad_reg (Rn);
14166 reject_bad_reg (Rm);
14167
14168 inst.instruction |= Rd << 8;
14169 inst.instruction |= Rn << 16;
14170 inst.instruction |= Rm;
c19d1205 14171}
b99bd4ef 14172
03ee1b7f
NC
14173static void
14174do_t_simd2 (void)
14175{
14176 unsigned Rd, Rn, Rm;
14177
14178 Rd = inst.operands[0].reg;
14179 Rm = inst.operands[1].reg;
14180 Rn = inst.operands[2].reg;
14181
14182 reject_bad_reg (Rd);
14183 reject_bad_reg (Rn);
14184 reject_bad_reg (Rm);
14185
14186 inst.instruction |= Rd << 8;
14187 inst.instruction |= Rn << 16;
14188 inst.instruction |= Rm;
14189}
14190
c19d1205 14191static void
3eb17e6b 14192do_t_smc (void)
c19d1205 14193{
e2b0ab59 14194 unsigned int value = inst.relocs[0].exp.X_add_number;
f4c65163
MGD
14195 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
14196 _("SMC is not permitted on this architecture"));
e2b0ab59 14197 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 14198 _("expression too complex"));
ba85f98c
BW
14199 constraint (value > 0xf, _("immediate too large (bigger than 0xF)"));
14200
e2b0ab59 14201 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205 14202 inst.instruction |= (value & 0x000f) << 16;
ba85f98c 14203
24382199 14204 /* PR gas/15623: SMC instructions must be last in an IT block. */
5ee91343 14205 set_pred_insn_type_last ();
c19d1205 14206}
b99bd4ef 14207
90ec0d68
MGD
14208static void
14209do_t_hvc (void)
14210{
e2b0ab59 14211 unsigned int value = inst.relocs[0].exp.X_add_number;
90ec0d68 14212
e2b0ab59 14213 inst.relocs[0].type = BFD_RELOC_UNUSED;
90ec0d68
MGD
14214 inst.instruction |= (value & 0x0fff);
14215 inst.instruction |= (value & 0xf000) << 4;
14216}
14217
c19d1205 14218static void
3a21c15a 14219do_t_ssat_usat (int bias)
c19d1205 14220{
fdfde340
JM
14221 unsigned Rd, Rn;
14222
14223 Rd = inst.operands[0].reg;
14224 Rn = inst.operands[2].reg;
14225
14226 reject_bad_reg (Rd);
14227 reject_bad_reg (Rn);
14228
14229 inst.instruction |= Rd << 8;
3a21c15a 14230 inst.instruction |= inst.operands[1].imm - bias;
fdfde340 14231 inst.instruction |= Rn << 16;
b99bd4ef 14232
c19d1205 14233 if (inst.operands[3].present)
b99bd4ef 14234 {
e2b0ab59 14235 offsetT shift_amount = inst.relocs[0].exp.X_add_number;
3a21c15a 14236
e2b0ab59 14237 inst.relocs[0].type = BFD_RELOC_UNUSED;
3a21c15a 14238
e2b0ab59 14239 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 14240 _("expression too complex"));
b99bd4ef 14241
3a21c15a 14242 if (shift_amount != 0)
6189168b 14243 {
3a21c15a
NC
14244 constraint (shift_amount > 31,
14245 _("shift expression is too large"));
14246
c19d1205 14247 if (inst.operands[3].shift_kind == SHIFT_ASR)
3a21c15a
NC
14248 inst.instruction |= 0x00200000; /* sh bit. */
14249
14250 inst.instruction |= (shift_amount & 0x1c) << 10;
14251 inst.instruction |= (shift_amount & 0x03) << 6;
6189168b
NC
14252 }
14253 }
b99bd4ef 14254}
c921be7d 14255
3a21c15a
NC
14256static void
14257do_t_ssat (void)
14258{
14259 do_t_ssat_usat (1);
14260}
b99bd4ef 14261
0dd132b6 14262static void
c19d1205 14263do_t_ssat16 (void)
0dd132b6 14264{
fdfde340
JM
14265 unsigned Rd, Rn;
14266
14267 Rd = inst.operands[0].reg;
14268 Rn = inst.operands[2].reg;
14269
14270 reject_bad_reg (Rd);
14271 reject_bad_reg (Rn);
14272
14273 inst.instruction |= Rd << 8;
c19d1205 14274 inst.instruction |= inst.operands[1].imm - 1;
fdfde340 14275 inst.instruction |= Rn << 16;
c19d1205 14276}
0dd132b6 14277
c19d1205
ZW
14278static void
14279do_t_strex (void)
14280{
14281 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
14282 || inst.operands[2].postind || inst.operands[2].writeback
14283 || inst.operands[2].immisreg || inst.operands[2].shifted
14284 || inst.operands[2].negative,
01cfc07f 14285 BAD_ADDR_MODE);
0dd132b6 14286
5be8be5d
DG
14287 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
14288
c19d1205
ZW
14289 inst.instruction |= inst.operands[0].reg << 8;
14290 inst.instruction |= inst.operands[1].reg << 12;
14291 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 14292 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
0dd132b6
NC
14293}
14294
b99bd4ef 14295static void
c19d1205 14296do_t_strexd (void)
b99bd4ef 14297{
c19d1205
ZW
14298 if (!inst.operands[2].present)
14299 inst.operands[2].reg = inst.operands[1].reg + 1;
b99bd4ef 14300
c19d1205
ZW
14301 constraint (inst.operands[0].reg == inst.operands[1].reg
14302 || inst.operands[0].reg == inst.operands[2].reg
f8a8e9d6 14303 || inst.operands[0].reg == inst.operands[3].reg,
c19d1205 14304 BAD_OVERLAP);
b99bd4ef 14305
c19d1205
ZW
14306 inst.instruction |= inst.operands[0].reg;
14307 inst.instruction |= inst.operands[1].reg << 12;
14308 inst.instruction |= inst.operands[2].reg << 8;
14309 inst.instruction |= inst.operands[3].reg << 16;
b99bd4ef
NC
14310}
14311
14312static void
c19d1205 14313do_t_sxtah (void)
b99bd4ef 14314{
fdfde340
JM
14315 unsigned Rd, Rn, Rm;
14316
14317 Rd = inst.operands[0].reg;
14318 Rn = inst.operands[1].reg;
14319 Rm = inst.operands[2].reg;
14320
14321 reject_bad_reg (Rd);
14322 reject_bad_reg (Rn);
14323 reject_bad_reg (Rm);
14324
14325 inst.instruction |= Rd << 8;
14326 inst.instruction |= Rn << 16;
14327 inst.instruction |= Rm;
c19d1205
ZW
14328 inst.instruction |= inst.operands[3].imm << 4;
14329}
b99bd4ef 14330
c19d1205
ZW
14331static void
14332do_t_sxth (void)
14333{
fdfde340
JM
14334 unsigned Rd, Rm;
14335
14336 Rd = inst.operands[0].reg;
14337 Rm = inst.operands[1].reg;
14338
14339 reject_bad_reg (Rd);
14340 reject_bad_reg (Rm);
c921be7d
NC
14341
14342 if (inst.instruction <= 0xffff
14343 && inst.size_req != 4
fdfde340 14344 && Rd <= 7 && Rm <= 7
c19d1205 14345 && (!inst.operands[2].present || inst.operands[2].imm == 0))
b99bd4ef 14346 {
c19d1205 14347 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
14348 inst.instruction |= Rd;
14349 inst.instruction |= Rm << 3;
b99bd4ef 14350 }
c19d1205 14351 else if (unified_syntax)
b99bd4ef 14352 {
c19d1205
ZW
14353 if (inst.instruction <= 0xffff)
14354 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
14355 inst.instruction |= Rd << 8;
14356 inst.instruction |= Rm;
c19d1205 14357 inst.instruction |= inst.operands[2].imm << 4;
b99bd4ef 14358 }
c19d1205 14359 else
b99bd4ef 14360 {
c19d1205
ZW
14361 constraint (inst.operands[2].present && inst.operands[2].imm != 0,
14362 _("Thumb encoding does not support rotation"));
14363 constraint (1, BAD_HIREG);
b99bd4ef 14364 }
c19d1205 14365}
b99bd4ef 14366
c19d1205
ZW
14367static void
14368do_t_swi (void)
14369{
e2b0ab59 14370 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
c19d1205 14371}
b99bd4ef 14372
92e90b6e
PB
14373static void
14374do_t_tb (void)
14375{
fdfde340 14376 unsigned Rn, Rm;
92e90b6e
PB
14377 int half;
14378
14379 half = (inst.instruction & 0x10) != 0;
5ee91343 14380 set_pred_insn_type_last ();
dfa9f0d5
PB
14381 constraint (inst.operands[0].immisreg,
14382 _("instruction requires register index"));
fdfde340
JM
14383
14384 Rn = inst.operands[0].reg;
14385 Rm = inst.operands[0].imm;
c921be7d 14386
5c8ed6a4
JW
14387 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
14388 constraint (Rn == REG_SP, BAD_SP);
fdfde340
JM
14389 reject_bad_reg (Rm);
14390
92e90b6e
PB
14391 constraint (!half && inst.operands[0].shifted,
14392 _("instruction does not allow shifted index"));
fdfde340 14393 inst.instruction |= (Rn << 16) | Rm;
92e90b6e
PB
14394}
14395
74db7efb
NC
14396static void
14397do_t_udf (void)
14398{
14399 if (!inst.operands[0].present)
14400 inst.operands[0].imm = 0;
14401
14402 if ((unsigned int) inst.operands[0].imm > 255 || inst.size_req == 4)
14403 {
14404 constraint (inst.size_req == 2,
14405 _("immediate value out of range"));
14406 inst.instruction = THUMB_OP32 (inst.instruction);
14407 inst.instruction |= (inst.operands[0].imm & 0xf000u) << 4;
14408 inst.instruction |= (inst.operands[0].imm & 0x0fffu) << 0;
14409 }
14410 else
14411 {
14412 inst.instruction = THUMB_OP16 (inst.instruction);
14413 inst.instruction |= inst.operands[0].imm;
14414 }
14415
5ee91343 14416 set_pred_insn_type (NEUTRAL_IT_INSN);
74db7efb
NC
14417}
14418
14419
c19d1205
ZW
14420static void
14421do_t_usat (void)
14422{
3a21c15a 14423 do_t_ssat_usat (0);
b99bd4ef
NC
14424}
14425
14426static void
c19d1205 14427do_t_usat16 (void)
b99bd4ef 14428{
fdfde340
JM
14429 unsigned Rd, Rn;
14430
14431 Rd = inst.operands[0].reg;
14432 Rn = inst.operands[2].reg;
14433
14434 reject_bad_reg (Rd);
14435 reject_bad_reg (Rn);
14436
14437 inst.instruction |= Rd << 8;
c19d1205 14438 inst.instruction |= inst.operands[1].imm;
fdfde340 14439 inst.instruction |= Rn << 16;
b99bd4ef 14440}
c19d1205 14441
e12437dc
AV
14442/* Checking the range of the branch offset (VAL) with NBITS bits
14443 and IS_SIGNED signedness. Also checks the LSB to be 0. */
14444static int
14445v8_1_branch_value_check (int val, int nbits, int is_signed)
14446{
14447 gas_assert (nbits > 0 && nbits <= 32);
14448 if (is_signed)
14449 {
14450 int cmp = (1 << (nbits - 1));
14451 if ((val < -cmp) || (val >= cmp) || (val & 0x01))
14452 return FAIL;
14453 }
14454 else
14455 {
14456 if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
14457 return FAIL;
14458 }
14459 return SUCCESS;
14460}
14461
4389b29a
AV
14462/* For branches in Armv8.1-M Mainline. */
14463static void
14464do_t_branch_future (void)
14465{
14466 unsigned long insn = inst.instruction;
14467
14468 inst.instruction = THUMB_OP32 (inst.instruction);
14469 if (inst.operands[0].hasreloc == 0)
14470 {
5b7c81bd 14471 if (v8_1_branch_value_check (inst.operands[0].imm, 5, false) == FAIL)
4389b29a
AV
14472 as_bad (BAD_BRANCH_OFF);
14473
14474 inst.instruction |= ((inst.operands[0].imm & 0x1f) >> 1) << 23;
14475 }
14476 else
14477 {
14478 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH5;
14479 inst.relocs[0].pc_rel = 1;
14480 }
14481
14482 switch (insn)
14483 {
14484 case T_MNEM_bf:
14485 if (inst.operands[1].hasreloc == 0)
14486 {
14487 int val = inst.operands[1].imm;
5b7c81bd 14488 if (v8_1_branch_value_check (inst.operands[1].imm, 17, true) == FAIL)
4389b29a
AV
14489 as_bad (BAD_BRANCH_OFF);
14490
14491 int immA = (val & 0x0001f000) >> 12;
14492 int immB = (val & 0x00000ffc) >> 2;
14493 int immC = (val & 0x00000002) >> 1;
14494 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14495 }
14496 else
14497 {
14498 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF17;
14499 inst.relocs[1].pc_rel = 1;
14500 }
14501 break;
14502
65d1bc05
AV
14503 case T_MNEM_bfl:
14504 if (inst.operands[1].hasreloc == 0)
14505 {
14506 int val = inst.operands[1].imm;
5b7c81bd 14507 if (v8_1_branch_value_check (inst.operands[1].imm, 19, true) == FAIL)
65d1bc05
AV
14508 as_bad (BAD_BRANCH_OFF);
14509
14510 int immA = (val & 0x0007f000) >> 12;
14511 int immB = (val & 0x00000ffc) >> 2;
14512 int immC = (val & 0x00000002) >> 1;
14513 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14514 }
14515 else
14516 {
14517 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
14518 inst.relocs[1].pc_rel = 1;
14519 }
14520 break;
14521
f6b2b12d
AV
14522 case T_MNEM_bfcsel:
14523 /* Operand 1. */
14524 if (inst.operands[1].hasreloc == 0)
14525 {
14526 int val = inst.operands[1].imm;
14527 int immA = (val & 0x00001000) >> 12;
14528 int immB = (val & 0x00000ffc) >> 2;
14529 int immC = (val & 0x00000002) >> 1;
14530 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14531 }
14532 else
14533 {
14534 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF13;
14535 inst.relocs[1].pc_rel = 1;
14536 }
14537
14538 /* Operand 2. */
14539 if (inst.operands[2].hasreloc == 0)
14540 {
14541 constraint ((inst.operands[0].hasreloc != 0), BAD_ARGS);
14542 int val2 = inst.operands[2].imm;
14543 int val0 = inst.operands[0].imm & 0x1f;
14544 int diff = val2 - val0;
14545 if (diff == 4)
14546 inst.instruction |= 1 << 17; /* T bit. */
14547 else if (diff != 2)
14548 as_bad (_("out of range label-relative fixup value"));
14549 }
14550 else
14551 {
14552 constraint ((inst.operands[0].hasreloc == 0), BAD_ARGS);
14553 inst.relocs[2].type = BFD_RELOC_THUMB_PCREL_BFCSEL;
14554 inst.relocs[2].pc_rel = 1;
14555 }
14556
14557 /* Operand 3. */
14558 constraint (inst.cond != COND_ALWAYS, BAD_COND);
14559 inst.instruction |= (inst.operands[3].imm & 0xf) << 18;
14560 break;
14561
f1c7f421
AV
14562 case T_MNEM_bfx:
14563 case T_MNEM_bflx:
14564 inst.instruction |= inst.operands[1].reg << 16;
14565 break;
14566
4389b29a
AV
14567 default: abort ();
14568 }
14569}
14570
60f993ce
AV
14571/* Helper function for do_t_loloop to handle relocations. */
14572static void
14573v8_1_loop_reloc (int is_le)
14574{
14575 if (inst.relocs[0].exp.X_op == O_constant)
14576 {
14577 int value = inst.relocs[0].exp.X_add_number;
14578 value = (is_le) ? -value : value;
14579
5b7c81bd 14580 if (v8_1_branch_value_check (value, 12, false) == FAIL)
60f993ce
AV
14581 as_bad (BAD_BRANCH_OFF);
14582
14583 int imml, immh;
14584
14585 immh = (value & 0x00000ffc) >> 2;
14586 imml = (value & 0x00000002) >> 1;
14587
14588 inst.instruction |= (imml << 11) | (immh << 1);
14589 }
14590 else
14591 {
14592 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_LOOP12;
14593 inst.relocs[0].pc_rel = 1;
14594 }
14595}
14596
08132bdd
SP
14597/* For shifts with four operands in MVE. */
14598static void
14599do_mve_scalar_shift1 (void)
14600{
14601 unsigned int value = inst.operands[2].imm;
14602
14603 inst.instruction |= inst.operands[0].reg << 16;
14604 inst.instruction |= inst.operands[1].reg << 8;
14605
14606 /* Setting the bit for saturation. */
14607 inst.instruction |= ((value == 64) ? 0: 1) << 7;
14608
14609 /* Assuming Rm is already checked not to be 11x1. */
14610 constraint (inst.operands[3].reg == inst.operands[0].reg, BAD_OVERLAP);
14611 constraint (inst.operands[3].reg == inst.operands[1].reg, BAD_OVERLAP);
14612 inst.instruction |= inst.operands[3].reg << 12;
14613}
14614
23d00a41
SD
14615/* For shifts in MVE. */
14616static void
14617do_mve_scalar_shift (void)
14618{
14619 if (!inst.operands[2].present)
14620 {
14621 inst.operands[2] = inst.operands[1];
14622 inst.operands[1].reg = 0xf;
14623 }
14624
14625 inst.instruction |= inst.operands[0].reg << 16;
14626 inst.instruction |= inst.operands[1].reg << 8;
14627
14628 if (inst.operands[2].isreg)
14629 {
14630 /* Assuming Rm is already checked not to be 11x1. */
14631 constraint (inst.operands[2].reg == inst.operands[0].reg, BAD_OVERLAP);
14632 constraint (inst.operands[2].reg == inst.operands[1].reg, BAD_OVERLAP);
14633 inst.instruction |= inst.operands[2].reg << 12;
14634 }
14635 else
14636 {
14637 /* Assuming imm is already checked as [1,32]. */
14638 unsigned int value = inst.operands[2].imm;
14639 inst.instruction |= (value & 0x1c) << 10;
14640 inst.instruction |= (value & 0x03) << 6;
14641 /* Change last 4 bits from 0xd to 0xf. */
14642 inst.instruction |= 0x2;
14643 }
14644}
14645
a302e574
AV
14646/* MVE instruction encoder helpers. */
14647#define M_MNEM_vabav 0xee800f01
14648#define M_MNEM_vmladav 0xeef00e00
14649#define M_MNEM_vmladava 0xeef00e20
14650#define M_MNEM_vmladavx 0xeef01e00
14651#define M_MNEM_vmladavax 0xeef01e20
14652#define M_MNEM_vmlsdav 0xeef00e01
14653#define M_MNEM_vmlsdava 0xeef00e21
14654#define M_MNEM_vmlsdavx 0xeef01e01
14655#define M_MNEM_vmlsdavax 0xeef01e21
886e1c73
AV
14656#define M_MNEM_vmullt 0xee011e00
14657#define M_MNEM_vmullb 0xee010e00
efd0b310 14658#define M_MNEM_vctp 0xf000e801
35c228db
AV
14659#define M_MNEM_vst20 0xfc801e00
14660#define M_MNEM_vst21 0xfc801e20
14661#define M_MNEM_vst40 0xfc801e01
14662#define M_MNEM_vst41 0xfc801e21
14663#define M_MNEM_vst42 0xfc801e41
14664#define M_MNEM_vst43 0xfc801e61
14665#define M_MNEM_vld20 0xfc901e00
14666#define M_MNEM_vld21 0xfc901e20
14667#define M_MNEM_vld40 0xfc901e01
14668#define M_MNEM_vld41 0xfc901e21
14669#define M_MNEM_vld42 0xfc901e41
14670#define M_MNEM_vld43 0xfc901e61
f5f10c66
AV
14671#define M_MNEM_vstrb 0xec000e00
14672#define M_MNEM_vstrh 0xec000e10
14673#define M_MNEM_vstrw 0xec000e40
14674#define M_MNEM_vstrd 0xec000e50
14675#define M_MNEM_vldrb 0xec100e00
14676#define M_MNEM_vldrh 0xec100e10
14677#define M_MNEM_vldrw 0xec100e40
14678#define M_MNEM_vldrd 0xec100e50
57785aa2
AV
14679#define M_MNEM_vmovlt 0xeea01f40
14680#define M_MNEM_vmovlb 0xeea00f40
14681#define M_MNEM_vmovnt 0xfe311e81
14682#define M_MNEM_vmovnb 0xfe310e81
c2dafc2a
AV
14683#define M_MNEM_vadc 0xee300f00
14684#define M_MNEM_vadci 0xee301f00
14685#define M_MNEM_vbrsr 0xfe011e60
26c1e780
AV
14686#define M_MNEM_vaddlv 0xee890f00
14687#define M_MNEM_vaddlva 0xee890f20
14688#define M_MNEM_vaddv 0xeef10f00
14689#define M_MNEM_vaddva 0xeef10f20
b409bdb6
AV
14690#define M_MNEM_vddup 0xee011f6e
14691#define M_MNEM_vdwdup 0xee011f60
14692#define M_MNEM_vidup 0xee010f6e
14693#define M_MNEM_viwdup 0xee010f60
13ccd4c0
AV
14694#define M_MNEM_vmaxv 0xeee20f00
14695#define M_MNEM_vmaxav 0xeee00f00
14696#define M_MNEM_vminv 0xeee20f80
14697#define M_MNEM_vminav 0xeee00f80
93925576
AV
14698#define M_MNEM_vmlaldav 0xee800e00
14699#define M_MNEM_vmlaldava 0xee800e20
14700#define M_MNEM_vmlaldavx 0xee801e00
14701#define M_MNEM_vmlaldavax 0xee801e20
14702#define M_MNEM_vmlsldav 0xee800e01
14703#define M_MNEM_vmlsldava 0xee800e21
14704#define M_MNEM_vmlsldavx 0xee801e01
14705#define M_MNEM_vmlsldavax 0xee801e21
14706#define M_MNEM_vrmlaldavhx 0xee801f00
14707#define M_MNEM_vrmlaldavhax 0xee801f20
14708#define M_MNEM_vrmlsldavh 0xfe800e01
14709#define M_MNEM_vrmlsldavha 0xfe800e21
14710#define M_MNEM_vrmlsldavhx 0xfe801e01
14711#define M_MNEM_vrmlsldavhax 0xfe801e21
1be7aba3
AV
14712#define M_MNEM_vqmovnt 0xee331e01
14713#define M_MNEM_vqmovnb 0xee330e01
14714#define M_MNEM_vqmovunt 0xee311e81
14715#define M_MNEM_vqmovunb 0xee310e81
4aa88b50
AV
14716#define M_MNEM_vshrnt 0xee801fc1
14717#define M_MNEM_vshrnb 0xee800fc1
14718#define M_MNEM_vrshrnt 0xfe801fc1
14719#define M_MNEM_vqshrnt 0xee801f40
14720#define M_MNEM_vqshrnb 0xee800f40
14721#define M_MNEM_vqshrunt 0xee801fc0
14722#define M_MNEM_vqshrunb 0xee800fc0
14723#define M_MNEM_vrshrnb 0xfe800fc1
14724#define M_MNEM_vqrshrnt 0xee801f41
14725#define M_MNEM_vqrshrnb 0xee800f41
14726#define M_MNEM_vqrshrunt 0xfe801fc0
14727#define M_MNEM_vqrshrunb 0xfe800fc0
a302e574 14728
aab2c27d
MM
14729/* Bfloat16 instruction encoder helpers. */
14730#define B_MNEM_vfmat 0xfc300850
14731#define B_MNEM_vfmab 0xfc300810
14732
5287ad62 14733/* Neon instruction encoder helpers. */
5f4273c7 14734
5287ad62 14735/* Encodings for the different types for various Neon opcodes. */
b99bd4ef 14736
5287ad62
JB
14737/* An "invalid" code for the following tables. */
14738#define N_INV -1u
14739
14740struct neon_tab_entry
b99bd4ef 14741{
5287ad62
JB
14742 unsigned integer;
14743 unsigned float_or_poly;
14744 unsigned scalar_or_imm;
14745};
5f4273c7 14746
5287ad62
JB
14747/* Map overloaded Neon opcodes to their respective encodings. */
14748#define NEON_ENC_TAB \
14749 X(vabd, 0x0000700, 0x1200d00, N_INV), \
5ee91343 14750 X(vabdl, 0x0800700, N_INV, N_INV), \
5287ad62
JB
14751 X(vmax, 0x0000600, 0x0000f00, N_INV), \
14752 X(vmin, 0x0000610, 0x0200f00, N_INV), \
14753 X(vpadd, 0x0000b10, 0x1000d00, N_INV), \
14754 X(vpmax, 0x0000a00, 0x1000f00, N_INV), \
14755 X(vpmin, 0x0000a10, 0x1200f00, N_INV), \
14756 X(vadd, 0x0000800, 0x0000d00, N_INV), \
5ee91343 14757 X(vaddl, 0x0800000, N_INV, N_INV), \
5287ad62 14758 X(vsub, 0x1000800, 0x0200d00, N_INV), \
5ee91343 14759 X(vsubl, 0x0800200, N_INV, N_INV), \
5287ad62
JB
14760 X(vceq, 0x1000810, 0x0000e00, 0x1b10100), \
14761 X(vcge, 0x0000310, 0x1000e00, 0x1b10080), \
14762 X(vcgt, 0x0000300, 0x1200e00, 0x1b10000), \
14763 /* Register variants of the following two instructions are encoded as
e07e6e58 14764 vcge / vcgt with the operands reversed. */ \
92559b5b
PB
14765 X(vclt, 0x0000300, 0x1200e00, 0x1b10200), \
14766 X(vcle, 0x0000310, 0x1000e00, 0x1b10180), \
62f3b8c8
PB
14767 X(vfma, N_INV, 0x0000c10, N_INV), \
14768 X(vfms, N_INV, 0x0200c10, N_INV), \
5287ad62
JB
14769 X(vmla, 0x0000900, 0x0000d10, 0x0800040), \
14770 X(vmls, 0x1000900, 0x0200d10, 0x0800440), \
14771 X(vmul, 0x0000910, 0x1000d10, 0x0800840), \
14772 X(vmull, 0x0800c00, 0x0800e00, 0x0800a40), /* polynomial not float. */ \
14773 X(vmlal, 0x0800800, N_INV, 0x0800240), \
14774 X(vmlsl, 0x0800a00, N_INV, 0x0800640), \
14775 X(vqdmlal, 0x0800900, N_INV, 0x0800340), \
14776 X(vqdmlsl, 0x0800b00, N_INV, 0x0800740), \
14777 X(vqdmull, 0x0800d00, N_INV, 0x0800b40), \
14778 X(vqdmulh, 0x0000b00, N_INV, 0x0800c40), \
14779 X(vqrdmulh, 0x1000b00, N_INV, 0x0800d40), \
d6b4b13e
MW
14780 X(vqrdmlah, 0x3000b10, N_INV, 0x0800e40), \
14781 X(vqrdmlsh, 0x3000c10, N_INV, 0x0800f40), \
5287ad62
JB
14782 X(vshl, 0x0000400, N_INV, 0x0800510), \
14783 X(vqshl, 0x0000410, N_INV, 0x0800710), \
14784 X(vand, 0x0000110, N_INV, 0x0800030), \
14785 X(vbic, 0x0100110, N_INV, 0x0800030), \
14786 X(veor, 0x1000110, N_INV, N_INV), \
14787 X(vorn, 0x0300110, N_INV, 0x0800010), \
14788 X(vorr, 0x0200110, N_INV, 0x0800010), \
14789 X(vmvn, 0x1b00580, N_INV, 0x0800030), \
14790 X(vshll, 0x1b20300, N_INV, 0x0800a10), /* max shift, immediate. */ \
14791 X(vcvt, 0x1b30600, N_INV, 0x0800e10), /* integer, fixed-point. */ \
14792 X(vdup, 0xe800b10, N_INV, 0x1b00c00), /* arm, scalar. */ \
14793 X(vld1, 0x0200000, 0x0a00000, 0x0a00c00), /* interlv, lane, dup. */ \
14794 X(vst1, 0x0000000, 0x0800000, N_INV), \
14795 X(vld2, 0x0200100, 0x0a00100, 0x0a00d00), \
14796 X(vst2, 0x0000100, 0x0800100, N_INV), \
14797 X(vld3, 0x0200200, 0x0a00200, 0x0a00e00), \
14798 X(vst3, 0x0000200, 0x0800200, N_INV), \
14799 X(vld4, 0x0200300, 0x0a00300, 0x0a00f00), \
14800 X(vst4, 0x0000300, 0x0800300, N_INV), \
14801 X(vmovn, 0x1b20200, N_INV, N_INV), \
14802 X(vtrn, 0x1b20080, N_INV, N_INV), \
14803 X(vqmovn, 0x1b20200, N_INV, N_INV), \
037e8744
JB
14804 X(vqmovun, 0x1b20240, N_INV, N_INV), \
14805 X(vnmul, 0xe200a40, 0xe200b40, N_INV), \
e6655fda
PB
14806 X(vnmla, 0xe100a40, 0xe100b40, N_INV), \
14807 X(vnmls, 0xe100a00, 0xe100b00, N_INV), \
62f3b8c8
PB
14808 X(vfnma, 0xe900a40, 0xe900b40, N_INV), \
14809 X(vfnms, 0xe900a00, 0xe900b00, N_INV), \
037e8744
JB
14810 X(vcmp, 0xeb40a40, 0xeb40b40, N_INV), \
14811 X(vcmpz, 0xeb50a40, 0xeb50b40, N_INV), \
14812 X(vcmpe, 0xeb40ac0, 0xeb40bc0, N_INV), \
33399f07
MGD
14813 X(vcmpez, 0xeb50ac0, 0xeb50bc0, N_INV), \
14814 X(vseleq, 0xe000a00, N_INV, N_INV), \
14815 X(vselvs, 0xe100a00, N_INV, N_INV), \
14816 X(vselge, 0xe200a00, N_INV, N_INV), \
73924fbc
MGD
14817 X(vselgt, 0xe300a00, N_INV, N_INV), \
14818 X(vmaxnm, 0xe800a00, 0x3000f10, N_INV), \
7e8e6784 14819 X(vminnm, 0xe800a40, 0x3200f10, N_INV), \
30bdf752
MGD
14820 X(vcvta, 0xebc0a40, 0x3bb0000, N_INV), \
14821 X(vrintr, 0xeb60a40, 0x3ba0400, N_INV), \
91ff7894 14822 X(vrinta, 0xeb80a40, 0x3ba0400, N_INV), \
48adcd8e 14823 X(aes, 0x3b00300, N_INV, N_INV), \
3c9017d2
MGD
14824 X(sha3op, 0x2000c00, N_INV, N_INV), \
14825 X(sha1h, 0x3b902c0, N_INV, N_INV), \
14826 X(sha2op, 0x3ba0380, N_INV, N_INV)
5287ad62
JB
14827
14828enum neon_opc
14829{
14830#define X(OPC,I,F,S) N_MNEM_##OPC
14831NEON_ENC_TAB
14832#undef X
14833};
b99bd4ef 14834
5287ad62
JB
14835static const struct neon_tab_entry neon_enc_tab[] =
14836{
14837#define X(OPC,I,F,S) { (I), (F), (S) }
14838NEON_ENC_TAB
14839#undef X
14840};
b99bd4ef 14841
88714cb8
DG
14842/* Do not use these macros; instead, use NEON_ENCODE defined below. */
14843#define NEON_ENC_INTEGER_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14844#define NEON_ENC_ARMREG_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14845#define NEON_ENC_POLY_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14846#define NEON_ENC_FLOAT_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14847#define NEON_ENC_SCALAR_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14848#define NEON_ENC_IMMED_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14849#define NEON_ENC_INTERLV_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14850#define NEON_ENC_LANE_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14851#define NEON_ENC_DUP_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14852#define NEON_ENC_SINGLE_(X) \
037e8744 14853 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf0000000))
88714cb8 14854#define NEON_ENC_DOUBLE_(X) \
037e8744 14855 ((neon_enc_tab[(X) & 0x0fffffff].float_or_poly) | ((X) & 0xf0000000))
33399f07
MGD
14856#define NEON_ENC_FPV8_(X) \
14857 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf000000))
5287ad62 14858
88714cb8
DG
14859#define NEON_ENCODE(type, inst) \
14860 do \
14861 { \
14862 inst.instruction = NEON_ENC_##type##_ (inst.instruction); \
14863 inst.is_neon = 1; \
14864 } \
14865 while (0)
14866
14867#define check_neon_suffixes \
14868 do \
14869 { \
14870 if (!inst.error && inst.vectype.elems > 0 && !inst.is_neon) \
14871 { \
14872 as_bad (_("invalid neon suffix for non neon instruction")); \
14873 return; \
14874 } \
14875 } \
14876 while (0)
14877
037e8744
JB
14878/* Define shapes for instruction operands. The following mnemonic characters
14879 are used in this table:
5287ad62 14880
037e8744 14881 F - VFP S<n> register
5287ad62
JB
14882 D - Neon D<n> register
14883 Q - Neon Q<n> register
14884 I - Immediate
14885 S - Scalar
14886 R - ARM register
14887 L - D<n> register list
5f4273c7 14888
037e8744
JB
14889 This table is used to generate various data:
14890 - enumerations of the form NS_DDR to be used as arguments to
14891 neon_select_shape.
14892 - a table classifying shapes into single, double, quad, mixed.
5f4273c7 14893 - a table used to drive neon_select_shape. */
b99bd4ef 14894
037e8744 14895#define NEON_SHAPE_DEF \
93925576 14896 X(4, (R, R, Q, Q), QUAD), \
b409bdb6 14897 X(4, (Q, R, R, I), QUAD), \
57785aa2
AV
14898 X(4, (R, R, S, S), QUAD), \
14899 X(4, (S, S, R, R), QUAD), \
b409bdb6 14900 X(3, (Q, R, I), QUAD), \
1b883319
AV
14901 X(3, (I, Q, Q), QUAD), \
14902 X(3, (I, Q, R), QUAD), \
a302e574 14903 X(3, (R, Q, Q), QUAD), \
037e8744
JB
14904 X(3, (D, D, D), DOUBLE), \
14905 X(3, (Q, Q, Q), QUAD), \
14906 X(3, (D, D, I), DOUBLE), \
14907 X(3, (Q, Q, I), QUAD), \
14908 X(3, (D, D, S), DOUBLE), \
14909 X(3, (Q, Q, S), QUAD), \
5ee91343 14910 X(3, (Q, Q, R), QUAD), \
26c1e780
AV
14911 X(3, (R, R, Q), QUAD), \
14912 X(2, (R, Q), QUAD), \
037e8744
JB
14913 X(2, (D, D), DOUBLE), \
14914 X(2, (Q, Q), QUAD), \
14915 X(2, (D, S), DOUBLE), \
14916 X(2, (Q, S), QUAD), \
14917 X(2, (D, R), DOUBLE), \
14918 X(2, (Q, R), QUAD), \
14919 X(2, (D, I), DOUBLE), \
14920 X(2, (Q, I), QUAD), \
5aae9ae9
MM
14921 X(3, (P, F, I), SINGLE), \
14922 X(3, (P, D, I), DOUBLE), \
14923 X(3, (P, Q, I), QUAD), \
14924 X(4, (P, F, F, I), SINGLE), \
14925 X(4, (P, D, D, I), DOUBLE), \
14926 X(4, (P, Q, Q, I), QUAD), \
14927 X(5, (P, F, F, F, I), SINGLE), \
14928 X(5, (P, D, D, D, I), DOUBLE), \
14929 X(5, (P, Q, Q, Q, I), QUAD), \
037e8744
JB
14930 X(3, (D, L, D), DOUBLE), \
14931 X(2, (D, Q), MIXED), \
14932 X(2, (Q, D), MIXED), \
14933 X(3, (D, Q, I), MIXED), \
14934 X(3, (Q, D, I), MIXED), \
14935 X(3, (Q, D, D), MIXED), \
14936 X(3, (D, Q, Q), MIXED), \
14937 X(3, (Q, Q, D), MIXED), \
14938 X(3, (Q, D, S), MIXED), \
14939 X(3, (D, Q, S), MIXED), \
14940 X(4, (D, D, D, I), DOUBLE), \
14941 X(4, (Q, Q, Q, I), QUAD), \
c28eeff2
SN
14942 X(4, (D, D, S, I), DOUBLE), \
14943 X(4, (Q, Q, S, I), QUAD), \
037e8744
JB
14944 X(2, (F, F), SINGLE), \
14945 X(3, (F, F, F), SINGLE), \
14946 X(2, (F, I), SINGLE), \
14947 X(2, (F, D), MIXED), \
14948 X(2, (D, F), MIXED), \
14949 X(3, (F, F, I), MIXED), \
14950 X(4, (R, R, F, F), SINGLE), \
14951 X(4, (F, F, R, R), SINGLE), \
14952 X(3, (D, R, R), DOUBLE), \
14953 X(3, (R, R, D), DOUBLE), \
14954 X(2, (S, R), SINGLE), \
14955 X(2, (R, S), SINGLE), \
14956 X(2, (F, R), SINGLE), \
d54af2d0 14957 X(2, (R, F), SINGLE), \
1f6234a3
AV
14958/* Used for MVE tail predicated loop instructions. */\
14959 X(2, (R, R), QUAD), \
d54af2d0
RL
14960/* Half float shape supported so far. */\
14961 X (2, (H, D), MIXED), \
14962 X (2, (D, H), MIXED), \
14963 X (2, (H, F), MIXED), \
14964 X (2, (F, H), MIXED), \
14965 X (2, (H, H), HALF), \
14966 X (2, (H, R), HALF), \
14967 X (2, (R, H), HALF), \
14968 X (2, (H, I), HALF), \
14969 X (3, (H, H, H), HALF), \
14970 X (3, (H, F, I), MIXED), \
dec41383
JW
14971 X (3, (F, H, I), MIXED), \
14972 X (3, (D, H, H), MIXED), \
14973 X (3, (D, H, S), MIXED)
037e8744
JB
14974
14975#define S2(A,B) NS_##A##B
14976#define S3(A,B,C) NS_##A##B##C
14977#define S4(A,B,C,D) NS_##A##B##C##D
5aae9ae9 14978#define S5(A,B,C,D,E) NS_##A##B##C##D##E
037e8744
JB
14979
14980#define X(N, L, C) S##N L
14981
5287ad62
JB
14982enum neon_shape
14983{
037e8744
JB
14984 NEON_SHAPE_DEF,
14985 NS_NULL
5287ad62 14986};
b99bd4ef 14987
037e8744
JB
14988#undef X
14989#undef S2
14990#undef S3
14991#undef S4
5aae9ae9 14992#undef S5
037e8744
JB
14993
14994enum neon_shape_class
14995{
d54af2d0 14996 SC_HALF,
037e8744
JB
14997 SC_SINGLE,
14998 SC_DOUBLE,
14999 SC_QUAD,
15000 SC_MIXED
15001};
15002
15003#define X(N, L, C) SC_##C
15004
15005static enum neon_shape_class neon_shape_class[] =
15006{
15007 NEON_SHAPE_DEF
15008};
15009
15010#undef X
15011
15012enum neon_shape_el
15013{
d54af2d0 15014 SE_H,
037e8744
JB
15015 SE_F,
15016 SE_D,
15017 SE_Q,
15018 SE_I,
15019 SE_S,
15020 SE_R,
5aae9ae9
MM
15021 SE_L,
15022 SE_P
037e8744
JB
15023};
15024
15025/* Register widths of above. */
15026static unsigned neon_shape_el_size[] =
15027{
d54af2d0 15028 16,
037e8744
JB
15029 32,
15030 64,
15031 128,
15032 0,
15033 32,
15034 32,
5aae9ae9 15035 0,
037e8744
JB
15036 0
15037};
15038
15039struct neon_shape_info
15040{
15041 unsigned els;
15042 enum neon_shape_el el[NEON_MAX_TYPE_ELS];
15043};
15044
15045#define S2(A,B) { SE_##A, SE_##B }
15046#define S3(A,B,C) { SE_##A, SE_##B, SE_##C }
15047#define S4(A,B,C,D) { SE_##A, SE_##B, SE_##C, SE_##D }
5aae9ae9 15048#define S5(A,B,C,D,E) { SE_##A, SE_##B, SE_##C, SE_##D, SE_##E }
037e8744
JB
15049
15050#define X(N, L, C) { N, S##N L }
15051
15052static struct neon_shape_info neon_shape_tab[] =
15053{
15054 NEON_SHAPE_DEF
15055};
15056
15057#undef X
15058#undef S2
15059#undef S3
15060#undef S4
5aae9ae9 15061#undef S5
037e8744 15062
5287ad62
JB
15063/* Bit masks used in type checking given instructions.
15064 'N_EQK' means the type must be the same as (or based on in some way) the key
15065 type, which itself is marked with the 'N_KEY' bit. If the 'N_EQK' bit is
15066 set, various other bits can be set as well in order to modify the meaning of
15067 the type constraint. */
15068
15069enum neon_type_mask
15070{
8e79c3df
CM
15071 N_S8 = 0x0000001,
15072 N_S16 = 0x0000002,
15073 N_S32 = 0x0000004,
15074 N_S64 = 0x0000008,
15075 N_U8 = 0x0000010,
15076 N_U16 = 0x0000020,
15077 N_U32 = 0x0000040,
15078 N_U64 = 0x0000080,
15079 N_I8 = 0x0000100,
15080 N_I16 = 0x0000200,
15081 N_I32 = 0x0000400,
15082 N_I64 = 0x0000800,
15083 N_8 = 0x0001000,
15084 N_16 = 0x0002000,
15085 N_32 = 0x0004000,
15086 N_64 = 0x0008000,
15087 N_P8 = 0x0010000,
15088 N_P16 = 0x0020000,
15089 N_F16 = 0x0040000,
15090 N_F32 = 0x0080000,
15091 N_F64 = 0x0100000,
4f51b4bd 15092 N_P64 = 0x0200000,
aab2c27d 15093 N_BF16 = 0x0400000,
c921be7d
NC
15094 N_KEY = 0x1000000, /* Key element (main type specifier). */
15095 N_EQK = 0x2000000, /* Given operand has the same type & size as the key. */
8e79c3df 15096 N_VFP = 0x4000000, /* VFP mode: operand size must match register width. */
91ff7894 15097 N_UNT = 0x8000000, /* Must be explicitly untyped. */
c921be7d
NC
15098 N_DBL = 0x0000001, /* If N_EQK, this operand is twice the size. */
15099 N_HLF = 0x0000002, /* If N_EQK, this operand is half the size. */
15100 N_SGN = 0x0000004, /* If N_EQK, this operand is forced to be signed. */
15101 N_UNS = 0x0000008, /* If N_EQK, this operand is forced to be unsigned. */
15102 N_INT = 0x0000010, /* If N_EQK, this operand is forced to be integer. */
15103 N_FLT = 0x0000020, /* If N_EQK, this operand is forced to be float. */
15104 N_SIZ = 0x0000040, /* If N_EQK, this operand is forced to be size-only. */
5287ad62 15105 N_UTYP = 0,
4f51b4bd 15106 N_MAX_NONSPECIAL = N_P64
5287ad62
JB
15107};
15108
dcbf9037
JB
15109#define N_ALLMODS (N_DBL | N_HLF | N_SGN | N_UNS | N_INT | N_FLT | N_SIZ)
15110
5287ad62
JB
15111#define N_SU_ALL (N_S8 | N_S16 | N_S32 | N_S64 | N_U8 | N_U16 | N_U32 | N_U64)
15112#define N_SU_32 (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
15113#define N_SU_16_64 (N_S16 | N_S32 | N_S64 | N_U16 | N_U32 | N_U64)
cc933301
JW
15114#define N_S_32 (N_S8 | N_S16 | N_S32)
15115#define N_F_16_32 (N_F16 | N_F32)
15116#define N_SUF_32 (N_SU_32 | N_F_16_32)
5287ad62 15117#define N_I_ALL (N_I8 | N_I16 | N_I32 | N_I64)
cc933301 15118#define N_IF_32 (N_I8 | N_I16 | N_I32 | N_F16 | N_F32)
d54af2d0 15119#define N_F_ALL (N_F16 | N_F32 | N_F64)
5ee91343
AV
15120#define N_I_MVE (N_I8 | N_I16 | N_I32)
15121#define N_F_MVE (N_F16 | N_F32)
15122#define N_SU_MVE (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
5287ad62
JB
15123
15124/* Pass this as the first type argument to neon_check_type to ignore types
15125 altogether. */
15126#define N_IGNORE_TYPE (N_KEY | N_EQK)
15127
037e8744
JB
15128/* Select a "shape" for the current instruction (describing register types or
15129 sizes) from a list of alternatives. Return NS_NULL if the current instruction
15130 doesn't fit. For non-polymorphic shapes, checking is usually done as a
15131 function of operand parsing, so this function doesn't need to be called.
15132 Shapes should be listed in order of decreasing length. */
5287ad62
JB
15133
15134static enum neon_shape
037e8744 15135neon_select_shape (enum neon_shape shape, ...)
5287ad62 15136{
037e8744
JB
15137 va_list ap;
15138 enum neon_shape first_shape = shape;
5287ad62
JB
15139
15140 /* Fix missing optional operands. FIXME: we don't know at this point how
15141 many arguments we should have, so this makes the assumption that we have
15142 > 1. This is true of all current Neon opcodes, I think, but may not be
15143 true in the future. */
15144 if (!inst.operands[1].present)
15145 inst.operands[1] = inst.operands[0];
15146
037e8744 15147 va_start (ap, shape);
5f4273c7 15148
21d799b5 15149 for (; shape != NS_NULL; shape = (enum neon_shape) va_arg (ap, int))
037e8744
JB
15150 {
15151 unsigned j;
15152 int matches = 1;
15153
15154 for (j = 0; j < neon_shape_tab[shape].els; j++)
477330fc
RM
15155 {
15156 if (!inst.operands[j].present)
15157 {
15158 matches = 0;
15159 break;
15160 }
15161
15162 switch (neon_shape_tab[shape].el[j])
15163 {
d54af2d0
RL
15164 /* If a .f16, .16, .u16, .s16 type specifier is given over
15165 a VFP single precision register operand, it's essentially
15166 means only half of the register is used.
15167
15168 If the type specifier is given after the mnemonics, the
15169 information is stored in inst.vectype. If the type specifier
15170 is given after register operand, the information is stored
15171 in inst.operands[].vectype.
15172
15173 When there is only one type specifier, and all the register
15174 operands are the same type of hardware register, the type
15175 specifier applies to all register operands.
15176
15177 If no type specifier is given, the shape is inferred from
15178 operand information.
15179
15180 for example:
15181 vadd.f16 s0, s1, s2: NS_HHH
15182 vabs.f16 s0, s1: NS_HH
15183 vmov.f16 s0, r1: NS_HR
15184 vmov.f16 r0, s1: NS_RH
15185 vcvt.f16 r0, s1: NS_RH
15186 vcvt.f16.s32 s2, s2, #29: NS_HFI
15187 vcvt.f16.s32 s2, s2: NS_HF
15188 */
15189 case SE_H:
15190 if (!(inst.operands[j].isreg
15191 && inst.operands[j].isvec
15192 && inst.operands[j].issingle
15193 && !inst.operands[j].isquad
15194 && ((inst.vectype.elems == 1
15195 && inst.vectype.el[0].size == 16)
15196 || (inst.vectype.elems > 1
15197 && inst.vectype.el[j].size == 16)
15198 || (inst.vectype.elems == 0
15199 && inst.operands[j].vectype.type != NT_invtype
15200 && inst.operands[j].vectype.size == 16))))
15201 matches = 0;
15202 break;
15203
477330fc
RM
15204 case SE_F:
15205 if (!(inst.operands[j].isreg
15206 && inst.operands[j].isvec
15207 && inst.operands[j].issingle
d54af2d0
RL
15208 && !inst.operands[j].isquad
15209 && ((inst.vectype.elems == 1 && inst.vectype.el[0].size == 32)
15210 || (inst.vectype.elems > 1 && inst.vectype.el[j].size == 32)
15211 || (inst.vectype.elems == 0
15212 && (inst.operands[j].vectype.size == 32
15213 || inst.operands[j].vectype.type == NT_invtype)))))
477330fc
RM
15214 matches = 0;
15215 break;
15216
15217 case SE_D:
15218 if (!(inst.operands[j].isreg
15219 && inst.operands[j].isvec
15220 && !inst.operands[j].isquad
15221 && !inst.operands[j].issingle))
15222 matches = 0;
15223 break;
15224
15225 case SE_R:
15226 if (!(inst.operands[j].isreg
15227 && !inst.operands[j].isvec))
15228 matches = 0;
15229 break;
15230
15231 case SE_Q:
15232 if (!(inst.operands[j].isreg
15233 && inst.operands[j].isvec
15234 && inst.operands[j].isquad
15235 && !inst.operands[j].issingle))
15236 matches = 0;
15237 break;
15238
15239 case SE_I:
15240 if (!(!inst.operands[j].isreg
15241 && !inst.operands[j].isscalar))
15242 matches = 0;
15243 break;
15244
15245 case SE_S:
15246 if (!(!inst.operands[j].isreg
15247 && inst.operands[j].isscalar))
15248 matches = 0;
15249 break;
15250
5aae9ae9 15251 case SE_P:
477330fc
RM
15252 case SE_L:
15253 break;
15254 }
3fde54a2
JZ
15255 if (!matches)
15256 break;
477330fc 15257 }
ad6cec43
MGD
15258 if (matches && (j >= ARM_IT_MAX_OPERANDS || !inst.operands[j].present))
15259 /* We've matched all the entries in the shape table, and we don't
15260 have any left over operands which have not been matched. */
477330fc 15261 break;
037e8744 15262 }
5f4273c7 15263
037e8744 15264 va_end (ap);
5287ad62 15265
037e8744
JB
15266 if (shape == NS_NULL && first_shape != NS_NULL)
15267 first_error (_("invalid instruction shape"));
5287ad62 15268
037e8744
JB
15269 return shape;
15270}
5287ad62 15271
037e8744
JB
15272/* True if SHAPE is predominantly a quadword operation (most of the time, this
15273 means the Q bit should be set). */
15274
15275static int
15276neon_quad (enum neon_shape shape)
15277{
15278 return neon_shape_class[shape] == SC_QUAD;
5287ad62 15279}
037e8744 15280
5287ad62
JB
15281static void
15282neon_modify_type_size (unsigned typebits, enum neon_el_type *g_type,
477330fc 15283 unsigned *g_size)
5287ad62
JB
15284{
15285 /* Allow modification to be made to types which are constrained to be
15286 based on the key element, based on bits set alongside N_EQK. */
15287 if ((typebits & N_EQK) != 0)
15288 {
15289 if ((typebits & N_HLF) != 0)
15290 *g_size /= 2;
15291 else if ((typebits & N_DBL) != 0)
15292 *g_size *= 2;
15293 if ((typebits & N_SGN) != 0)
15294 *g_type = NT_signed;
15295 else if ((typebits & N_UNS) != 0)
477330fc 15296 *g_type = NT_unsigned;
5287ad62 15297 else if ((typebits & N_INT) != 0)
477330fc 15298 *g_type = NT_integer;
5287ad62 15299 else if ((typebits & N_FLT) != 0)
477330fc 15300 *g_type = NT_float;
dcbf9037 15301 else if ((typebits & N_SIZ) != 0)
477330fc 15302 *g_type = NT_untyped;
5287ad62
JB
15303 }
15304}
5f4273c7 15305
5287ad62
JB
15306/* Return operand OPNO promoted by bits set in THISARG. KEY should be the "key"
15307 operand type, i.e. the single type specified in a Neon instruction when it
15308 is the only one given. */
15309
15310static struct neon_type_el
15311neon_type_promote (struct neon_type_el *key, unsigned thisarg)
15312{
15313 struct neon_type_el dest = *key;
5f4273c7 15314
9c2799c2 15315 gas_assert ((thisarg & N_EQK) != 0);
5f4273c7 15316
5287ad62
JB
15317 neon_modify_type_size (thisarg, &dest.type, &dest.size);
15318
15319 return dest;
15320}
15321
15322/* Convert Neon type and size into compact bitmask representation. */
15323
15324static enum neon_type_mask
15325type_chk_of_el_type (enum neon_el_type type, unsigned size)
15326{
15327 switch (type)
15328 {
15329 case NT_untyped:
15330 switch (size)
477330fc
RM
15331 {
15332 case 8: return N_8;
15333 case 16: return N_16;
15334 case 32: return N_32;
15335 case 64: return N_64;
15336 default: ;
15337 }
5287ad62
JB
15338 break;
15339
15340 case NT_integer:
15341 switch (size)
477330fc
RM
15342 {
15343 case 8: return N_I8;
15344 case 16: return N_I16;
15345 case 32: return N_I32;
15346 case 64: return N_I64;
15347 default: ;
15348 }
5287ad62
JB
15349 break;
15350
15351 case NT_float:
037e8744 15352 switch (size)
477330fc 15353 {
8e79c3df 15354 case 16: return N_F16;
477330fc
RM
15355 case 32: return N_F32;
15356 case 64: return N_F64;
15357 default: ;
15358 }
5287ad62
JB
15359 break;
15360
15361 case NT_poly:
15362 switch (size)
477330fc
RM
15363 {
15364 case 8: return N_P8;
15365 case 16: return N_P16;
4f51b4bd 15366 case 64: return N_P64;
477330fc
RM
15367 default: ;
15368 }
5287ad62
JB
15369 break;
15370
15371 case NT_signed:
15372 switch (size)
477330fc
RM
15373 {
15374 case 8: return N_S8;
15375 case 16: return N_S16;
15376 case 32: return N_S32;
15377 case 64: return N_S64;
15378 default: ;
15379 }
5287ad62
JB
15380 break;
15381
15382 case NT_unsigned:
15383 switch (size)
477330fc
RM
15384 {
15385 case 8: return N_U8;
15386 case 16: return N_U16;
15387 case 32: return N_U32;
15388 case 64: return N_U64;
15389 default: ;
15390 }
5287ad62
JB
15391 break;
15392
aab2c27d
MM
15393 case NT_bfloat:
15394 if (size == 16) return N_BF16;
15395 break;
15396
5287ad62
JB
15397 default: ;
15398 }
5f4273c7 15399
5287ad62
JB
15400 return N_UTYP;
15401}
15402
15403/* Convert compact Neon bitmask type representation to a type and size. Only
15404 handles the case where a single bit is set in the mask. */
15405
dcbf9037 15406static int
5287ad62 15407el_type_of_type_chk (enum neon_el_type *type, unsigned *size,
477330fc 15408 enum neon_type_mask mask)
5287ad62 15409{
dcbf9037
JB
15410 if ((mask & N_EQK) != 0)
15411 return FAIL;
15412
5287ad62
JB
15413 if ((mask & (N_S8 | N_U8 | N_I8 | N_8 | N_P8)) != 0)
15414 *size = 8;
aab2c27d
MM
15415 else if ((mask & (N_S16 | N_U16 | N_I16 | N_16 | N_F16 | N_P16 | N_BF16))
15416 != 0)
5287ad62 15417 *size = 16;
dcbf9037 15418 else if ((mask & (N_S32 | N_U32 | N_I32 | N_32 | N_F32)) != 0)
5287ad62 15419 *size = 32;
4f51b4bd 15420 else if ((mask & (N_S64 | N_U64 | N_I64 | N_64 | N_F64 | N_P64)) != 0)
5287ad62 15421 *size = 64;
dcbf9037
JB
15422 else
15423 return FAIL;
15424
5287ad62
JB
15425 if ((mask & (N_S8 | N_S16 | N_S32 | N_S64)) != 0)
15426 *type = NT_signed;
dcbf9037 15427 else if ((mask & (N_U8 | N_U16 | N_U32 | N_U64)) != 0)
5287ad62 15428 *type = NT_unsigned;
dcbf9037 15429 else if ((mask & (N_I8 | N_I16 | N_I32 | N_I64)) != 0)
5287ad62 15430 *type = NT_integer;
dcbf9037 15431 else if ((mask & (N_8 | N_16 | N_32 | N_64)) != 0)
5287ad62 15432 *type = NT_untyped;
4f51b4bd 15433 else if ((mask & (N_P8 | N_P16 | N_P64)) != 0)
5287ad62 15434 *type = NT_poly;
d54af2d0 15435 else if ((mask & (N_F_ALL)) != 0)
5287ad62 15436 *type = NT_float;
aab2c27d
MM
15437 else if ((mask & (N_BF16)) != 0)
15438 *type = NT_bfloat;
dcbf9037
JB
15439 else
15440 return FAIL;
5f4273c7 15441
dcbf9037 15442 return SUCCESS;
5287ad62
JB
15443}
15444
15445/* Modify a bitmask of allowed types. This is only needed for type
15446 relaxation. */
15447
15448static unsigned
15449modify_types_allowed (unsigned allowed, unsigned mods)
15450{
15451 unsigned size;
15452 enum neon_el_type type;
15453 unsigned destmask;
15454 int i;
5f4273c7 15455
5287ad62 15456 destmask = 0;
5f4273c7 15457
5287ad62
JB
15458 for (i = 1; i <= N_MAX_NONSPECIAL; i <<= 1)
15459 {
21d799b5 15460 if (el_type_of_type_chk (&type, &size,
477330fc
RM
15461 (enum neon_type_mask) (allowed & i)) == SUCCESS)
15462 {
15463 neon_modify_type_size (mods, &type, &size);
15464 destmask |= type_chk_of_el_type (type, size);
15465 }
5287ad62 15466 }
5f4273c7 15467
5287ad62
JB
15468 return destmask;
15469}
15470
15471/* Check type and return type classification.
15472 The manual states (paraphrase): If one datatype is given, it indicates the
15473 type given in:
15474 - the second operand, if there is one
15475 - the operand, if there is no second operand
15476 - the result, if there are no operands.
15477 This isn't quite good enough though, so we use a concept of a "key" datatype
15478 which is set on a per-instruction basis, which is the one which matters when
15479 only one data type is written.
15480 Note: this function has side-effects (e.g. filling in missing operands). All
037e8744 15481 Neon instructions should call it before performing bit encoding. */
5287ad62
JB
15482
15483static struct neon_type_el
15484neon_check_type (unsigned els, enum neon_shape ns, ...)
15485{
15486 va_list ap;
15487 unsigned i, pass, key_el = 0;
15488 unsigned types[NEON_MAX_TYPE_ELS];
15489 enum neon_el_type k_type = NT_invtype;
15490 unsigned k_size = -1u;
15491 struct neon_type_el badtype = {NT_invtype, -1};
15492 unsigned key_allowed = 0;
15493
15494 /* Optional registers in Neon instructions are always (not) in operand 1.
15495 Fill in the missing operand here, if it was omitted. */
15496 if (els > 1 && !inst.operands[1].present)
15497 inst.operands[1] = inst.operands[0];
15498
15499 /* Suck up all the varargs. */
15500 va_start (ap, ns);
15501 for (i = 0; i < els; i++)
15502 {
15503 unsigned thisarg = va_arg (ap, unsigned);
15504 if (thisarg == N_IGNORE_TYPE)
477330fc
RM
15505 {
15506 va_end (ap);
15507 return badtype;
15508 }
5287ad62
JB
15509 types[i] = thisarg;
15510 if ((thisarg & N_KEY) != 0)
477330fc 15511 key_el = i;
5287ad62
JB
15512 }
15513 va_end (ap);
15514
dcbf9037
JB
15515 if (inst.vectype.elems > 0)
15516 for (i = 0; i < els; i++)
15517 if (inst.operands[i].vectype.type != NT_invtype)
477330fc
RM
15518 {
15519 first_error (_("types specified in both the mnemonic and operands"));
15520 return badtype;
15521 }
dcbf9037 15522
5287ad62
JB
15523 /* Duplicate inst.vectype elements here as necessary.
15524 FIXME: No idea if this is exactly the same as the ARM assembler,
15525 particularly when an insn takes one register and one non-register
15526 operand. */
15527 if (inst.vectype.elems == 1 && els > 1)
15528 {
15529 unsigned j;
15530 inst.vectype.elems = els;
15531 inst.vectype.el[key_el] = inst.vectype.el[0];
15532 for (j = 0; j < els; j++)
477330fc
RM
15533 if (j != key_el)
15534 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
15535 types[j]);
dcbf9037
JB
15536 }
15537 else if (inst.vectype.elems == 0 && els > 0)
15538 {
15539 unsigned j;
15540 /* No types were given after the mnemonic, so look for types specified
477330fc
RM
15541 after each operand. We allow some flexibility here; as long as the
15542 "key" operand has a type, we can infer the others. */
dcbf9037 15543 for (j = 0; j < els; j++)
477330fc
RM
15544 if (inst.operands[j].vectype.type != NT_invtype)
15545 inst.vectype.el[j] = inst.operands[j].vectype;
dcbf9037
JB
15546
15547 if (inst.operands[key_el].vectype.type != NT_invtype)
477330fc
RM
15548 {
15549 for (j = 0; j < els; j++)
15550 if (inst.operands[j].vectype.type == NT_invtype)
15551 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
15552 types[j]);
15553 }
dcbf9037 15554 else
477330fc
RM
15555 {
15556 first_error (_("operand types can't be inferred"));
15557 return badtype;
15558 }
5287ad62
JB
15559 }
15560 else if (inst.vectype.elems != els)
15561 {
dcbf9037 15562 first_error (_("type specifier has the wrong number of parts"));
5287ad62
JB
15563 return badtype;
15564 }
15565
15566 for (pass = 0; pass < 2; pass++)
15567 {
15568 for (i = 0; i < els; i++)
477330fc
RM
15569 {
15570 unsigned thisarg = types[i];
15571 unsigned types_allowed = ((thisarg & N_EQK) != 0 && pass != 0)
15572 ? modify_types_allowed (key_allowed, thisarg) : thisarg;
15573 enum neon_el_type g_type = inst.vectype.el[i].type;
15574 unsigned g_size = inst.vectype.el[i].size;
15575
15576 /* Decay more-specific signed & unsigned types to sign-insensitive
5287ad62 15577 integer types if sign-specific variants are unavailable. */
477330fc 15578 if ((g_type == NT_signed || g_type == NT_unsigned)
5287ad62
JB
15579 && (types_allowed & N_SU_ALL) == 0)
15580 g_type = NT_integer;
15581
477330fc 15582 /* If only untyped args are allowed, decay any more specific types to
5287ad62
JB
15583 them. Some instructions only care about signs for some element
15584 sizes, so handle that properly. */
477330fc 15585 if (((types_allowed & N_UNT) == 0)
91ff7894
MGD
15586 && ((g_size == 8 && (types_allowed & N_8) != 0)
15587 || (g_size == 16 && (types_allowed & N_16) != 0)
15588 || (g_size == 32 && (types_allowed & N_32) != 0)
15589 || (g_size == 64 && (types_allowed & N_64) != 0)))
5287ad62
JB
15590 g_type = NT_untyped;
15591
477330fc
RM
15592 if (pass == 0)
15593 {
15594 if ((thisarg & N_KEY) != 0)
15595 {
15596 k_type = g_type;
15597 k_size = g_size;
15598 key_allowed = thisarg & ~N_KEY;
cc933301
JW
15599
15600 /* Check architecture constraint on FP16 extension. */
15601 if (k_size == 16
15602 && k_type == NT_float
15603 && ! ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15604 {
15605 inst.error = _(BAD_FP16);
15606 return badtype;
15607 }
477330fc
RM
15608 }
15609 }
15610 else
15611 {
15612 if ((thisarg & N_VFP) != 0)
15613 {
15614 enum neon_shape_el regshape;
15615 unsigned regwidth, match;
99b253c5
NC
15616
15617 /* PR 11136: Catch the case where we are passed a shape of NS_NULL. */
15618 if (ns == NS_NULL)
15619 {
15620 first_error (_("invalid instruction shape"));
15621 return badtype;
15622 }
477330fc
RM
15623 regshape = neon_shape_tab[ns].el[i];
15624 regwidth = neon_shape_el_size[regshape];
15625
15626 /* In VFP mode, operands must match register widths. If we
15627 have a key operand, use its width, else use the width of
15628 the current operand. */
15629 if (k_size != -1u)
15630 match = k_size;
15631 else
15632 match = g_size;
15633
9db2f6b4
RL
15634 /* FP16 will use a single precision register. */
15635 if (regwidth == 32 && match == 16)
15636 {
15637 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15638 match = regwidth;
15639 else
15640 {
15641 inst.error = _(BAD_FP16);
15642 return badtype;
15643 }
15644 }
15645
477330fc
RM
15646 if (regwidth != match)
15647 {
15648 first_error (_("operand size must match register width"));
15649 return badtype;
15650 }
15651 }
15652
15653 if ((thisarg & N_EQK) == 0)
15654 {
15655 unsigned given_type = type_chk_of_el_type (g_type, g_size);
15656
15657 if ((given_type & types_allowed) == 0)
15658 {
a302e574 15659 first_error (BAD_SIMD_TYPE);
477330fc
RM
15660 return badtype;
15661 }
15662 }
15663 else
15664 {
15665 enum neon_el_type mod_k_type = k_type;
15666 unsigned mod_k_size = k_size;
15667 neon_modify_type_size (thisarg, &mod_k_type, &mod_k_size);
15668 if (g_type != mod_k_type || g_size != mod_k_size)
15669 {
15670 first_error (_("inconsistent types in Neon instruction"));
15671 return badtype;
15672 }
15673 }
15674 }
15675 }
5287ad62
JB
15676 }
15677
15678 return inst.vectype.el[key_el];
15679}
15680
037e8744 15681/* Neon-style VFP instruction forwarding. */
5287ad62 15682
037e8744
JB
15683/* Thumb VFP instructions have 0xE in the condition field. */
15684
15685static void
15686do_vfp_cond_or_thumb (void)
5287ad62 15687{
88714cb8
DG
15688 inst.is_neon = 1;
15689
5287ad62 15690 if (thumb_mode)
037e8744 15691 inst.instruction |= 0xe0000000;
5287ad62 15692 else
037e8744 15693 inst.instruction |= inst.cond << 28;
5287ad62
JB
15694}
15695
037e8744
JB
15696/* Look up and encode a simple mnemonic, for use as a helper function for the
15697 Neon-style VFP syntax. This avoids duplication of bits of the insns table,
15698 etc. It is assumed that operand parsing has already been done, and that the
15699 operands are in the form expected by the given opcode (this isn't necessarily
15700 the same as the form in which they were parsed, hence some massaging must
15701 take place before this function is called).
15702 Checks current arch version against that in the looked-up opcode. */
5287ad62 15703
037e8744
JB
15704static void
15705do_vfp_nsyn_opcode (const char *opname)
5287ad62 15706{
037e8744 15707 const struct asm_opcode *opcode;
5f4273c7 15708
629310ab 15709 opcode = (const struct asm_opcode *) str_hash_find (arm_ops_hsh, opname);
5287ad62 15710
037e8744
JB
15711 if (!opcode)
15712 abort ();
5287ad62 15713
037e8744 15714 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant,
477330fc
RM
15715 thumb_mode ? *opcode->tvariant : *opcode->avariant),
15716 _(BAD_FPU));
5287ad62 15717
88714cb8
DG
15718 inst.is_neon = 1;
15719
037e8744
JB
15720 if (thumb_mode)
15721 {
15722 inst.instruction = opcode->tvalue;
15723 opcode->tencode ();
15724 }
15725 else
15726 {
15727 inst.instruction = (inst.cond << 28) | opcode->avalue;
15728 opcode->aencode ();
15729 }
15730}
5287ad62
JB
15731
15732static void
037e8744 15733do_vfp_nsyn_add_sub (enum neon_shape rs)
5287ad62 15734{
037e8744
JB
15735 int is_add = (inst.instruction & 0x0fffffff) == N_MNEM_vadd;
15736
9db2f6b4 15737 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15738 {
15739 if (is_add)
477330fc 15740 do_vfp_nsyn_opcode ("fadds");
037e8744 15741 else
477330fc 15742 do_vfp_nsyn_opcode ("fsubs");
9db2f6b4
RL
15743
15744 /* ARMv8.2 fp16 instruction. */
15745 if (rs == NS_HHH)
15746 do_scalar_fp16_v82_encode ();
037e8744
JB
15747 }
15748 else
15749 {
15750 if (is_add)
477330fc 15751 do_vfp_nsyn_opcode ("faddd");
037e8744 15752 else
477330fc 15753 do_vfp_nsyn_opcode ("fsubd");
037e8744
JB
15754 }
15755}
15756
15757/* Check operand types to see if this is a VFP instruction, and if so call
15758 PFN (). */
15759
15760static int
15761try_vfp_nsyn (int args, void (*pfn) (enum neon_shape))
15762{
15763 enum neon_shape rs;
15764 struct neon_type_el et;
15765
15766 switch (args)
15767 {
15768 case 2:
9db2f6b4
RL
15769 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15770 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
037e8744 15771 break;
5f4273c7 15772
037e8744 15773 case 3:
9db2f6b4
RL
15774 rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
15775 et = neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
15776 N_F_ALL | N_KEY | N_VFP);
037e8744
JB
15777 break;
15778
15779 default:
15780 abort ();
15781 }
15782
15783 if (et.type != NT_invtype)
15784 {
15785 pfn (rs);
15786 return SUCCESS;
15787 }
037e8744 15788
99b253c5 15789 inst.error = NULL;
037e8744
JB
15790 return FAIL;
15791}
15792
15793static void
15794do_vfp_nsyn_mla_mls (enum neon_shape rs)
15795{
15796 int is_mla = (inst.instruction & 0x0fffffff) == N_MNEM_vmla;
5f4273c7 15797
9db2f6b4 15798 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15799 {
15800 if (is_mla)
477330fc 15801 do_vfp_nsyn_opcode ("fmacs");
037e8744 15802 else
477330fc 15803 do_vfp_nsyn_opcode ("fnmacs");
9db2f6b4
RL
15804
15805 /* ARMv8.2 fp16 instruction. */
15806 if (rs == NS_HHH)
15807 do_scalar_fp16_v82_encode ();
037e8744
JB
15808 }
15809 else
15810 {
15811 if (is_mla)
477330fc 15812 do_vfp_nsyn_opcode ("fmacd");
037e8744 15813 else
477330fc 15814 do_vfp_nsyn_opcode ("fnmacd");
037e8744
JB
15815 }
15816}
15817
62f3b8c8
PB
15818static void
15819do_vfp_nsyn_fma_fms (enum neon_shape rs)
15820{
15821 int is_fma = (inst.instruction & 0x0fffffff) == N_MNEM_vfma;
15822
9db2f6b4 15823 if (rs == NS_FFF || rs == NS_HHH)
62f3b8c8
PB
15824 {
15825 if (is_fma)
477330fc 15826 do_vfp_nsyn_opcode ("ffmas");
62f3b8c8 15827 else
477330fc 15828 do_vfp_nsyn_opcode ("ffnmas");
9db2f6b4
RL
15829
15830 /* ARMv8.2 fp16 instruction. */
15831 if (rs == NS_HHH)
15832 do_scalar_fp16_v82_encode ();
62f3b8c8
PB
15833 }
15834 else
15835 {
15836 if (is_fma)
477330fc 15837 do_vfp_nsyn_opcode ("ffmad");
62f3b8c8 15838 else
477330fc 15839 do_vfp_nsyn_opcode ("ffnmad");
62f3b8c8
PB
15840 }
15841}
15842
037e8744
JB
15843static void
15844do_vfp_nsyn_mul (enum neon_shape rs)
15845{
9db2f6b4
RL
15846 if (rs == NS_FFF || rs == NS_HHH)
15847 {
15848 do_vfp_nsyn_opcode ("fmuls");
15849
15850 /* ARMv8.2 fp16 instruction. */
15851 if (rs == NS_HHH)
15852 do_scalar_fp16_v82_encode ();
15853 }
037e8744
JB
15854 else
15855 do_vfp_nsyn_opcode ("fmuld");
15856}
15857
15858static void
15859do_vfp_nsyn_abs_neg (enum neon_shape rs)
15860{
15861 int is_neg = (inst.instruction & 0x80) != 0;
9db2f6b4 15862 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_VFP | N_KEY);
037e8744 15863
9db2f6b4 15864 if (rs == NS_FF || rs == NS_HH)
037e8744
JB
15865 {
15866 if (is_neg)
477330fc 15867 do_vfp_nsyn_opcode ("fnegs");
037e8744 15868 else
477330fc 15869 do_vfp_nsyn_opcode ("fabss");
9db2f6b4
RL
15870
15871 /* ARMv8.2 fp16 instruction. */
15872 if (rs == NS_HH)
15873 do_scalar_fp16_v82_encode ();
037e8744
JB
15874 }
15875 else
15876 {
15877 if (is_neg)
477330fc 15878 do_vfp_nsyn_opcode ("fnegd");
037e8744 15879 else
477330fc 15880 do_vfp_nsyn_opcode ("fabsd");
037e8744
JB
15881 }
15882}
15883
15884/* Encode single-precision (only!) VFP fldm/fstm instructions. Double precision
15885 insns belong to Neon, and are handled elsewhere. */
15886
15887static void
15888do_vfp_nsyn_ldm_stm (int is_dbmode)
15889{
15890 int is_ldm = (inst.instruction & (1 << 20)) != 0;
15891 if (is_ldm)
15892 {
15893 if (is_dbmode)
477330fc 15894 do_vfp_nsyn_opcode ("fldmdbs");
037e8744 15895 else
477330fc 15896 do_vfp_nsyn_opcode ("fldmias");
037e8744
JB
15897 }
15898 else
15899 {
15900 if (is_dbmode)
477330fc 15901 do_vfp_nsyn_opcode ("fstmdbs");
037e8744 15902 else
477330fc 15903 do_vfp_nsyn_opcode ("fstmias");
037e8744
JB
15904 }
15905}
15906
037e8744
JB
15907static void
15908do_vfp_nsyn_sqrt (void)
15909{
9db2f6b4
RL
15910 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15911 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 15912
9db2f6b4
RL
15913 if (rs == NS_FF || rs == NS_HH)
15914 {
15915 do_vfp_nsyn_opcode ("fsqrts");
15916
15917 /* ARMv8.2 fp16 instruction. */
15918 if (rs == NS_HH)
15919 do_scalar_fp16_v82_encode ();
15920 }
037e8744
JB
15921 else
15922 do_vfp_nsyn_opcode ("fsqrtd");
15923}
15924
15925static void
15926do_vfp_nsyn_div (void)
15927{
9db2f6b4 15928 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15929 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15930 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15931
9db2f6b4
RL
15932 if (rs == NS_FFF || rs == NS_HHH)
15933 {
15934 do_vfp_nsyn_opcode ("fdivs");
15935
15936 /* ARMv8.2 fp16 instruction. */
15937 if (rs == NS_HHH)
15938 do_scalar_fp16_v82_encode ();
15939 }
037e8744
JB
15940 else
15941 do_vfp_nsyn_opcode ("fdivd");
15942}
15943
15944static void
15945do_vfp_nsyn_nmul (void)
15946{
9db2f6b4 15947 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15948 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15949 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15950
9db2f6b4 15951 if (rs == NS_FFF || rs == NS_HHH)
037e8744 15952 {
88714cb8 15953 NEON_ENCODE (SINGLE, inst);
037e8744 15954 do_vfp_sp_dyadic ();
9db2f6b4
RL
15955
15956 /* ARMv8.2 fp16 instruction. */
15957 if (rs == NS_HHH)
15958 do_scalar_fp16_v82_encode ();
037e8744
JB
15959 }
15960 else
15961 {
88714cb8 15962 NEON_ENCODE (DOUBLE, inst);
037e8744
JB
15963 do_vfp_dp_rd_rn_rm ();
15964 }
15965 do_vfp_cond_or_thumb ();
9db2f6b4 15966
037e8744
JB
15967}
15968
1b883319
AV
15969/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
15970 (0, 1, 2, 3). */
15971
15972static unsigned
15973neon_logbits (unsigned x)
15974{
15975 return ffs (x) - 4;
15976}
15977
15978#define LOW4(R) ((R) & 0xf)
15979#define HI1(R) (((R) >> 4) & 1)
5aae9ae9
MM
15980#define LOW1(R) ((R) & 0x1)
15981#define HI4(R) (((R) >> 1) & 0xf)
1b883319
AV
15982
15983static unsigned
15984mve_get_vcmp_vpt_cond (struct neon_type_el et)
15985{
15986 switch (et.type)
15987 {
15988 default:
15989 first_error (BAD_EL_TYPE);
15990 return 0;
15991 case NT_float:
15992 switch (inst.operands[0].imm)
15993 {
15994 default:
15995 first_error (_("invalid condition"));
15996 return 0;
15997 case 0x0:
15998 /* eq. */
15999 return 0;
16000 case 0x1:
16001 /* ne. */
16002 return 1;
16003 case 0xa:
16004 /* ge/ */
16005 return 4;
16006 case 0xb:
16007 /* lt. */
16008 return 5;
16009 case 0xc:
16010 /* gt. */
16011 return 6;
16012 case 0xd:
16013 /* le. */
16014 return 7;
16015 }
16016 case NT_integer:
16017 /* only accept eq and ne. */
16018 if (inst.operands[0].imm > 1)
16019 {
16020 first_error (_("invalid condition"));
16021 return 0;
16022 }
16023 return inst.operands[0].imm;
16024 case NT_unsigned:
16025 if (inst.operands[0].imm == 0x2)
16026 return 2;
16027 else if (inst.operands[0].imm == 0x8)
16028 return 3;
16029 else
16030 {
16031 first_error (_("invalid condition"));
16032 return 0;
16033 }
16034 case NT_signed:
16035 switch (inst.operands[0].imm)
16036 {
16037 default:
16038 first_error (_("invalid condition"));
16039 return 0;
16040 case 0xa:
16041 /* ge. */
16042 return 4;
16043 case 0xb:
16044 /* lt. */
16045 return 5;
16046 case 0xc:
16047 /* gt. */
16048 return 6;
16049 case 0xd:
16050 /* le. */
16051 return 7;
16052 }
16053 }
16054 /* Should be unreachable. */
16055 abort ();
16056}
16057
efd0b310
SP
16058/* For VCTP (create vector tail predicate) in MVE. */
16059static void
16060do_mve_vctp (void)
16061{
16062 int dt = 0;
16063 unsigned size = 0x0;
16064
16065 if (inst.cond > COND_ALWAYS)
16066 inst.pred_insn_type = INSIDE_VPT_INSN;
16067 else
16068 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16069
16070 /* This is a typical MVE instruction which has no type but have size 8, 16,
16071 32 and 64. For instructions with no type, inst.vectype.el[j].type is set
16072 to NT_untyped and size is updated in inst.vectype.el[j].size. */
16073 if ((inst.operands[0].present) && (inst.vectype.el[0].type == NT_untyped))
16074 dt = inst.vectype.el[0].size;
16075
16076 /* Setting this does not indicate an actual NEON instruction, but only
16077 indicates that the mnemonic accepts neon-style type suffixes. */
16078 inst.is_neon = 1;
16079
16080 switch (dt)
16081 {
16082 case 8:
16083 break;
16084 case 16:
16085 size = 0x1; break;
16086 case 32:
16087 size = 0x2; break;
16088 case 64:
16089 size = 0x3; break;
16090 default:
16091 first_error (_("Type is not allowed for this instruction"));
16092 }
16093 inst.instruction |= size << 20;
16094 inst.instruction |= inst.operands[0].reg << 16;
16095}
16096
1b883319
AV
16097static void
16098do_mve_vpt (void)
16099{
16100 /* We are dealing with a vector predicated block. */
16101 if (inst.operands[0].present)
16102 {
16103 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
16104 struct neon_type_el et
16105 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
16106 N_EQK);
16107
16108 unsigned fcond = mve_get_vcmp_vpt_cond (et);
16109
16110 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
16111
16112 if (et.type == NT_invtype)
16113 return;
16114
16115 if (et.type == NT_float)
16116 {
16117 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
16118 BAD_FPU);
16119 constraint (et.size != 16 && et.size != 32, BAD_EL_TYPE);
16120 inst.instruction |= (et.size == 16) << 28;
16121 inst.instruction |= 0x3 << 20;
16122 }
16123 else
16124 {
16125 constraint (et.size != 8 && et.size != 16 && et.size != 32,
16126 BAD_EL_TYPE);
16127 inst.instruction |= 1 << 28;
16128 inst.instruction |= neon_logbits (et.size) << 20;
16129 }
16130
16131 if (inst.operands[2].isquad)
16132 {
16133 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16134 inst.instruction |= LOW4 (inst.operands[2].reg);
16135 inst.instruction |= (fcond & 0x2) >> 1;
16136 }
16137 else
16138 {
16139 if (inst.operands[2].reg == REG_SP)
16140 as_tsktsk (MVE_BAD_SP);
16141 inst.instruction |= 1 << 6;
16142 inst.instruction |= (fcond & 0x2) << 4;
16143 inst.instruction |= inst.operands[2].reg;
16144 }
16145 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16146 inst.instruction |= (fcond & 0x4) << 10;
16147 inst.instruction |= (fcond & 0x1) << 7;
16148
16149 }
16150 set_pred_insn_type (VPT_INSN);
16151 now_pred.cc = 0;
16152 now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
16153 | ((inst.instruction & 0xe000) >> 13);
5b7c81bd 16154 now_pred.warn_deprecated = false;
1b883319
AV
16155 now_pred.type = VECTOR_PRED;
16156 inst.is_neon = 1;
16157}
16158
16159static void
16160do_mve_vcmp (void)
16161{
16162 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
16163 if (!inst.operands[1].isreg || !inst.operands[1].isquad)
16164 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
16165 if (!inst.operands[2].present)
16166 first_error (_("MVE vector or ARM register expected"));
16167 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
16168
16169 /* Deal with 'else' conditional MVE's vcmp, it will be parsed as vcmpe. */
16170 if ((inst.instruction & 0xffffffff) == N_MNEM_vcmpe
16171 && inst.operands[1].isquad)
16172 {
16173 inst.instruction = N_MNEM_vcmp;
16174 inst.cond = 0x10;
16175 }
16176
16177 if (inst.cond > COND_ALWAYS)
16178 inst.pred_insn_type = INSIDE_VPT_INSN;
16179 else
16180 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16181
16182 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
16183 struct neon_type_el et
16184 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
16185 N_EQK);
16186
16187 constraint (rs == NS_IQR && inst.operands[2].reg == REG_PC
16188 && !inst.operands[2].iszr, BAD_PC);
16189
16190 unsigned fcond = mve_get_vcmp_vpt_cond (et);
16191
16192 inst.instruction = 0xee010f00;
16193 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16194 inst.instruction |= (fcond & 0x4) << 10;
16195 inst.instruction |= (fcond & 0x1) << 7;
16196 if (et.type == NT_float)
16197 {
16198 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
16199 BAD_FPU);
16200 inst.instruction |= (et.size == 16) << 28;
16201 inst.instruction |= 0x3 << 20;
16202 }
16203 else
16204 {
16205 inst.instruction |= 1 << 28;
16206 inst.instruction |= neon_logbits (et.size) << 20;
16207 }
16208 if (inst.operands[2].isquad)
16209 {
16210 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16211 inst.instruction |= (fcond & 0x2) >> 1;
16212 inst.instruction |= LOW4 (inst.operands[2].reg);
16213 }
16214 else
16215 {
16216 if (inst.operands[2].reg == REG_SP)
16217 as_tsktsk (MVE_BAD_SP);
16218 inst.instruction |= 1 << 6;
16219 inst.instruction |= (fcond & 0x2) << 4;
16220 inst.instruction |= inst.operands[2].reg;
16221 }
16222
16223 inst.is_neon = 1;
16224 return;
16225}
16226
935295b5
AV
16227static void
16228do_mve_vmaxa_vmina (void)
16229{
16230 if (inst.cond > COND_ALWAYS)
16231 inst.pred_insn_type = INSIDE_VPT_INSN;
16232 else
16233 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16234
16235 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
16236 struct neon_type_el et
16237 = neon_check_type (2, rs, N_EQK, N_KEY | N_S8 | N_S16 | N_S32);
16238
16239 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16240 inst.instruction |= neon_logbits (et.size) << 18;
16241 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16242 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16243 inst.instruction |= LOW4 (inst.operands[1].reg);
16244 inst.is_neon = 1;
16245}
16246
f30ee27c
AV
16247static void
16248do_mve_vfmas (void)
16249{
16250 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
16251 struct neon_type_el et
16252 = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK, N_EQK);
16253
16254 if (inst.cond > COND_ALWAYS)
16255 inst.pred_insn_type = INSIDE_VPT_INSN;
16256 else
16257 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16258
16259 if (inst.operands[2].reg == REG_SP)
16260 as_tsktsk (MVE_BAD_SP);
16261 else if (inst.operands[2].reg == REG_PC)
16262 as_tsktsk (MVE_BAD_PC);
16263
16264 inst.instruction |= (et.size == 16) << 28;
16265 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16266 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16267 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16268 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16269 inst.instruction |= inst.operands[2].reg;
16270 inst.is_neon = 1;
16271}
16272
b409bdb6
AV
16273static void
16274do_mve_viddup (void)
16275{
16276 if (inst.cond > COND_ALWAYS)
16277 inst.pred_insn_type = INSIDE_VPT_INSN;
16278 else
16279 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16280
16281 unsigned imm = inst.relocs[0].exp.X_add_number;
16282 constraint (imm != 1 && imm != 2 && imm != 4 && imm != 8,
16283 _("immediate must be either 1, 2, 4 or 8"));
16284
16285 enum neon_shape rs;
16286 struct neon_type_el et;
16287 unsigned Rm;
16288 if (inst.instruction == M_MNEM_vddup || inst.instruction == M_MNEM_vidup)
16289 {
16290 rs = neon_select_shape (NS_QRI, NS_NULL);
16291 et = neon_check_type (2, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK);
16292 Rm = 7;
16293 }
16294 else
16295 {
16296 constraint ((inst.operands[2].reg % 2) != 1, BAD_EVEN);
16297 if (inst.operands[2].reg == REG_SP)
16298 as_tsktsk (MVE_BAD_SP);
16299 else if (inst.operands[2].reg == REG_PC)
16300 first_error (BAD_PC);
16301
16302 rs = neon_select_shape (NS_QRRI, NS_NULL);
16303 et = neon_check_type (3, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK, N_EQK);
16304 Rm = inst.operands[2].reg >> 1;
16305 }
16306 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16307 inst.instruction |= neon_logbits (et.size) << 20;
16308 inst.instruction |= inst.operands[1].reg << 16;
16309 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16310 inst.instruction |= (imm > 2) << 7;
16311 inst.instruction |= Rm << 1;
16312 inst.instruction |= (imm == 2 || imm == 8);
16313 inst.is_neon = 1;
16314}
16315
2d78f95b
AV
16316static void
16317do_mve_vmlas (void)
16318{
16319 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
16320 struct neon_type_el et
16321 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
16322
16323 if (inst.operands[2].reg == REG_PC)
16324 as_tsktsk (MVE_BAD_PC);
16325 else if (inst.operands[2].reg == REG_SP)
16326 as_tsktsk (MVE_BAD_SP);
16327
16328 if (inst.cond > COND_ALWAYS)
16329 inst.pred_insn_type = INSIDE_VPT_INSN;
16330 else
16331 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16332
16333 inst.instruction |= (et.type == NT_unsigned) << 28;
16334 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16335 inst.instruction |= neon_logbits (et.size) << 20;
16336 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16337 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16338 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16339 inst.instruction |= inst.operands[2].reg;
16340 inst.is_neon = 1;
16341}
16342
acca5630
AV
16343static void
16344do_mve_vshll (void)
16345{
16346 struct neon_type_el et
16347 = neon_check_type (2, NS_QQI, N_EQK, N_S8 | N_U8 | N_S16 | N_U16 | N_KEY);
16348
16349 if (inst.cond > COND_ALWAYS)
16350 inst.pred_insn_type = INSIDE_VPT_INSN;
16351 else
16352 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16353
16354 int imm = inst.operands[2].imm;
16355 constraint (imm < 1 || (unsigned)imm > et.size,
16356 _("immediate value out of range"));
16357
16358 if ((unsigned)imm == et.size)
16359 {
16360 inst.instruction |= neon_logbits (et.size) << 18;
16361 inst.instruction |= 0x110001;
16362 }
16363 else
16364 {
16365 inst.instruction |= (et.size + imm) << 16;
16366 inst.instruction |= 0x800140;
16367 }
16368
16369 inst.instruction |= (et.type == NT_unsigned) << 28;
16370 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16371 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16372 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16373 inst.instruction |= LOW4 (inst.operands[1].reg);
16374 inst.is_neon = 1;
16375}
16376
16377static void
16378do_mve_vshlc (void)
16379{
16380 if (inst.cond > COND_ALWAYS)
16381 inst.pred_insn_type = INSIDE_VPT_INSN;
16382 else
16383 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16384
16385 if (inst.operands[1].reg == REG_PC)
16386 as_tsktsk (MVE_BAD_PC);
16387 else if (inst.operands[1].reg == REG_SP)
16388 as_tsktsk (MVE_BAD_SP);
16389
16390 int imm = inst.operands[2].imm;
16391 constraint (imm < 1 || imm > 32, _("immediate value out of range"));
16392
16393 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16394 inst.instruction |= (imm & 0x1f) << 16;
16395 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16396 inst.instruction |= inst.operands[1].reg;
16397 inst.is_neon = 1;
16398}
16399
4aa88b50
AV
16400static void
16401do_mve_vshrn (void)
16402{
16403 unsigned types;
16404 switch (inst.instruction)
16405 {
16406 case M_MNEM_vshrnt:
16407 case M_MNEM_vshrnb:
16408 case M_MNEM_vrshrnt:
16409 case M_MNEM_vrshrnb:
16410 types = N_I16 | N_I32;
16411 break;
16412 case M_MNEM_vqshrnt:
16413 case M_MNEM_vqshrnb:
16414 case M_MNEM_vqrshrnt:
16415 case M_MNEM_vqrshrnb:
16416 types = N_U16 | N_U32 | N_S16 | N_S32;
16417 break;
16418 case M_MNEM_vqshrunt:
16419 case M_MNEM_vqshrunb:
16420 case M_MNEM_vqrshrunt:
16421 case M_MNEM_vqrshrunb:
16422 types = N_S16 | N_S32;
16423 break;
16424 default:
16425 abort ();
16426 }
16427
16428 struct neon_type_el et = neon_check_type (2, NS_QQI, N_EQK, types | N_KEY);
16429
16430 if (inst.cond > COND_ALWAYS)
16431 inst.pred_insn_type = INSIDE_VPT_INSN;
16432 else
16433 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16434
16435 unsigned Qd = inst.operands[0].reg;
16436 unsigned Qm = inst.operands[1].reg;
16437 unsigned imm = inst.operands[2].imm;
16438 constraint (imm < 1 || ((unsigned) imm) > (et.size / 2),
16439 et.size == 16
16440 ? _("immediate operand expected in the range [1,8]")
16441 : _("immediate operand expected in the range [1,16]"));
16442
16443 inst.instruction |= (et.type == NT_unsigned) << 28;
16444 inst.instruction |= HI1 (Qd) << 22;
16445 inst.instruction |= (et.size - imm) << 16;
16446 inst.instruction |= LOW4 (Qd) << 12;
16447 inst.instruction |= HI1 (Qm) << 5;
16448 inst.instruction |= LOW4 (Qm);
16449 inst.is_neon = 1;
16450}
16451
1be7aba3
AV
16452static void
16453do_mve_vqmovn (void)
16454{
16455 struct neon_type_el et;
16456 if (inst.instruction == M_MNEM_vqmovnt
16457 || inst.instruction == M_MNEM_vqmovnb)
16458 et = neon_check_type (2, NS_QQ, N_EQK,
16459 N_U16 | N_U32 | N_S16 | N_S32 | N_KEY);
16460 else
16461 et = neon_check_type (2, NS_QQ, N_EQK, N_S16 | N_S32 | N_KEY);
16462
16463 if (inst.cond > COND_ALWAYS)
16464 inst.pred_insn_type = INSIDE_VPT_INSN;
16465 else
16466 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16467
16468 inst.instruction |= (et.type == NT_unsigned) << 28;
16469 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16470 inst.instruction |= (et.size == 32) << 18;
16471 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16472 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16473 inst.instruction |= LOW4 (inst.operands[1].reg);
16474 inst.is_neon = 1;
16475}
16476
3063888e
AV
16477static void
16478do_mve_vpsel (void)
16479{
16480 neon_select_shape (NS_QQQ, NS_NULL);
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 |= HI1 (inst.operands[0].reg) << 22;
16488 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16489 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16490 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16491 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16492 inst.instruction |= LOW4 (inst.operands[2].reg);
16493 inst.is_neon = 1;
16494}
16495
16496static void
16497do_mve_vpnot (void)
16498{
16499 if (inst.cond > COND_ALWAYS)
16500 inst.pred_insn_type = INSIDE_VPT_INSN;
16501 else
16502 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16503}
16504
935295b5
AV
16505static void
16506do_mve_vmaxnma_vminnma (void)
16507{
16508 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
16509 struct neon_type_el et
16510 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
16511
16512 if (inst.cond > COND_ALWAYS)
16513 inst.pred_insn_type = INSIDE_VPT_INSN;
16514 else
16515 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16516
16517 inst.instruction |= (et.size == 16) << 28;
16518 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16519 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16520 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16521 inst.instruction |= LOW4 (inst.operands[1].reg);
16522 inst.is_neon = 1;
16523}
16524
5d281bf0
AV
16525static void
16526do_mve_vcmul (void)
16527{
16528 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
16529 struct neon_type_el et
16530 = neon_check_type (3, rs, N_EQK, N_EQK, N_F_MVE | N_KEY);
16531
16532 if (inst.cond > COND_ALWAYS)
16533 inst.pred_insn_type = INSIDE_VPT_INSN;
16534 else
16535 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16536
16537 unsigned rot = inst.relocs[0].exp.X_add_number;
16538 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
16539 _("immediate out of range"));
16540
16541 if (et.size == 32 && (inst.operands[0].reg == inst.operands[1].reg
16542 || inst.operands[0].reg == inst.operands[2].reg))
16543 as_tsktsk (BAD_MVE_SRCDEST);
16544
16545 inst.instruction |= (et.size == 32) << 28;
16546 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16547 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16548 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16549 inst.instruction |= (rot > 90) << 12;
16550 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16551 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16552 inst.instruction |= LOW4 (inst.operands[2].reg);
16553 inst.instruction |= (rot == 90 || rot == 270);
16554 inst.is_neon = 1;
16555}
16556
1f6234a3
AV
16557/* To handle the Low Overhead Loop instructions
16558 in Armv8.1-M Mainline and MVE. */
16559static void
16560do_t_loloop (void)
16561{
16562 unsigned long insn = inst.instruction;
16563
16564 inst.instruction = THUMB_OP32 (inst.instruction);
16565
16566 if (insn == T_MNEM_lctp)
16567 return;
16568
16569 set_pred_insn_type (MVE_OUTSIDE_PRED_INSN);
16570
16571 if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
16572 {
16573 struct neon_type_el et
16574 = neon_check_type (2, NS_RR, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
16575 inst.instruction |= neon_logbits (et.size) << 20;
16576 inst.is_neon = 1;
16577 }
16578
16579 switch (insn)
16580 {
16581 case T_MNEM_letp:
16582 constraint (!inst.operands[0].present,
16583 _("expected LR"));
16584 /* fall through. */
16585 case T_MNEM_le:
16586 /* le <label>. */
16587 if (!inst.operands[0].present)
16588 inst.instruction |= 1 << 21;
16589
5b7c81bd 16590 v8_1_loop_reloc (true);
1f6234a3
AV
16591 break;
16592
16593 case T_MNEM_wls:
16594 case T_MNEM_wlstp:
5b7c81bd 16595 v8_1_loop_reloc (false);
1f6234a3
AV
16596 /* fall through. */
16597 case T_MNEM_dlstp:
16598 case T_MNEM_dls:
16599 constraint (inst.operands[1].isreg != 1, BAD_ARGS);
16600
16601 if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
16602 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
16603 else if (inst.operands[1].reg == REG_PC)
16604 as_tsktsk (MVE_BAD_PC);
16605 if (inst.operands[1].reg == REG_SP)
16606 as_tsktsk (MVE_BAD_SP);
16607
16608 inst.instruction |= (inst.operands[1].reg << 16);
16609 break;
16610
16611 default:
16612 abort ();
16613 }
16614}
16615
16616
037e8744
JB
16617static void
16618do_vfp_nsyn_cmp (void)
16619{
9db2f6b4 16620 enum neon_shape rs;
1b883319
AV
16621 if (!inst.operands[0].isreg)
16622 {
16623 do_mve_vcmp ();
16624 return;
16625 }
16626 else
16627 {
16628 constraint (inst.operands[2].present, BAD_SYNTAX);
16629 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd),
16630 BAD_FPU);
16631 }
16632
037e8744
JB
16633 if (inst.operands[1].isreg)
16634 {
9db2f6b4
RL
16635 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
16636 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 16637
9db2f6b4 16638 if (rs == NS_FF || rs == NS_HH)
477330fc
RM
16639 {
16640 NEON_ENCODE (SINGLE, inst);
16641 do_vfp_sp_monadic ();
16642 }
037e8744 16643 else
477330fc
RM
16644 {
16645 NEON_ENCODE (DOUBLE, inst);
16646 do_vfp_dp_rd_rm ();
16647 }
037e8744
JB
16648 }
16649 else
16650 {
9db2f6b4
RL
16651 rs = neon_select_shape (NS_HI, NS_FI, NS_DI, NS_NULL);
16652 neon_check_type (2, rs, N_F_ALL | N_KEY | N_VFP, N_EQK);
037e8744
JB
16653
16654 switch (inst.instruction & 0x0fffffff)
477330fc
RM
16655 {
16656 case N_MNEM_vcmp:
16657 inst.instruction += N_MNEM_vcmpz - N_MNEM_vcmp;
16658 break;
16659 case N_MNEM_vcmpe:
16660 inst.instruction += N_MNEM_vcmpez - N_MNEM_vcmpe;
16661 break;
16662 default:
16663 abort ();
16664 }
5f4273c7 16665
9db2f6b4 16666 if (rs == NS_FI || rs == NS_HI)
477330fc
RM
16667 {
16668 NEON_ENCODE (SINGLE, inst);
16669 do_vfp_sp_compare_z ();
16670 }
037e8744 16671 else
477330fc
RM
16672 {
16673 NEON_ENCODE (DOUBLE, inst);
16674 do_vfp_dp_rd ();
16675 }
037e8744
JB
16676 }
16677 do_vfp_cond_or_thumb ();
9db2f6b4
RL
16678
16679 /* ARMv8.2 fp16 instruction. */
16680 if (rs == NS_HI || rs == NS_HH)
16681 do_scalar_fp16_v82_encode ();
037e8744
JB
16682}
16683
16684static void
16685nsyn_insert_sp (void)
16686{
16687 inst.operands[1] = inst.operands[0];
16688 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
fdfde340 16689 inst.operands[0].reg = REG_SP;
037e8744
JB
16690 inst.operands[0].isreg = 1;
16691 inst.operands[0].writeback = 1;
16692 inst.operands[0].present = 1;
16693}
16694
037e8744
JB
16695/* Fix up Neon data-processing instructions, ORing in the correct bits for
16696 ARM mode or Thumb mode and moving the encoded bit 24 to bit 28. */
16697
88714cb8
DG
16698static void
16699neon_dp_fixup (struct arm_it* insn)
037e8744 16700{
88714cb8
DG
16701 unsigned int i = insn->instruction;
16702 insn->is_neon = 1;
16703
037e8744
JB
16704 if (thumb_mode)
16705 {
16706 /* The U bit is at bit 24 by default. Move to bit 28 in Thumb mode. */
16707 if (i & (1 << 24))
477330fc 16708 i |= 1 << 28;
5f4273c7 16709
037e8744 16710 i &= ~(1 << 24);
5f4273c7 16711
037e8744
JB
16712 i |= 0xef000000;
16713 }
16714 else
16715 i |= 0xf2000000;
5f4273c7 16716
88714cb8 16717 insn->instruction = i;
037e8744
JB
16718}
16719
5ee91343 16720static void
7df54120 16721mve_encode_qqr (int size, int U, int fp)
5ee91343
AV
16722{
16723 if (inst.operands[2].reg == REG_SP)
16724 as_tsktsk (MVE_BAD_SP);
16725 else if (inst.operands[2].reg == REG_PC)
16726 as_tsktsk (MVE_BAD_PC);
16727
16728 if (fp)
16729 {
16730 /* vadd. */
16731 if (((unsigned)inst.instruction) == 0xd00)
16732 inst.instruction = 0xee300f40;
16733 /* vsub. */
16734 else if (((unsigned)inst.instruction) == 0x200d00)
16735 inst.instruction = 0xee301f40;
a8465a06
AV
16736 /* vmul. */
16737 else if (((unsigned)inst.instruction) == 0x1000d10)
16738 inst.instruction = 0xee310e60;
5ee91343
AV
16739
16740 /* Setting size which is 1 for F16 and 0 for F32. */
16741 inst.instruction |= (size == 16) << 28;
16742 }
16743 else
16744 {
16745 /* vadd. */
16746 if (((unsigned)inst.instruction) == 0x800)
16747 inst.instruction = 0xee010f40;
16748 /* vsub. */
16749 else if (((unsigned)inst.instruction) == 0x1000800)
16750 inst.instruction = 0xee011f40;
7df54120
AV
16751 /* vhadd. */
16752 else if (((unsigned)inst.instruction) == 0)
16753 inst.instruction = 0xee000f40;
16754 /* vhsub. */
16755 else if (((unsigned)inst.instruction) == 0x200)
16756 inst.instruction = 0xee001f40;
a8465a06
AV
16757 /* vmla. */
16758 else if (((unsigned)inst.instruction) == 0x900)
16759 inst.instruction = 0xee010e40;
16760 /* vmul. */
16761 else if (((unsigned)inst.instruction) == 0x910)
16762 inst.instruction = 0xee011e60;
16763 /* vqadd. */
16764 else if (((unsigned)inst.instruction) == 0x10)
16765 inst.instruction = 0xee000f60;
16766 /* vqsub. */
16767 else if (((unsigned)inst.instruction) == 0x210)
16768 inst.instruction = 0xee001f60;
42b16635
AV
16769 /* vqrdmlah. */
16770 else if (((unsigned)inst.instruction) == 0x3000b10)
16771 inst.instruction = 0xee000e40;
16772 /* vqdmulh. */
16773 else if (((unsigned)inst.instruction) == 0x0000b00)
16774 inst.instruction = 0xee010e60;
16775 /* vqrdmulh. */
16776 else if (((unsigned)inst.instruction) == 0x1000b00)
16777 inst.instruction = 0xfe010e60;
7df54120
AV
16778
16779 /* Set U-bit. */
16780 inst.instruction |= U << 28;
16781
5ee91343
AV
16782 /* Setting bits for size. */
16783 inst.instruction |= neon_logbits (size) << 20;
16784 }
16785 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16786 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16787 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16788 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16789 inst.instruction |= inst.operands[2].reg;
16790 inst.is_neon = 1;
16791}
16792
a302e574
AV
16793static void
16794mve_encode_rqq (unsigned bit28, unsigned size)
16795{
16796 inst.instruction |= bit28 << 28;
16797 inst.instruction |= neon_logbits (size) << 20;
16798 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16799 inst.instruction |= inst.operands[0].reg << 12;
16800 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16801 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16802 inst.instruction |= LOW4 (inst.operands[2].reg);
16803 inst.is_neon = 1;
16804}
16805
886e1c73
AV
16806static void
16807mve_encode_qqq (int ubit, int size)
16808{
16809
16810 inst.instruction |= (ubit != 0) << 28;
16811 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16812 inst.instruction |= neon_logbits (size) << 20;
16813 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16814 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16815 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16816 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16817 inst.instruction |= LOW4 (inst.operands[2].reg);
16818
16819 inst.is_neon = 1;
16820}
16821
26c1e780
AV
16822static void
16823mve_encode_rq (unsigned bit28, unsigned size)
16824{
16825 inst.instruction |= bit28 << 28;
16826 inst.instruction |= neon_logbits (size) << 18;
16827 inst.instruction |= inst.operands[0].reg << 12;
16828 inst.instruction |= LOW4 (inst.operands[1].reg);
16829 inst.is_neon = 1;
16830}
886e1c73 16831
93925576
AV
16832static void
16833mve_encode_rrqq (unsigned U, unsigned size)
16834{
16835 constraint (inst.operands[3].reg > 14, MVE_BAD_QREG);
16836
16837 inst.instruction |= U << 28;
16838 inst.instruction |= (inst.operands[1].reg >> 1) << 20;
16839 inst.instruction |= LOW4 (inst.operands[2].reg) << 16;
16840 inst.instruction |= (size == 32) << 16;
16841 inst.instruction |= inst.operands[0].reg << 12;
16842 inst.instruction |= HI1 (inst.operands[2].reg) << 7;
16843 inst.instruction |= inst.operands[3].reg;
16844 inst.is_neon = 1;
16845}
16846
aab2c27d
MM
16847/* Helper function for neon_three_same handling the operands. */
16848static void
16849neon_three_args (int isquad)
16850{
16851 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16852 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16853 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16854 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16855 inst.instruction |= LOW4 (inst.operands[2].reg);
16856 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16857 inst.instruction |= (isquad != 0) << 6;
16858 inst.is_neon = 1;
16859}
16860
037e8744
JB
16861/* Encode insns with bit pattern:
16862
16863 |28/24|23|22 |21 20|19 16|15 12|11 8|7|6|5|4|3 0|
16864 | U |x |D |size | Rn | Rd |x x x x|N|Q|M|x| Rm |
5f4273c7 16865
037e8744
JB
16866 SIZE is passed in bits. -1 means size field isn't changed, in case it has a
16867 different meaning for some instruction. */
16868
16869static void
16870neon_three_same (int isquad, int ubit, int size)
16871{
aab2c27d 16872 neon_three_args (isquad);
037e8744
JB
16873 inst.instruction |= (ubit != 0) << 24;
16874 if (size != -1)
16875 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 16876
88714cb8 16877 neon_dp_fixup (&inst);
037e8744
JB
16878}
16879
16880/* Encode instructions of the form:
16881
16882 |28/24|23|22|21 20|19 18|17 16|15 12|11 7|6|5|4|3 0|
16883 | U |x |D |x x |size |x x | Rd |x x x x x|Q|M|x| Rm |
5287ad62
JB
16884
16885 Don't write size if SIZE == -1. */
16886
16887static void
16888neon_two_same (int qbit, int ubit, int size)
16889{
16890 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16891 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16892 inst.instruction |= LOW4 (inst.operands[1].reg);
16893 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16894 inst.instruction |= (qbit != 0) << 6;
16895 inst.instruction |= (ubit != 0) << 24;
16896
16897 if (size != -1)
16898 inst.instruction |= neon_logbits (size) << 18;
16899
88714cb8 16900 neon_dp_fixup (&inst);
5287ad62
JB
16901}
16902
7df54120
AV
16903enum vfp_or_neon_is_neon_bits
16904{
16905NEON_CHECK_CC = 1,
16906NEON_CHECK_ARCH = 2,
16907NEON_CHECK_ARCH8 = 4
16908};
16909
16910/* Call this function if an instruction which may have belonged to the VFP or
16911 Neon instruction sets, but turned out to be a Neon instruction (due to the
16912 operand types involved, etc.). We have to check and/or fix-up a couple of
16913 things:
16914
16915 - Make sure the user hasn't attempted to make a Neon instruction
16916 conditional.
16917 - Alter the value in the condition code field if necessary.
16918 - Make sure that the arch supports Neon instructions.
16919
16920 Which of these operations take place depends on bits from enum
16921 vfp_or_neon_is_neon_bits.
16922
16923 WARNING: This function has side effects! If NEON_CHECK_CC is used and the
16924 current instruction's condition is COND_ALWAYS, the condition field is
16925 changed to inst.uncond_value. This is necessary because instructions shared
16926 between VFP and Neon may be conditional for the VFP variants only, and the
16927 unconditional Neon version must have, e.g., 0xF in the condition field. */
16928
16929static int
16930vfp_or_neon_is_neon (unsigned check)
16931{
16932/* Conditions are always legal in Thumb mode (IT blocks). */
16933if (!thumb_mode && (check & NEON_CHECK_CC))
16934 {
16935 if (inst.cond != COND_ALWAYS)
16936 {
16937 first_error (_(BAD_COND));
16938 return FAIL;
16939 }
7af67752 16940 if (inst.uncond_value != -1u)
7df54120
AV
16941 inst.instruction |= inst.uncond_value << 28;
16942 }
16943
16944
16945 if (((check & NEON_CHECK_ARCH) && !mark_feature_used (&fpu_neon_ext_v1))
16946 || ((check & NEON_CHECK_ARCH8)
16947 && !mark_feature_used (&fpu_neon_ext_armv8)))
16948 {
16949 first_error (_(BAD_FPU));
16950 return FAIL;
16951 }
16952
16953return SUCCESS;
16954}
16955
64c350f2
AV
16956
16957/* Return TRUE if the SIMD instruction is available for the current
16958 cpu_variant. FP is set to TRUE if this is a SIMD floating-point
16959 instruction. CHECK contains th. CHECK contains the set of bits to pass to
16960 vfp_or_neon_is_neon for the NEON specific checks. */
16961
5b7c81bd 16962static bool
7df54120
AV
16963check_simd_pred_availability (int fp, unsigned check)
16964{
16965if (inst.cond > COND_ALWAYS)
16966 {
16967 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16968 {
16969 inst.error = BAD_FPU;
5b7c81bd 16970 return false;
7df54120
AV
16971 }
16972 inst.pred_insn_type = INSIDE_VPT_INSN;
16973 }
16974else if (inst.cond < COND_ALWAYS)
16975 {
16976 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16977 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16978 else if (vfp_or_neon_is_neon (check) == FAIL)
5b7c81bd 16979 return false;
7df54120
AV
16980 }
16981else
16982 {
16983 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fp ? mve_fp_ext : mve_ext)
16984 && vfp_or_neon_is_neon (check) == FAIL)
5b7c81bd 16985 return false;
7df54120
AV
16986
16987 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16988 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16989 }
5b7c81bd 16990return true;
7df54120
AV
16991}
16992
5287ad62
JB
16993/* Neon instruction encoders, in approximate order of appearance. */
16994
16995static void
16996do_neon_dyadic_i_su (void)
16997{
5b7c81bd 16998 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
7df54120
AV
16999 return;
17000
17001 enum neon_shape rs;
17002 struct neon_type_el et;
17003 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17004 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17005 else
17006 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17007
17008 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_32 | N_KEY);
17009
17010
17011 if (rs != NS_QQR)
17012 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17013 else
17014 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
5287ad62
JB
17015}
17016
17017static void
17018do_neon_dyadic_i64_su (void)
17019{
5b7c81bd 17020 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
a8465a06
AV
17021 return;
17022 enum neon_shape rs;
17023 struct neon_type_el et;
17024 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17025 {
17026 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
17027 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17028 }
17029 else
17030 {
17031 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17032 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
17033 }
17034 if (rs == NS_QQR)
17035 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
17036 else
17037 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
17038}
17039
17040static void
17041neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
477330fc 17042 unsigned immbits)
5287ad62
JB
17043{
17044 unsigned size = et.size >> 3;
17045 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17046 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17047 inst.instruction |= LOW4 (inst.operands[1].reg);
17048 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
17049 inst.instruction |= (isquad != 0) << 6;
17050 inst.instruction |= immbits << 16;
17051 inst.instruction |= (size >> 3) << 7;
17052 inst.instruction |= (size & 0x7) << 19;
17053 if (write_ubit)
17054 inst.instruction |= (uval != 0) << 24;
17055
88714cb8 17056 neon_dp_fixup (&inst);
5287ad62
JB
17057}
17058
17059static void
5150f0d8 17060do_neon_shl (void)
5287ad62 17061{
5b7c81bd 17062 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
17063 return;
17064
5287ad62
JB
17065 if (!inst.operands[2].isreg)
17066 {
5150f0d8
AV
17067 enum neon_shape rs;
17068 struct neon_type_el et;
17069 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17070 {
17071 rs = neon_select_shape (NS_QQI, NS_NULL);
17072 et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_MVE);
17073 }
17074 else
17075 {
17076 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
17077 et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
17078 }
cb3b1e65
JB
17079 int imm = inst.operands[2].imm;
17080
17081 constraint (imm < 0 || (unsigned)imm >= et.size,
17082 _("immediate out of range for shift"));
88714cb8 17083 NEON_ENCODE (IMMED, inst);
5b7c81bd 17084 neon_imm_shift (false, 0, neon_quad (rs), et, imm);
5287ad62
JB
17085 }
17086 else
17087 {
5150f0d8
AV
17088 enum neon_shape rs;
17089 struct neon_type_el et;
17090 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17091 {
17092 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17093 et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
17094 }
17095 else
17096 {
17097 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17098 et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
17099 }
17100
17101
17102 if (rs == NS_QQR)
17103 {
17104 constraint (inst.operands[0].reg != inst.operands[1].reg,
17105 _("invalid instruction shape"));
17106 if (inst.operands[2].reg == REG_SP)
17107 as_tsktsk (MVE_BAD_SP);
17108 else if (inst.operands[2].reg == REG_PC)
17109 as_tsktsk (MVE_BAD_PC);
17110
17111 inst.instruction = 0xee311e60;
17112 inst.instruction |= (et.type == NT_unsigned) << 28;
17113 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17114 inst.instruction |= neon_logbits (et.size) << 18;
17115 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17116 inst.instruction |= inst.operands[2].reg;
17117 inst.is_neon = 1;
17118 }
17119 else
17120 {
17121 unsigned int tmp;
17122
17123 /* VSHL/VQSHL 3-register variants have syntax such as:
17124 vshl.xx Dd, Dm, Dn
17125 whereas other 3-register operations encoded by neon_three_same have
17126 syntax like:
17127 vadd.xx Dd, Dn, Dm
17128 (i.e. with Dn & Dm reversed). Swap operands[1].reg and
17129 operands[2].reg here. */
17130 tmp = inst.operands[2].reg;
17131 inst.operands[2].reg = inst.operands[1].reg;
17132 inst.operands[1].reg = tmp;
17133 NEON_ENCODE (INTEGER, inst);
17134 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17135 }
5287ad62
JB
17136 }
17137}
17138
17139static void
5150f0d8 17140do_neon_qshl (void)
5287ad62 17141{
5b7c81bd 17142 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
17143 return;
17144
5287ad62
JB
17145 if (!inst.operands[2].isreg)
17146 {
5150f0d8
AV
17147 enum neon_shape rs;
17148 struct neon_type_el et;
17149 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17150 {
17151 rs = neon_select_shape (NS_QQI, NS_NULL);
17152 et = neon_check_type (2, rs, N_EQK, N_KEY | N_SU_MVE);
17153 }
17154 else
17155 {
17156 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
17157 et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
17158 }
cb3b1e65 17159 int imm = inst.operands[2].imm;
627907b7 17160
cb3b1e65
JB
17161 constraint (imm < 0 || (unsigned)imm >= et.size,
17162 _("immediate out of range for shift"));
88714cb8 17163 NEON_ENCODE (IMMED, inst);
5b7c81bd 17164 neon_imm_shift (true, et.type == NT_unsigned, neon_quad (rs), et, imm);
5287ad62
JB
17165 }
17166 else
17167 {
5150f0d8
AV
17168 enum neon_shape rs;
17169 struct neon_type_el et;
627907b7 17170
5150f0d8
AV
17171 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17172 {
17173 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17174 et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
17175 }
17176 else
17177 {
17178 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17179 et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
17180 }
17181
17182 if (rs == NS_QQR)
17183 {
17184 constraint (inst.operands[0].reg != inst.operands[1].reg,
17185 _("invalid instruction shape"));
17186 if (inst.operands[2].reg == REG_SP)
17187 as_tsktsk (MVE_BAD_SP);
17188 else if (inst.operands[2].reg == REG_PC)
17189 as_tsktsk (MVE_BAD_PC);
17190
17191 inst.instruction = 0xee311ee0;
17192 inst.instruction |= (et.type == NT_unsigned) << 28;
17193 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17194 inst.instruction |= neon_logbits (et.size) << 18;
17195 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17196 inst.instruction |= inst.operands[2].reg;
17197 inst.is_neon = 1;
17198 }
17199 else
17200 {
17201 unsigned int tmp;
17202
17203 /* See note in do_neon_shl. */
17204 tmp = inst.operands[2].reg;
17205 inst.operands[2].reg = inst.operands[1].reg;
17206 inst.operands[1].reg = tmp;
17207 NEON_ENCODE (INTEGER, inst);
17208 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17209 }
5287ad62
JB
17210 }
17211}
17212
627907b7
JB
17213static void
17214do_neon_rshl (void)
17215{
5b7c81bd 17216 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
1be7aba3
AV
17217 return;
17218
17219 enum neon_shape rs;
17220 struct neon_type_el et;
17221 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17222 {
17223 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
17224 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17225 }
17226 else
17227 {
17228 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17229 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
17230 }
17231
627907b7
JB
17232 unsigned int tmp;
17233
1be7aba3
AV
17234 if (rs == NS_QQR)
17235 {
17236 if (inst.operands[2].reg == REG_PC)
17237 as_tsktsk (MVE_BAD_PC);
17238 else if (inst.operands[2].reg == REG_SP)
17239 as_tsktsk (MVE_BAD_SP);
17240
17241 constraint (inst.operands[0].reg != inst.operands[1].reg,
17242 _("invalid instruction shape"));
17243
17244 if (inst.instruction == 0x0000510)
17245 /* We are dealing with vqrshl. */
17246 inst.instruction = 0xee331ee0;
17247 else
17248 /* We are dealing with vrshl. */
17249 inst.instruction = 0xee331e60;
17250
17251 inst.instruction |= (et.type == NT_unsigned) << 28;
17252 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17253 inst.instruction |= neon_logbits (et.size) << 18;
17254 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17255 inst.instruction |= inst.operands[2].reg;
17256 inst.is_neon = 1;
17257 }
17258 else
17259 {
17260 tmp = inst.operands[2].reg;
17261 inst.operands[2].reg = inst.operands[1].reg;
17262 inst.operands[1].reg = tmp;
17263 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17264 }
627907b7
JB
17265}
17266
5287ad62
JB
17267static int
17268neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
17269{
036dc3f7
PB
17270 /* Handle .I8 pseudo-instructions. */
17271 if (size == 8)
5287ad62 17272 {
5287ad62 17273 /* Unfortunately, this will make everything apart from zero out-of-range.
477330fc
RM
17274 FIXME is this the intended semantics? There doesn't seem much point in
17275 accepting .I8 if so. */
5287ad62
JB
17276 immediate |= immediate << 8;
17277 size = 16;
036dc3f7
PB
17278 }
17279
17280 if (size >= 32)
17281 {
17282 if (immediate == (immediate & 0x000000ff))
17283 {
17284 *immbits = immediate;
17285 return 0x1;
17286 }
17287 else if (immediate == (immediate & 0x0000ff00))
17288 {
17289 *immbits = immediate >> 8;
17290 return 0x3;
17291 }
17292 else if (immediate == (immediate & 0x00ff0000))
17293 {
17294 *immbits = immediate >> 16;
17295 return 0x5;
17296 }
17297 else if (immediate == (immediate & 0xff000000))
17298 {
17299 *immbits = immediate >> 24;
17300 return 0x7;
17301 }
17302 if ((immediate & 0xffff) != (immediate >> 16))
17303 goto bad_immediate;
17304 immediate &= 0xffff;
5287ad62
JB
17305 }
17306
17307 if (immediate == (immediate & 0x000000ff))
17308 {
17309 *immbits = immediate;
036dc3f7 17310 return 0x9;
5287ad62
JB
17311 }
17312 else if (immediate == (immediate & 0x0000ff00))
17313 {
17314 *immbits = immediate >> 8;
036dc3f7 17315 return 0xb;
5287ad62
JB
17316 }
17317
17318 bad_immediate:
dcbf9037 17319 first_error (_("immediate value out of range"));
5287ad62
JB
17320 return FAIL;
17321}
17322
5287ad62
JB
17323static void
17324do_neon_logic (void)
17325{
17326 if (inst.operands[2].present && inst.operands[2].isreg)
17327 {
037e8744 17328 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
f601a00c 17329 if (rs == NS_QQQ
5b7c81bd 17330 && !check_simd_pred_availability (false,
64c350f2 17331 NEON_CHECK_ARCH | NEON_CHECK_CC))
f601a00c
AV
17332 return;
17333 else if (rs != NS_QQQ
17334 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
17335 first_error (BAD_FPU);
17336
5287ad62
JB
17337 neon_check_type (3, rs, N_IGNORE_TYPE);
17338 /* U bit and size field were set as part of the bitmask. */
88714cb8 17339 NEON_ENCODE (INTEGER, inst);
037e8744 17340 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
17341 }
17342 else
17343 {
4316f0d2
DG
17344 const int three_ops_form = (inst.operands[2].present
17345 && !inst.operands[2].isreg);
17346 const int immoperand = (three_ops_form ? 2 : 1);
17347 enum neon_shape rs = (three_ops_form
17348 ? neon_select_shape (NS_DDI, NS_QQI, NS_NULL)
17349 : neon_select_shape (NS_DI, NS_QI, NS_NULL));
f601a00c
AV
17350 /* Because neon_select_shape makes the second operand a copy of the first
17351 if the second operand is not present. */
17352 if (rs == NS_QQI
5b7c81bd 17353 && !check_simd_pred_availability (false,
64c350f2 17354 NEON_CHECK_ARCH | NEON_CHECK_CC))
f601a00c
AV
17355 return;
17356 else if (rs != NS_QQI
17357 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
17358 first_error (BAD_FPU);
17359
17360 struct neon_type_el et;
17361 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17362 et = neon_check_type (2, rs, N_I32 | N_I16 | N_KEY, N_EQK);
17363 else
17364 et = neon_check_type (2, rs, N_I8 | N_I16 | N_I32 | N_I64 | N_F32
17365 | N_KEY, N_EQK);
17366
17367 if (et.type == NT_invtype)
17368 return;
21d799b5 17369 enum neon_opc opcode = (enum neon_opc) inst.instruction & 0x0fffffff;
5287ad62
JB
17370 unsigned immbits;
17371 int cmode;
5f4273c7 17372
5f4273c7 17373
4316f0d2
DG
17374 if (three_ops_form)
17375 constraint (inst.operands[0].reg != inst.operands[1].reg,
17376 _("first and second operands shall be the same register"));
17377
88714cb8 17378 NEON_ENCODE (IMMED, inst);
5287ad62 17379
4316f0d2 17380 immbits = inst.operands[immoperand].imm;
036dc3f7
PB
17381 if (et.size == 64)
17382 {
17383 /* .i64 is a pseudo-op, so the immediate must be a repeating
17384 pattern. */
4316f0d2
DG
17385 if (immbits != (inst.operands[immoperand].regisimm ?
17386 inst.operands[immoperand].reg : 0))
036dc3f7
PB
17387 {
17388 /* Set immbits to an invalid constant. */
17389 immbits = 0xdeadbeef;
17390 }
17391 }
17392
5287ad62 17393 switch (opcode)
477330fc
RM
17394 {
17395 case N_MNEM_vbic:
17396 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17397 break;
17398
17399 case N_MNEM_vorr:
17400 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17401 break;
17402
17403 case N_MNEM_vand:
17404 /* Pseudo-instruction for VBIC. */
17405 neon_invert_size (&immbits, 0, et.size);
17406 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17407 break;
17408
17409 case N_MNEM_vorn:
17410 /* Pseudo-instruction for VORR. */
17411 neon_invert_size (&immbits, 0, et.size);
17412 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17413 break;
17414
17415 default:
17416 abort ();
17417 }
5287ad62
JB
17418
17419 if (cmode == FAIL)
477330fc 17420 return;
5287ad62 17421
037e8744 17422 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
17423 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17424 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17425 inst.instruction |= cmode << 8;
17426 neon_write_immbits (immbits);
5f4273c7 17427
88714cb8 17428 neon_dp_fixup (&inst);
5287ad62
JB
17429 }
17430}
17431
17432static void
17433do_neon_bitfield (void)
17434{
037e8744 17435 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 17436 neon_check_type (3, rs, N_IGNORE_TYPE);
037e8744 17437 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
17438}
17439
17440static void
dcbf9037 17441neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types,
477330fc 17442 unsigned destbits)
5287ad62 17443{
5ee91343 17444 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
dcbf9037 17445 struct neon_type_el et = neon_check_type (3, rs, N_EQK | destbits, N_EQK,
477330fc 17446 types | N_KEY);
5287ad62
JB
17447 if (et.type == NT_float)
17448 {
88714cb8 17449 NEON_ENCODE (FLOAT, inst);
5ee91343 17450 if (rs == NS_QQR)
7df54120 17451 mve_encode_qqr (et.size, 0, 1);
5ee91343
AV
17452 else
17453 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
17454 }
17455 else
17456 {
88714cb8 17457 NEON_ENCODE (INTEGER, inst);
5ee91343 17458 if (rs == NS_QQR)
a8465a06 17459 mve_encode_qqr (et.size, et.type == ubit_meaning, 0);
5ee91343
AV
17460 else
17461 neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
5287ad62
JB
17462 }
17463}
17464
5287ad62
JB
17465
17466static void
17467do_neon_dyadic_if_su_d (void)
17468{
17469 /* This version only allow D registers, but that constraint is enforced during
17470 operand parsing so we don't need to do anything extra here. */
dcbf9037 17471 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
17472}
17473
5287ad62
JB
17474static void
17475do_neon_dyadic_if_i_d (void)
17476{
428e3f1f
PB
17477 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17478 affected if we specify unsigned args. */
17479 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
5287ad62
JB
17480}
17481
f5f10c66
AV
17482static void
17483do_mve_vstr_vldr_QI (int size, int elsize, int load)
17484{
17485 constraint (size < 32, BAD_ADDR_MODE);
17486 constraint (size != elsize, BAD_EL_TYPE);
17487 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
17488 constraint (!inst.operands[1].preind, BAD_ADDR_MODE);
17489 constraint (load && inst.operands[0].reg == inst.operands[1].reg,
17490 _("destination register and offset register may not be the"
17491 " same"));
17492
17493 int imm = inst.relocs[0].exp.X_add_number;
17494 int add = 1;
17495 if (imm < 0)
17496 {
17497 add = 0;
17498 imm = -imm;
17499 }
17500 constraint ((imm % (size / 8) != 0)
17501 || imm > (0x7f << neon_logbits (size)),
17502 (size == 32) ? _("immediate must be a multiple of 4 in the"
17503 " range of +/-[0,508]")
17504 : _("immediate must be a multiple of 8 in the"
17505 " range of +/-[0,1016]"));
17506 inst.instruction |= 0x11 << 24;
17507 inst.instruction |= add << 23;
17508 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17509 inst.instruction |= inst.operands[1].writeback << 21;
17510 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17511 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17512 inst.instruction |= 1 << 12;
17513 inst.instruction |= (size == 64) << 8;
17514 inst.instruction &= 0xffffff00;
17515 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17516 inst.instruction |= imm >> neon_logbits (size);
17517}
17518
17519static void
17520do_mve_vstr_vldr_RQ (int size, int elsize, int load)
17521{
17522 unsigned os = inst.operands[1].imm >> 5;
e449ea97 17523 unsigned type = inst.vectype.el[0].type;
f5f10c66
AV
17524 constraint (os != 0 && size == 8,
17525 _("can not shift offsets when accessing less than half-word"));
17526 constraint (os && os != neon_logbits (size),
17527 _("shift immediate must be 1, 2 or 3 for half-word, word"
17528 " or double-word accesses respectively"));
17529 if (inst.operands[1].reg == REG_PC)
17530 as_tsktsk (MVE_BAD_PC);
17531
17532 switch (size)
17533 {
17534 case 8:
17535 constraint (elsize >= 64, BAD_EL_TYPE);
17536 break;
17537 case 16:
17538 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
17539 break;
17540 case 32:
17541 case 64:
17542 constraint (elsize != size, BAD_EL_TYPE);
17543 break;
17544 default:
17545 break;
17546 }
17547 constraint (inst.operands[1].writeback || !inst.operands[1].preind,
17548 BAD_ADDR_MODE);
17549 if (load)
17550 {
17551 constraint (inst.operands[0].reg == (inst.operands[1].imm & 0x1f),
17552 _("destination register and offset register may not be"
17553 " the same"));
e449ea97
SP
17554 constraint (size == elsize && type == NT_signed, BAD_EL_TYPE);
17555 constraint (size != elsize && type != NT_unsigned && type != NT_signed,
f5f10c66 17556 BAD_EL_TYPE);
e449ea97 17557 inst.instruction |= ((size == elsize) || (type == NT_unsigned)) << 28;
f5f10c66
AV
17558 }
17559 else
17560 {
e449ea97 17561 constraint (type != NT_untyped, BAD_EL_TYPE);
f5f10c66
AV
17562 }
17563
17564 inst.instruction |= 1 << 23;
17565 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17566 inst.instruction |= inst.operands[1].reg << 16;
17567 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17568 inst.instruction |= neon_logbits (elsize) << 7;
17569 inst.instruction |= HI1 (inst.operands[1].imm) << 5;
17570 inst.instruction |= LOW4 (inst.operands[1].imm);
17571 inst.instruction |= !!os;
17572}
17573
17574static void
17575do_mve_vstr_vldr_RI (int size, int elsize, int load)
17576{
17577 enum neon_el_type type = inst.vectype.el[0].type;
17578
17579 constraint (size >= 64, BAD_ADDR_MODE);
17580 switch (size)
17581 {
17582 case 16:
17583 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
17584 break;
17585 case 32:
17586 constraint (elsize != size, BAD_EL_TYPE);
17587 break;
17588 default:
17589 break;
17590 }
17591 if (load)
17592 {
17593 constraint (elsize != size && type != NT_unsigned
17594 && type != NT_signed, BAD_EL_TYPE);
17595 }
17596 else
17597 {
17598 constraint (elsize != size && type != NT_untyped, BAD_EL_TYPE);
17599 }
17600
17601 int imm = inst.relocs[0].exp.X_add_number;
17602 int add = 1;
17603 if (imm < 0)
17604 {
17605 add = 0;
17606 imm = -imm;
17607 }
17608
17609 if ((imm % (size / 8) != 0) || imm > (0x7f << neon_logbits (size)))
17610 {
17611 switch (size)
17612 {
17613 case 8:
17614 constraint (1, _("immediate must be in the range of +/-[0,127]"));
17615 break;
17616 case 16:
17617 constraint (1, _("immediate must be a multiple of 2 in the"
17618 " range of +/-[0,254]"));
17619 break;
17620 case 32:
17621 constraint (1, _("immediate must be a multiple of 4 in the"
17622 " range of +/-[0,508]"));
17623 break;
17624 }
17625 }
17626
17627 if (size != elsize)
17628 {
17629 constraint (inst.operands[1].reg > 7, BAD_HIREG);
17630 constraint (inst.operands[0].reg > 14,
17631 _("MVE vector register in the range [Q0..Q7] expected"));
17632 inst.instruction |= (load && type == NT_unsigned) << 28;
17633 inst.instruction |= (size == 16) << 19;
17634 inst.instruction |= neon_logbits (elsize) << 7;
17635 }
17636 else
17637 {
17638 if (inst.operands[1].reg == REG_PC)
17639 as_tsktsk (MVE_BAD_PC);
17640 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
17641 as_tsktsk (MVE_BAD_SP);
17642 inst.instruction |= 1 << 12;
17643 inst.instruction |= neon_logbits (size) << 7;
17644 }
17645 inst.instruction |= inst.operands[1].preind << 24;
17646 inst.instruction |= add << 23;
17647 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17648 inst.instruction |= inst.operands[1].writeback << 21;
17649 inst.instruction |= inst.operands[1].reg << 16;
17650 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17651 inst.instruction &= 0xffffff80;
17652 inst.instruction |= imm >> neon_logbits (size);
17653
17654}
17655
17656static void
17657do_mve_vstr_vldr (void)
17658{
17659 unsigned size;
17660 int load = 0;
17661
17662 if (inst.cond > COND_ALWAYS)
17663 inst.pred_insn_type = INSIDE_VPT_INSN;
17664 else
17665 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17666
17667 switch (inst.instruction)
17668 {
17669 default:
17670 gas_assert (0);
17671 break;
17672 case M_MNEM_vldrb:
17673 load = 1;
17674 /* fall through. */
17675 case M_MNEM_vstrb:
17676 size = 8;
17677 break;
17678 case M_MNEM_vldrh:
17679 load = 1;
17680 /* fall through. */
17681 case M_MNEM_vstrh:
17682 size = 16;
17683 break;
17684 case M_MNEM_vldrw:
17685 load = 1;
17686 /* fall through. */
17687 case M_MNEM_vstrw:
17688 size = 32;
17689 break;
17690 case M_MNEM_vldrd:
17691 load = 1;
17692 /* fall through. */
17693 case M_MNEM_vstrd:
17694 size = 64;
17695 break;
17696 }
17697 unsigned elsize = inst.vectype.el[0].size;
17698
17699 if (inst.operands[1].isquad)
17700 {
17701 /* We are dealing with [Q, imm]{!} cases. */
17702 do_mve_vstr_vldr_QI (size, elsize, load);
17703 }
17704 else
17705 {
17706 if (inst.operands[1].immisreg == 2)
17707 {
17708 /* We are dealing with [R, Q, {UXTW #os}] cases. */
17709 do_mve_vstr_vldr_RQ (size, elsize, load);
17710 }
17711 else if (!inst.operands[1].immisreg)
17712 {
17713 /* We are dealing with [R, Imm]{!}/[R], Imm cases. */
17714 do_mve_vstr_vldr_RI (size, elsize, load);
17715 }
17716 else
17717 constraint (1, BAD_ADDR_MODE);
17718 }
17719
17720 inst.is_neon = 1;
17721}
17722
35c228db
AV
17723static void
17724do_mve_vst_vld (void)
17725{
17726 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17727 return;
17728
17729 constraint (!inst.operands[1].preind || inst.relocs[0].exp.X_add_symbol != 0
17730 || inst.relocs[0].exp.X_add_number != 0
17731 || inst.operands[1].immisreg != 0,
17732 BAD_ADDR_MODE);
17733 constraint (inst.vectype.el[0].size > 32, BAD_EL_TYPE);
17734 if (inst.operands[1].reg == REG_PC)
17735 as_tsktsk (MVE_BAD_PC);
17736 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
17737 as_tsktsk (MVE_BAD_SP);
17738
17739
17740 /* These instructions are one of the "exceptions" mentioned in
17741 handle_pred_state. They are MVE instructions that are not VPT compatible
17742 and do not accept a VPT code, thus appending such a code is a syntax
17743 error. */
17744 if (inst.cond > COND_ALWAYS)
17745 first_error (BAD_SYNTAX);
17746 /* If we append a scalar condition code we can set this to
17747 MVE_OUTSIDE_PRED_INSN as it will also lead to a syntax error. */
17748 else if (inst.cond < COND_ALWAYS)
17749 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17750 else
17751 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
17752
17753 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17754 inst.instruction |= inst.operands[1].writeback << 21;
17755 inst.instruction |= inst.operands[1].reg << 16;
17756 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17757 inst.instruction |= neon_logbits (inst.vectype.el[0].size) << 7;
17758 inst.is_neon = 1;
17759}
17760
26c1e780
AV
17761static void
17762do_mve_vaddlv (void)
17763{
17764 enum neon_shape rs = neon_select_shape (NS_RRQ, NS_NULL);
17765 struct neon_type_el et
17766 = neon_check_type (3, rs, N_EQK, N_EQK, N_S32 | N_U32 | N_KEY);
17767
17768 if (et.type == NT_invtype)
17769 first_error (BAD_EL_TYPE);
17770
17771 if (inst.cond > COND_ALWAYS)
17772 inst.pred_insn_type = INSIDE_VPT_INSN;
17773 else
17774 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17775
17776 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
17777
17778 inst.instruction |= (et.type == NT_unsigned) << 28;
17779 inst.instruction |= inst.operands[1].reg << 19;
17780 inst.instruction |= inst.operands[0].reg << 12;
17781 inst.instruction |= inst.operands[2].reg;
17782 inst.is_neon = 1;
17783}
17784
5287ad62 17785static void
5ee91343 17786do_neon_dyadic_if_su (void)
5287ad62 17787{
5ee91343
AV
17788 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
17789 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
17790 N_SUF_32 | N_KEY);
17791
935295b5
AV
17792 constraint ((inst.instruction == ((unsigned) N_MNEM_vmax)
17793 || inst.instruction == ((unsigned) N_MNEM_vmin))
17794 && et.type == NT_float
17795 && !ARM_CPU_HAS_FEATURE (cpu_variant,fpu_neon_ext_v1), BAD_FPU);
17796
64c350f2
AV
17797 if (!check_simd_pred_availability (et.type == NT_float,
17798 NEON_CHECK_ARCH | NEON_CHECK_CC))
037e8744
JB
17799 return;
17800
5ee91343
AV
17801 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
17802}
17803
17804static void
17805do_neon_addsub_if_i (void)
17806{
17807 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
17808 && try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
037e8744
JB
17809 return;
17810
5ee91343
AV
17811 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
17812 struct neon_type_el et = neon_check_type (3, rs, N_EQK,
17813 N_EQK, N_IF_32 | N_I64 | N_KEY);
17814
17815 constraint (rs == NS_QQR && et.size == 64, BAD_FPU);
17816 /* If we are parsing Q registers and the element types match MVE, which NEON
17817 also supports, then we must check whether this is an instruction that can
17818 be used by both MVE/NEON. This distinction can be made based on whether
17819 they are predicated or not. */
17820 if ((rs == NS_QQQ || rs == NS_QQR) && et.size != 64)
17821 {
64c350f2
AV
17822 if (!check_simd_pred_availability (et.type == NT_float,
17823 NEON_CHECK_ARCH | NEON_CHECK_CC))
5ee91343
AV
17824 return;
17825 }
17826 else
17827 {
17828 /* If they are either in a D register or are using an unsupported. */
17829 if (rs != NS_QQR
17830 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
17831 return;
17832 }
17833
5287ad62
JB
17834 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17835 affected if we specify unsigned args. */
dcbf9037 17836 neon_dyadic_misc (NT_untyped, N_IF_32 | N_I64, 0);
5287ad62
JB
17837}
17838
17839/* Swaps operands 1 and 2. If operand 1 (optional arg) was omitted, we want the
17840 result to be:
17841 V<op> A,B (A is operand 0, B is operand 2)
17842 to mean:
17843 V<op> A,B,A
17844 not:
17845 V<op> A,B,B
17846 so handle that case specially. */
17847
17848static void
17849neon_exchange_operands (void)
17850{
5287ad62
JB
17851 if (inst.operands[1].present)
17852 {
e1fa0163
NC
17853 void *scratch = xmalloc (sizeof (inst.operands[0]));
17854
5287ad62
JB
17855 /* Swap operands[1] and operands[2]. */
17856 memcpy (scratch, &inst.operands[1], sizeof (inst.operands[0]));
17857 inst.operands[1] = inst.operands[2];
17858 memcpy (&inst.operands[2], scratch, sizeof (inst.operands[0]));
e1fa0163 17859 free (scratch);
5287ad62
JB
17860 }
17861 else
17862 {
17863 inst.operands[1] = inst.operands[2];
17864 inst.operands[2] = inst.operands[0];
17865 }
17866}
17867
17868static void
17869neon_compare (unsigned regtypes, unsigned immtypes, int invert)
17870{
17871 if (inst.operands[2].isreg)
17872 {
17873 if (invert)
477330fc 17874 neon_exchange_operands ();
dcbf9037 17875 neon_dyadic_misc (NT_unsigned, regtypes, N_SIZ);
5287ad62
JB
17876 }
17877 else
17878 {
037e8744 17879 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
dcbf9037 17880 struct neon_type_el et = neon_check_type (2, rs,
477330fc 17881 N_EQK | N_SIZ, immtypes | N_KEY);
5287ad62 17882
88714cb8 17883 NEON_ENCODE (IMMED, inst);
5287ad62
JB
17884 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17885 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17886 inst.instruction |= LOW4 (inst.operands[1].reg);
17887 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 17888 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
17889 inst.instruction |= (et.type == NT_float) << 10;
17890 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 17891
88714cb8 17892 neon_dp_fixup (&inst);
5287ad62
JB
17893 }
17894}
17895
17896static void
17897do_neon_cmp (void)
17898{
5b7c81bd 17899 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, false);
5287ad62
JB
17900}
17901
17902static void
17903do_neon_cmp_inv (void)
17904{
5b7c81bd 17905 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, true);
5287ad62
JB
17906}
17907
17908static void
17909do_neon_ceq (void)
17910{
5b7c81bd 17911 neon_compare (N_IF_32, N_IF_32, false);
5287ad62
JB
17912}
17913
17914/* For multiply instructions, we have the possibility of 16-bit or 32-bit
17915 scalars, which are encoded in 5 bits, M : Rm.
17916 For 16-bit scalars, the register is encoded in Rm[2:0] and the index in
17917 M:Rm[3], and for 32-bit scalars, the register is encoded in Rm[3:0] and the
c604a79a
JW
17918 index in M.
17919
17920 Dot Product instructions are similar to multiply instructions except elsize
17921 should always be 32.
17922
17923 This function translates SCALAR, which is GAS's internal encoding of indexed
17924 scalar register, to raw encoding. There is also register and index range
17925 check based on ELSIZE. */
5287ad62
JB
17926
17927static unsigned
17928neon_scalar_for_mul (unsigned scalar, unsigned elsize)
17929{
dcbf9037
JB
17930 unsigned regno = NEON_SCALAR_REG (scalar);
17931 unsigned elno = NEON_SCALAR_INDEX (scalar);
5287ad62
JB
17932
17933 switch (elsize)
17934 {
17935 case 16:
17936 if (regno > 7 || elno > 3)
477330fc 17937 goto bad_scalar;
5287ad62 17938 return regno | (elno << 3);
5f4273c7 17939
5287ad62
JB
17940 case 32:
17941 if (regno > 15 || elno > 1)
477330fc 17942 goto bad_scalar;
5287ad62
JB
17943 return regno | (elno << 4);
17944
17945 default:
17946 bad_scalar:
dcbf9037 17947 first_error (_("scalar out of range for multiply instruction"));
5287ad62
JB
17948 }
17949
17950 return 0;
17951}
17952
17953/* Encode multiply / multiply-accumulate scalar instructions. */
17954
17955static void
17956neon_mul_mac (struct neon_type_el et, int ubit)
17957{
dcbf9037
JB
17958 unsigned scalar;
17959
17960 /* Give a more helpful error message if we have an invalid type. */
17961 if (et.type == NT_invtype)
17962 return;
5f4273c7 17963
dcbf9037 17964 scalar = neon_scalar_for_mul (inst.operands[2].reg, et.size);
5287ad62
JB
17965 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17966 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17967 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17968 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17969 inst.instruction |= LOW4 (scalar);
17970 inst.instruction |= HI1 (scalar) << 5;
17971 inst.instruction |= (et.type == NT_float) << 8;
17972 inst.instruction |= neon_logbits (et.size) << 20;
17973 inst.instruction |= (ubit != 0) << 24;
17974
88714cb8 17975 neon_dp_fixup (&inst);
5287ad62
JB
17976}
17977
17978static void
17979do_neon_mac_maybe_scalar (void)
17980{
037e8744
JB
17981 if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
17982 return;
17983
5b7c81bd 17984 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
17985 return;
17986
5287ad62
JB
17987 if (inst.operands[2].isscalar)
17988 {
a8465a06 17989 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 17990 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 17991 struct neon_type_el et = neon_check_type (3, rs,
589a7d88 17992 N_EQK, N_EQK, N_I16 | N_I32 | N_F_16_32 | N_KEY);
88714cb8 17993 NEON_ENCODE (SCALAR, inst);
037e8744 17994 neon_mul_mac (et, neon_quad (rs));
5287ad62 17995 }
a8465a06
AV
17996 else if (!inst.operands[2].isvec)
17997 {
17998 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
17999
18000 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18001 neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
18002
18003 neon_dyadic_misc (NT_unsigned, N_SU_MVE, 0);
18004 }
5287ad62 18005 else
428e3f1f 18006 {
a8465a06 18007 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
428e3f1f
PB
18008 /* The "untyped" case can't happen. Do this to stop the "U" bit being
18009 affected if we specify unsigned args. */
18010 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
18011 }
5287ad62
JB
18012}
18013
aab2c27d
MM
18014static void
18015do_bfloat_vfma (void)
18016{
18017 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
18018 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
18019 enum neon_shape rs;
18020 int t_bit = 0;
18021
18022 if (inst.instruction != B_MNEM_vfmab)
18023 {
18024 t_bit = 1;
18025 inst.instruction = B_MNEM_vfmat;
18026 }
18027
18028 if (inst.operands[2].isscalar)
18029 {
18030 rs = neon_select_shape (NS_QQS, NS_NULL);
18031 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
18032
18033 inst.instruction |= (1 << 25);
1db66fb6
JB
18034 int idx = inst.operands[2].reg & 0xf;
18035 constraint (!(idx < 4), _("index must be in the range 0 to 3"));
aab2c27d
MM
18036 inst.operands[2].reg >>= 4;
18037 constraint (!(inst.operands[2].reg < 8),
18038 _("indexed register must be less than 8"));
18039 neon_three_args (t_bit);
1db66fb6
JB
18040 inst.instruction |= ((idx & 1) << 3);
18041 inst.instruction |= ((idx & 2) << 4);
aab2c27d
MM
18042 }
18043 else
18044 {
18045 rs = neon_select_shape (NS_QQQ, NS_NULL);
18046 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
18047 neon_three_args (t_bit);
18048 }
18049
18050}
18051
62f3b8c8
PB
18052static void
18053do_neon_fmac (void)
18054{
d58196e0
AV
18055 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_fma)
18056 && try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS)
62f3b8c8
PB
18057 return;
18058
5b7c81bd 18059 if (!check_simd_pred_availability (true, NEON_CHECK_CC | NEON_CHECK_ARCH))
62f3b8c8
PB
18060 return;
18061
d58196e0
AV
18062 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
18063 {
18064 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
18065 struct neon_type_el et = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK,
18066 N_EQK);
18067
18068 if (rs == NS_QQR)
18069 {
aab2c27d 18070
d58196e0
AV
18071 if (inst.operands[2].reg == REG_SP)
18072 as_tsktsk (MVE_BAD_SP);
18073 else if (inst.operands[2].reg == REG_PC)
18074 as_tsktsk (MVE_BAD_PC);
18075
18076 inst.instruction = 0xee310e40;
18077 inst.instruction |= (et.size == 16) << 28;
18078 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18079 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
18080 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18081 inst.instruction |= HI1 (inst.operands[1].reg) << 6;
18082 inst.instruction |= inst.operands[2].reg;
18083 inst.is_neon = 1;
18084 return;
18085 }
18086 }
18087 else
18088 {
18089 constraint (!inst.operands[2].isvec, BAD_FPU);
18090 }
18091
62f3b8c8
PB
18092 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
18093}
18094
aab2c27d
MM
18095static void
18096do_mve_vfma (void)
18097{
18098 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_bf16) &&
18099 inst.cond == COND_ALWAYS)
18100 {
18101 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
18102 inst.instruction = N_MNEM_vfma;
18103 inst.pred_insn_type = INSIDE_VPT_INSN;
18104 inst.cond = 0xf;
18105 return do_neon_fmac();
18106 }
18107 else
18108 {
18109 do_bfloat_vfma();
18110 }
18111}
18112
5287ad62
JB
18113static void
18114do_neon_tst (void)
18115{
037e8744 18116 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
18117 struct neon_type_el et = neon_check_type (3, rs,
18118 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
037e8744 18119 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
18120}
18121
18122/* VMUL with 3 registers allows the P8 type. The scalar version supports the
18123 same types as the MAC equivalents. The polynomial type for this instruction
18124 is encoded the same as the integer type. */
18125
18126static void
18127do_neon_mul (void)
18128{
037e8744
JB
18129 if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
18130 return;
18131
5b7c81bd 18132 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
18133 return;
18134
5287ad62 18135 if (inst.operands[2].isscalar)
a8465a06
AV
18136 {
18137 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
18138 do_neon_mac_maybe_scalar ();
18139 }
5287ad62 18140 else
a8465a06
AV
18141 {
18142 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18143 {
18144 enum neon_shape rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
18145 struct neon_type_el et
18146 = neon_check_type (3, rs, N_EQK, N_EQK, N_I_MVE | N_F_MVE | N_KEY);
18147 if (et.type == NT_float)
18148 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
18149 BAD_FPU);
18150
18151 neon_dyadic_misc (NT_float, N_I_MVE | N_F_MVE, 0);
18152 }
18153 else
18154 {
18155 constraint (!inst.operands[2].isvec, BAD_FPU);
18156 neon_dyadic_misc (NT_poly,
18157 N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
18158 }
18159 }
5287ad62
JB
18160}
18161
18162static void
18163do_neon_qdmulh (void)
18164{
5b7c81bd 18165 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
42b16635
AV
18166 return;
18167
5287ad62
JB
18168 if (inst.operands[2].isscalar)
18169 {
42b16635 18170 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 18171 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 18172 struct neon_type_el et = neon_check_type (3, rs,
477330fc 18173 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 18174 NEON_ENCODE (SCALAR, inst);
037e8744 18175 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
18176 }
18177 else
18178 {
42b16635
AV
18179 enum neon_shape rs;
18180 struct neon_type_el et;
18181 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18182 {
18183 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
18184 et = neon_check_type (3, rs,
18185 N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18186 }
18187 else
18188 {
18189 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
18190 et = neon_check_type (3, rs,
18191 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18192 }
18193
88714cb8 18194 NEON_ENCODE (INTEGER, inst);
42b16635
AV
18195 if (rs == NS_QQR)
18196 mve_encode_qqr (et.size, 0, 0);
18197 else
18198 /* The U bit (rounding) comes from bit mask. */
18199 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
18200 }
18201}
18202
26c1e780
AV
18203static void
18204do_mve_vaddv (void)
18205{
18206 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18207 struct neon_type_el et
18208 = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
18209
18210 if (et.type == NT_invtype)
18211 first_error (BAD_EL_TYPE);
18212
18213 if (inst.cond > COND_ALWAYS)
18214 inst.pred_insn_type = INSIDE_VPT_INSN;
18215 else
18216 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18217
18218 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
18219
18220 mve_encode_rq (et.type == NT_unsigned, et.size);
18221}
18222
7df54120
AV
18223static void
18224do_mve_vhcadd (void)
18225{
18226 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
18227 struct neon_type_el et
18228 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18229
18230 if (inst.cond > COND_ALWAYS)
18231 inst.pred_insn_type = INSIDE_VPT_INSN;
18232 else
18233 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18234
18235 unsigned rot = inst.relocs[0].exp.X_add_number;
18236 constraint (rot != 90 && rot != 270, _("immediate out of range"));
18237
18238 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
18239 as_tsktsk (_("Warning: 32-bit element size and same first and third "
18240 "operand makes instruction UNPREDICTABLE"));
18241
18242 mve_encode_qqq (0, et.size);
18243 inst.instruction |= (rot == 270) << 12;
18244 inst.is_neon = 1;
18245}
18246
35d1cfc2
AV
18247static void
18248do_mve_vqdmull (void)
18249{
18250 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
18251 struct neon_type_el et
18252 = neon_check_type (3, rs, N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18253
18254 if (et.size == 32
18255 && (inst.operands[0].reg == inst.operands[1].reg
18256 || (rs == NS_QQQ && inst.operands[0].reg == inst.operands[2].reg)))
18257 as_tsktsk (BAD_MVE_SRCDEST);
18258
18259 if (inst.cond > COND_ALWAYS)
18260 inst.pred_insn_type = INSIDE_VPT_INSN;
18261 else
18262 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18263
18264 if (rs == NS_QQQ)
18265 {
18266 mve_encode_qqq (et.size == 32, 64);
18267 inst.instruction |= 1;
18268 }
18269 else
18270 {
18271 mve_encode_qqr (64, et.size == 32, 0);
18272 inst.instruction |= 0x3 << 5;
18273 }
18274}
18275
c2dafc2a
AV
18276static void
18277do_mve_vadc (void)
18278{
18279 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
18280 struct neon_type_el et
18281 = neon_check_type (3, rs, N_KEY | N_I32, N_EQK, N_EQK);
18282
18283 if (et.type == NT_invtype)
18284 first_error (BAD_EL_TYPE);
18285
18286 if (inst.cond > COND_ALWAYS)
18287 inst.pred_insn_type = INSIDE_VPT_INSN;
18288 else
18289 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18290
18291 mve_encode_qqq (0, 64);
18292}
18293
18294static void
18295do_mve_vbrsr (void)
18296{
18297 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18298 struct neon_type_el et
18299 = neon_check_type (3, rs, N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18300
18301 if (inst.cond > COND_ALWAYS)
18302 inst.pred_insn_type = INSIDE_VPT_INSN;
18303 else
18304 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18305
7df54120 18306 mve_encode_qqr (et.size, 0, 0);
c2dafc2a
AV
18307}
18308
18309static void
18310do_mve_vsbc (void)
18311{
18312 neon_check_type (3, NS_QQQ, N_EQK, N_EQK, N_I32 | N_KEY);
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_qqq (1, 64);
18320}
18321
2d78f95b
AV
18322static void
18323do_mve_vmulh (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_SU_MVE | 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
18334 mve_encode_qqq (et.type == NT_unsigned, et.size);
18335}
18336
42b16635
AV
18337static void
18338do_mve_vqdmlah (void)
18339{
18340 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18341 struct neon_type_el et
23d188c7 18342 = neon_check_type (3, rs, N_EQK, N_EQK, N_S_32 | N_KEY);
42b16635
AV
18343
18344 if (inst.cond > COND_ALWAYS)
18345 inst.pred_insn_type = INSIDE_VPT_INSN;
18346 else
18347 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18348
18349 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
18350}
8b8b22a4
AV
18351
18352static void
18353do_mve_vqdmladh (void)
18354{
18355 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
18356 struct neon_type_el et
18357 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18358
18359 if (inst.cond > COND_ALWAYS)
18360 inst.pred_insn_type = INSIDE_VPT_INSN;
18361 else
18362 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18363
8b8b22a4
AV
18364 mve_encode_qqq (0, et.size);
18365}
18366
18367
886e1c73
AV
18368static void
18369do_mve_vmull (void)
18370{
18371
18372 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_DDS,
18373 NS_QQS, NS_QQQ, NS_QQR, NS_NULL);
fe05f369 18374 if (inst.cond == COND_ALWAYS
886e1c73
AV
18375 && ((unsigned)inst.instruction) == M_MNEM_vmullt)
18376 {
fe05f369 18377
886e1c73
AV
18378 if (rs == NS_QQQ)
18379 {
fe05f369 18380 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
886e1c73
AV
18381 goto neon_vmul;
18382 }
18383 else
18384 goto neon_vmul;
18385 }
18386
18387 constraint (rs != NS_QQQ, BAD_FPU);
18388 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
18389 N_SU_32 | N_P8 | N_P16 | N_KEY);
18390
18391 /* We are dealing with MVE's vmullt. */
18392 if (et.size == 32
18393 && (inst.operands[0].reg == inst.operands[1].reg
18394 || inst.operands[0].reg == inst.operands[2].reg))
18395 as_tsktsk (BAD_MVE_SRCDEST);
18396
18397 if (inst.cond > COND_ALWAYS)
18398 inst.pred_insn_type = INSIDE_VPT_INSN;
18399 else
18400 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18401
18402 if (et.type == NT_poly)
18403 mve_encode_qqq (neon_logbits (et.size), 64);
18404 else
18405 mve_encode_qqq (et.type == NT_unsigned, et.size);
18406
18407 return;
18408
dc1e8a47 18409 neon_vmul:
886e1c73
AV
18410 inst.instruction = N_MNEM_vmul;
18411 inst.cond = 0xb;
18412 if (thumb_mode)
18413 inst.pred_insn_type = INSIDE_IT_INSN;
18414 do_neon_mul ();
18415}
18416
a302e574
AV
18417static void
18418do_mve_vabav (void)
18419{
18420 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
18421
18422 if (rs == NS_NULL)
18423 return;
18424
18425 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18426 return;
18427
18428 struct neon_type_el et = neon_check_type (2, NS_NULL, N_EQK, N_KEY | N_S8
18429 | N_S16 | N_S32 | N_U8 | N_U16
18430 | N_U32);
18431
18432 if (inst.cond > COND_ALWAYS)
18433 inst.pred_insn_type = INSIDE_VPT_INSN;
18434 else
18435 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18436
18437 mve_encode_rqq (et.type == NT_unsigned, et.size);
18438}
18439
18440static void
18441do_mve_vmladav (void)
18442{
18443 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
18444 struct neon_type_el et = neon_check_type (3, rs,
18445 N_EQK, N_EQK, N_SU_MVE | N_KEY);
18446
18447 if (et.type == NT_unsigned
18448 && (inst.instruction == M_MNEM_vmladavx
18449 || inst.instruction == M_MNEM_vmladavax
18450 || inst.instruction == M_MNEM_vmlsdav
18451 || inst.instruction == M_MNEM_vmlsdava
18452 || inst.instruction == M_MNEM_vmlsdavx
18453 || inst.instruction == M_MNEM_vmlsdavax))
18454 first_error (BAD_SIMD_TYPE);
18455
18456 constraint (inst.operands[2].reg > 14,
18457 _("MVE vector register in the range [Q0..Q7] expected"));
18458
18459 if (inst.cond > COND_ALWAYS)
18460 inst.pred_insn_type = INSIDE_VPT_INSN;
18461 else
18462 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18463
18464 if (inst.instruction == M_MNEM_vmlsdav
18465 || inst.instruction == M_MNEM_vmlsdava
18466 || inst.instruction == M_MNEM_vmlsdavx
18467 || inst.instruction == M_MNEM_vmlsdavax)
18468 inst.instruction |= (et.size == 8) << 28;
18469 else
18470 inst.instruction |= (et.size == 8) << 8;
18471
18472 mve_encode_rqq (et.type == NT_unsigned, 64);
18473 inst.instruction |= (et.size == 32) << 16;
18474}
18475
93925576
AV
18476static void
18477do_mve_vmlaldav (void)
18478{
18479 enum neon_shape rs = neon_select_shape (NS_RRQQ, NS_NULL);
18480 struct neon_type_el et
18481 = neon_check_type (4, rs, N_EQK, N_EQK, N_EQK,
18482 N_S16 | N_S32 | N_U16 | N_U32 | N_KEY);
18483
18484 if (et.type == NT_unsigned
18485 && (inst.instruction == M_MNEM_vmlsldav
18486 || inst.instruction == M_MNEM_vmlsldava
18487 || inst.instruction == M_MNEM_vmlsldavx
18488 || inst.instruction == M_MNEM_vmlsldavax))
18489 first_error (BAD_SIMD_TYPE);
18490
18491 if (inst.cond > COND_ALWAYS)
18492 inst.pred_insn_type = INSIDE_VPT_INSN;
18493 else
18494 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18495
18496 mve_encode_rrqq (et.type == NT_unsigned, et.size);
18497}
18498
18499static void
18500do_mve_vrmlaldavh (void)
18501{
18502 struct neon_type_el et;
18503 if (inst.instruction == M_MNEM_vrmlsldavh
18504 || inst.instruction == M_MNEM_vrmlsldavha
18505 || inst.instruction == M_MNEM_vrmlsldavhx
18506 || inst.instruction == M_MNEM_vrmlsldavhax)
18507 {
18508 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
18509 if (inst.operands[1].reg == REG_SP)
18510 as_tsktsk (MVE_BAD_SP);
18511 }
18512 else
18513 {
18514 if (inst.instruction == M_MNEM_vrmlaldavhx
18515 || inst.instruction == M_MNEM_vrmlaldavhax)
18516 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
18517 else
18518 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK,
18519 N_U32 | N_S32 | N_KEY);
18520 /* vrmlaldavh's encoding with SP as the second, odd, GPR operand may alias
18521 with vmax/min instructions, making the use of SP in assembly really
18522 nonsensical, so instead of issuing a warning like we do for other uses
18523 of SP for the odd register operand we error out. */
18524 constraint (inst.operands[1].reg == REG_SP, BAD_SP);
18525 }
18526
18527 /* Make sure we still check the second operand is an odd one and that PC is
18528 disallowed. This because we are parsing for any GPR operand, to be able
18529 to distinguish between giving a warning or an error for SP as described
18530 above. */
18531 constraint ((inst.operands[1].reg % 2) != 1, BAD_EVEN);
18532 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
18533
18534 if (inst.cond > COND_ALWAYS)
18535 inst.pred_insn_type = INSIDE_VPT_INSN;
18536 else
18537 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18538
18539 mve_encode_rrqq (et.type == NT_unsigned, 0);
18540}
18541
18542
8cd78170
AV
18543static void
18544do_mve_vmaxnmv (void)
18545{
18546 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18547 struct neon_type_el et
18548 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
18549
18550 if (inst.cond > COND_ALWAYS)
18551 inst.pred_insn_type = INSIDE_VPT_INSN;
18552 else
18553 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18554
18555 if (inst.operands[0].reg == REG_SP)
18556 as_tsktsk (MVE_BAD_SP);
18557 else if (inst.operands[0].reg == REG_PC)
18558 as_tsktsk (MVE_BAD_PC);
18559
18560 mve_encode_rq (et.size == 16, 64);
18561}
18562
13ccd4c0
AV
18563static void
18564do_mve_vmaxv (void)
18565{
18566 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18567 struct neon_type_el et;
18568
18569 if (inst.instruction == M_MNEM_vmaxv || inst.instruction == M_MNEM_vminv)
18570 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
18571 else
18572 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18573
18574 if (inst.cond > COND_ALWAYS)
18575 inst.pred_insn_type = INSIDE_VPT_INSN;
18576 else
18577 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18578
18579 if (inst.operands[0].reg == REG_SP)
18580 as_tsktsk (MVE_BAD_SP);
18581 else if (inst.operands[0].reg == REG_PC)
18582 as_tsktsk (MVE_BAD_PC);
18583
18584 mve_encode_rq (et.type == NT_unsigned, et.size);
18585}
18586
18587
643afb90
MW
18588static void
18589do_neon_qrdmlah (void)
18590{
5b7c81bd 18591 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
42b16635
AV
18592 return;
18593 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
643afb90 18594 {
42b16635
AV
18595 /* Check we're on the correct architecture. */
18596 if (!mark_feature_used (&fpu_neon_ext_armv8))
18597 inst.error
18598 = _("instruction form not available on this architecture.");
18599 else if (!mark_feature_used (&fpu_neon_ext_v8_1))
18600 {
18601 as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
18602 record_feature_use (&fpu_neon_ext_v8_1);
18603 }
18604 if (inst.operands[2].isscalar)
18605 {
18606 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
18607 struct neon_type_el et = neon_check_type (3, rs,
18608 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18609 NEON_ENCODE (SCALAR, inst);
18610 neon_mul_mac (et, neon_quad (rs));
18611 }
18612 else
18613 {
18614 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
18615 struct neon_type_el et = neon_check_type (3, rs,
18616 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18617 NEON_ENCODE (INTEGER, inst);
18618 /* The U bit (rounding) comes from bit mask. */
18619 neon_three_same (neon_quad (rs), 0, et.size);
18620 }
643afb90
MW
18621 }
18622 else
18623 {
42b16635
AV
18624 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18625 struct neon_type_el et
23d188c7 18626 = neon_check_type (3, rs, N_EQK, N_EQK, N_S_32 | N_KEY);
42b16635 18627
643afb90 18628 NEON_ENCODE (INTEGER, inst);
42b16635 18629 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
643afb90
MW
18630 }
18631}
18632
5287ad62
JB
18633static void
18634do_neon_fcmp_absolute (void)
18635{
037e8744 18636 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
18637 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
18638 N_F_16_32 | N_KEY);
5287ad62 18639 /* Size field comes from bit mask. */
cc933301 18640 neon_three_same (neon_quad (rs), 1, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
18641}
18642
18643static void
18644do_neon_fcmp_absolute_inv (void)
18645{
18646 neon_exchange_operands ();
18647 do_neon_fcmp_absolute ();
18648}
18649
18650static void
18651do_neon_step (void)
18652{
037e8744 18653 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
18654 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
18655 N_F_16_32 | N_KEY);
18656 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
18657}
18658
18659static void
18660do_neon_abs_neg (void)
18661{
037e8744
JB
18662 enum neon_shape rs;
18663 struct neon_type_el et;
5f4273c7 18664
037e8744
JB
18665 if (try_vfp_nsyn (2, do_vfp_nsyn_abs_neg) == SUCCESS)
18666 return;
18667
037e8744 18668 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
cc933301 18669 et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
5f4273c7 18670
64c350f2
AV
18671 if (!check_simd_pred_availability (et.type == NT_float,
18672 NEON_CHECK_ARCH | NEON_CHECK_CC))
485dee97
AV
18673 return;
18674
5287ad62
JB
18675 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18676 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18677 inst.instruction |= LOW4 (inst.operands[1].reg);
18678 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 18679 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18680 inst.instruction |= (et.type == NT_float) << 10;
18681 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 18682
88714cb8 18683 neon_dp_fixup (&inst);
5287ad62
JB
18684}
18685
18686static void
18687do_neon_sli (void)
18688{
5b7c81bd 18689 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
18690 return;
18691
18692 enum neon_shape rs;
18693 struct neon_type_el et;
18694 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18695 {
18696 rs = neon_select_shape (NS_QQI, NS_NULL);
18697 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18698 }
18699 else
18700 {
18701 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18702 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18703 }
18704
18705
5287ad62
JB
18706 int imm = inst.operands[2].imm;
18707 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 18708 _("immediate out of range for insert"));
5b7c81bd 18709 neon_imm_shift (false, 0, neon_quad (rs), et, imm);
5287ad62
JB
18710}
18711
18712static void
18713do_neon_sri (void)
18714{
5b7c81bd 18715 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
18716 return;
18717
18718 enum neon_shape rs;
18719 struct neon_type_el et;
18720 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18721 {
18722 rs = neon_select_shape (NS_QQI, NS_NULL);
18723 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18724 }
18725 else
18726 {
18727 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18728 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18729 }
18730
5287ad62
JB
18731 int imm = inst.operands[2].imm;
18732 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18733 _("immediate out of range for insert"));
5b7c81bd 18734 neon_imm_shift (false, 0, neon_quad (rs), et, et.size - imm);
5287ad62
JB
18735}
18736
18737static void
18738do_neon_qshlu_imm (void)
18739{
5b7c81bd 18740 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
18741 return;
18742
18743 enum neon_shape rs;
18744 struct neon_type_el et;
18745 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18746 {
18747 rs = neon_select_shape (NS_QQI, NS_NULL);
18748 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18749 }
18750 else
18751 {
18752 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18753 et = neon_check_type (2, rs, N_EQK | N_UNS,
18754 N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
18755 }
18756
5287ad62
JB
18757 int imm = inst.operands[2].imm;
18758 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 18759 _("immediate out of range for shift"));
5287ad62
JB
18760 /* Only encodes the 'U present' variant of the instruction.
18761 In this case, signed types have OP (bit 8) set to 0.
18762 Unsigned types have OP set to 1. */
18763 inst.instruction |= (et.type == NT_unsigned) << 8;
18764 /* The rest of the bits are the same as other immediate shifts. */
5b7c81bd 18765 neon_imm_shift (false, 0, neon_quad (rs), et, imm);
5287ad62
JB
18766}
18767
18768static void
18769do_neon_qmovn (void)
18770{
18771 struct neon_type_el et = neon_check_type (2, NS_DQ,
18772 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
18773 /* Saturating move where operands can be signed or unsigned, and the
18774 destination has the same signedness. */
88714cb8 18775 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18776 if (et.type == NT_unsigned)
18777 inst.instruction |= 0xc0;
18778 else
18779 inst.instruction |= 0x80;
18780 neon_two_same (0, 1, et.size / 2);
18781}
18782
18783static void
18784do_neon_qmovun (void)
18785{
18786 struct neon_type_el et = neon_check_type (2, NS_DQ,
18787 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
18788 /* Saturating move with unsigned results. Operands must be signed. */
88714cb8 18789 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18790 neon_two_same (0, 1, et.size / 2);
18791}
18792
18793static void
18794do_neon_rshift_sat_narrow (void)
18795{
18796 /* FIXME: Types for narrowing. If operands are signed, results can be signed
18797 or unsigned. If operands are unsigned, results must also be unsigned. */
18798 struct neon_type_el et = neon_check_type (2, NS_DQI,
18799 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
18800 int imm = inst.operands[2].imm;
18801 /* This gets the bounds check, size encoding and immediate bits calculation
18802 right. */
18803 et.size /= 2;
5f4273c7 18804
5287ad62
JB
18805 /* VQ{R}SHRN.I<size> <Dd>, <Qm>, #0 is a synonym for
18806 VQMOVN.I<size> <Dd>, <Qm>. */
18807 if (imm == 0)
18808 {
18809 inst.operands[2].present = 0;
18810 inst.instruction = N_MNEM_vqmovn;
18811 do_neon_qmovn ();
18812 return;
18813 }
5f4273c7 18814
5287ad62 18815 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18816 _("immediate out of range"));
5b7c81bd 18817 neon_imm_shift (true, et.type == NT_unsigned, 0, et, et.size - imm);
5287ad62
JB
18818}
18819
18820static void
18821do_neon_rshift_sat_narrow_u (void)
18822{
18823 /* FIXME: Types for narrowing. If operands are signed, results can be signed
18824 or unsigned. If operands are unsigned, results must also be unsigned. */
18825 struct neon_type_el et = neon_check_type (2, NS_DQI,
18826 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
18827 int imm = inst.operands[2].imm;
18828 /* This gets the bounds check, size encoding and immediate bits calculation
18829 right. */
18830 et.size /= 2;
18831
18832 /* VQSHRUN.I<size> <Dd>, <Qm>, #0 is a synonym for
18833 VQMOVUN.I<size> <Dd>, <Qm>. */
18834 if (imm == 0)
18835 {
18836 inst.operands[2].present = 0;
18837 inst.instruction = N_MNEM_vqmovun;
18838 do_neon_qmovun ();
18839 return;
18840 }
18841
18842 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18843 _("immediate out of range"));
5287ad62
JB
18844 /* FIXME: The manual is kind of unclear about what value U should have in
18845 VQ{R}SHRUN instructions, but U=0, op=0 definitely encodes VRSHR, so it
18846 must be 1. */
5b7c81bd 18847 neon_imm_shift (true, 1, 0, et, et.size - imm);
5287ad62
JB
18848}
18849
18850static void
18851do_neon_movn (void)
18852{
18853 struct neon_type_el et = neon_check_type (2, NS_DQ,
18854 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
88714cb8 18855 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18856 neon_two_same (0, 1, et.size / 2);
18857}
18858
18859static void
18860do_neon_rshift_narrow (void)
18861{
18862 struct neon_type_el et = neon_check_type (2, NS_DQI,
18863 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
18864 int imm = inst.operands[2].imm;
18865 /* This gets the bounds check, size encoding and immediate bits calculation
18866 right. */
18867 et.size /= 2;
5f4273c7 18868
5287ad62
JB
18869 /* If immediate is zero then we are a pseudo-instruction for
18870 VMOVN.I<size> <Dd>, <Qm> */
18871 if (imm == 0)
18872 {
18873 inst.operands[2].present = 0;
18874 inst.instruction = N_MNEM_vmovn;
18875 do_neon_movn ();
18876 return;
18877 }
5f4273c7 18878
5287ad62 18879 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18880 _("immediate out of range for narrowing operation"));
5b7c81bd 18881 neon_imm_shift (false, 0, 0, et, et.size - imm);
5287ad62
JB
18882}
18883
18884static void
18885do_neon_shll (void)
18886{
18887 /* FIXME: Type checking when lengthening. */
18888 struct neon_type_el et = neon_check_type (2, NS_QDI,
18889 N_EQK | N_DBL, N_I8 | N_I16 | N_I32 | N_KEY);
18890 unsigned imm = inst.operands[2].imm;
18891
18892 if (imm == et.size)
18893 {
18894 /* Maximum shift variant. */
88714cb8 18895 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18896 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18897 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18898 inst.instruction |= LOW4 (inst.operands[1].reg);
18899 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18900 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 18901
88714cb8 18902 neon_dp_fixup (&inst);
5287ad62
JB
18903 }
18904 else
18905 {
18906 /* A more-specific type check for non-max versions. */
18907 et = neon_check_type (2, NS_QDI,
477330fc 18908 N_EQK | N_DBL, N_SU_32 | N_KEY);
88714cb8 18909 NEON_ENCODE (IMMED, inst);
5b7c81bd 18910 neon_imm_shift (true, et.type == NT_unsigned, 0, et, imm);
5287ad62
JB
18911 }
18912}
18913
037e8744 18914/* Check the various types for the VCVT instruction, and return which version
5287ad62
JB
18915 the current instruction is. */
18916
6b9a8b67
MGD
18917#define CVT_FLAVOUR_VAR \
18918 CVT_VAR (s32_f32, N_S32, N_F32, whole_reg, "ftosls", "ftosis", "ftosizs") \
18919 CVT_VAR (u32_f32, N_U32, N_F32, whole_reg, "ftouls", "ftouis", "ftouizs") \
18920 CVT_VAR (f32_s32, N_F32, N_S32, whole_reg, "fsltos", "fsitos", NULL) \
18921 CVT_VAR (f32_u32, N_F32, N_U32, whole_reg, "fultos", "fuitos", NULL) \
18922 /* Half-precision conversions. */ \
cc933301
JW
18923 CVT_VAR (s16_f16, N_S16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
18924 CVT_VAR (u16_f16, N_U16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
18925 CVT_VAR (f16_s16, N_F16 | N_KEY, N_S16, whole_reg, NULL, NULL, NULL) \
18926 CVT_VAR (f16_u16, N_F16 | N_KEY, N_U16, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
18927 CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
18928 CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
9db2f6b4
RL
18929 /* New VCVT instructions introduced by ARMv8.2 fp16 extension. \
18930 Compared with single/double precision variants, only the co-processor \
18931 field is different, so the encoding flow is reused here. */ \
18932 CVT_VAR (f16_s32, N_F16 | N_KEY, N_S32, N_VFP, "fsltos", "fsitos", NULL) \
18933 CVT_VAR (f16_u32, N_F16 | N_KEY, N_U32, N_VFP, "fultos", "fuitos", NULL) \
18934 CVT_VAR (u32_f16, N_U32, N_F16 | N_KEY, N_VFP, "ftouls", "ftouis", "ftouizs")\
18935 CVT_VAR (s32_f16, N_S32, N_F16 | N_KEY, N_VFP, "ftosls", "ftosis", "ftosizs")\
aab2c27d 18936 CVT_VAR (bf16_f32, N_BF16, N_F32, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
18937 /* VFP instructions. */ \
18938 CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
18939 CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
18940 CVT_VAR (s32_f64, N_S32, N_F64 | key, N_VFP, "ftosld", "ftosid", "ftosizd") \
18941 CVT_VAR (u32_f64, N_U32, N_F64 | key, N_VFP, "ftould", "ftouid", "ftouizd") \
18942 CVT_VAR (f64_s32, N_F64 | key, N_S32, N_VFP, "fsltod", "fsitod", NULL) \
18943 CVT_VAR (f64_u32, N_F64 | key, N_U32, N_VFP, "fultod", "fuitod", NULL) \
18944 /* VFP instructions with bitshift. */ \
18945 CVT_VAR (f32_s16, N_F32 | key, N_S16, N_VFP, "fshtos", NULL, NULL) \
18946 CVT_VAR (f32_u16, N_F32 | key, N_U16, N_VFP, "fuhtos", NULL, NULL) \
18947 CVT_VAR (f64_s16, N_F64 | key, N_S16, N_VFP, "fshtod", NULL, NULL) \
18948 CVT_VAR (f64_u16, N_F64 | key, N_U16, N_VFP, "fuhtod", NULL, NULL) \
18949 CVT_VAR (s16_f32, N_S16, N_F32 | key, N_VFP, "ftoshs", NULL, NULL) \
18950 CVT_VAR (u16_f32, N_U16, N_F32 | key, N_VFP, "ftouhs", NULL, NULL) \
18951 CVT_VAR (s16_f64, N_S16, N_F64 | key, N_VFP, "ftoshd", NULL, NULL) \
18952 CVT_VAR (u16_f64, N_U16, N_F64 | key, N_VFP, "ftouhd", NULL, NULL)
18953
18954#define CVT_VAR(C, X, Y, R, BSN, CN, ZN) \
18955 neon_cvt_flavour_##C,
18956
18957/* The different types of conversions we can do. */
18958enum neon_cvt_flavour
18959{
18960 CVT_FLAVOUR_VAR
18961 neon_cvt_flavour_invalid,
18962 neon_cvt_flavour_first_fp = neon_cvt_flavour_f32_f64
18963};
18964
18965#undef CVT_VAR
18966
18967static enum neon_cvt_flavour
18968get_neon_cvt_flavour (enum neon_shape rs)
5287ad62 18969{
6b9a8b67
MGD
18970#define CVT_VAR(C,X,Y,R,BSN,CN,ZN) \
18971 et = neon_check_type (2, rs, (R) | (X), (R) | (Y)); \
18972 if (et.type != NT_invtype) \
18973 { \
18974 inst.error = NULL; \
18975 return (neon_cvt_flavour_##C); \
5287ad62 18976 }
6b9a8b67 18977
5287ad62 18978 struct neon_type_el et;
037e8744 18979 unsigned whole_reg = (rs == NS_FFI || rs == NS_FD || rs == NS_DF
477330fc 18980 || rs == NS_FF) ? N_VFP : 0;
037e8744
JB
18981 /* The instruction versions which take an immediate take one register
18982 argument, which is extended to the width of the full register. Thus the
18983 "source" and "destination" registers must have the same width. Hack that
18984 here by making the size equal to the key (wider, in this case) operand. */
18985 unsigned key = (rs == NS_QQI || rs == NS_DDI || rs == NS_FFI) ? N_KEY : 0;
5f4273c7 18986
6b9a8b67
MGD
18987 CVT_FLAVOUR_VAR;
18988
18989 return neon_cvt_flavour_invalid;
5287ad62
JB
18990#undef CVT_VAR
18991}
18992
7e8e6784
MGD
18993enum neon_cvt_mode
18994{
18995 neon_cvt_mode_a,
18996 neon_cvt_mode_n,
18997 neon_cvt_mode_p,
18998 neon_cvt_mode_m,
18999 neon_cvt_mode_z,
30bdf752
MGD
19000 neon_cvt_mode_x,
19001 neon_cvt_mode_r
7e8e6784
MGD
19002};
19003
037e8744
JB
19004/* Neon-syntax VFP conversions. */
19005
5287ad62 19006static void
6b9a8b67 19007do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
5287ad62 19008{
037e8744 19009 const char *opname = 0;
5f4273c7 19010
d54af2d0
RL
19011 if (rs == NS_DDI || rs == NS_QQI || rs == NS_FFI
19012 || rs == NS_FHI || rs == NS_HFI)
5287ad62 19013 {
037e8744
JB
19014 /* Conversions with immediate bitshift. */
19015 const char *enc[] =
477330fc 19016 {
6b9a8b67
MGD
19017#define CVT_VAR(C,A,B,R,BSN,CN,ZN) BSN,
19018 CVT_FLAVOUR_VAR
19019 NULL
19020#undef CVT_VAR
477330fc 19021 };
037e8744 19022
6b9a8b67 19023 if (flavour < (int) ARRAY_SIZE (enc))
477330fc
RM
19024 {
19025 opname = enc[flavour];
19026 constraint (inst.operands[0].reg != inst.operands[1].reg,
19027 _("operands 0 and 1 must be the same register"));
19028 inst.operands[1] = inst.operands[2];
19029 memset (&inst.operands[2], '\0', sizeof (inst.operands[2]));
19030 }
5287ad62
JB
19031 }
19032 else
19033 {
037e8744
JB
19034 /* Conversions without bitshift. */
19035 const char *enc[] =
477330fc 19036 {
6b9a8b67
MGD
19037#define CVT_VAR(C,A,B,R,BSN,CN,ZN) CN,
19038 CVT_FLAVOUR_VAR
19039 NULL
19040#undef CVT_VAR
477330fc 19041 };
037e8744 19042
6b9a8b67 19043 if (flavour < (int) ARRAY_SIZE (enc))
477330fc 19044 opname = enc[flavour];
037e8744
JB
19045 }
19046
19047 if (opname)
19048 do_vfp_nsyn_opcode (opname);
9db2f6b4
RL
19049
19050 /* ARMv8.2 fp16 VCVT instruction. */
19051 if (flavour == neon_cvt_flavour_s32_f16
19052 || flavour == neon_cvt_flavour_u32_f16
19053 || flavour == neon_cvt_flavour_f16_u32
19054 || flavour == neon_cvt_flavour_f16_s32)
19055 do_scalar_fp16_v82_encode ();
037e8744
JB
19056}
19057
19058static void
19059do_vfp_nsyn_cvtz (void)
19060{
d54af2d0 19061 enum neon_shape rs = neon_select_shape (NS_FH, NS_FF, NS_FD, NS_NULL);
6b9a8b67 19062 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744
JB
19063 const char *enc[] =
19064 {
6b9a8b67
MGD
19065#define CVT_VAR(C,A,B,R,BSN,CN,ZN) ZN,
19066 CVT_FLAVOUR_VAR
19067 NULL
19068#undef CVT_VAR
037e8744
JB
19069 };
19070
6b9a8b67 19071 if (flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
037e8744
JB
19072 do_vfp_nsyn_opcode (enc[flavour]);
19073}
f31fef98 19074
037e8744 19075static void
bacebabc 19076do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
7e8e6784
MGD
19077 enum neon_cvt_mode mode)
19078{
19079 int sz, op;
19080 int rm;
19081
a715796b
TG
19082 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
19083 D register operands. */
19084 if (flavour == neon_cvt_flavour_s32_f64
19085 || flavour == neon_cvt_flavour_u32_f64)
19086 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19087 _(BAD_FPU));
19088
9db2f6b4
RL
19089 if (flavour == neon_cvt_flavour_s32_f16
19090 || flavour == neon_cvt_flavour_u32_f16)
19091 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
19092 _(BAD_FP16));
19093
5ee91343 19094 set_pred_insn_type (OUTSIDE_PRED_INSN);
7e8e6784
MGD
19095
19096 switch (flavour)
19097 {
19098 case neon_cvt_flavour_s32_f64:
19099 sz = 1;
827f64ff 19100 op = 1;
7e8e6784
MGD
19101 break;
19102 case neon_cvt_flavour_s32_f32:
19103 sz = 0;
19104 op = 1;
19105 break;
9db2f6b4
RL
19106 case neon_cvt_flavour_s32_f16:
19107 sz = 0;
19108 op = 1;
19109 break;
7e8e6784
MGD
19110 case neon_cvt_flavour_u32_f64:
19111 sz = 1;
19112 op = 0;
19113 break;
19114 case neon_cvt_flavour_u32_f32:
19115 sz = 0;
19116 op = 0;
19117 break;
9db2f6b4
RL
19118 case neon_cvt_flavour_u32_f16:
19119 sz = 0;
19120 op = 0;
19121 break;
7e8e6784
MGD
19122 default:
19123 first_error (_("invalid instruction shape"));
19124 return;
19125 }
19126
19127 switch (mode)
19128 {
19129 case neon_cvt_mode_a: rm = 0; break;
19130 case neon_cvt_mode_n: rm = 1; break;
19131 case neon_cvt_mode_p: rm = 2; break;
19132 case neon_cvt_mode_m: rm = 3; break;
19133 default: first_error (_("invalid rounding mode")); return;
19134 }
19135
19136 NEON_ENCODE (FPV8, inst);
19137 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
19138 encode_arm_vfp_reg (inst.operands[1].reg, sz == 1 ? VFP_REG_Dm : VFP_REG_Sm);
19139 inst.instruction |= sz << 8;
9db2f6b4
RL
19140
19141 /* ARMv8.2 fp16 VCVT instruction. */
19142 if (flavour == neon_cvt_flavour_s32_f16
19143 ||flavour == neon_cvt_flavour_u32_f16)
19144 do_scalar_fp16_v82_encode ();
7e8e6784
MGD
19145 inst.instruction |= op << 7;
19146 inst.instruction |= rm << 16;
19147 inst.instruction |= 0xf0000000;
5b7c81bd 19148 inst.is_neon = true;
7e8e6784
MGD
19149}
19150
19151static void
19152do_neon_cvt_1 (enum neon_cvt_mode mode)
037e8744
JB
19153{
19154 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
d54af2d0
RL
19155 NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ,
19156 NS_FH, NS_HF, NS_FHI, NS_HFI,
19157 NS_NULL);
6b9a8b67 19158 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744 19159
cc933301
JW
19160 if (flavour == neon_cvt_flavour_invalid)
19161 return;
19162
e3e535bc 19163 /* PR11109: Handle round-to-zero for VCVT conversions. */
7e8e6784 19164 if (mode == neon_cvt_mode_z
e3e535bc 19165 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
cc933301
JW
19166 && (flavour == neon_cvt_flavour_s16_f16
19167 || flavour == neon_cvt_flavour_u16_f16
19168 || flavour == neon_cvt_flavour_s32_f32
bacebabc
RM
19169 || flavour == neon_cvt_flavour_u32_f32
19170 || flavour == neon_cvt_flavour_s32_f64
6b9a8b67 19171 || flavour == neon_cvt_flavour_u32_f64)
e3e535bc
NC
19172 && (rs == NS_FD || rs == NS_FF))
19173 {
19174 do_vfp_nsyn_cvtz ();
19175 return;
19176 }
19177
9db2f6b4
RL
19178 /* ARMv8.2 fp16 VCVT conversions. */
19179 if (mode == neon_cvt_mode_z
19180 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16)
19181 && (flavour == neon_cvt_flavour_s32_f16
19182 || flavour == neon_cvt_flavour_u32_f16)
19183 && (rs == NS_FH))
19184 {
19185 do_vfp_nsyn_cvtz ();
19186 do_scalar_fp16_v82_encode ();
19187 return;
19188 }
19189
037e8744 19190 /* VFP rather than Neon conversions. */
6b9a8b67 19191 if (flavour >= neon_cvt_flavour_first_fp)
037e8744 19192 {
7e8e6784
MGD
19193 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
19194 do_vfp_nsyn_cvt (rs, flavour);
19195 else
19196 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
19197
037e8744
JB
19198 return;
19199 }
19200
19201 switch (rs)
19202 {
037e8744 19203 case NS_QQI:
dd9634d9
AV
19204 if (mode == neon_cvt_mode_z
19205 && (flavour == neon_cvt_flavour_f16_s16
19206 || flavour == neon_cvt_flavour_f16_u16
19207 || flavour == neon_cvt_flavour_s16_f16
19208 || flavour == neon_cvt_flavour_u16_f16
19209 || flavour == neon_cvt_flavour_f32_u32
19210 || flavour == neon_cvt_flavour_f32_s32
19211 || flavour == neon_cvt_flavour_s32_f32
19212 || flavour == neon_cvt_flavour_u32_f32))
19213 {
5b7c81bd 19214 if (!check_simd_pred_availability (true,
64c350f2 19215 NEON_CHECK_CC | NEON_CHECK_ARCH))
dd9634d9
AV
19216 return;
19217 }
dd9634d9
AV
19218 /* fall through. */
19219 case NS_DDI:
037e8744 19220 {
477330fc 19221 unsigned immbits;
cc933301
JW
19222 unsigned enctab[] = {0x0000100, 0x1000100, 0x0, 0x1000000,
19223 0x0000100, 0x1000100, 0x0, 0x1000000};
35997600 19224
dd9634d9
AV
19225 if ((rs != NS_QQI || !ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19226 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19227 return;
19228
19229 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19230 {
19231 constraint (inst.operands[2].present && inst.operands[2].imm == 0,
19232 _("immediate value out of range"));
19233 switch (flavour)
19234 {
19235 case neon_cvt_flavour_f16_s16:
19236 case neon_cvt_flavour_f16_u16:
19237 case neon_cvt_flavour_s16_f16:
19238 case neon_cvt_flavour_u16_f16:
19239 constraint (inst.operands[2].imm > 16,
19240 _("immediate value out of range"));
19241 break;
19242 case neon_cvt_flavour_f32_u32:
19243 case neon_cvt_flavour_f32_s32:
19244 case neon_cvt_flavour_s32_f32:
19245 case neon_cvt_flavour_u32_f32:
19246 constraint (inst.operands[2].imm > 32,
19247 _("immediate value out of range"));
19248 break;
19249 default:
19250 inst.error = BAD_FPU;
19251 return;
19252 }
19253 }
037e8744 19254
477330fc
RM
19255 /* Fixed-point conversion with #0 immediate is encoded as an
19256 integer conversion. */
19257 if (inst.operands[2].present && inst.operands[2].imm == 0)
19258 goto int_encode;
477330fc
RM
19259 NEON_ENCODE (IMMED, inst);
19260 if (flavour != neon_cvt_flavour_invalid)
19261 inst.instruction |= enctab[flavour];
19262 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19263 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19264 inst.instruction |= LOW4 (inst.operands[1].reg);
19265 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19266 inst.instruction |= neon_quad (rs) << 6;
19267 inst.instruction |= 1 << 21;
cc933301
JW
19268 if (flavour < neon_cvt_flavour_s16_f16)
19269 {
19270 inst.instruction |= 1 << 21;
19271 immbits = 32 - inst.operands[2].imm;
19272 inst.instruction |= immbits << 16;
19273 }
19274 else
19275 {
19276 inst.instruction |= 3 << 20;
19277 immbits = 16 - inst.operands[2].imm;
19278 inst.instruction |= immbits << 16;
19279 inst.instruction &= ~(1 << 9);
19280 }
477330fc
RM
19281
19282 neon_dp_fixup (&inst);
037e8744
JB
19283 }
19284 break;
19285
037e8744 19286 case NS_QQ:
dd9634d9
AV
19287 if ((mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
19288 || mode == neon_cvt_mode_m || mode == neon_cvt_mode_p)
19289 && (flavour == neon_cvt_flavour_s16_f16
19290 || flavour == neon_cvt_flavour_u16_f16
19291 || flavour == neon_cvt_flavour_s32_f32
19292 || flavour == neon_cvt_flavour_u32_f32))
19293 {
5b7c81bd 19294 if (!check_simd_pred_availability (true,
64c350f2 19295 NEON_CHECK_CC | NEON_CHECK_ARCH8))
dd9634d9
AV
19296 return;
19297 }
19298 else if (mode == neon_cvt_mode_z
19299 && (flavour == neon_cvt_flavour_f16_s16
19300 || flavour == neon_cvt_flavour_f16_u16
19301 || flavour == neon_cvt_flavour_s16_f16
19302 || flavour == neon_cvt_flavour_u16_f16
19303 || flavour == neon_cvt_flavour_f32_u32
19304 || flavour == neon_cvt_flavour_f32_s32
19305 || flavour == neon_cvt_flavour_s32_f32
19306 || flavour == neon_cvt_flavour_u32_f32))
19307 {
5b7c81bd 19308 if (!check_simd_pred_availability (true,
64c350f2 19309 NEON_CHECK_CC | NEON_CHECK_ARCH))
dd9634d9
AV
19310 return;
19311 }
19312 /* fall through. */
19313 case NS_DD:
7e8e6784
MGD
19314 if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
19315 {
7e8e6784 19316
dd9634d9 19317 NEON_ENCODE (FLOAT, inst);
5b7c81bd 19318 if (!check_simd_pred_availability (true,
64c350f2 19319 NEON_CHECK_CC | NEON_CHECK_ARCH8))
7e8e6784
MGD
19320 return;
19321
19322 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19323 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19324 inst.instruction |= LOW4 (inst.operands[1].reg);
19325 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19326 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
19327 inst.instruction |= (flavour == neon_cvt_flavour_u16_f16
19328 || flavour == neon_cvt_flavour_u32_f32) << 7;
7e8e6784 19329 inst.instruction |= mode << 8;
cc933301
JW
19330 if (flavour == neon_cvt_flavour_u16_f16
19331 || flavour == neon_cvt_flavour_s16_f16)
19332 /* Mask off the original size bits and reencode them. */
19333 inst.instruction = ((inst.instruction & 0xfff3ffff) | (1 << 18));
19334
7e8e6784
MGD
19335 if (thumb_mode)
19336 inst.instruction |= 0xfc000000;
19337 else
19338 inst.instruction |= 0xf0000000;
19339 }
19340 else
19341 {
037e8744 19342 int_encode:
7e8e6784 19343 {
cc933301
JW
19344 unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080,
19345 0x100, 0x180, 0x0, 0x080};
037e8744 19346
7e8e6784 19347 NEON_ENCODE (INTEGER, inst);
037e8744 19348
dd9634d9
AV
19349 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19350 {
19351 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19352 return;
19353 }
037e8744 19354
7e8e6784
MGD
19355 if (flavour != neon_cvt_flavour_invalid)
19356 inst.instruction |= enctab[flavour];
037e8744 19357
7e8e6784
MGD
19358 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19359 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19360 inst.instruction |= LOW4 (inst.operands[1].reg);
19361 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19362 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
19363 if (flavour >= neon_cvt_flavour_s16_f16
19364 && flavour <= neon_cvt_flavour_f16_u16)
19365 /* Half precision. */
19366 inst.instruction |= 1 << 18;
19367 else
19368 inst.instruction |= 2 << 18;
037e8744 19369
7e8e6784
MGD
19370 neon_dp_fixup (&inst);
19371 }
19372 }
19373 break;
037e8744 19374
8e79c3df
CM
19375 /* Half-precision conversions for Advanced SIMD -- neon. */
19376 case NS_QD:
19377 case NS_DQ:
bc52d49c
MM
19378 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19379 return;
8e79c3df
CM
19380
19381 if ((rs == NS_DQ)
19382 && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
19383 {
19384 as_bad (_("operand size must match register width"));
19385 break;
19386 }
19387
19388 if ((rs == NS_QD)
19389 && ((inst.vectype.el[0].size != 32 || inst.vectype.el[1].size != 16)))
19390 {
19391 as_bad (_("operand size must match register width"));
19392 break;
19393 }
19394
19395 if (rs == NS_DQ)
aab2c27d
MM
19396 {
19397 if (flavour == neon_cvt_flavour_bf16_f32)
19398 {
19399 if (vfp_or_neon_is_neon (NEON_CHECK_ARCH8) == FAIL)
19400 return;
19401 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
19402 /* VCVT.bf16.f32. */
19403 inst.instruction = 0x11b60640;
19404 }
19405 else
19406 /* VCVT.f16.f32. */
19407 inst.instruction = 0x3b60600;
19408 }
8e79c3df 19409 else
aab2c27d 19410 /* VCVT.f32.f16. */
8e79c3df
CM
19411 inst.instruction = 0x3b60700;
19412
19413 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19414 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19415 inst.instruction |= LOW4 (inst.operands[1].reg);
19416 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
88714cb8 19417 neon_dp_fixup (&inst);
8e79c3df
CM
19418 break;
19419
037e8744
JB
19420 default:
19421 /* Some VFP conversions go here (s32 <-> f32, u32 <-> f32). */
7e8e6784
MGD
19422 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
19423 do_vfp_nsyn_cvt (rs, flavour);
19424 else
19425 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
5287ad62 19426 }
5287ad62
JB
19427}
19428
e3e535bc
NC
19429static void
19430do_neon_cvtr (void)
19431{
7e8e6784 19432 do_neon_cvt_1 (neon_cvt_mode_x);
e3e535bc
NC
19433}
19434
19435static void
19436do_neon_cvt (void)
19437{
7e8e6784
MGD
19438 do_neon_cvt_1 (neon_cvt_mode_z);
19439}
19440
19441static void
19442do_neon_cvta (void)
19443{
19444 do_neon_cvt_1 (neon_cvt_mode_a);
19445}
19446
19447static void
19448do_neon_cvtn (void)
19449{
19450 do_neon_cvt_1 (neon_cvt_mode_n);
19451}
19452
19453static void
19454do_neon_cvtp (void)
19455{
19456 do_neon_cvt_1 (neon_cvt_mode_p);
19457}
19458
19459static void
19460do_neon_cvtm (void)
19461{
19462 do_neon_cvt_1 (neon_cvt_mode_m);
e3e535bc
NC
19463}
19464
8e79c3df 19465static void
5b7c81bd 19466do_neon_cvttb_2 (bool t, bool to, bool is_double)
8e79c3df 19467{
c70a8987
MGD
19468 if (is_double)
19469 mark_feature_used (&fpu_vfp_ext_armv8);
8e79c3df 19470
c70a8987
MGD
19471 encode_arm_vfp_reg (inst.operands[0].reg,
19472 (is_double && !to) ? VFP_REG_Dd : VFP_REG_Sd);
19473 encode_arm_vfp_reg (inst.operands[1].reg,
19474 (is_double && to) ? VFP_REG_Dm : VFP_REG_Sm);
19475 inst.instruction |= to ? 0x10000 : 0;
19476 inst.instruction |= t ? 0x80 : 0;
19477 inst.instruction |= is_double ? 0x100 : 0;
19478 do_vfp_cond_or_thumb ();
19479}
8e79c3df 19480
c70a8987 19481static void
5b7c81bd 19482do_neon_cvttb_1 (bool t)
c70a8987 19483{
d54af2d0 19484 enum neon_shape rs = neon_select_shape (NS_HF, NS_HD, NS_FH, NS_FF, NS_FD,
dd9634d9 19485 NS_DF, NS_DH, NS_QQ, NS_QQI, NS_NULL);
8e79c3df 19486
c70a8987
MGD
19487 if (rs == NS_NULL)
19488 return;
dd9634d9
AV
19489 else if (rs == NS_QQ || rs == NS_QQI)
19490 {
19491 int single_to_half = 0;
5b7c81bd 19492 if (!check_simd_pred_availability (true, NEON_CHECK_ARCH))
dd9634d9
AV
19493 return;
19494
19495 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
19496
19497 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19498 && (flavour == neon_cvt_flavour_u16_f16
19499 || flavour == neon_cvt_flavour_s16_f16
19500 || flavour == neon_cvt_flavour_f16_s16
19501 || flavour == neon_cvt_flavour_f16_u16
19502 || flavour == neon_cvt_flavour_u32_f32
19503 || flavour == neon_cvt_flavour_s32_f32
19504 || flavour == neon_cvt_flavour_f32_s32
19505 || flavour == neon_cvt_flavour_f32_u32))
19506 {
19507 inst.cond = 0xf;
19508 inst.instruction = N_MNEM_vcvt;
19509 set_pred_insn_type (INSIDE_VPT_INSN);
19510 do_neon_cvt_1 (neon_cvt_mode_z);
19511 return;
19512 }
19513 else if (rs == NS_QQ && flavour == neon_cvt_flavour_f32_f16)
19514 single_to_half = 1;
19515 else if (rs == NS_QQ && flavour != neon_cvt_flavour_f16_f32)
19516 {
19517 first_error (BAD_FPU);
19518 return;
19519 }
19520
19521 inst.instruction = 0xee3f0e01;
19522 inst.instruction |= single_to_half << 28;
19523 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19524 inst.instruction |= LOW4 (inst.operands[0].reg) << 13;
19525 inst.instruction |= t << 12;
19526 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19527 inst.instruction |= LOW4 (inst.operands[1].reg) << 1;
19528 inst.is_neon = 1;
19529 }
c70a8987
MGD
19530 else if (neon_check_type (2, rs, N_F16, N_F32 | N_VFP).type != NT_invtype)
19531 {
19532 inst.error = NULL;
5b7c81bd 19533 do_neon_cvttb_2 (t, /*to=*/true, /*is_double=*/false);
c70a8987
MGD
19534 }
19535 else if (neon_check_type (2, rs, N_F32 | N_VFP, N_F16).type != NT_invtype)
19536 {
19537 inst.error = NULL;
5b7c81bd 19538 do_neon_cvttb_2 (t, /*to=*/false, /*is_double=*/false);
c70a8987
MGD
19539 }
19540 else if (neon_check_type (2, rs, N_F16, N_F64 | N_VFP).type != NT_invtype)
19541 {
a715796b
TG
19542 /* The VCVTB and VCVTT instructions with D-register operands
19543 don't work for SP only targets. */
19544 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19545 _(BAD_FPU));
19546
c70a8987 19547 inst.error = NULL;
5b7c81bd 19548 do_neon_cvttb_2 (t, /*to=*/true, /*is_double=*/true);
c70a8987
MGD
19549 }
19550 else if (neon_check_type (2, rs, N_F64 | N_VFP, N_F16).type != NT_invtype)
19551 {
a715796b
TG
19552 /* The VCVTB and VCVTT instructions with D-register operands
19553 don't work for SP only targets. */
19554 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19555 _(BAD_FPU));
19556
c70a8987 19557 inst.error = NULL;
5b7c81bd 19558 do_neon_cvttb_2 (t, /*to=*/false, /*is_double=*/true);
c70a8987 19559 }
aab2c27d
MM
19560 else if (neon_check_type (2, rs, N_BF16 | N_VFP, N_F32).type != NT_invtype)
19561 {
19562 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
19563 inst.error = NULL;
19564 inst.instruction |= (1 << 8);
19565 inst.instruction &= ~(1 << 9);
5b7c81bd 19566 do_neon_cvttb_2 (t, /*to=*/true, /*is_double=*/false);
aab2c27d 19567 }
c70a8987
MGD
19568 else
19569 return;
19570}
19571
19572static void
19573do_neon_cvtb (void)
19574{
5b7c81bd 19575 do_neon_cvttb_1 (false);
8e79c3df
CM
19576}
19577
19578
19579static void
19580do_neon_cvtt (void)
19581{
5b7c81bd 19582 do_neon_cvttb_1 (true);
8e79c3df
CM
19583}
19584
5287ad62
JB
19585static void
19586neon_move_immediate (void)
19587{
037e8744
JB
19588 enum neon_shape rs = neon_select_shape (NS_DI, NS_QI, NS_NULL);
19589 struct neon_type_el et = neon_check_type (2, rs,
19590 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
5287ad62 19591 unsigned immlo, immhi = 0, immbits;
c96612cc 19592 int op, cmode, float_p;
5287ad62 19593
037e8744 19594 constraint (et.type == NT_invtype,
477330fc 19595 _("operand size must be specified for immediate VMOV"));
037e8744 19596
5287ad62
JB
19597 /* We start out as an MVN instruction if OP = 1, MOV otherwise. */
19598 op = (inst.instruction & (1 << 5)) != 0;
19599
19600 immlo = inst.operands[1].imm;
19601 if (inst.operands[1].regisimm)
19602 immhi = inst.operands[1].reg;
19603
19604 constraint (et.size < 32 && (immlo & ~((1 << et.size) - 1)) != 0,
477330fc 19605 _("immediate has bits set outside the operand size"));
5287ad62 19606
c96612cc
JB
19607 float_p = inst.operands[1].immisfloat;
19608
19609 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits, &op,
477330fc 19610 et.size, et.type)) == FAIL)
5287ad62
JB
19611 {
19612 /* Invert relevant bits only. */
19613 neon_invert_size (&immlo, &immhi, et.size);
19614 /* Flip from VMOV/VMVN to VMVN/VMOV. Some immediate types are unavailable
477330fc
RM
19615 with one or the other; those cases are caught by
19616 neon_cmode_for_move_imm. */
5287ad62 19617 op = !op;
c96612cc
JB
19618 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits,
19619 &op, et.size, et.type)) == FAIL)
477330fc
RM
19620 {
19621 first_error (_("immediate out of range"));
19622 return;
19623 }
5287ad62
JB
19624 }
19625
19626 inst.instruction &= ~(1 << 5);
19627 inst.instruction |= op << 5;
19628
19629 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19630 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
037e8744 19631 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
19632 inst.instruction |= cmode << 8;
19633
19634 neon_write_immbits (immbits);
19635}
19636
19637static void
19638do_neon_mvn (void)
19639{
5b7c81bd 19640 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
1a186d29
AV
19641 return;
19642
5287ad62
JB
19643 if (inst.operands[1].isreg)
19644 {
1a186d29
AV
19645 enum neon_shape rs;
19646 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19647 rs = neon_select_shape (NS_QQ, NS_NULL);
19648 else
19649 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5f4273c7 19650
250dd99f
AM
19651 if (rs == NS_NULL)
19652 return;
19653
88714cb8 19654 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
19655 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19656 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19657 inst.instruction |= LOW4 (inst.operands[1].reg);
19658 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 19659 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
19660 }
19661 else
19662 {
88714cb8 19663 NEON_ENCODE (IMMED, inst);
5287ad62
JB
19664 neon_move_immediate ();
19665 }
19666
88714cb8 19667 neon_dp_fixup (&inst);
1a186d29
AV
19668
19669 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19670 {
19671 constraint (!inst.operands[1].isreg && !inst.operands[0].isquad, BAD_FPU);
1a186d29 19672 }
5287ad62
JB
19673}
19674
19675/* Encode instructions of form:
19676
19677 |28/24|23|22|21 20|19 16|15 12|11 8|7|6|5|4|3 0|
5f4273c7 19678 | U |x |D |size | Rn | Rd |x x x x|N|x|M|x| Rm | */
5287ad62
JB
19679
19680static void
19681neon_mixed_length (struct neon_type_el et, unsigned size)
19682{
19683 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19684 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19685 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19686 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19687 inst.instruction |= LOW4 (inst.operands[2].reg);
19688 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
19689 inst.instruction |= (et.type == NT_unsigned) << 24;
19690 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 19691
88714cb8 19692 neon_dp_fixup (&inst);
5287ad62
JB
19693}
19694
19695static void
19696do_neon_dyadic_long (void)
19697{
66d1f7cc 19698 enum neon_shape rs = neon_select_shape (NS_QDD, NS_HHH, NS_FFF, NS_DDD, NS_NULL);
5ee91343
AV
19699 if (rs == NS_QDD)
19700 {
19701 if (vfp_or_neon_is_neon (NEON_CHECK_ARCH | NEON_CHECK_CC) == FAIL)
19702 return;
19703
19704 NEON_ENCODE (INTEGER, inst);
19705 /* FIXME: Type checking for lengthening op. */
19706 struct neon_type_el et = neon_check_type (3, NS_QDD,
19707 N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
19708 neon_mixed_length (et, et.size);
19709 }
19710 else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19711 && (inst.cond == 0xf || inst.cond == 0x10))
19712 {
19713 /* If parsing for MVE, vaddl/vsubl/vabdl{e,t} can only be vadd/vsub/vabd
19714 in an IT block with le/lt conditions. */
19715
19716 if (inst.cond == 0xf)
19717 inst.cond = 0xb;
19718 else if (inst.cond == 0x10)
19719 inst.cond = 0xd;
19720
19721 inst.pred_insn_type = INSIDE_IT_INSN;
19722
19723 if (inst.instruction == N_MNEM_vaddl)
19724 {
19725 inst.instruction = N_MNEM_vadd;
19726 do_neon_addsub_if_i ();
19727 }
19728 else if (inst.instruction == N_MNEM_vsubl)
19729 {
19730 inst.instruction = N_MNEM_vsub;
19731 do_neon_addsub_if_i ();
19732 }
19733 else if (inst.instruction == N_MNEM_vabdl)
19734 {
19735 inst.instruction = N_MNEM_vabd;
19736 do_neon_dyadic_if_su ();
19737 }
19738 }
19739 else
19740 first_error (BAD_FPU);
5287ad62
JB
19741}
19742
19743static void
19744do_neon_abal (void)
19745{
19746 struct neon_type_el et = neon_check_type (3, NS_QDD,
19747 N_EQK | N_INT | N_DBL, N_EQK, N_SU_32 | N_KEY);
19748 neon_mixed_length (et, et.size);
19749}
19750
19751static void
19752neon_mac_reg_scalar_long (unsigned regtypes, unsigned scalartypes)
19753{
19754 if (inst.operands[2].isscalar)
19755 {
dcbf9037 19756 struct neon_type_el et = neon_check_type (3, NS_QDS,
477330fc 19757 N_EQK | N_DBL, N_EQK, regtypes | N_KEY);
88714cb8 19758 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
19759 neon_mul_mac (et, et.type == NT_unsigned);
19760 }
19761 else
19762 {
19763 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 19764 N_EQK | N_DBL, N_EQK, scalartypes | N_KEY);
88714cb8 19765 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
19766 neon_mixed_length (et, et.size);
19767 }
19768}
19769
19770static void
19771do_neon_mac_maybe_scalar_long (void)
19772{
19773 neon_mac_reg_scalar_long (N_S16 | N_S32 | N_U16 | N_U32, N_SU_32);
19774}
19775
dec41383
JW
19776/* Like neon_scalar_for_mul, this function generate Rm encoding from GAS's
19777 internal SCALAR. QUAD_P is 1 if it's for Q format, otherwise it's 0. */
19778
19779static unsigned
19780neon_scalar_for_fmac_fp16_long (unsigned scalar, unsigned quad_p)
19781{
19782 unsigned regno = NEON_SCALAR_REG (scalar);
19783 unsigned elno = NEON_SCALAR_INDEX (scalar);
19784
19785 if (quad_p)
19786 {
19787 if (regno > 7 || elno > 3)
19788 goto bad_scalar;
19789
19790 return ((regno & 0x7)
19791 | ((elno & 0x1) << 3)
19792 | (((elno >> 1) & 0x1) << 5));
19793 }
19794 else
19795 {
19796 if (regno > 15 || elno > 1)
19797 goto bad_scalar;
19798
19799 return (((regno & 0x1) << 5)
19800 | ((regno >> 1) & 0x7)
19801 | ((elno & 0x1) << 3));
19802 }
19803
dc1e8a47 19804 bad_scalar:
dec41383
JW
19805 first_error (_("scalar out of range for multiply instruction"));
19806 return 0;
19807}
19808
19809static void
19810do_neon_fmac_maybe_scalar_long (int subtype)
19811{
19812 enum neon_shape rs;
19813 int high8;
19814 /* NOTE: vfmal/vfmsl use slightly different NEON three-same encoding. 'size"
19815 field (bits[21:20]) has different meaning. For scalar index variant, it's
19816 used to differentiate add and subtract, otherwise it's with fixed value
19817 0x2. */
19818 int size = -1;
19819
dec41383
JW
19820 /* vfmal/vfmsl are in three-same D/Q register format or the third operand can
19821 be a scalar index register. */
19822 if (inst.operands[2].isscalar)
19823 {
19824 high8 = 0xfe000000;
19825 if (subtype)
19826 size = 16;
19827 rs = neon_select_shape (NS_DHS, NS_QDS, NS_NULL);
19828 }
19829 else
19830 {
19831 high8 = 0xfc000000;
19832 size = 32;
19833 if (subtype)
19834 inst.instruction |= (0x1 << 23);
19835 rs = neon_select_shape (NS_DHH, NS_QDD, NS_NULL);
19836 }
19837
aab2c27d
MM
19838
19839 if (inst.cond != COND_ALWAYS)
19840 as_warn (_("vfmal/vfmsl with FP16 type cannot be conditional, the "
19841 "behaviour is UNPREDICTABLE"));
19842
19843 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16_fml),
19844 _(BAD_FP16));
19845
19846 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
19847 _(BAD_FPU));
dec41383
JW
19848
19849 /* "opcode" from template has included "ubit", so simply pass 0 here. Also,
19850 the "S" bit in size field has been reused to differentiate vfmal and vfmsl,
19851 so we simply pass -1 as size. */
19852 unsigned quad_p = (rs == NS_QDD || rs == NS_QDS);
19853 neon_three_same (quad_p, 0, size);
19854
19855 /* Undo neon_dp_fixup. Redo the high eight bits. */
19856 inst.instruction &= 0x00ffffff;
19857 inst.instruction |= high8;
19858
dec41383
JW
19859 /* Unlike usually NEON three-same, encoding for Vn and Vm will depend on
19860 whether the instruction is in Q form and whether Vm is a scalar indexed
19861 operand. */
19862 if (inst.operands[2].isscalar)
19863 {
19864 unsigned rm
19865 = neon_scalar_for_fmac_fp16_long (inst.operands[2].reg, quad_p);
19866 inst.instruction &= 0xffffffd0;
19867 inst.instruction |= rm;
19868
19869 if (!quad_p)
19870 {
19871 /* Redo Rn as well. */
19872 inst.instruction &= 0xfff0ff7f;
19873 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
19874 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
19875 }
19876 }
19877 else if (!quad_p)
19878 {
19879 /* Redo Rn and Rm. */
19880 inst.instruction &= 0xfff0ff50;
19881 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
19882 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
19883 inst.instruction |= HI4 (inst.operands[2].reg);
19884 inst.instruction |= LOW1 (inst.operands[2].reg) << 5;
19885 }
19886}
19887
19888static void
19889do_neon_vfmal (void)
19890{
19891 return do_neon_fmac_maybe_scalar_long (0);
19892}
19893
19894static void
19895do_neon_vfmsl (void)
19896{
19897 return do_neon_fmac_maybe_scalar_long (1);
19898}
19899
5287ad62
JB
19900static void
19901do_neon_dyadic_wide (void)
19902{
19903 struct neon_type_el et = neon_check_type (3, NS_QQD,
19904 N_EQK | N_DBL, N_EQK | N_DBL, N_SU_32 | N_KEY);
19905 neon_mixed_length (et, et.size);
19906}
19907
19908static void
19909do_neon_dyadic_narrow (void)
19910{
19911 struct neon_type_el et = neon_check_type (3, NS_QDD,
19912 N_EQK | N_DBL, N_EQK, N_I16 | N_I32 | N_I64 | N_KEY);
428e3f1f
PB
19913 /* Operand sign is unimportant, and the U bit is part of the opcode,
19914 so force the operand type to integer. */
19915 et.type = NT_integer;
5287ad62
JB
19916 neon_mixed_length (et, et.size / 2);
19917}
19918
19919static void
19920do_neon_mul_sat_scalar_long (void)
19921{
19922 neon_mac_reg_scalar_long (N_S16 | N_S32, N_S16 | N_S32);
19923}
19924
19925static void
19926do_neon_vmull (void)
19927{
19928 if (inst.operands[2].isscalar)
19929 do_neon_mac_maybe_scalar_long ();
19930 else
19931 {
19932 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 19933 N_EQK | N_DBL, N_EQK, N_SU_32 | N_P8 | N_P64 | N_KEY);
4f51b4bd 19934
5287ad62 19935 if (et.type == NT_poly)
477330fc 19936 NEON_ENCODE (POLY, inst);
5287ad62 19937 else
477330fc 19938 NEON_ENCODE (INTEGER, inst);
4f51b4bd
MGD
19939
19940 /* For polynomial encoding the U bit must be zero, and the size must
19941 be 8 (encoded as 0b00) or, on ARMv8 or later 64 (encoded, non
19942 obviously, as 0b10). */
19943 if (et.size == 64)
19944 {
19945 /* Check we're on the correct architecture. */
19946 if (!mark_feature_used (&fpu_crypto_ext_armv8))
19947 inst.error =
19948 _("Instruction form not available on this architecture.");
19949
19950 et.size = 32;
19951 }
19952
5287ad62
JB
19953 neon_mixed_length (et, et.size);
19954 }
19955}
19956
19957static void
19958do_neon_ext (void)
19959{
037e8744 19960 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
5287ad62
JB
19961 struct neon_type_el et = neon_check_type (3, rs,
19962 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
19963 unsigned imm = (inst.operands[3].imm * et.size) / 8;
35997600
NC
19964
19965 constraint (imm >= (unsigned) (neon_quad (rs) ? 16 : 8),
19966 _("shift out of range"));
5287ad62
JB
19967 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19968 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19969 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19970 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19971 inst.instruction |= LOW4 (inst.operands[2].reg);
19972 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
037e8744 19973 inst.instruction |= neon_quad (rs) << 6;
5287ad62 19974 inst.instruction |= imm << 8;
5f4273c7 19975
88714cb8 19976 neon_dp_fixup (&inst);
5287ad62
JB
19977}
19978
19979static void
19980do_neon_rev (void)
19981{
5b7c81bd 19982 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
19983 return;
19984
19985 enum neon_shape rs;
19986 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19987 rs = neon_select_shape (NS_QQ, NS_NULL);
19988 else
19989 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
19990
5287ad62
JB
19991 struct neon_type_el et = neon_check_type (2, rs,
19992 N_EQK, N_8 | N_16 | N_32 | N_KEY);
4401c241 19993
5287ad62
JB
19994 unsigned op = (inst.instruction >> 7) & 3;
19995 /* N (width of reversed regions) is encoded as part of the bitmask. We
19996 extract it here to check the elements to be reversed are smaller.
19997 Otherwise we'd get a reserved instruction. */
19998 unsigned elsize = (op == 2) ? 16 : (op == 1) ? 32 : (op == 0) ? 64 : 0;
4401c241
AV
19999
20000 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext) && elsize == 64
20001 && inst.operands[0].reg == inst.operands[1].reg)
20002 as_tsktsk (_("Warning: 64-bit element size and same destination and source"
20003 " operands makes instruction UNPREDICTABLE"));
20004
9c2799c2 20005 gas_assert (elsize != 0);
5287ad62 20006 constraint (et.size >= elsize,
477330fc 20007 _("elements must be smaller than reversal region"));
037e8744 20008 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20009}
20010
20011static void
20012do_neon_dup (void)
20013{
20014 if (inst.operands[1].isscalar)
20015 {
b409bdb6
AV
20016 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
20017 BAD_FPU);
037e8744 20018 enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
dcbf9037 20019 struct neon_type_el et = neon_check_type (2, rs,
477330fc 20020 N_EQK, N_8 | N_16 | N_32 | N_KEY);
5287ad62 20021 unsigned sizebits = et.size >> 3;
dcbf9037 20022 unsigned dm = NEON_SCALAR_REG (inst.operands[1].reg);
5287ad62 20023 int logsize = neon_logbits (et.size);
dcbf9037 20024 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg) << logsize;
037e8744
JB
20025
20026 if (vfp_or_neon_is_neon (NEON_CHECK_CC) == FAIL)
477330fc 20027 return;
037e8744 20028
88714cb8 20029 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
20030 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20031 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20032 inst.instruction |= LOW4 (dm);
20033 inst.instruction |= HI1 (dm) << 5;
037e8744 20034 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
20035 inst.instruction |= x << 17;
20036 inst.instruction |= sizebits << 16;
5f4273c7 20037
88714cb8 20038 neon_dp_fixup (&inst);
5287ad62
JB
20039 }
20040 else
20041 {
037e8744
JB
20042 enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
20043 struct neon_type_el et = neon_check_type (2, rs,
477330fc 20044 N_8 | N_16 | N_32 | N_KEY, N_EQK);
b409bdb6
AV
20045 if (rs == NS_QR)
20046 {
5b7c81bd 20047 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH))
b409bdb6
AV
20048 return;
20049 }
20050 else
20051 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
20052 BAD_FPU);
20053
20054 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20055 {
20056 if (inst.operands[1].reg == REG_SP)
20057 as_tsktsk (MVE_BAD_SP);
20058 else if (inst.operands[1].reg == REG_PC)
20059 as_tsktsk (MVE_BAD_PC);
20060 }
20061
5287ad62 20062 /* Duplicate ARM register to lanes of vector. */
88714cb8 20063 NEON_ENCODE (ARMREG, inst);
5287ad62 20064 switch (et.size)
477330fc
RM
20065 {
20066 case 8: inst.instruction |= 0x400000; break;
20067 case 16: inst.instruction |= 0x000020; break;
20068 case 32: inst.instruction |= 0x000000; break;
20069 default: break;
20070 }
5287ad62
JB
20071 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
20072 inst.instruction |= LOW4 (inst.operands[0].reg) << 16;
20073 inst.instruction |= HI1 (inst.operands[0].reg) << 7;
037e8744 20074 inst.instruction |= neon_quad (rs) << 21;
5287ad62 20075 /* The encoding for this instruction is identical for the ARM and Thumb
477330fc 20076 variants, except for the condition field. */
037e8744 20077 do_vfp_cond_or_thumb ();
5287ad62
JB
20078 }
20079}
20080
57785aa2
AV
20081static void
20082do_mve_mov (int toQ)
20083{
20084 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20085 return;
20086 if (inst.cond > COND_ALWAYS)
20087 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
20088
20089 unsigned Rt = 0, Rt2 = 1, Q0 = 2, Q1 = 3;
20090 if (toQ)
20091 {
20092 Q0 = 0;
20093 Q1 = 1;
20094 Rt = 2;
20095 Rt2 = 3;
20096 }
20097
20098 constraint (inst.operands[Q0].reg != inst.operands[Q1].reg + 2,
20099 _("Index one must be [2,3] and index two must be two less than"
20100 " index one."));
e683cb41
AC
20101 constraint (!toQ && inst.operands[Rt].reg == inst.operands[Rt2].reg,
20102 _("Destination registers may not be the same"));
57785aa2
AV
20103 constraint (inst.operands[Rt].reg == REG_SP
20104 || inst.operands[Rt2].reg == REG_SP,
20105 BAD_SP);
20106 constraint (inst.operands[Rt].reg == REG_PC
20107 || inst.operands[Rt2].reg == REG_PC,
20108 BAD_PC);
20109
20110 inst.instruction = 0xec000f00;
20111 inst.instruction |= HI1 (inst.operands[Q1].reg / 32) << 23;
20112 inst.instruction |= !!toQ << 20;
20113 inst.instruction |= inst.operands[Rt2].reg << 16;
20114 inst.instruction |= LOW4 (inst.operands[Q1].reg / 32) << 13;
20115 inst.instruction |= (inst.operands[Q1].reg % 4) << 4;
20116 inst.instruction |= inst.operands[Rt].reg;
20117}
20118
20119static void
20120do_mve_movn (void)
20121{
20122 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20123 return;
20124
20125 if (inst.cond > COND_ALWAYS)
20126 inst.pred_insn_type = INSIDE_VPT_INSN;
20127 else
20128 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
20129
20130 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_I16 | N_I32
20131 | N_KEY);
20132
20133 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20134 inst.instruction |= (neon_logbits (et.size) - 1) << 18;
20135 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20136 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20137 inst.instruction |= LOW4 (inst.operands[1].reg);
20138 inst.is_neon = 1;
20139
20140}
20141
5287ad62
JB
20142/* VMOV has particularly many variations. It can be one of:
20143 0. VMOV<c><q> <Qd>, <Qm>
20144 1. VMOV<c><q> <Dd>, <Dm>
20145 (Register operations, which are VORR with Rm = Rn.)
20146 2. VMOV<c><q>.<dt> <Qd>, #<imm>
20147 3. VMOV<c><q>.<dt> <Dd>, #<imm>
20148 (Immediate loads.)
20149 4. VMOV<c><q>.<size> <Dn[x]>, <Rd>
20150 (ARM register to scalar.)
20151 5. VMOV<c><q> <Dm>, <Rd>, <Rn>
20152 (Two ARM registers to vector.)
20153 6. VMOV<c><q>.<dt> <Rd>, <Dn[x]>
20154 (Scalar to ARM register.)
20155 7. VMOV<c><q> <Rd>, <Rn>, <Dm>
20156 (Vector to two ARM registers.)
037e8744
JB
20157 8. VMOV.F32 <Sd>, <Sm>
20158 9. VMOV.F64 <Dd>, <Dm>
20159 (VFP register moves.)
20160 10. VMOV.F32 <Sd>, #imm
20161 11. VMOV.F64 <Dd>, #imm
20162 (VFP float immediate load.)
20163 12. VMOV <Rd>, <Sm>
20164 (VFP single to ARM reg.)
20165 13. VMOV <Sd>, <Rm>
20166 (ARM reg to VFP single.)
20167 14. VMOV <Rd>, <Re>, <Sn>, <Sm>
20168 (Two ARM regs to two VFP singles.)
20169 15. VMOV <Sd>, <Se>, <Rn>, <Rm>
20170 (Two VFP singles to two ARM regs.)
57785aa2
AV
20171 16. VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]>
20172 17. VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2>
20173 18. VMOV<c>.<dt> <Rt>, <Qn[idx]>
20174 19. VMOV<c>.<dt> <Qd[idx]>, <Rt>
5f4273c7 20175
037e8744
JB
20176 These cases can be disambiguated using neon_select_shape, except cases 1/9
20177 and 3/11 which depend on the operand type too.
5f4273c7 20178
5287ad62 20179 All the encoded bits are hardcoded by this function.
5f4273c7 20180
b7fc2769
JB
20181 Cases 4, 6 may be used with VFPv1 and above (only 32-bit transfers!).
20182 Cases 5, 7 may be used with VFPv2 and above.
5f4273c7 20183
5287ad62 20184 FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
5f4273c7 20185 can specify a type where it doesn't make sense to, and is ignored). */
5287ad62
JB
20186
20187static void
20188do_neon_mov (void)
20189{
57785aa2
AV
20190 enum neon_shape rs = neon_select_shape (NS_RRSS, NS_SSRR, NS_RRFF, NS_FFRR,
20191 NS_DRR, NS_RRD, NS_QQ, NS_DD, NS_QI,
20192 NS_DI, NS_SR, NS_RS, NS_FF, NS_FI,
20193 NS_RF, NS_FR, NS_HR, NS_RH, NS_HI,
20194 NS_NULL);
037e8744
JB
20195 struct neon_type_el et;
20196 const char *ldconst = 0;
5287ad62 20197
037e8744 20198 switch (rs)
5287ad62 20199 {
037e8744
JB
20200 case NS_DD: /* case 1/9. */
20201 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
20202 /* It is not an error here if no type is given. */
20203 inst.error = NULL;
1c1e0fe5
SP
20204
20205 /* In MVE we interpret the following instructions as same, so ignoring
20206 the following type (float) and size (64) checks.
20207 a: VMOV<c><q> <Dd>, <Dm>
20208 b: VMOV<c><q>.F64 <Dd>, <Dm>. */
20209 if ((et.type == NT_float && et.size == 64)
20210 || (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)))
477330fc
RM
20211 {
20212 do_vfp_nsyn_opcode ("fcpyd");
20213 break;
20214 }
037e8744 20215 /* fall through. */
5287ad62 20216
037e8744
JB
20217 case NS_QQ: /* case 0/1. */
20218 {
5b7c81bd 20219 if (!check_simd_pred_availability (false,
64c350f2 20220 NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc
RM
20221 return;
20222 /* The architecture manual I have doesn't explicitly state which
20223 value the U bit should have for register->register moves, but
20224 the equivalent VORR instruction has U = 0, so do that. */
20225 inst.instruction = 0x0200110;
20226 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20227 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20228 inst.instruction |= LOW4 (inst.operands[1].reg);
20229 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20230 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20231 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20232 inst.instruction |= neon_quad (rs) << 6;
20233
20234 neon_dp_fixup (&inst);
037e8744
JB
20235 }
20236 break;
5f4273c7 20237
037e8744
JB
20238 case NS_DI: /* case 3/11. */
20239 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
20240 inst.error = NULL;
20241 if (et.type == NT_float && et.size == 64)
477330fc
RM
20242 {
20243 /* case 11 (fconstd). */
20244 ldconst = "fconstd";
20245 goto encode_fconstd;
20246 }
037e8744
JB
20247 /* fall through. */
20248
20249 case NS_QI: /* case 2/3. */
5b7c81bd 20250 if (!check_simd_pred_availability (false,
64c350f2 20251 NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc 20252 return;
037e8744
JB
20253 inst.instruction = 0x0800010;
20254 neon_move_immediate ();
88714cb8 20255 neon_dp_fixup (&inst);
5287ad62 20256 break;
5f4273c7 20257
037e8744
JB
20258 case NS_SR: /* case 4. */
20259 {
477330fc
RM
20260 unsigned bcdebits = 0;
20261 int logsize;
20262 unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
20263 unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
037e8744 20264
05ac0ffb
JB
20265 /* .<size> is optional here, defaulting to .32. */
20266 if (inst.vectype.elems == 0
20267 && inst.operands[0].vectype.type == NT_invtype
20268 && inst.operands[1].vectype.type == NT_invtype)
20269 {
20270 inst.vectype.el[0].type = NT_untyped;
20271 inst.vectype.el[0].size = 32;
20272 inst.vectype.elems = 1;
20273 }
20274
477330fc
RM
20275 et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
20276 logsize = neon_logbits (et.size);
20277
57785aa2
AV
20278 if (et.size != 32)
20279 {
20280 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
20281 && vfp_or_neon_is_neon (NEON_CHECK_ARCH) == FAIL)
20282 return;
20283 }
20284 else
20285 {
20286 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
20287 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20288 _(BAD_FPU));
20289 }
20290
20291 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20292 {
20293 if (inst.operands[1].reg == REG_SP)
20294 as_tsktsk (MVE_BAD_SP);
20295 else if (inst.operands[1].reg == REG_PC)
20296 as_tsktsk (MVE_BAD_PC);
20297 }
20298 unsigned size = inst.operands[0].isscalar == 1 ? 64 : 128;
20299
477330fc 20300 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2
AV
20301 constraint (x >= size / et.size, _("scalar index out of range"));
20302
477330fc
RM
20303
20304 switch (et.size)
20305 {
20306 case 8: bcdebits = 0x8; break;
20307 case 16: bcdebits = 0x1; break;
20308 case 32: bcdebits = 0x0; break;
20309 default: ;
20310 }
20311
57785aa2 20312 bcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
20313
20314 inst.instruction = 0xe000b10;
20315 do_vfp_cond_or_thumb ();
20316 inst.instruction |= LOW4 (dn) << 16;
20317 inst.instruction |= HI1 (dn) << 7;
20318 inst.instruction |= inst.operands[1].reg << 12;
20319 inst.instruction |= (bcdebits & 3) << 5;
57785aa2
AV
20320 inst.instruction |= ((bcdebits >> 2) & 3) << 21;
20321 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
20322 }
20323 break;
5f4273c7 20324
037e8744 20325 case NS_DRR: /* case 5 (fmdrr). */
57785aa2
AV
20326 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20327 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 20328 _(BAD_FPU));
b7fc2769 20329
037e8744
JB
20330 inst.instruction = 0xc400b10;
20331 do_vfp_cond_or_thumb ();
20332 inst.instruction |= LOW4 (inst.operands[0].reg);
20333 inst.instruction |= HI1 (inst.operands[0].reg) << 5;
20334 inst.instruction |= inst.operands[1].reg << 12;
20335 inst.instruction |= inst.operands[2].reg << 16;
20336 break;
5f4273c7 20337
037e8744
JB
20338 case NS_RS: /* case 6. */
20339 {
477330fc
RM
20340 unsigned logsize;
20341 unsigned dn = NEON_SCALAR_REG (inst.operands[1].reg);
20342 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
20343 unsigned abcdebits = 0;
037e8744 20344
05ac0ffb
JB
20345 /* .<dt> is optional here, defaulting to .32. */
20346 if (inst.vectype.elems == 0
20347 && inst.operands[0].vectype.type == NT_invtype
20348 && inst.operands[1].vectype.type == NT_invtype)
20349 {
20350 inst.vectype.el[0].type = NT_untyped;
20351 inst.vectype.el[0].size = 32;
20352 inst.vectype.elems = 1;
20353 }
20354
91d6fa6a
NC
20355 et = neon_check_type (2, NS_NULL,
20356 N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
477330fc
RM
20357 logsize = neon_logbits (et.size);
20358
57785aa2
AV
20359 if (et.size != 32)
20360 {
20361 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
20362 && vfp_or_neon_is_neon (NEON_CHECK_CC
20363 | NEON_CHECK_ARCH) == FAIL)
20364 return;
20365 }
20366 else
20367 {
20368 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
20369 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20370 _(BAD_FPU));
20371 }
20372
20373 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20374 {
20375 if (inst.operands[0].reg == REG_SP)
20376 as_tsktsk (MVE_BAD_SP);
20377 else if (inst.operands[0].reg == REG_PC)
20378 as_tsktsk (MVE_BAD_PC);
20379 }
20380
20381 unsigned size = inst.operands[1].isscalar == 1 ? 64 : 128;
20382
477330fc 20383 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2 20384 constraint (x >= size / et.size, _("scalar index out of range"));
477330fc
RM
20385
20386 switch (et.size)
20387 {
20388 case 8: abcdebits = (et.type == NT_signed) ? 0x08 : 0x18; break;
20389 case 16: abcdebits = (et.type == NT_signed) ? 0x01 : 0x11; break;
20390 case 32: abcdebits = 0x00; break;
20391 default: ;
20392 }
20393
57785aa2 20394 abcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
20395 inst.instruction = 0xe100b10;
20396 do_vfp_cond_or_thumb ();
20397 inst.instruction |= LOW4 (dn) << 16;
20398 inst.instruction |= HI1 (dn) << 7;
20399 inst.instruction |= inst.operands[0].reg << 12;
20400 inst.instruction |= (abcdebits & 3) << 5;
20401 inst.instruction |= (abcdebits >> 2) << 21;
57785aa2 20402 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
20403 }
20404 break;
5f4273c7 20405
037e8744 20406 case NS_RRD: /* case 7 (fmrrd). */
57785aa2
AV
20407 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20408 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 20409 _(BAD_FPU));
037e8744
JB
20410
20411 inst.instruction = 0xc500b10;
20412 do_vfp_cond_or_thumb ();
20413 inst.instruction |= inst.operands[0].reg << 12;
20414 inst.instruction |= inst.operands[1].reg << 16;
20415 inst.instruction |= LOW4 (inst.operands[2].reg);
20416 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20417 break;
5f4273c7 20418
037e8744
JB
20419 case NS_FF: /* case 8 (fcpys). */
20420 do_vfp_nsyn_opcode ("fcpys");
20421 break;
5f4273c7 20422
9db2f6b4 20423 case NS_HI:
037e8744
JB
20424 case NS_FI: /* case 10 (fconsts). */
20425 ldconst = "fconsts";
4ef4710f 20426 encode_fconstd:
58ed5c38
TC
20427 if (!inst.operands[1].immisfloat)
20428 {
4ef4710f 20429 unsigned new_imm;
58ed5c38 20430 /* Immediate has to fit in 8 bits so float is enough. */
4ef4710f
NC
20431 float imm = (float) inst.operands[1].imm;
20432 memcpy (&new_imm, &imm, sizeof (float));
20433 /* But the assembly may have been written to provide an integer
20434 bit pattern that equates to a float, so check that the
20435 conversion has worked. */
20436 if (is_quarter_float (new_imm))
20437 {
20438 if (is_quarter_float (inst.operands[1].imm))
20439 as_warn (_("immediate constant is valid both as a bit-pattern and a floating point value (using the fp value)"));
20440
20441 inst.operands[1].imm = new_imm;
20442 inst.operands[1].immisfloat = 1;
20443 }
58ed5c38
TC
20444 }
20445
037e8744 20446 if (is_quarter_float (inst.operands[1].imm))
477330fc
RM
20447 {
20448 inst.operands[1].imm = neon_qfloat_bits (inst.operands[1].imm);
20449 do_vfp_nsyn_opcode (ldconst);
9db2f6b4
RL
20450
20451 /* ARMv8.2 fp16 vmov.f16 instruction. */
20452 if (rs == NS_HI)
20453 do_scalar_fp16_v82_encode ();
477330fc 20454 }
5287ad62 20455 else
477330fc 20456 first_error (_("immediate out of range"));
037e8744 20457 break;
5f4273c7 20458
9db2f6b4 20459 case NS_RH:
037e8744
JB
20460 case NS_RF: /* case 12 (fmrs). */
20461 do_vfp_nsyn_opcode ("fmrs");
9db2f6b4
RL
20462 /* ARMv8.2 fp16 vmov.f16 instruction. */
20463 if (rs == NS_RH)
20464 do_scalar_fp16_v82_encode ();
037e8744 20465 break;
5f4273c7 20466
9db2f6b4 20467 case NS_HR:
037e8744
JB
20468 case NS_FR: /* case 13 (fmsr). */
20469 do_vfp_nsyn_opcode ("fmsr");
9db2f6b4
RL
20470 /* ARMv8.2 fp16 vmov.f16 instruction. */
20471 if (rs == NS_HR)
20472 do_scalar_fp16_v82_encode ();
037e8744 20473 break;
5f4273c7 20474
57785aa2
AV
20475 case NS_RRSS:
20476 do_mve_mov (0);
20477 break;
20478 case NS_SSRR:
20479 do_mve_mov (1);
20480 break;
20481
037e8744
JB
20482 /* The encoders for the fmrrs and fmsrr instructions expect three operands
20483 (one of which is a list), but we have parsed four. Do some fiddling to
20484 make the operands what do_vfp_reg2_from_sp2 and do_vfp_sp2_from_reg2
20485 expect. */
20486 case NS_RRFF: /* case 14 (fmrrs). */
57785aa2
AV
20487 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20488 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20489 _(BAD_FPU));
037e8744 20490 constraint (inst.operands[3].reg != inst.operands[2].reg + 1,
477330fc 20491 _("VFP registers must be adjacent"));
037e8744
JB
20492 inst.operands[2].imm = 2;
20493 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
20494 do_vfp_nsyn_opcode ("fmrrs");
20495 break;
5f4273c7 20496
037e8744 20497 case NS_FFRR: /* case 15 (fmsrr). */
57785aa2
AV
20498 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20499 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20500 _(BAD_FPU));
037e8744 20501 constraint (inst.operands[1].reg != inst.operands[0].reg + 1,
477330fc 20502 _("VFP registers must be adjacent"));
037e8744
JB
20503 inst.operands[1] = inst.operands[2];
20504 inst.operands[2] = inst.operands[3];
20505 inst.operands[0].imm = 2;
20506 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
20507 do_vfp_nsyn_opcode ("fmsrr");
5287ad62 20508 break;
5f4273c7 20509
4c261dff
NC
20510 case NS_NULL:
20511 /* neon_select_shape has determined that the instruction
20512 shape is wrong and has already set the error message. */
20513 break;
20514
5287ad62
JB
20515 default:
20516 abort ();
20517 }
20518}
20519
57785aa2
AV
20520static void
20521do_mve_movl (void)
20522{
20523 if (!(inst.operands[0].present && inst.operands[0].isquad
20524 && inst.operands[1].present && inst.operands[1].isquad
20525 && !inst.operands[2].present))
20526 {
20527 inst.instruction = 0;
20528 inst.cond = 0xb;
20529 if (thumb_mode)
20530 set_pred_insn_type (INSIDE_IT_INSN);
20531 do_neon_mov ();
20532 return;
20533 }
20534
20535 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20536 return;
20537
20538 if (inst.cond != COND_ALWAYS)
20539 inst.pred_insn_type = INSIDE_VPT_INSN;
20540
20541 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_S8 | N_U8
20542 | N_S16 | N_U16 | N_KEY);
20543
20544 inst.instruction |= (et.type == NT_unsigned) << 28;
20545 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20546 inst.instruction |= (neon_logbits (et.size) + 1) << 19;
20547 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20548 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20549 inst.instruction |= LOW4 (inst.operands[1].reg);
20550 inst.is_neon = 1;
20551}
20552
5287ad62
JB
20553static void
20554do_neon_rshift_round_imm (void)
20555{
5b7c81bd 20556 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
20557 return;
20558
20559 enum neon_shape rs;
20560 struct neon_type_el et;
20561
20562 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20563 {
20564 rs = neon_select_shape (NS_QQI, NS_NULL);
20565 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
20566 }
20567 else
20568 {
20569 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
20570 et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
20571 }
5287ad62
JB
20572 int imm = inst.operands[2].imm;
20573
20574 /* imm == 0 case is encoded as VMOV for V{R}SHR. */
20575 if (imm == 0)
20576 {
20577 inst.operands[2].present = 0;
20578 do_neon_mov ();
20579 return;
20580 }
20581
20582 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 20583 _("immediate out of range for shift"));
5b7c81bd 20584 neon_imm_shift (true, et.type == NT_unsigned, neon_quad (rs), et,
477330fc 20585 et.size - imm);
5287ad62
JB
20586}
20587
9db2f6b4
RL
20588static void
20589do_neon_movhf (void)
20590{
20591 enum neon_shape rs = neon_select_shape (NS_HH, NS_NULL);
20592 constraint (rs != NS_HH, _("invalid suffix"));
20593
7bdf778b
ASDV
20594 if (inst.cond != COND_ALWAYS)
20595 {
20596 if (thumb_mode)
20597 {
55e0daa3 20598 as_warn (_("scalar fp16 instruction cannot be conditional,"
7bdf778b
ASDV
20599 " the behaviour is UNPREDICTABLE"));
20600 }
20601 else
20602 {
20603 inst.error = BAD_COND;
20604 return;
20605 }
20606 }
20607
9db2f6b4
RL
20608 do_vfp_sp_monadic ();
20609
20610 inst.is_neon = 1;
20611 inst.instruction |= 0xf0000000;
20612}
20613
5287ad62
JB
20614static void
20615do_neon_movl (void)
20616{
20617 struct neon_type_el et = neon_check_type (2, NS_QD,
20618 N_EQK | N_DBL, N_SU_32 | N_KEY);
20619 unsigned sizebits = et.size >> 3;
20620 inst.instruction |= sizebits << 19;
20621 neon_two_same (0, et.type == NT_unsigned, -1);
20622}
20623
20624static void
20625do_neon_trn (void)
20626{
037e8744 20627 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20628 struct neon_type_el et = neon_check_type (2, rs,
20629 N_EQK, N_8 | N_16 | N_32 | N_KEY);
88714cb8 20630 NEON_ENCODE (INTEGER, inst);
037e8744 20631 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20632}
20633
20634static void
20635do_neon_zip_uzp (void)
20636{
037e8744 20637 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20638 struct neon_type_el et = neon_check_type (2, rs,
20639 N_EQK, N_8 | N_16 | N_32 | N_KEY);
20640 if (rs == NS_DD && et.size == 32)
20641 {
20642 /* Special case: encode as VTRN.32 <Dd>, <Dm>. */
20643 inst.instruction = N_MNEM_vtrn;
20644 do_neon_trn ();
20645 return;
20646 }
037e8744 20647 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20648}
20649
20650static void
20651do_neon_sat_abs_neg (void)
20652{
5b7c81bd 20653 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
1a186d29
AV
20654 return;
20655
20656 enum neon_shape rs;
20657 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20658 rs = neon_select_shape (NS_QQ, NS_NULL);
20659 else
20660 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20661 struct neon_type_el et = neon_check_type (2, rs,
20662 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 20663 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20664}
20665
20666static void
20667do_neon_pair_long (void)
20668{
037e8744 20669 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20670 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
20671 /* Unsigned is encoded in OP field (bit 7) for these instruction. */
20672 inst.instruction |= (et.type == NT_unsigned) << 7;
037e8744 20673 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20674}
20675
20676static void
20677do_neon_recip_est (void)
20678{
037e8744 20679 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62 20680 struct neon_type_el et = neon_check_type (2, rs,
cc933301 20681 N_EQK | N_FLT, N_F_16_32 | N_U32 | N_KEY);
5287ad62 20682 inst.instruction |= (et.type == NT_float) << 8;
037e8744 20683 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20684}
20685
20686static void
20687do_neon_cls (void)
20688{
5b7c81bd 20689 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
f30ee27c
AV
20690 return;
20691
20692 enum neon_shape rs;
20693 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20694 rs = neon_select_shape (NS_QQ, NS_NULL);
20695 else
20696 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20697
5287ad62
JB
20698 struct neon_type_el et = neon_check_type (2, rs,
20699 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 20700 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20701}
20702
20703static void
20704do_neon_clz (void)
20705{
5b7c81bd 20706 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
f30ee27c
AV
20707 return;
20708
20709 enum neon_shape rs;
20710 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20711 rs = neon_select_shape (NS_QQ, NS_NULL);
20712 else
20713 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20714
5287ad62
JB
20715 struct neon_type_el et = neon_check_type (2, rs,
20716 N_EQK, N_I8 | N_I16 | N_I32 | N_KEY);
037e8744 20717 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20718}
20719
20720static void
20721do_neon_cnt (void)
20722{
037e8744 20723 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20724 struct neon_type_el et = neon_check_type (2, rs,
20725 N_EQK | N_INT, N_8 | N_KEY);
037e8744 20726 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20727}
20728
20729static void
20730do_neon_swp (void)
20731{
037e8744 20732 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
250dd99f
AM
20733 if (rs == NS_NULL)
20734 return;
037e8744 20735 neon_two_same (neon_quad (rs), 1, -1);
5287ad62
JB
20736}
20737
20738static void
20739do_neon_tbl_tbx (void)
20740{
20741 unsigned listlenbits;
dcbf9037 20742 neon_check_type (3, NS_DLD, N_EQK, N_EQK, N_8 | N_KEY);
5f4273c7 20743
5287ad62
JB
20744 if (inst.operands[1].imm < 1 || inst.operands[1].imm > 4)
20745 {
dcbf9037 20746 first_error (_("bad list length for table lookup"));
5287ad62
JB
20747 return;
20748 }
5f4273c7 20749
5287ad62
JB
20750 listlenbits = inst.operands[1].imm - 1;
20751 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20752 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20753 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20754 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20755 inst.instruction |= LOW4 (inst.operands[2].reg);
20756 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20757 inst.instruction |= listlenbits << 8;
5f4273c7 20758
88714cb8 20759 neon_dp_fixup (&inst);
5287ad62
JB
20760}
20761
20762static void
20763do_neon_ldm_stm (void)
20764{
ef8f595f
MI
20765 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
20766 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20767 _(BAD_FPU));
5287ad62
JB
20768 /* P, U and L bits are part of bitmask. */
20769 int is_dbmode = (inst.instruction & (1 << 24)) != 0;
20770 unsigned offsetbits = inst.operands[1].imm * 2;
20771
037e8744
JB
20772 if (inst.operands[1].issingle)
20773 {
20774 do_vfp_nsyn_ldm_stm (is_dbmode);
20775 return;
20776 }
20777
5287ad62 20778 constraint (is_dbmode && !inst.operands[0].writeback,
477330fc 20779 _("writeback (!) must be used for VLDMDB and VSTMDB"));
5287ad62
JB
20780
20781 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
477330fc
RM
20782 _("register list must contain at least 1 and at most 16 "
20783 "registers"));
5287ad62
JB
20784
20785 inst.instruction |= inst.operands[0].reg << 16;
20786 inst.instruction |= inst.operands[0].writeback << 21;
20787 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
20788 inst.instruction |= HI1 (inst.operands[1].reg) << 22;
20789
20790 inst.instruction |= offsetbits;
5f4273c7 20791
037e8744 20792 do_vfp_cond_or_thumb ();
5287ad62
JB
20793}
20794
d6dc01ba
MK
20795static void
20796do_vfp_nsyn_push_pop_check (void)
20797{
20798 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd), _(BAD_FPU));
20799
20800 if (inst.operands[1].issingle)
20801 {
20802 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 32,
20803 _("register list must contain at least 1 and at most 32 registers"));
20804 }
20805 else
20806 {
20807 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
20808 _("register list must contain at least 1 and at most 16 registers"));
20809 }
20810}
20811
ef8f595f
MI
20812static void
20813do_vfp_nsyn_pop (void)
20814{
20815 nsyn_insert_sp ();
ef8f595f 20816
d6dc01ba
MK
20817 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20818 return do_vfp_nsyn_opcode ("vldm");
ef8f595f 20819
d6dc01ba 20820 do_vfp_nsyn_push_pop_check ();
ef8f595f
MI
20821
20822 if (inst.operands[1].issingle)
20823 do_vfp_nsyn_opcode ("fldmias");
20824 else
20825 do_vfp_nsyn_opcode ("fldmiad");
20826}
20827
20828static void
20829do_vfp_nsyn_push (void)
20830{
20831 nsyn_insert_sp ();
ef8f595f 20832
d6dc01ba
MK
20833 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20834 return do_vfp_nsyn_opcode ("vstmdb");
ef8f595f 20835
d6dc01ba 20836 do_vfp_nsyn_push_pop_check ();
ef8f595f
MI
20837
20838 if (inst.operands[1].issingle)
20839 do_vfp_nsyn_opcode ("fstmdbs");
20840 else
20841 do_vfp_nsyn_opcode ("fstmdbd");
20842}
20843
5287ad62
JB
20844static void
20845do_neon_ldr_str (void)
20846{
5287ad62 20847 int is_ldr = (inst.instruction & (1 << 20)) != 0;
5f4273c7 20848
6844b2c2
MGD
20849 /* Use of PC in vstr in ARM mode is deprecated in ARMv7.
20850 And is UNPREDICTABLE in thumb mode. */
fa94de6b 20851 if (!is_ldr
6844b2c2 20852 && inst.operands[1].reg == REG_PC
ba86b375 20853 && (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7) || thumb_mode))
6844b2c2 20854 {
94dcf8bf 20855 if (thumb_mode)
6844b2c2 20856 inst.error = _("Use of PC here is UNPREDICTABLE");
94dcf8bf 20857 else if (warn_on_deprecated)
5c3696f8 20858 as_tsktsk (_("Use of PC here is deprecated"));
6844b2c2
MGD
20859 }
20860
037e8744
JB
20861 if (inst.operands[0].issingle)
20862 {
cd2f129f 20863 if (is_ldr)
477330fc 20864 do_vfp_nsyn_opcode ("flds");
cd2f129f 20865 else
477330fc 20866 do_vfp_nsyn_opcode ("fsts");
9db2f6b4
RL
20867
20868 /* ARMv8.2 vldr.16/vstr.16 instruction. */
20869 if (inst.vectype.el[0].size == 16)
20870 do_scalar_fp16_v82_encode ();
5287ad62
JB
20871 }
20872 else
5287ad62 20873 {
cd2f129f 20874 if (is_ldr)
477330fc 20875 do_vfp_nsyn_opcode ("fldd");
5287ad62 20876 else
477330fc 20877 do_vfp_nsyn_opcode ("fstd");
5287ad62 20878 }
5287ad62
JB
20879}
20880
32c36c3c
AV
20881static void
20882do_t_vldr_vstr_sysreg (void)
20883{
20884 int fp_vldr_bitno = 20, sysreg_vldr_bitno = 20;
5b7c81bd 20885 bool is_vldr = ((inst.instruction & (1 << fp_vldr_bitno)) != 0);
32c36c3c
AV
20886
20887 /* Use of PC is UNPREDICTABLE. */
20888 if (inst.operands[1].reg == REG_PC)
20889 inst.error = _("Use of PC here is UNPREDICTABLE");
20890
20891 if (inst.operands[1].immisreg)
20892 inst.error = _("instruction does not accept register index");
20893
20894 if (!inst.operands[1].isreg)
20895 inst.error = _("instruction does not accept PC-relative addressing");
20896
20897 if (abs (inst.operands[1].imm) >= (1 << 7))
20898 inst.error = _("immediate value out of range");
20899
20900 inst.instruction = 0xec000f80;
20901 if (is_vldr)
20902 inst.instruction |= 1 << sysreg_vldr_bitno;
5b7c81bd 20903 encode_arm_cp_address (1, true, false, BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM);
32c36c3c
AV
20904 inst.instruction |= (inst.operands[0].imm & 0x7) << 13;
20905 inst.instruction |= (inst.operands[0].imm & 0x8) << 19;
20906}
20907
20908static void
20909do_vldr_vstr (void)
20910{
5b7c81bd 20911 bool sysreg_op = !inst.operands[0].isreg;
32c36c3c
AV
20912
20913 /* VLDR/VSTR (System Register). */
20914 if (sysreg_op)
20915 {
20916 if (!mark_feature_used (&arm_ext_v8_1m_main))
20917 as_bad (_("Instruction not permitted on this architecture"));
20918
20919 do_t_vldr_vstr_sysreg ();
20920 }
20921 /* VLDR/VSTR. */
20922 else
20923 {
ef8f595f
MI
20924 if (!mark_feature_used (&fpu_vfp_ext_v1xd)
20925 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
32c36c3c
AV
20926 as_bad (_("Instruction not permitted on this architecture"));
20927 do_neon_ldr_str ();
20928 }
20929}
20930
5287ad62
JB
20931/* "interleave" version also handles non-interleaving register VLD1/VST1
20932 instructions. */
20933
20934static void
20935do_neon_ld_st_interleave (void)
20936{
037e8744 20937 struct neon_type_el et = neon_check_type (1, NS_NULL,
477330fc 20938 N_8 | N_16 | N_32 | N_64);
5287ad62
JB
20939 unsigned alignbits = 0;
20940 unsigned idx;
20941 /* The bits in this table go:
20942 0: register stride of one (0) or two (1)
20943 1,2: register list length, minus one (1, 2, 3, 4).
20944 3,4: <n> in instruction type, minus one (VLD<n> / VST<n>).
20945 We use -1 for invalid entries. */
20946 const int typetable[] =
20947 {
20948 0x7, -1, 0xa, -1, 0x6, -1, 0x2, -1, /* VLD1 / VST1. */
20949 -1, -1, 0x8, 0x9, -1, -1, 0x3, -1, /* VLD2 / VST2. */
20950 -1, -1, -1, -1, 0x4, 0x5, -1, -1, /* VLD3 / VST3. */
20951 -1, -1, -1, -1, -1, -1, 0x0, 0x1 /* VLD4 / VST4. */
20952 };
20953 int typebits;
20954
dcbf9037
JB
20955 if (et.type == NT_invtype)
20956 return;
20957
5287ad62
JB
20958 if (inst.operands[1].immisalign)
20959 switch (inst.operands[1].imm >> 8)
20960 {
20961 case 64: alignbits = 1; break;
20962 case 128:
477330fc 20963 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2
e23c0ad8 20964 && NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
477330fc
RM
20965 goto bad_alignment;
20966 alignbits = 2;
20967 break;
5287ad62 20968 case 256:
477330fc
RM
20969 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
20970 goto bad_alignment;
20971 alignbits = 3;
20972 break;
5287ad62
JB
20973 default:
20974 bad_alignment:
477330fc
RM
20975 first_error (_("bad alignment"));
20976 return;
5287ad62
JB
20977 }
20978
20979 inst.instruction |= alignbits << 4;
20980 inst.instruction |= neon_logbits (et.size) << 6;
20981
20982 /* Bits [4:6] of the immediate in a list specifier encode register stride
20983 (minus 1) in bit 4, and list length in bits [5:6]. We put the <n> of
20984 VLD<n>/VST<n> in bits [9:8] of the initial bitmask. Suck it out here, look
20985 up the right value for "type" in a table based on this value and the given
20986 list style, then stick it back. */
20987 idx = ((inst.operands[0].imm >> 4) & 7)
477330fc 20988 | (((inst.instruction >> 8) & 3) << 3);
5287ad62
JB
20989
20990 typebits = typetable[idx];
5f4273c7 20991
5287ad62 20992 constraint (typebits == -1, _("bad list type for instruction"));
1d50d57c 20993 constraint (((inst.instruction >> 8) & 3) && et.size == 64,
35c228db 20994 BAD_EL_TYPE);
5287ad62
JB
20995
20996 inst.instruction &= ~0xf00;
20997 inst.instruction |= typebits << 8;
20998}
20999
21000/* Check alignment is valid for do_neon_ld_st_lane and do_neon_ld_dup.
21001 *DO_ALIGN is set to 1 if the relevant alignment bit should be set, 0
21002 otherwise. The variable arguments are a list of pairs of legal (size, align)
21003 values, terminated with -1. */
21004
21005static int
aa8a0863 21006neon_alignment_bit (int size, int align, int *do_alignment, ...)
5287ad62
JB
21007{
21008 va_list ap;
21009 int result = FAIL, thissize, thisalign;
5f4273c7 21010
5287ad62
JB
21011 if (!inst.operands[1].immisalign)
21012 {
aa8a0863 21013 *do_alignment = 0;
5287ad62
JB
21014 return SUCCESS;
21015 }
5f4273c7 21016
aa8a0863 21017 va_start (ap, do_alignment);
5287ad62
JB
21018
21019 do
21020 {
21021 thissize = va_arg (ap, int);
21022 if (thissize == -1)
477330fc 21023 break;
5287ad62
JB
21024 thisalign = va_arg (ap, int);
21025
21026 if (size == thissize && align == thisalign)
477330fc 21027 result = SUCCESS;
5287ad62
JB
21028 }
21029 while (result != SUCCESS);
21030
21031 va_end (ap);
21032
21033 if (result == SUCCESS)
aa8a0863 21034 *do_alignment = 1;
5287ad62 21035 else
dcbf9037 21036 first_error (_("unsupported alignment for instruction"));
5f4273c7 21037
5287ad62
JB
21038 return result;
21039}
21040
21041static void
21042do_neon_ld_st_lane (void)
21043{
037e8744 21044 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 21045 int align_good, do_alignment = 0;
5287ad62
JB
21046 int logsize = neon_logbits (et.size);
21047 int align = inst.operands[1].imm >> 8;
21048 int n = (inst.instruction >> 8) & 3;
21049 int max_el = 64 / et.size;
5f4273c7 21050
dcbf9037
JB
21051 if (et.type == NT_invtype)
21052 return;
5f4273c7 21053
5287ad62 21054 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != n + 1,
477330fc 21055 _("bad list length"));
5287ad62 21056 constraint (NEON_LANE (inst.operands[0].imm) >= max_el,
477330fc 21057 _("scalar index out of range"));
5287ad62 21058 constraint (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2
477330fc
RM
21059 && et.size == 8,
21060 _("stride of 2 unavailable when element size is 8"));
5f4273c7 21061
5287ad62
JB
21062 switch (n)
21063 {
21064 case 0: /* VLD1 / VST1. */
aa8a0863 21065 align_good = neon_alignment_bit (et.size, align, &do_alignment, 16, 16,
477330fc 21066 32, 32, -1);
5287ad62 21067 if (align_good == FAIL)
477330fc 21068 return;
aa8a0863 21069 if (do_alignment)
477330fc
RM
21070 {
21071 unsigned alignbits = 0;
21072 switch (et.size)
21073 {
21074 case 16: alignbits = 0x1; break;
21075 case 32: alignbits = 0x3; break;
21076 default: ;
21077 }
21078 inst.instruction |= alignbits << 4;
21079 }
5287ad62
JB
21080 break;
21081
21082 case 1: /* VLD2 / VST2. */
aa8a0863
TS
21083 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 16,
21084 16, 32, 32, 64, -1);
5287ad62 21085 if (align_good == FAIL)
477330fc 21086 return;
aa8a0863 21087 if (do_alignment)
477330fc 21088 inst.instruction |= 1 << 4;
5287ad62
JB
21089 break;
21090
21091 case 2: /* VLD3 / VST3. */
21092 constraint (inst.operands[1].immisalign,
477330fc 21093 _("can't use alignment with this instruction"));
5287ad62
JB
21094 break;
21095
21096 case 3: /* VLD4 / VST4. */
aa8a0863 21097 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc 21098 16, 64, 32, 64, 32, 128, -1);
5287ad62 21099 if (align_good == FAIL)
477330fc 21100 return;
aa8a0863 21101 if (do_alignment)
477330fc
RM
21102 {
21103 unsigned alignbits = 0;
21104 switch (et.size)
21105 {
21106 case 8: alignbits = 0x1; break;
21107 case 16: alignbits = 0x1; break;
21108 case 32: alignbits = (align == 64) ? 0x1 : 0x2; break;
21109 default: ;
21110 }
21111 inst.instruction |= alignbits << 4;
21112 }
5287ad62
JB
21113 break;
21114
21115 default: ;
21116 }
21117
21118 /* Reg stride of 2 is encoded in bit 5 when size==16, bit 6 when size==32. */
21119 if (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2)
21120 inst.instruction |= 1 << (4 + logsize);
5f4273c7 21121
5287ad62
JB
21122 inst.instruction |= NEON_LANE (inst.operands[0].imm) << (logsize + 5);
21123 inst.instruction |= logsize << 10;
21124}
21125
21126/* Encode single n-element structure to all lanes VLD<n> instructions. */
21127
21128static void
21129do_neon_ld_dup (void)
21130{
037e8744 21131 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 21132 int align_good, do_alignment = 0;
5287ad62 21133
dcbf9037
JB
21134 if (et.type == NT_invtype)
21135 return;
21136
5287ad62
JB
21137 switch ((inst.instruction >> 8) & 3)
21138 {
21139 case 0: /* VLD1. */
9c2799c2 21140 gas_assert (NEON_REG_STRIDE (inst.operands[0].imm) != 2);
5287ad62 21141 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863 21142 &do_alignment, 16, 16, 32, 32, -1);
5287ad62 21143 if (align_good == FAIL)
477330fc 21144 return;
5287ad62 21145 switch (NEON_REGLIST_LENGTH (inst.operands[0].imm))
477330fc
RM
21146 {
21147 case 1: break;
21148 case 2: inst.instruction |= 1 << 5; break;
21149 default: first_error (_("bad list length")); return;
21150 }
5287ad62
JB
21151 inst.instruction |= neon_logbits (et.size) << 6;
21152 break;
21153
21154 case 1: /* VLD2. */
21155 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863
TS
21156 &do_alignment, 8, 16, 16, 32, 32, 64,
21157 -1);
5287ad62 21158 if (align_good == FAIL)
477330fc 21159 return;
5287ad62 21160 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2,
477330fc 21161 _("bad list length"));
5287ad62 21162 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 21163 inst.instruction |= 1 << 5;
5287ad62
JB
21164 inst.instruction |= neon_logbits (et.size) << 6;
21165 break;
21166
21167 case 2: /* VLD3. */
21168 constraint (inst.operands[1].immisalign,
477330fc 21169 _("can't use alignment with this instruction"));
5287ad62 21170 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 3,
477330fc 21171 _("bad list length"));
5287ad62 21172 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 21173 inst.instruction |= 1 << 5;
5287ad62
JB
21174 inst.instruction |= neon_logbits (et.size) << 6;
21175 break;
21176
21177 case 3: /* VLD4. */
21178 {
477330fc 21179 int align = inst.operands[1].imm >> 8;
aa8a0863 21180 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc
RM
21181 16, 64, 32, 64, 32, 128, -1);
21182 if (align_good == FAIL)
21183 return;
21184 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4,
21185 _("bad list length"));
21186 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
21187 inst.instruction |= 1 << 5;
21188 if (et.size == 32 && align == 128)
21189 inst.instruction |= 0x3 << 6;
21190 else
21191 inst.instruction |= neon_logbits (et.size) << 6;
5287ad62
JB
21192 }
21193 break;
21194
21195 default: ;
21196 }
21197
aa8a0863 21198 inst.instruction |= do_alignment << 4;
5287ad62
JB
21199}
21200
21201/* Disambiguate VLD<n> and VST<n> instructions, and fill in common bits (those
21202 apart from bits [11:4]. */
21203
21204static void
21205do_neon_ldx_stx (void)
21206{
b1a769ed
DG
21207 if (inst.operands[1].isreg)
21208 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
21209
5287ad62
JB
21210 switch (NEON_LANE (inst.operands[0].imm))
21211 {
21212 case NEON_INTERLEAVE_LANES:
88714cb8 21213 NEON_ENCODE (INTERLV, inst);
5287ad62
JB
21214 do_neon_ld_st_interleave ();
21215 break;
5f4273c7 21216
5287ad62 21217 case NEON_ALL_LANES:
88714cb8 21218 NEON_ENCODE (DUP, inst);
2d51fb74
JB
21219 if (inst.instruction == N_INV)
21220 {
21221 first_error ("only loads support such operands");
21222 break;
21223 }
5287ad62
JB
21224 do_neon_ld_dup ();
21225 break;
5f4273c7 21226
5287ad62 21227 default:
88714cb8 21228 NEON_ENCODE (LANE, inst);
5287ad62
JB
21229 do_neon_ld_st_lane ();
21230 }
21231
21232 /* L bit comes from bit mask. */
21233 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21234 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21235 inst.instruction |= inst.operands[1].reg << 16;
5f4273c7 21236
5287ad62
JB
21237 if (inst.operands[1].postind)
21238 {
21239 int postreg = inst.operands[1].imm & 0xf;
21240 constraint (!inst.operands[1].immisreg,
477330fc 21241 _("post-index must be a register"));
5287ad62 21242 constraint (postreg == 0xd || postreg == 0xf,
477330fc 21243 _("bad register for post-index"));
5287ad62
JB
21244 inst.instruction |= postreg;
21245 }
4f2374c7 21246 else
5287ad62 21247 {
4f2374c7 21248 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
e2b0ab59
AV
21249 constraint (inst.relocs[0].exp.X_op != O_constant
21250 || inst.relocs[0].exp.X_add_number != 0,
4f2374c7
WN
21251 BAD_ADDR_MODE);
21252
21253 if (inst.operands[1].writeback)
21254 {
21255 inst.instruction |= 0xd;
21256 }
21257 else
21258 inst.instruction |= 0xf;
5287ad62 21259 }
5f4273c7 21260
5287ad62
JB
21261 if (thumb_mode)
21262 inst.instruction |= 0xf9000000;
21263 else
21264 inst.instruction |= 0xf4000000;
21265}
33399f07
MGD
21266
21267/* FP v8. */
21268static void
21269do_vfp_nsyn_fpv8 (enum neon_shape rs)
21270{
a715796b
TG
21271 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
21272 D register operands. */
21273 if (neon_shape_class[rs] == SC_DOUBLE)
21274 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
21275 _(BAD_FPU));
21276
33399f07
MGD
21277 NEON_ENCODE (FPV8, inst);
21278
9db2f6b4
RL
21279 if (rs == NS_FFF || rs == NS_HHH)
21280 {
21281 do_vfp_sp_dyadic ();
21282
21283 /* ARMv8.2 fp16 instruction. */
21284 if (rs == NS_HHH)
21285 do_scalar_fp16_v82_encode ();
21286 }
33399f07
MGD
21287 else
21288 do_vfp_dp_rd_rn_rm ();
21289
21290 if (rs == NS_DDD)
21291 inst.instruction |= 0x100;
21292
21293 inst.instruction |= 0xf0000000;
21294}
21295
21296static void
21297do_vsel (void)
21298{
5ee91343 21299 set_pred_insn_type (OUTSIDE_PRED_INSN);
33399f07
MGD
21300
21301 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
21302 first_error (_("invalid instruction shape"));
21303}
21304
73924fbc
MGD
21305static void
21306do_vmaxnm (void)
21307{
935295b5
AV
21308 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
21309 set_pred_insn_type (OUTSIDE_PRED_INSN);
73924fbc
MGD
21310
21311 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
21312 return;
21313
5b7c81bd 21314 if (!check_simd_pred_availability (true, NEON_CHECK_CC | NEON_CHECK_ARCH8))
73924fbc
MGD
21315 return;
21316
cc933301 21317 neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
73924fbc
MGD
21318}
21319
30bdf752
MGD
21320static void
21321do_vrint_1 (enum neon_cvt_mode mode)
21322{
9db2f6b4 21323 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_QQ, NS_NULL);
30bdf752
MGD
21324 struct neon_type_el et;
21325
21326 if (rs == NS_NULL)
21327 return;
21328
a715796b
TG
21329 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
21330 D register operands. */
21331 if (neon_shape_class[rs] == SC_DOUBLE)
21332 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
21333 _(BAD_FPU));
21334
9db2f6b4
RL
21335 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY
21336 | N_VFP);
30bdf752
MGD
21337 if (et.type != NT_invtype)
21338 {
21339 /* VFP encodings. */
21340 if (mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
21341 || mode == neon_cvt_mode_p || mode == neon_cvt_mode_m)
5ee91343 21342 set_pred_insn_type (OUTSIDE_PRED_INSN);
30bdf752
MGD
21343
21344 NEON_ENCODE (FPV8, inst);
9db2f6b4 21345 if (rs == NS_FF || rs == NS_HH)
30bdf752
MGD
21346 do_vfp_sp_monadic ();
21347 else
21348 do_vfp_dp_rd_rm ();
21349
21350 switch (mode)
21351 {
21352 case neon_cvt_mode_r: inst.instruction |= 0x00000000; break;
21353 case neon_cvt_mode_z: inst.instruction |= 0x00000080; break;
21354 case neon_cvt_mode_x: inst.instruction |= 0x00010000; break;
21355 case neon_cvt_mode_a: inst.instruction |= 0xf0000000; break;
21356 case neon_cvt_mode_n: inst.instruction |= 0xf0010000; break;
21357 case neon_cvt_mode_p: inst.instruction |= 0xf0020000; break;
21358 case neon_cvt_mode_m: inst.instruction |= 0xf0030000; break;
21359 default: abort ();
21360 }
21361
21362 inst.instruction |= (rs == NS_DD) << 8;
21363 do_vfp_cond_or_thumb ();
9db2f6b4
RL
21364
21365 /* ARMv8.2 fp16 vrint instruction. */
21366 if (rs == NS_HH)
21367 do_scalar_fp16_v82_encode ();
30bdf752
MGD
21368 }
21369 else
21370 {
21371 /* Neon encodings (or something broken...). */
21372 inst.error = NULL;
cc933301 21373 et = neon_check_type (2, rs, N_EQK, N_F_16_32 | N_KEY);
30bdf752
MGD
21374
21375 if (et.type == NT_invtype)
21376 return;
21377
5b7c81bd 21378 if (!check_simd_pred_availability (true,
64c350f2 21379 NEON_CHECK_CC | NEON_CHECK_ARCH8))
30bdf752
MGD
21380 return;
21381
a710b305
AV
21382 NEON_ENCODE (FLOAT, inst);
21383
30bdf752
MGD
21384 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21385 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21386 inst.instruction |= LOW4 (inst.operands[1].reg);
21387 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
21388 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
21389 /* Mask off the original size bits and reencode them. */
21390 inst.instruction = ((inst.instruction & 0xfff3ffff)
21391 | neon_logbits (et.size) << 18);
21392
30bdf752
MGD
21393 switch (mode)
21394 {
21395 case neon_cvt_mode_z: inst.instruction |= 3 << 7; break;
21396 case neon_cvt_mode_x: inst.instruction |= 1 << 7; break;
21397 case neon_cvt_mode_a: inst.instruction |= 2 << 7; break;
21398 case neon_cvt_mode_n: inst.instruction |= 0 << 7; break;
21399 case neon_cvt_mode_p: inst.instruction |= 7 << 7; break;
21400 case neon_cvt_mode_m: inst.instruction |= 5 << 7; break;
21401 case neon_cvt_mode_r: inst.error = _("invalid rounding mode"); break;
21402 default: abort ();
21403 }
21404
21405 if (thumb_mode)
21406 inst.instruction |= 0xfc000000;
21407 else
21408 inst.instruction |= 0xf0000000;
21409 }
21410}
21411
21412static void
21413do_vrintx (void)
21414{
21415 do_vrint_1 (neon_cvt_mode_x);
21416}
21417
21418static void
21419do_vrintz (void)
21420{
21421 do_vrint_1 (neon_cvt_mode_z);
21422}
21423
21424static void
21425do_vrintr (void)
21426{
21427 do_vrint_1 (neon_cvt_mode_r);
21428}
21429
21430static void
21431do_vrinta (void)
21432{
21433 do_vrint_1 (neon_cvt_mode_a);
21434}
21435
21436static void
21437do_vrintn (void)
21438{
21439 do_vrint_1 (neon_cvt_mode_n);
21440}
21441
21442static void
21443do_vrintp (void)
21444{
21445 do_vrint_1 (neon_cvt_mode_p);
21446}
21447
21448static void
21449do_vrintm (void)
21450{
21451 do_vrint_1 (neon_cvt_mode_m);
21452}
21453
c28eeff2
SN
21454static unsigned
21455neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
21456{
21457 unsigned regno = NEON_SCALAR_REG (opnd);
21458 unsigned elno = NEON_SCALAR_INDEX (opnd);
21459
21460 if (elsize == 16 && elno < 2 && regno < 16)
21461 return regno | (elno << 4);
21462 else if (elsize == 32 && elno == 0)
21463 return regno;
21464
21465 first_error (_("scalar out of range"));
21466 return 0;
21467}
21468
21469static void
21470do_vcmla (void)
21471{
5d281bf0
AV
21472 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext)
21473 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
21474 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
21475 constraint (inst.relocs[0].exp.X_op != O_constant,
21476 _("expression too complex"));
21477 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
21478 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
21479 _("immediate out of range"));
21480 rot /= 90;
5d281bf0 21481
5b7c81bd 21482 if (!check_simd_pred_availability (true,
64c350f2 21483 NEON_CHECK_ARCH8 | NEON_CHECK_CC))
5d281bf0
AV
21484 return;
21485
c28eeff2
SN
21486 if (inst.operands[2].isscalar)
21487 {
5d281bf0
AV
21488 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
21489 first_error (_("invalid instruction shape"));
c28eeff2
SN
21490 enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
21491 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
21492 N_KEY | N_F16 | N_F32).size;
21493 unsigned m = neon_scalar_for_vcmla (inst.operands[2].reg, size);
21494 inst.is_neon = 1;
21495 inst.instruction = 0xfe000800;
21496 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21497 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21498 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
21499 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
21500 inst.instruction |= LOW4 (m);
21501 inst.instruction |= HI1 (m) << 5;
21502 inst.instruction |= neon_quad (rs) << 6;
21503 inst.instruction |= rot << 20;
21504 inst.instruction |= (size == 32) << 23;
21505 }
21506 else
21507 {
5d281bf0
AV
21508 enum neon_shape rs;
21509 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
21510 rs = neon_select_shape (NS_QQQI, NS_NULL);
21511 else
21512 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
21513
c28eeff2
SN
21514 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
21515 N_KEY | N_F16 | N_F32).size;
5d281bf0
AV
21516 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext) && size == 32
21517 && (inst.operands[0].reg == inst.operands[1].reg
21518 || inst.operands[0].reg == inst.operands[2].reg))
21519 as_tsktsk (BAD_MVE_SRCDEST);
21520
c28eeff2
SN
21521 neon_three_same (neon_quad (rs), 0, -1);
21522 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
21523 inst.instruction |= 0xfc200800;
21524 inst.instruction |= rot << 23;
21525 inst.instruction |= (size == 32) << 20;
21526 }
21527}
21528
21529static void
21530do_vcadd (void)
21531{
5d281bf0
AV
21532 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
21533 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
21534 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
21535 constraint (inst.relocs[0].exp.X_op != O_constant,
21536 _("expression too complex"));
5d281bf0 21537
e2b0ab59 21538 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2 21539 constraint (rot != 90 && rot != 270, _("immediate out of range"));
5d281bf0
AV
21540 enum neon_shape rs;
21541 struct neon_type_el et;
21542 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
21543 {
21544 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
21545 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32);
21546 }
21547 else
21548 {
21549 rs = neon_select_shape (NS_QQQI, NS_NULL);
21550 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32 | N_I8
21551 | N_I16 | N_I32);
21552 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
21553 as_tsktsk (_("Warning: 32-bit element size and same first and third "
21554 "operand makes instruction UNPREDICTABLE"));
21555 }
21556
21557 if (et.type == NT_invtype)
21558 return;
21559
64c350f2
AV
21560 if (!check_simd_pred_availability (et.type == NT_float,
21561 NEON_CHECK_ARCH8 | NEON_CHECK_CC))
5d281bf0
AV
21562 return;
21563
21564 if (et.type == NT_float)
21565 {
21566 neon_three_same (neon_quad (rs), 0, -1);
21567 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
21568 inst.instruction |= 0xfc800800;
21569 inst.instruction |= (rot == 270) << 24;
21570 inst.instruction |= (et.size == 32) << 20;
21571 }
21572 else
21573 {
21574 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
21575 inst.instruction = 0xfe000f00;
21576 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21577 inst.instruction |= neon_logbits (et.size) << 20;
21578 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
21579 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21580 inst.instruction |= (rot == 270) << 12;
21581 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
21582 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
21583 inst.instruction |= LOW4 (inst.operands[2].reg);
21584 inst.is_neon = 1;
21585 }
c28eeff2
SN
21586}
21587
c604a79a
JW
21588/* Dot Product instructions encoding support. */
21589
21590static void
21591do_neon_dotproduct (int unsigned_p)
21592{
21593 enum neon_shape rs;
21594 unsigned scalar_oprd2 = 0;
21595 int high8;
21596
21597 if (inst.cond != COND_ALWAYS)
21598 as_warn (_("Dot Product instructions cannot be conditional, the behaviour "
21599 "is UNPREDICTABLE"));
21600
21601 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
21602 _(BAD_FPU));
21603
21604 /* Dot Product instructions are in three-same D/Q register format or the third
21605 operand can be a scalar index register. */
21606 if (inst.operands[2].isscalar)
21607 {
21608 scalar_oprd2 = neon_scalar_for_mul (inst.operands[2].reg, 32);
21609 high8 = 0xfe000000;
21610 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21611 }
21612 else
21613 {
21614 high8 = 0xfc000000;
21615 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
21616 }
21617
21618 if (unsigned_p)
21619 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_U8);
21620 else
21621 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_S8);
21622
21623 /* The "U" bit in traditional Three Same encoding is fixed to 0 for Dot
21624 Product instruction, so we pass 0 as the "ubit" parameter. And the
21625 "Size" field are fixed to 0x2, so we pass 32 as the "size" parameter. */
21626 neon_three_same (neon_quad (rs), 0, 32);
21627
21628 /* Undo neon_dp_fixup. Dot Product instructions are using a slightly
21629 different NEON three-same encoding. */
21630 inst.instruction &= 0x00ffffff;
21631 inst.instruction |= high8;
21632 /* Encode 'U' bit which indicates signedness. */
21633 inst.instruction |= (unsigned_p ? 1 : 0) << 4;
21634 /* Re-encode operand2 if it's indexed scalar operand. What has been encoded
21635 from inst.operand[2].reg in neon_three_same is GAS's internal encoding, not
21636 the instruction encoding. */
21637 if (inst.operands[2].isscalar)
21638 {
21639 inst.instruction &= 0xffffffd0;
21640 inst.instruction |= LOW4 (scalar_oprd2);
21641 inst.instruction |= HI1 (scalar_oprd2) << 5;
21642 }
21643}
21644
21645/* Dot Product instructions for signed integer. */
21646
21647static void
21648do_neon_dotproduct_s (void)
21649{
21650 return do_neon_dotproduct (0);
21651}
21652
21653/* Dot Product instructions for unsigned integer. */
21654
21655static void
21656do_neon_dotproduct_u (void)
21657{
21658 return do_neon_dotproduct (1);
21659}
21660
616ce08e
MM
21661static void
21662do_vusdot (void)
21663{
21664 enum neon_shape rs;
21665 set_pred_insn_type (OUTSIDE_PRED_INSN);
21666 if (inst.operands[2].isscalar)
21667 {
21668 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21669 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21670
21671 inst.instruction |= (1 << 25);
1db66fb6
JB
21672 int idx = inst.operands[2].reg & 0xf;
21673 constraint ((idx != 1 && idx != 0), _("index must be 0 or 1"));
616ce08e
MM
21674 inst.operands[2].reg >>= 4;
21675 constraint (!(inst.operands[2].reg < 16),
21676 _("indexed register must be less than 16"));
21677 neon_three_args (rs == NS_QQS);
1db66fb6 21678 inst.instruction |= (idx << 5);
616ce08e
MM
21679 }
21680 else
21681 {
21682 inst.instruction |= (1 << 21);
21683 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
21684 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21685 neon_three_args (rs == NS_QQQ);
21686 }
21687}
21688
21689static void
21690do_vsudot (void)
21691{
21692 enum neon_shape rs;
21693 set_pred_insn_type (OUTSIDE_PRED_INSN);
21694 if (inst.operands[2].isscalar)
21695 {
21696 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21697 neon_check_type (3, rs, N_EQK, N_EQK, N_U8 | N_KEY);
21698
21699 inst.instruction |= (1 << 25);
1db66fb6
JB
21700 int idx = inst.operands[2].reg & 0xf;
21701 constraint ((idx != 1 && idx != 0), _("index must be 0 or 1"));
616ce08e
MM
21702 inst.operands[2].reg >>= 4;
21703 constraint (!(inst.operands[2].reg < 16),
21704 _("indexed register must be less than 16"));
21705 neon_three_args (rs == NS_QQS);
1db66fb6 21706 inst.instruction |= (idx << 5);
616ce08e
MM
21707 }
21708}
21709
21710static void
21711do_vsmmla (void)
21712{
21713 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
21714 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21715
21716 set_pred_insn_type (OUTSIDE_PRED_INSN);
21717
21718 neon_three_args (1);
21719
21720}
21721
21722static void
21723do_vummla (void)
21724{
21725 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
21726 neon_check_type (3, rs, N_EQK, N_EQK, N_U8 | N_KEY);
21727
21728 set_pred_insn_type (OUTSIDE_PRED_INSN);
21729
21730 neon_three_args (1);
21731
21732}
21733
4934a27c 21734static void
1db66fb6 21735check_cde_operand (size_t idx, int is_dual)
4934a27c 21736{
1db66fb6
JB
21737 unsigned Rx = inst.operands[idx].reg;
21738 bool isvec = inst.operands[idx].isvec;
4934a27c
MM
21739 if (is_dual == 0 && thumb_mode)
21740 constraint (
21741 !((Rx <= 14 && Rx != 13) || (Rx == REG_PC && isvec)),
21742 _("Register must be r0-r14 except r13, or APSR_nzcv."));
21743 else
21744 constraint ( !((Rx <= 10 && Rx % 2 == 0 )),
21745 _("Register must be an even register between r0-r10."));
21746}
21747
5b7c81bd 21748static bool
4934a27c
MM
21749cde_coproc_enabled (unsigned coproc)
21750{
21751 switch (coproc)
21752 {
21753 case 0: return mark_feature_used (&arm_ext_cde0);
21754 case 1: return mark_feature_used (&arm_ext_cde1);
21755 case 2: return mark_feature_used (&arm_ext_cde2);
21756 case 3: return mark_feature_used (&arm_ext_cde3);
21757 case 4: return mark_feature_used (&arm_ext_cde4);
21758 case 5: return mark_feature_used (&arm_ext_cde5);
21759 case 6: return mark_feature_used (&arm_ext_cde6);
21760 case 7: return mark_feature_used (&arm_ext_cde7);
5b7c81bd 21761 default: return false;
4934a27c
MM
21762 }
21763}
21764
21765#define cde_coproc_pos 8
21766static void
21767cde_handle_coproc (void)
21768{
21769 unsigned coproc = inst.operands[0].reg;
21770 constraint (coproc > 7, _("CDE Coprocessor must be in range 0-7"));
21771 constraint (!(cde_coproc_enabled (coproc)), BAD_CDE_COPROC);
21772 inst.instruction |= coproc << cde_coproc_pos;
21773}
21774#undef cde_coproc_pos
21775
21776static void
5b7c81bd 21777cxn_handle_predication (bool is_accum)
4934a27c 21778{
cceb53b8
MM
21779 if (is_accum && conditional_insn ())
21780 set_pred_insn_type (INSIDE_IT_INSN);
21781 else if (conditional_insn ())
21782 /* conditional_insn essentially checks for a suffix, not whether the
21783 instruction is inside an IT block or not.
21784 The non-accumulator versions should not have suffixes. */
4934a27c 21785 inst.error = BAD_SYNTAX;
4934a27c
MM
21786 else
21787 set_pred_insn_type (OUTSIDE_PRED_INSN);
21788}
21789
21790static void
5b7c81bd 21791do_custom_instruction_1 (int is_dual, bool is_accum)
4934a27c
MM
21792{
21793
21794 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21795
21796 unsigned imm, Rd;
21797
21798 Rd = inst.operands[1].reg;
21799 check_cde_operand (1, is_dual);
21800
21801 if (is_dual == 1)
21802 {
21803 constraint (inst.operands[2].reg != Rd + 1,
21804 _("cx1d requires consecutive destination registers."));
21805 imm = inst.operands[3].imm;
21806 }
21807 else if (is_dual == 0)
21808 imm = inst.operands[2].imm;
21809 else
21810 abort ();
21811
21812 inst.instruction |= Rd << 12;
21813 inst.instruction |= (imm & 0x1F80) << 9;
21814 inst.instruction |= (imm & 0x0040) << 1;
21815 inst.instruction |= (imm & 0x003f);
21816
21817 cde_handle_coproc ();
21818 cxn_handle_predication (is_accum);
21819}
21820
21821static void
5b7c81bd 21822do_custom_instruction_2 (int is_dual, bool is_accum)
4934a27c
MM
21823{
21824
21825 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21826
21827 unsigned imm, Rd, Rn;
21828
21829 Rd = inst.operands[1].reg;
21830
21831 if (is_dual == 1)
21832 {
21833 constraint (inst.operands[2].reg != Rd + 1,
21834 _("cx2d requires consecutive destination registers."));
21835 imm = inst.operands[4].imm;
21836 Rn = inst.operands[3].reg;
21837 }
21838 else if (is_dual == 0)
21839 {
21840 imm = inst.operands[3].imm;
21841 Rn = inst.operands[2].reg;
21842 }
21843 else
21844 abort ();
21845
21846 check_cde_operand (2 + is_dual, /* is_dual = */0);
21847 check_cde_operand (1, is_dual);
21848
21849 inst.instruction |= Rd << 12;
21850 inst.instruction |= Rn << 16;
21851
21852 inst.instruction |= (imm & 0x0380) << 13;
21853 inst.instruction |= (imm & 0x0040) << 1;
21854 inst.instruction |= (imm & 0x003f);
21855
21856 cde_handle_coproc ();
21857 cxn_handle_predication (is_accum);
21858}
21859
21860static void
5b7c81bd 21861do_custom_instruction_3 (int is_dual, bool is_accum)
4934a27c
MM
21862{
21863
21864 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21865
21866 unsigned imm, Rd, Rn, Rm;
21867
21868 Rd = inst.operands[1].reg;
21869
21870 if (is_dual == 1)
21871 {
21872 constraint (inst.operands[2].reg != Rd + 1,
21873 _("cx3d requires consecutive destination registers."));
21874 imm = inst.operands[5].imm;
21875 Rn = inst.operands[3].reg;
21876 Rm = inst.operands[4].reg;
21877 }
21878 else if (is_dual == 0)
21879 {
21880 imm = inst.operands[4].imm;
21881 Rn = inst.operands[2].reg;
21882 Rm = inst.operands[3].reg;
21883 }
21884 else
21885 abort ();
21886
21887 check_cde_operand (1, is_dual);
21888 check_cde_operand (2 + is_dual, /* is_dual = */0);
21889 check_cde_operand (3 + is_dual, /* is_dual = */0);
21890
21891 inst.instruction |= Rd;
21892 inst.instruction |= Rn << 16;
21893 inst.instruction |= Rm << 12;
21894
21895 inst.instruction |= (imm & 0x0038) << 17;
21896 inst.instruction |= (imm & 0x0004) << 5;
21897 inst.instruction |= (imm & 0x0003) << 4;
21898
21899 cde_handle_coproc ();
21900 cxn_handle_predication (is_accum);
21901}
21902
21903static void
21904do_cx1 (void)
21905{
21906 return do_custom_instruction_1 (0, 0);
21907}
21908
21909static void
21910do_cx1a (void)
21911{
21912 return do_custom_instruction_1 (0, 1);
21913}
21914
21915static void
21916do_cx1d (void)
21917{
21918 return do_custom_instruction_1 (1, 0);
21919}
21920
21921static void
21922do_cx1da (void)
21923{
21924 return do_custom_instruction_1 (1, 1);
21925}
21926
21927static void
21928do_cx2 (void)
21929{
21930 return do_custom_instruction_2 (0, 0);
21931}
21932
21933static void
21934do_cx2a (void)
21935{
21936 return do_custom_instruction_2 (0, 1);
21937}
21938
21939static void
21940do_cx2d (void)
21941{
21942 return do_custom_instruction_2 (1, 0);
21943}
21944
21945static void
21946do_cx2da (void)
21947{
21948 return do_custom_instruction_2 (1, 1);
21949}
21950
21951static void
21952do_cx3 (void)
21953{
21954 return do_custom_instruction_3 (0, 0);
21955}
21956
21957static void
21958do_cx3a (void)
21959{
21960 return do_custom_instruction_3 (0, 1);
21961}
21962
21963static void
21964do_cx3d (void)
21965{
21966 return do_custom_instruction_3 (1, 0);
21967}
21968
21969static void
21970do_cx3da (void)
21971{
21972 return do_custom_instruction_3 (1, 1);
21973}
21974
5aae9ae9
MM
21975static void
21976vcx_assign_vec_d (unsigned regnum)
21977{
21978 inst.instruction |= HI4 (regnum) << 12;
21979 inst.instruction |= LOW1 (regnum) << 22;
21980}
21981
21982static void
21983vcx_assign_vec_m (unsigned regnum)
21984{
21985 inst.instruction |= HI4 (regnum);
21986 inst.instruction |= LOW1 (regnum) << 5;
21987}
21988
21989static void
21990vcx_assign_vec_n (unsigned regnum)
21991{
21992 inst.instruction |= HI4 (regnum) << 16;
21993 inst.instruction |= LOW1 (regnum) << 7;
21994}
21995
21996enum vcx_reg_type {
21997 q_reg,
21998 d_reg,
21999 s_reg
22000};
22001
22002static enum vcx_reg_type
22003vcx_get_reg_type (enum neon_shape ns)
22004{
22005 gas_assert (ns == NS_PQI
22006 || ns == NS_PDI
22007 || ns == NS_PFI
22008 || ns == NS_PQQI
22009 || ns == NS_PDDI
22010 || ns == NS_PFFI
22011 || ns == NS_PQQQI
22012 || ns == NS_PDDDI
22013 || ns == NS_PFFFI);
22014 if (ns == NS_PQI || ns == NS_PQQI || ns == NS_PQQQI)
22015 return q_reg;
22016 if (ns == NS_PDI || ns == NS_PDDI || ns == NS_PDDDI)
22017 return d_reg;
22018 return s_reg;
22019}
22020
22021#define vcx_size_pos 24
22022#define vcx_vec_pos 6
22023static unsigned
22024vcx_handle_shape (enum vcx_reg_type reg_type)
22025{
22026 unsigned mult = 2;
22027 if (reg_type == q_reg)
22028 inst.instruction |= 1 << vcx_vec_pos;
22029 else if (reg_type == d_reg)
22030 inst.instruction |= 1 << vcx_size_pos;
22031 else
22032 mult = 1;
22033 /* NOTE:
22034 The documentation says that the Q registers are encoded as 2*N in the D:Vd
22035 bits (or equivalent for N and M registers).
22036 Similarly the D registers are encoded as N in D:Vd bits.
22037 While the S registers are encoded as N in the Vd:D bits.
22038
22039 Taking into account the maximum values of these registers we can see a
22040 nicer pattern for calculation:
22041 Q -> 7, D -> 15, S -> 31
22042
22043 If we say that everything is encoded in the Vd:D bits, then we can say
22044 that Q is encoded as 4*N, and D is encoded as 2*N.
22045 This way the bits will end up the same, and calculation is simpler.
22046 (calculation is now:
22047 1. Multiply by a number determined by the register letter.
22048 2. Encode resulting number in Vd:D bits.)
22049
22050 This is made a little more complicated by automatic handling of 'Q'
22051 registers elsewhere, which means the register number is already 2*N where
22052 N is the number the user wrote after the register letter.
22053 */
22054 return mult;
22055}
22056#undef vcx_vec_pos
22057#undef vcx_size_pos
22058
22059static void
22060vcx_ensure_register_in_range (unsigned R, enum vcx_reg_type reg_type)
22061{
22062 if (reg_type == q_reg)
22063 {
22064 gas_assert (R % 2 == 0);
22065 constraint (R >= 16, _("'q' register must be in range 0-7"));
22066 }
22067 else if (reg_type == d_reg)
22068 constraint (R >= 16, _("'d' register must be in range 0-15"));
22069 else
22070 constraint (R >= 32, _("'s' register must be in range 0-31"));
22071}
22072
22073static void (*vcx_assign_vec[3]) (unsigned) = {
22074 vcx_assign_vec_d,
22075 vcx_assign_vec_m,
22076 vcx_assign_vec_n
22077};
22078
22079static void
22080vcx_handle_register_arguments (unsigned num_registers,
22081 enum vcx_reg_type reg_type)
22082{
1ed818b4 22083 unsigned R, i;
5aae9ae9 22084 unsigned reg_mult = vcx_handle_shape (reg_type);
1ed818b4 22085 for (i = 0; i < num_registers; i++)
5aae9ae9
MM
22086 {
22087 R = inst.operands[i+1].reg;
22088 vcx_ensure_register_in_range (R, reg_type);
22089 if (num_registers == 3 && i > 0)
22090 {
22091 if (i == 2)
22092 vcx_assign_vec[1] (R * reg_mult);
22093 else
22094 vcx_assign_vec[2] (R * reg_mult);
22095 continue;
22096 }
22097 vcx_assign_vec[i](R * reg_mult);
22098 }
22099}
22100
22101static void
22102vcx_handle_insn_block (enum vcx_reg_type reg_type)
22103{
22104 if (reg_type == q_reg)
22105 if (inst.cond > COND_ALWAYS)
22106 inst.pred_insn_type = INSIDE_VPT_INSN;
22107 else
22108 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
22109 else if (inst.cond == COND_ALWAYS)
22110 inst.pred_insn_type = OUTSIDE_PRED_INSN;
22111 else
22112 inst.error = BAD_NOT_IT;
22113}
22114
22115static void
22116vcx_handle_common_checks (unsigned num_args, enum neon_shape rs)
22117{
22118 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
22119 cde_handle_coproc ();
22120 enum vcx_reg_type reg_type = vcx_get_reg_type (rs);
22121 vcx_handle_register_arguments (num_args, reg_type);
22122 vcx_handle_insn_block (reg_type);
22123 if (reg_type == q_reg)
22124 constraint (!mark_feature_used (&mve_ext),
22125 _("vcx instructions with Q registers require MVE"));
22126 else
22127 constraint (!(ARM_FSET_CPU_SUBSET (armv8m_fp, cpu_variant)
22128 && mark_feature_used (&armv8m_fp))
22129 && !mark_feature_used (&mve_ext),
22130 _("vcx instructions with S or D registers require either MVE"
ddc73fa9 22131 " or Armv8-M floating point extension."));
5aae9ae9
MM
22132}
22133
22134static void
22135do_vcx1 (void)
22136{
22137 enum neon_shape rs = neon_select_shape (NS_PQI, NS_PDI, NS_PFI, NS_NULL);
22138 vcx_handle_common_checks (1, rs);
22139
22140 unsigned imm = inst.operands[2].imm;
22141 inst.instruction |= (imm & 0x03f);
22142 inst.instruction |= (imm & 0x040) << 1;
22143 inst.instruction |= (imm & 0x780) << 9;
22144 if (rs != NS_PQI)
22145 constraint (imm >= 2048,
22146 _("vcx1 with S or D registers takes immediate within 0-2047"));
22147 inst.instruction |= (imm & 0x800) << 13;
22148}
22149
22150static void
22151do_vcx2 (void)
22152{
22153 enum neon_shape rs = neon_select_shape (NS_PQQI, NS_PDDI, NS_PFFI, NS_NULL);
22154 vcx_handle_common_checks (2, rs);
22155
22156 unsigned imm = inst.operands[3].imm;
22157 inst.instruction |= (imm & 0x01) << 4;
22158 inst.instruction |= (imm & 0x02) << 6;
22159 inst.instruction |= (imm & 0x3c) << 14;
22160 if (rs != NS_PQQI)
22161 constraint (imm >= 64,
22162 _("vcx2 with S or D registers takes immediate within 0-63"));
22163 inst.instruction |= (imm & 0x40) << 18;
22164}
22165
22166static void
22167do_vcx3 (void)
22168{
22169 enum neon_shape rs = neon_select_shape (NS_PQQQI, NS_PDDDI, NS_PFFFI, NS_NULL);
22170 vcx_handle_common_checks (3, rs);
22171
22172 unsigned imm = inst.operands[4].imm;
22173 inst.instruction |= (imm & 0x1) << 4;
22174 inst.instruction |= (imm & 0x6) << 19;
22175 if (rs != NS_PQQQI)
22176 constraint (imm >= 8,
22177 _("vcx2 with S or D registers takes immediate within 0-7"));
22178 inst.instruction |= (imm & 0x8) << 21;
22179}
22180
91ff7894
MGD
22181/* Crypto v1 instructions. */
22182static void
22183do_crypto_2op_1 (unsigned elttype, int op)
22184{
5ee91343 22185 set_pred_insn_type (OUTSIDE_PRED_INSN);
91ff7894
MGD
22186
22187 if (neon_check_type (2, NS_QQ, N_EQK | N_UNT, elttype | N_UNT | N_KEY).type
22188 == NT_invtype)
22189 return;
22190
22191 inst.error = NULL;
22192
22193 NEON_ENCODE (INTEGER, inst);
22194 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
22195 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
22196 inst.instruction |= LOW4 (inst.operands[1].reg);
22197 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
22198 if (op != -1)
22199 inst.instruction |= op << 6;
22200
22201 if (thumb_mode)
22202 inst.instruction |= 0xfc000000;
22203 else
22204 inst.instruction |= 0xf0000000;
22205}
22206
48adcd8e
MGD
22207static void
22208do_crypto_3op_1 (int u, int op)
22209{
5ee91343 22210 set_pred_insn_type (OUTSIDE_PRED_INSN);
48adcd8e
MGD
22211
22212 if (neon_check_type (3, NS_QQQ, N_EQK | N_UNT, N_EQK | N_UNT,
22213 N_32 | N_UNT | N_KEY).type == NT_invtype)
22214 return;
22215
22216 inst.error = NULL;
22217
22218 NEON_ENCODE (INTEGER, inst);
22219 neon_three_same (1, u, 8 << op);
22220}
22221
91ff7894
MGD
22222static void
22223do_aese (void)
22224{
22225 do_crypto_2op_1 (N_8, 0);
22226}
22227
22228static void
22229do_aesd (void)
22230{
22231 do_crypto_2op_1 (N_8, 1);
22232}
22233
22234static void
22235do_aesmc (void)
22236{
22237 do_crypto_2op_1 (N_8, 2);
22238}
22239
22240static void
22241do_aesimc (void)
22242{
22243 do_crypto_2op_1 (N_8, 3);
22244}
22245
48adcd8e
MGD
22246static void
22247do_sha1c (void)
22248{
22249 do_crypto_3op_1 (0, 0);
22250}
22251
22252static void
22253do_sha1p (void)
22254{
22255 do_crypto_3op_1 (0, 1);
22256}
22257
22258static void
22259do_sha1m (void)
22260{
22261 do_crypto_3op_1 (0, 2);
22262}
22263
22264static void
22265do_sha1su0 (void)
22266{
22267 do_crypto_3op_1 (0, 3);
22268}
91ff7894 22269
48adcd8e
MGD
22270static void
22271do_sha256h (void)
22272{
22273 do_crypto_3op_1 (1, 0);
22274}
22275
22276static void
22277do_sha256h2 (void)
22278{
22279 do_crypto_3op_1 (1, 1);
22280}
22281
22282static void
22283do_sha256su1 (void)
22284{
22285 do_crypto_3op_1 (1, 2);
22286}
3c9017d2
MGD
22287
22288static void
22289do_sha1h (void)
22290{
22291 do_crypto_2op_1 (N_32, -1);
22292}
22293
22294static void
22295do_sha1su1 (void)
22296{
22297 do_crypto_2op_1 (N_32, 0);
22298}
22299
22300static void
22301do_sha256su0 (void)
22302{
22303 do_crypto_2op_1 (N_32, 1);
22304}
dd5181d5
KT
22305
22306static void
22307do_crc32_1 (unsigned int poly, unsigned int sz)
22308{
22309 unsigned int Rd = inst.operands[0].reg;
22310 unsigned int Rn = inst.operands[1].reg;
22311 unsigned int Rm = inst.operands[2].reg;
22312
5ee91343 22313 set_pred_insn_type (OUTSIDE_PRED_INSN);
dd5181d5
KT
22314 inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
22315 inst.instruction |= LOW4 (Rn) << 16;
22316 inst.instruction |= LOW4 (Rm);
22317 inst.instruction |= sz << (thumb_mode ? 4 : 21);
22318 inst.instruction |= poly << (thumb_mode ? 20 : 9);
22319
22320 if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
22321 as_warn (UNPRED_REG ("r15"));
dd5181d5
KT
22322}
22323
22324static void
22325do_crc32b (void)
22326{
22327 do_crc32_1 (0, 0);
22328}
22329
22330static void
22331do_crc32h (void)
22332{
22333 do_crc32_1 (0, 1);
22334}
22335
22336static void
22337do_crc32w (void)
22338{
22339 do_crc32_1 (0, 2);
22340}
22341
22342static void
22343do_crc32cb (void)
22344{
22345 do_crc32_1 (1, 0);
22346}
22347
22348static void
22349do_crc32ch (void)
22350{
22351 do_crc32_1 (1, 1);
22352}
22353
22354static void
22355do_crc32cw (void)
22356{
22357 do_crc32_1 (1, 2);
22358}
22359
49e8a725
SN
22360static void
22361do_vjcvt (void)
22362{
22363 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
22364 _(BAD_FPU));
22365 neon_check_type (2, NS_FD, N_S32, N_F64);
22366 do_vfp_sp_dp_cvt ();
22367 do_vfp_cond_or_thumb ();
22368}
22369
aab2c27d
MM
22370static void
22371do_vdot (void)
22372{
22373 enum neon_shape rs;
22374 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
22375 set_pred_insn_type (OUTSIDE_PRED_INSN);
22376 if (inst.operands[2].isscalar)
22377 {
22378 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
22379 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22380
22381 inst.instruction |= (1 << 25);
1db66fb6
JB
22382 int idx = inst.operands[2].reg & 0xf;
22383 constraint ((idx != 1 && idx != 0), _("index must be 0 or 1"));
aab2c27d
MM
22384 inst.operands[2].reg >>= 4;
22385 constraint (!(inst.operands[2].reg < 16),
22386 _("indexed register must be less than 16"));
22387 neon_three_args (rs == NS_QQS);
1db66fb6 22388 inst.instruction |= (idx << 5);
aab2c27d
MM
22389 }
22390 else
22391 {
22392 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
22393 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22394 neon_three_args (rs == NS_QQQ);
22395 }
22396}
22397
22398static void
22399do_vmmla (void)
22400{
22401 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
22402 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22403
22404 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
22405 set_pred_insn_type (OUTSIDE_PRED_INSN);
22406
22407 neon_three_args (1);
22408}
22409
f1e1d7f3
AC
22410static void
22411do_t_pacbti (void)
22412{
22413 inst.instruction = THUMB_OP32 (inst.instruction);
22414}
22415
e07352fa
AC
22416static void
22417do_t_pacbti_nonop (void)
22418{
22419 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, pacbti_ext),
22420 _(BAD_PACBTI));
22421
22422 inst.instruction = THUMB_OP32 (inst.instruction);
22423 inst.instruction |= inst.operands[0].reg << 12;
22424 inst.instruction |= inst.operands[1].reg << 16;
22425 inst.instruction |= inst.operands[2].reg;
22426}
22427
5c43020d
AC
22428static void
22429do_t_pacbti_pacg (void)
22430{
22431 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, pacbti_ext),
22432 _(BAD_PACBTI));
22433
22434 inst.instruction = THUMB_OP32 (inst.instruction);
22435 inst.instruction |= inst.operands[0].reg << 8;
22436 inst.instruction |= inst.operands[1].reg << 16;
22437 inst.instruction |= inst.operands[2].reg;
22438}
22439
5287ad62
JB
22440\f
22441/* Overall per-instruction processing. */
22442
22443/* We need to be able to fix up arbitrary expressions in some statements.
22444 This is so that we can handle symbols that are an arbitrary distance from
22445 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
22446 which returns part of an address in a form which will be valid for
22447 a data instruction. We do this by pushing the expression into a symbol
22448 in the expr_section, and creating a fix for that. */
22449
22450static void
22451fix_new_arm (fragS * frag,
22452 int where,
22453 short int size,
22454 expressionS * exp,
22455 int pc_rel,
22456 int reloc)
22457{
22458 fixS * new_fix;
22459
22460 switch (exp->X_op)
22461 {
22462 case O_constant:
6e7ce2cd
PB
22463 if (pc_rel)
22464 {
22465 /* Create an absolute valued symbol, so we have something to
477330fc
RM
22466 refer to in the object file. Unfortunately for us, gas's
22467 generic expression parsing will already have folded out
22468 any use of .set foo/.type foo %function that may have
22469 been used to set type information of the target location,
22470 that's being specified symbolically. We have to presume
22471 the user knows what they are doing. */
6e7ce2cd
PB
22472 char name[16 + 8];
22473 symbolS *symbol;
22474
22475 sprintf (name, "*ABS*0x%lx", (unsigned long)exp->X_add_number);
22476
22477 symbol = symbol_find_or_make (name);
22478 S_SET_SEGMENT (symbol, absolute_section);
22479 symbol_set_frag (symbol, &zero_address_frag);
22480 S_SET_VALUE (symbol, exp->X_add_number);
22481 exp->X_op = O_symbol;
22482 exp->X_add_symbol = symbol;
22483 exp->X_add_number = 0;
22484 }
22485 /* FALLTHROUGH */
5287ad62
JB
22486 case O_symbol:
22487 case O_add:
22488 case O_subtract:
21d799b5 22489 new_fix = fix_new_exp (frag, where, size, exp, pc_rel,
477330fc 22490 (enum bfd_reloc_code_real) reloc);
5287ad62
JB
22491 break;
22492
22493 default:
21d799b5 22494 new_fix = (fixS *) fix_new (frag, where, size, make_expr_symbol (exp), 0,
477330fc 22495 pc_rel, (enum bfd_reloc_code_real) reloc);
5287ad62
JB
22496 break;
22497 }
22498
22499 /* Mark whether the fix is to a THUMB instruction, or an ARM
22500 instruction. */
22501 new_fix->tc_fix_data = thumb_mode;
22502}
22503
22504/* Create a frg for an instruction requiring relaxation. */
22505static void
22506output_relax_insn (void)
22507{
22508 char * to;
22509 symbolS *sym;
0110f2b8
PB
22510 int offset;
22511
6e1cb1a6
PB
22512 /* The size of the instruction is unknown, so tie the debug info to the
22513 start of the instruction. */
22514 dwarf2_emit_insn (0);
6e1cb1a6 22515
e2b0ab59 22516 switch (inst.relocs[0].exp.X_op)
0110f2b8
PB
22517 {
22518 case O_symbol:
e2b0ab59
AV
22519 sym = inst.relocs[0].exp.X_add_symbol;
22520 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
22521 break;
22522 case O_constant:
22523 sym = NULL;
e2b0ab59 22524 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
22525 break;
22526 default:
e2b0ab59 22527 sym = make_expr_symbol (&inst.relocs[0].exp);
0110f2b8
PB
22528 offset = 0;
22529 break;
22530 }
22531 to = frag_var (rs_machine_dependent, INSN_SIZE, THUMB_SIZE,
22532 inst.relax, sym, offset, NULL/*offset, opcode*/);
22533 md_number_to_chars (to, inst.instruction, THUMB_SIZE);
0110f2b8
PB
22534}
22535
22536/* Write a 32-bit thumb instruction to buf. */
22537static void
22538put_thumb32_insn (char * buf, unsigned long insn)
22539{
22540 md_number_to_chars (buf, insn >> 16, THUMB_SIZE);
22541 md_number_to_chars (buf + THUMB_SIZE, insn, THUMB_SIZE);
22542}
22543
b99bd4ef 22544static void
c19d1205 22545output_inst (const char * str)
b99bd4ef 22546{
c19d1205 22547 char * to = NULL;
b99bd4ef 22548
c19d1205 22549 if (inst.error)
b99bd4ef 22550 {
c19d1205 22551 as_bad ("%s -- `%s'", inst.error, str);
b99bd4ef
NC
22552 return;
22553 }
5f4273c7
NC
22554 if (inst.relax)
22555 {
22556 output_relax_insn ();
0110f2b8 22557 return;
5f4273c7 22558 }
c19d1205
ZW
22559 if (inst.size == 0)
22560 return;
b99bd4ef 22561
c19d1205 22562 to = frag_more (inst.size);
8dc2430f
NC
22563 /* PR 9814: Record the thumb mode into the current frag so that we know
22564 what type of NOP padding to use, if necessary. We override any previous
22565 setting so that if the mode has changed then the NOPS that we use will
22566 match the encoding of the last instruction in the frag. */
cd000bff 22567 frag_now->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
c19d1205
ZW
22568
22569 if (thumb_mode && (inst.size > THUMB_SIZE))
b99bd4ef 22570 {
9c2799c2 22571 gas_assert (inst.size == (2 * THUMB_SIZE));
0110f2b8 22572 put_thumb32_insn (to, inst.instruction);
b99bd4ef 22573 }
c19d1205 22574 else if (inst.size > INSN_SIZE)
b99bd4ef 22575 {
9c2799c2 22576 gas_assert (inst.size == (2 * INSN_SIZE));
c19d1205
ZW
22577 md_number_to_chars (to, inst.instruction, INSN_SIZE);
22578 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
b99bd4ef 22579 }
c19d1205
ZW
22580 else
22581 md_number_to_chars (to, inst.instruction, inst.size);
b99bd4ef 22582
e2b0ab59
AV
22583 int r;
22584 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
22585 {
22586 if (inst.relocs[r].type != BFD_RELOC_UNUSED)
22587 fix_new_arm (frag_now, to - frag_now->fr_literal,
22588 inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
22589 inst.relocs[r].type);
22590 }
b99bd4ef 22591
c19d1205 22592 dwarf2_emit_insn (inst.size);
c19d1205 22593}
b99bd4ef 22594
e07e6e58
NC
22595static char *
22596output_it_inst (int cond, int mask, char * to)
22597{
22598 unsigned long instruction = 0xbf00;
22599
22600 mask &= 0xf;
22601 instruction |= mask;
22602 instruction |= cond << 4;
22603
22604 if (to == NULL)
22605 {
22606 to = frag_more (2);
22607#ifdef OBJ_ELF
22608 dwarf2_emit_insn (2);
22609#endif
22610 }
22611
22612 md_number_to_chars (to, instruction, 2);
22613
22614 return to;
22615}
22616
c19d1205
ZW
22617/* Tag values used in struct asm_opcode's tag field. */
22618enum opcode_tag
22619{
22620 OT_unconditional, /* Instruction cannot be conditionalized.
22621 The ARM condition field is still 0xE. */
22622 OT_unconditionalF, /* Instruction cannot be conditionalized
22623 and carries 0xF in its ARM condition field. */
22624 OT_csuffix, /* Instruction takes a conditional suffix. */
5ee91343
AV
22625 OT_csuffixF, /* Some forms of the instruction take a scalar
22626 conditional suffix, others place 0xF where the
22627 condition field would be, others take a vector
22628 conditional suffix. */
c19d1205
ZW
22629 OT_cinfix3, /* Instruction takes a conditional infix,
22630 beginning at character index 3. (In
22631 unified mode, it becomes a suffix.) */
088fa78e
KH
22632 OT_cinfix3_deprecated, /* The same as OT_cinfix3. This is used for
22633 tsts, cmps, cmns, and teqs. */
e3cb604e
PB
22634 OT_cinfix3_legacy, /* Legacy instruction takes a conditional infix at
22635 character index 3, even in unified mode. Used for
22636 legacy instructions where suffix and infix forms
22637 may be ambiguous. */
c19d1205 22638 OT_csuf_or_in3, /* Instruction takes either a conditional
e3cb604e 22639 suffix or an infix at character index 3. */
c19d1205
ZW
22640 OT_odd_infix_unc, /* This is the unconditional variant of an
22641 instruction that takes a conditional infix
22642 at an unusual position. In unified mode,
22643 this variant will accept a suffix. */
22644 OT_odd_infix_0 /* Values greater than or equal to OT_odd_infix_0
22645 are the conditional variants of instructions that
22646 take conditional infixes in unusual positions.
22647 The infix appears at character index
22648 (tag - OT_odd_infix_0). These are not accepted
22649 in unified mode. */
22650};
b99bd4ef 22651
c19d1205
ZW
22652/* Subroutine of md_assemble, responsible for looking up the primary
22653 opcode from the mnemonic the user wrote. STR points to the
22654 beginning of the mnemonic.
22655
22656 This is not simply a hash table lookup, because of conditional
22657 variants. Most instructions have conditional variants, which are
22658 expressed with a _conditional affix_ to the mnemonic. If we were
22659 to encode each conditional variant as a literal string in the opcode
22660 table, it would have approximately 20,000 entries.
22661
22662 Most mnemonics take this affix as a suffix, and in unified syntax,
22663 'most' is upgraded to 'all'. However, in the divided syntax, some
22664 instructions take the affix as an infix, notably the s-variants of
22665 the arithmetic instructions. Of those instructions, all but six
22666 have the infix appear after the third character of the mnemonic.
22667
22668 Accordingly, the algorithm for looking up primary opcodes given
22669 an identifier is:
22670
22671 1. Look up the identifier in the opcode table.
22672 If we find a match, go to step U.
22673
22674 2. Look up the last two characters of the identifier in the
22675 conditions table. If we find a match, look up the first N-2
22676 characters of the identifier in the opcode table. If we
22677 find a match, go to step CE.
22678
22679 3. Look up the fourth and fifth characters of the identifier in
22680 the conditions table. If we find a match, extract those
22681 characters from the identifier, and look up the remaining
22682 characters in the opcode table. If we find a match, go
22683 to step CM.
22684
22685 4. Fail.
22686
22687 U. Examine the tag field of the opcode structure, in case this is
22688 one of the six instructions with its conditional infix in an
22689 unusual place. If it is, the tag tells us where to find the
22690 infix; look it up in the conditions table and set inst.cond
22691 accordingly. Otherwise, this is an unconditional instruction.
22692 Again set inst.cond accordingly. Return the opcode structure.
22693
22694 CE. Examine the tag field to make sure this is an instruction that
22695 should receive a conditional suffix. If it is not, fail.
22696 Otherwise, set inst.cond from the suffix we already looked up,
22697 and return the opcode structure.
22698
22699 CM. Examine the tag field to make sure this is an instruction that
22700 should receive a conditional infix after the third character.
22701 If it is not, fail. Otherwise, undo the edits to the current
22702 line of input and proceed as for case CE. */
22703
22704static const struct asm_opcode *
22705opcode_lookup (char **str)
22706{
22707 char *end, *base;
22708 char *affix;
22709 const struct asm_opcode *opcode;
22710 const struct asm_cond *cond;
e3cb604e 22711 char save[2];
c19d1205
ZW
22712
22713 /* Scan up to the end of the mnemonic, which must end in white space,
721a8186 22714 '.' (in unified mode, or for Neon/VFP instructions), or end of string. */
c19d1205 22715 for (base = end = *str; *end != '\0'; end++)
721a8186 22716 if (*end == ' ' || *end == '.')
c19d1205 22717 break;
b99bd4ef 22718
c19d1205 22719 if (end == base)
c921be7d 22720 return NULL;
b99bd4ef 22721
5287ad62 22722 /* Handle a possible width suffix and/or Neon type suffix. */
c19d1205 22723 if (end[0] == '.')
b99bd4ef 22724 {
5287ad62 22725 int offset = 2;
5f4273c7 22726
267d2029 22727 /* The .w and .n suffixes are only valid if the unified syntax is in
477330fc 22728 use. */
267d2029 22729 if (unified_syntax && end[1] == 'w')
c19d1205 22730 inst.size_req = 4;
267d2029 22731 else if (unified_syntax && end[1] == 'n')
c19d1205
ZW
22732 inst.size_req = 2;
22733 else
477330fc 22734 offset = 0;
5287ad62
JB
22735
22736 inst.vectype.elems = 0;
22737
22738 *str = end + offset;
b99bd4ef 22739
5f4273c7 22740 if (end[offset] == '.')
5287ad62 22741 {
267d2029 22742 /* See if we have a Neon type suffix (possible in either unified or
477330fc
RM
22743 non-unified ARM syntax mode). */
22744 if (parse_neon_type (&inst.vectype, str) == FAIL)
c921be7d 22745 return NULL;
477330fc 22746 }
5287ad62 22747 else if (end[offset] != '\0' && end[offset] != ' ')
477330fc 22748 return NULL;
b99bd4ef 22749 }
c19d1205
ZW
22750 else
22751 *str = end;
b99bd4ef 22752
c19d1205 22753 /* Look for unaffixed or special-case affixed mnemonic. */
629310ab 22754 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22755 end - base);
f3da8a96 22756 cond = NULL;
c19d1205 22757 if (opcode)
b99bd4ef 22758 {
c19d1205
ZW
22759 /* step U */
22760 if (opcode->tag < OT_odd_infix_0)
b99bd4ef 22761 {
c19d1205
ZW
22762 inst.cond = COND_ALWAYS;
22763 return opcode;
b99bd4ef 22764 }
b99bd4ef 22765
278df34e 22766 if (warn_on_deprecated && unified_syntax)
5c3696f8 22767 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205 22768 affix = base + (opcode->tag - OT_odd_infix_0);
629310ab 22769 cond = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, affix, 2);
9c2799c2 22770 gas_assert (cond);
b99bd4ef 22771
c19d1205
ZW
22772 inst.cond = cond->value;
22773 return opcode;
22774 }
5ee91343
AV
22775 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
22776 {
22777 /* Cannot have a conditional suffix on a mnemonic of less than a character.
22778 */
22779 if (end - base < 2)
22780 return NULL;
22781 affix = end - 1;
629310ab
ML
22782 cond = (const struct asm_cond *) str_hash_find_n (arm_vcond_hsh, affix, 1);
22783 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22784 affix - base);
656412a7
SMW
22785
22786 /* A known edge case is a conflict between an 'e' as a suffix for an
22787 Else of a VPT predication block and an 'ne' suffix for an IT block.
22788 If we detect that edge case here and we are not in a VPT VECTOR_PRED
22789 block, reset opcode and cond, so that the 'ne' case can be detected
22790 in the next section for 2-character conditional suffixes.
22791 An example where this is a problem is between the MVE 'vcvtn' and the
22792 non-MVE 'vcvt' instructions. */
22793 if (cond && opcode
22794 && cond->template_name[0] == 'e'
22795 && opcode->template_name[affix - base - 1] == 'n'
22796 && now_pred.type != VECTOR_PRED)
22797 {
22798 opcode = NULL;
22799 cond = NULL;
22800 }
22801
5ee91343
AV
22802 /* If this opcode can not be vector predicated then don't accept it with a
22803 vector predication code. */
22804 if (opcode && !opcode->mayBeVecPred)
22805 opcode = NULL;
22806 }
22807 if (!opcode || !cond)
22808 {
22809 /* Cannot have a conditional suffix on a mnemonic of less than two
22810 characters. */
22811 if (end - base < 3)
22812 return NULL;
b99bd4ef 22813
5ee91343
AV
22814 /* Look for suffixed mnemonic. */
22815 affix = end - 2;
629310ab
ML
22816 cond = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, affix, 2);
22817 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22818 affix - base);
5ee91343 22819 }
b99bd4ef 22820
c19d1205
ZW
22821 if (opcode && cond)
22822 {
22823 /* step CE */
22824 switch (opcode->tag)
22825 {
e3cb604e
PB
22826 case OT_cinfix3_legacy:
22827 /* Ignore conditional suffixes matched on infix only mnemonics. */
22828 break;
22829
c19d1205 22830 case OT_cinfix3:
088fa78e 22831 case OT_cinfix3_deprecated:
c19d1205
ZW
22832 case OT_odd_infix_unc:
22833 if (!unified_syntax)
0198d5e6 22834 return NULL;
1a0670f3 22835 /* Fall through. */
c19d1205
ZW
22836
22837 case OT_csuffix:
477330fc 22838 case OT_csuffixF:
c19d1205
ZW
22839 case OT_csuf_or_in3:
22840 inst.cond = cond->value;
22841 return opcode;
22842
22843 case OT_unconditional:
22844 case OT_unconditionalF:
dfa9f0d5 22845 if (thumb_mode)
c921be7d 22846 inst.cond = cond->value;
dfa9f0d5
PB
22847 else
22848 {
c921be7d 22849 /* Delayed diagnostic. */
dfa9f0d5
PB
22850 inst.error = BAD_COND;
22851 inst.cond = COND_ALWAYS;
22852 }
c19d1205 22853 return opcode;
b99bd4ef 22854
c19d1205 22855 default:
c921be7d 22856 return NULL;
c19d1205
ZW
22857 }
22858 }
b99bd4ef 22859
c19d1205
ZW
22860 /* Cannot have a usual-position infix on a mnemonic of less than
22861 six characters (five would be a suffix). */
22862 if (end - base < 6)
c921be7d 22863 return NULL;
b99bd4ef 22864
c19d1205
ZW
22865 /* Look for infixed mnemonic in the usual position. */
22866 affix = base + 3;
629310ab 22867 cond = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, affix, 2);
e3cb604e 22868 if (!cond)
c921be7d 22869 return NULL;
e3cb604e
PB
22870
22871 memcpy (save, affix, 2);
22872 memmove (affix, affix + 2, (end - affix) - 2);
629310ab 22873 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22874 (end - base) - 2);
e3cb604e
PB
22875 memmove (affix + 2, affix, (end - affix) - 2);
22876 memcpy (affix, save, 2);
22877
088fa78e
KH
22878 if (opcode
22879 && (opcode->tag == OT_cinfix3
22880 || opcode->tag == OT_cinfix3_deprecated
22881 || opcode->tag == OT_csuf_or_in3
22882 || opcode->tag == OT_cinfix3_legacy))
b99bd4ef 22883 {
c921be7d 22884 /* Step CM. */
278df34e 22885 if (warn_on_deprecated && unified_syntax
088fa78e
KH
22886 && (opcode->tag == OT_cinfix3
22887 || opcode->tag == OT_cinfix3_deprecated))
5c3696f8 22888 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205
ZW
22889
22890 inst.cond = cond->value;
22891 return opcode;
b99bd4ef
NC
22892 }
22893
c921be7d 22894 return NULL;
b99bd4ef
NC
22895}
22896
e07e6e58
NC
22897/* This function generates an initial IT instruction, leaving its block
22898 virtually open for the new instructions. Eventually,
5ee91343 22899 the mask will be updated by now_pred_add_mask () each time
e07e6e58
NC
22900 a new instruction needs to be included in the IT block.
22901 Finally, the block is closed with close_automatic_it_block ().
22902 The block closure can be requested either from md_assemble (),
22903 a tencode (), or due to a label hook. */
22904
22905static void
22906new_automatic_it_block (int cond)
22907{
5ee91343
AV
22908 now_pred.state = AUTOMATIC_PRED_BLOCK;
22909 now_pred.mask = 0x18;
22910 now_pred.cc = cond;
22911 now_pred.block_length = 1;
cd000bff 22912 mapping_state (MAP_THUMB);
5ee91343 22913 now_pred.insn = output_it_inst (cond, now_pred.mask, NULL);
5b7c81bd
AM
22914 now_pred.warn_deprecated = false;
22915 now_pred.insn_cond = true;
e07e6e58
NC
22916}
22917
22918/* Close an automatic IT block.
22919 See comments in new_automatic_it_block (). */
22920
22921static void
22922close_automatic_it_block (void)
22923{
5ee91343
AV
22924 now_pred.mask = 0x10;
22925 now_pred.block_length = 0;
e07e6e58
NC
22926}
22927
22928/* Update the mask of the current automatically-generated IT
22929 instruction. See comments in new_automatic_it_block (). */
22930
22931static void
5ee91343 22932now_pred_add_mask (int cond)
e07e6e58
NC
22933{
22934#define CLEAR_BIT(value, nbit) ((value) & ~(1 << (nbit)))
22935#define SET_BIT_VALUE(value, bitvalue, nbit) (CLEAR_BIT (value, nbit) \
477330fc 22936 | ((bitvalue) << (nbit)))
e07e6e58 22937 const int resulting_bit = (cond & 1);
c921be7d 22938
5ee91343
AV
22939 now_pred.mask &= 0xf;
22940 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 22941 resulting_bit,
5ee91343
AV
22942 (5 - now_pred.block_length));
22943 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 22944 1,
5ee91343
AV
22945 ((5 - now_pred.block_length) - 1));
22946 output_it_inst (now_pred.cc, now_pred.mask, now_pred.insn);
e07e6e58
NC
22947
22948#undef CLEAR_BIT
22949#undef SET_BIT_VALUE
e07e6e58
NC
22950}
22951
22952/* The IT blocks handling machinery is accessed through the these functions:
22953 it_fsm_pre_encode () from md_assemble ()
5ee91343
AV
22954 set_pred_insn_type () optional, from the tencode functions
22955 set_pred_insn_type_last () ditto
22956 in_pred_block () ditto
e07e6e58 22957 it_fsm_post_encode () from md_assemble ()
33eaf5de 22958 force_automatic_it_block_close () from label handling functions
e07e6e58
NC
22959
22960 Rationale:
22961 1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
477330fc
RM
22962 initializing the IT insn type with a generic initial value depending
22963 on the inst.condition.
e07e6e58 22964 2) During the tencode function, two things may happen:
477330fc 22965 a) The tencode function overrides the IT insn type by
5ee91343
AV
22966 calling either set_pred_insn_type (type) or
22967 set_pred_insn_type_last ().
477330fc 22968 b) The tencode function queries the IT block state by
5ee91343 22969 calling in_pred_block () (i.e. to determine narrow/not narrow mode).
477330fc 22970
5ee91343
AV
22971 Both set_pred_insn_type and in_pred_block run the internal FSM state
22972 handling function (handle_pred_state), because: a) setting the IT insn
477330fc
RM
22973 type may incur in an invalid state (exiting the function),
22974 and b) querying the state requires the FSM to be updated.
22975 Specifically we want to avoid creating an IT block for conditional
22976 branches, so it_fsm_pre_encode is actually a guess and we can't
22977 determine whether an IT block is required until the tencode () routine
22978 has decided what type of instruction this actually it.
5ee91343
AV
22979 Because of this, if set_pred_insn_type and in_pred_block have to be
22980 used, set_pred_insn_type has to be called first.
477330fc 22981
5ee91343
AV
22982 set_pred_insn_type_last () is a wrapper of set_pred_insn_type (type),
22983 that determines the insn IT type depending on the inst.cond code.
477330fc
RM
22984 When a tencode () routine encodes an instruction that can be
22985 either outside an IT block, or, in the case of being inside, has to be
5ee91343 22986 the last one, set_pred_insn_type_last () will determine the proper
477330fc 22987 IT instruction type based on the inst.cond code. Otherwise,
5ee91343 22988 set_pred_insn_type can be called for overriding that logic or
477330fc
RM
22989 for covering other cases.
22990
5ee91343
AV
22991 Calling handle_pred_state () may not transition the IT block state to
22992 OUTSIDE_PRED_BLOCK immediately, since the (current) state could be
477330fc 22993 still queried. Instead, if the FSM determines that the state should
5ee91343 22994 be transitioned to OUTSIDE_PRED_BLOCK, a flag is marked to be closed
477330fc
RM
22995 after the tencode () function: that's what it_fsm_post_encode () does.
22996
5ee91343 22997 Since in_pred_block () calls the state handling function to get an
477330fc
RM
22998 updated state, an error may occur (due to invalid insns combination).
22999 In that case, inst.error is set.
23000 Therefore, inst.error has to be checked after the execution of
23001 the tencode () routine.
e07e6e58
NC
23002
23003 3) Back in md_assemble(), it_fsm_post_encode () is called to commit
477330fc 23004 any pending state change (if any) that didn't take place in
5ee91343 23005 handle_pred_state () as explained above. */
e07e6e58
NC
23006
23007static void
23008it_fsm_pre_encode (void)
23009{
23010 if (inst.cond != COND_ALWAYS)
5ee91343 23011 inst.pred_insn_type = INSIDE_IT_INSN;
e07e6e58 23012 else
5ee91343 23013 inst.pred_insn_type = OUTSIDE_PRED_INSN;
e07e6e58 23014
5ee91343 23015 now_pred.state_handled = 0;
e07e6e58
NC
23016}
23017
23018/* IT state FSM handling function. */
5ee91343
AV
23019/* MVE instructions and non-MVE instructions are handled differently because of
23020 the introduction of VPT blocks.
23021 Specifications say that any non-MVE instruction inside a VPT block is
23022 UNPREDICTABLE, with the exception of the BKPT instruction. Whereas most MVE
23023 instructions are deemed to be UNPREDICTABLE if inside an IT block. For the
35c228db 23024 few exceptions we have MVE_UNPREDICABLE_INSN.
5ee91343
AV
23025 The error messages provided depending on the different combinations possible
23026 are described in the cases below:
23027 For 'most' MVE instructions:
23028 1) In an IT block, with an IT code: syntax error
23029 2) In an IT block, with a VPT code: error: must be in a VPT block
23030 3) In an IT block, with no code: warning: UNPREDICTABLE
23031 4) In a VPT block, with an IT code: syntax error
23032 5) In a VPT block, with a VPT code: OK!
23033 6) In a VPT block, with no code: error: missing code
23034 7) Outside a pred block, with an IT code: error: syntax error
23035 8) Outside a pred block, with a VPT code: error: should be in a VPT block
23036 9) Outside a pred block, with no code: OK!
23037 For non-MVE instructions:
23038 10) In an IT block, with an IT code: OK!
23039 11) In an IT block, with a VPT code: syntax error
23040 12) In an IT block, with no code: error: missing code
23041 13) In a VPT block, with an IT code: error: should be in an IT block
23042 14) In a VPT block, with a VPT code: syntax error
23043 15) In a VPT block, with no code: UNPREDICTABLE
23044 16) Outside a pred block, with an IT code: error: should be in an IT block
23045 17) Outside a pred block, with a VPT code: syntax error
23046 18) Outside a pred block, with no code: OK!
23047 */
23048
e07e6e58
NC
23049
23050static int
5ee91343 23051handle_pred_state (void)
e07e6e58 23052{
5ee91343 23053 now_pred.state_handled = 1;
5b7c81bd 23054 now_pred.insn_cond = false;
e07e6e58 23055
5ee91343 23056 switch (now_pred.state)
e07e6e58 23057 {
5ee91343
AV
23058 case OUTSIDE_PRED_BLOCK:
23059 switch (inst.pred_insn_type)
e07e6e58 23060 {
35c228db 23061 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
23062 case MVE_OUTSIDE_PRED_INSN:
23063 if (inst.cond < COND_ALWAYS)
23064 {
23065 /* Case 7: Outside a pred block, with an IT code: error: syntax
23066 error. */
23067 inst.error = BAD_SYNTAX;
23068 return FAIL;
23069 }
23070 /* Case 9: Outside a pred block, with no code: OK! */
23071 break;
23072 case OUTSIDE_PRED_INSN:
23073 if (inst.cond > COND_ALWAYS)
23074 {
23075 /* Case 17: Outside a pred block, with a VPT code: syntax error.
23076 */
23077 inst.error = BAD_SYNTAX;
23078 return FAIL;
23079 }
23080 /* Case 18: Outside a pred block, with no code: OK! */
e07e6e58
NC
23081 break;
23082
5ee91343
AV
23083 case INSIDE_VPT_INSN:
23084 /* Case 8: Outside a pred block, with a VPT code: error: should be in
23085 a VPT block. */
23086 inst.error = BAD_OUT_VPT;
23087 return FAIL;
23088
e07e6e58
NC
23089 case INSIDE_IT_INSN:
23090 case INSIDE_IT_LAST_INSN:
5ee91343 23091 if (inst.cond < COND_ALWAYS)
e07e6e58 23092 {
5ee91343
AV
23093 /* Case 16: Outside a pred block, with an IT code: error: should
23094 be in an IT block. */
23095 if (thumb_mode == 0)
e07e6e58 23096 {
5ee91343
AV
23097 if (unified_syntax
23098 && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
23099 as_tsktsk (_("Warning: conditional outside an IT block"\
23100 " for Thumb."));
e07e6e58
NC
23101 }
23102 else
23103 {
5ee91343
AV
23104 if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
23105 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
23106 {
23107 /* Automatically generate the IT instruction. */
23108 new_automatic_it_block (inst.cond);
23109 if (inst.pred_insn_type == INSIDE_IT_LAST_INSN)
23110 close_automatic_it_block ();
23111 }
23112 else
23113 {
23114 inst.error = BAD_OUT_IT;
23115 return FAIL;
23116 }
e07e6e58 23117 }
5ee91343 23118 break;
e07e6e58 23119 }
5ee91343
AV
23120 else if (inst.cond > COND_ALWAYS)
23121 {
23122 /* Case 17: Outside a pred block, with a VPT code: syntax error.
23123 */
23124 inst.error = BAD_SYNTAX;
23125 return FAIL;
23126 }
23127 else
23128 gas_assert (0);
e07e6e58
NC
23129 case IF_INSIDE_IT_LAST_INSN:
23130 case NEUTRAL_IT_INSN:
23131 break;
23132
5ee91343
AV
23133 case VPT_INSN:
23134 if (inst.cond != COND_ALWAYS)
23135 first_error (BAD_SYNTAX);
23136 now_pred.state = MANUAL_PRED_BLOCK;
23137 now_pred.block_length = 0;
23138 now_pred.type = VECTOR_PRED;
23139 now_pred.cc = 0;
23140 break;
e07e6e58 23141 case IT_INSN:
5ee91343
AV
23142 now_pred.state = MANUAL_PRED_BLOCK;
23143 now_pred.block_length = 0;
23144 now_pred.type = SCALAR_PRED;
e07e6e58
NC
23145 break;
23146 }
23147 break;
23148
5ee91343 23149 case AUTOMATIC_PRED_BLOCK:
e07e6e58
NC
23150 /* Three things may happen now:
23151 a) We should increment current it block size;
23152 b) We should close current it block (closing insn or 4 insns);
23153 c) We should close current it block and start a new one (due
23154 to incompatible conditions or
23155 4 insns-length block reached). */
23156
5ee91343 23157 switch (inst.pred_insn_type)
e07e6e58 23158 {
5ee91343
AV
23159 case INSIDE_VPT_INSN:
23160 case VPT_INSN:
35c228db 23161 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
23162 case MVE_OUTSIDE_PRED_INSN:
23163 gas_assert (0);
23164 case OUTSIDE_PRED_INSN:
2b0f3761 23165 /* The closure of the block shall happen immediately,
5ee91343 23166 so any in_pred_block () call reports the block as closed. */
e07e6e58
NC
23167 force_automatic_it_block_close ();
23168 break;
23169
23170 case INSIDE_IT_INSN:
23171 case INSIDE_IT_LAST_INSN:
23172 case IF_INSIDE_IT_LAST_INSN:
5ee91343 23173 now_pred.block_length++;
e07e6e58 23174
5ee91343
AV
23175 if (now_pred.block_length > 4
23176 || !now_pred_compatible (inst.cond))
e07e6e58
NC
23177 {
23178 force_automatic_it_block_close ();
5ee91343 23179 if (inst.pred_insn_type != IF_INSIDE_IT_LAST_INSN)
e07e6e58
NC
23180 new_automatic_it_block (inst.cond);
23181 }
23182 else
23183 {
5b7c81bd 23184 now_pred.insn_cond = true;
5ee91343 23185 now_pred_add_mask (inst.cond);
e07e6e58
NC
23186 }
23187
5ee91343
AV
23188 if (now_pred.state == AUTOMATIC_PRED_BLOCK
23189 && (inst.pred_insn_type == INSIDE_IT_LAST_INSN
23190 || inst.pred_insn_type == IF_INSIDE_IT_LAST_INSN))
e07e6e58
NC
23191 close_automatic_it_block ();
23192 break;
23193
4934a27c 23194 /* Fallthrough. */
e07e6e58 23195 case NEUTRAL_IT_INSN:
5ee91343 23196 now_pred.block_length++;
5b7c81bd 23197 now_pred.insn_cond = true;
e07e6e58 23198
5ee91343 23199 if (now_pred.block_length > 4)
e07e6e58
NC
23200 force_automatic_it_block_close ();
23201 else
5ee91343 23202 now_pred_add_mask (now_pred.cc & 1);
e07e6e58
NC
23203 break;
23204
23205 case IT_INSN:
23206 close_automatic_it_block ();
5ee91343 23207 now_pred.state = MANUAL_PRED_BLOCK;
e07e6e58
NC
23208 break;
23209 }
23210 break;
23211
5ee91343 23212 case MANUAL_PRED_BLOCK:
e07e6e58 23213 {
7af67752
AM
23214 unsigned int cond;
23215 int is_last;
5ee91343 23216 if (now_pred.type == SCALAR_PRED)
e07e6e58 23217 {
5ee91343
AV
23218 /* Check conditional suffixes. */
23219 cond = now_pred.cc ^ ((now_pred.mask >> 4) & 1) ^ 1;
23220 now_pred.mask <<= 1;
23221 now_pred.mask &= 0x1f;
23222 is_last = (now_pred.mask == 0x10);
23223 }
23224 else
23225 {
23226 now_pred.cc ^= (now_pred.mask >> 4);
23227 cond = now_pred.cc + 0xf;
23228 now_pred.mask <<= 1;
23229 now_pred.mask &= 0x1f;
23230 is_last = now_pred.mask == 0x10;
23231 }
5b7c81bd 23232 now_pred.insn_cond = true;
e07e6e58 23233
5ee91343
AV
23234 switch (inst.pred_insn_type)
23235 {
23236 case OUTSIDE_PRED_INSN:
23237 if (now_pred.type == SCALAR_PRED)
23238 {
23239 if (inst.cond == COND_ALWAYS)
23240 {
23241 /* Case 12: In an IT block, with no code: error: missing
23242 code. */
23243 inst.error = BAD_NOT_IT;
23244 return FAIL;
23245 }
23246 else if (inst.cond > COND_ALWAYS)
23247 {
23248 /* Case 11: In an IT block, with a VPT code: syntax error.
23249 */
23250 inst.error = BAD_SYNTAX;
23251 return FAIL;
23252 }
23253 else if (thumb_mode)
23254 {
23255 /* This is for some special cases where a non-MVE
23256 instruction is not allowed in an IT block, such as cbz,
23257 but are put into one with a condition code.
23258 You could argue this should be a syntax error, but we
23259 gave the 'not allowed in IT block' diagnostic in the
23260 past so we will keep doing so. */
23261 inst.error = BAD_NOT_IT;
23262 return FAIL;
23263 }
23264 break;
23265 }
23266 else
23267 {
23268 /* Case 15: In a VPT block, with no code: UNPREDICTABLE. */
23269 as_tsktsk (MVE_NOT_VPT);
23270 return SUCCESS;
23271 }
23272 case MVE_OUTSIDE_PRED_INSN:
23273 if (now_pred.type == SCALAR_PRED)
23274 {
23275 if (inst.cond == COND_ALWAYS)
23276 {
23277 /* Case 3: In an IT block, with no code: warning:
23278 UNPREDICTABLE. */
23279 as_tsktsk (MVE_NOT_IT);
23280 return SUCCESS;
23281 }
23282 else if (inst.cond < COND_ALWAYS)
23283 {
23284 /* Case 1: In an IT block, with an IT code: syntax error.
23285 */
23286 inst.error = BAD_SYNTAX;
23287 return FAIL;
23288 }
23289 else
23290 gas_assert (0);
23291 }
23292 else
23293 {
23294 if (inst.cond < COND_ALWAYS)
23295 {
23296 /* Case 4: In a VPT block, with an IT code: syntax error.
23297 */
23298 inst.error = BAD_SYNTAX;
23299 return FAIL;
23300 }
23301 else if (inst.cond == COND_ALWAYS)
23302 {
23303 /* Case 6: In a VPT block, with no code: error: missing
23304 code. */
23305 inst.error = BAD_NOT_VPT;
23306 return FAIL;
23307 }
23308 else
23309 {
23310 gas_assert (0);
23311 }
23312 }
35c228db
AV
23313 case MVE_UNPREDICABLE_INSN:
23314 as_tsktsk (now_pred.type == SCALAR_PRED ? MVE_NOT_IT : MVE_NOT_VPT);
23315 return SUCCESS;
e07e6e58 23316 case INSIDE_IT_INSN:
5ee91343 23317 if (inst.cond > COND_ALWAYS)
e07e6e58 23318 {
5ee91343
AV
23319 /* Case 11: In an IT block, with a VPT code: syntax error. */
23320 /* Case 14: In a VPT block, with a VPT code: syntax error. */
23321 inst.error = BAD_SYNTAX;
23322 return FAIL;
23323 }
23324 else if (now_pred.type == SCALAR_PRED)
23325 {
23326 /* Case 10: In an IT block, with an IT code: OK! */
23327 if (cond != inst.cond)
23328 {
23329 inst.error = now_pred.type == SCALAR_PRED ? BAD_IT_COND :
23330 BAD_VPT_COND;
23331 return FAIL;
23332 }
23333 }
23334 else
23335 {
23336 /* Case 13: In a VPT block, with an IT code: error: should be
23337 in an IT block. */
23338 inst.error = BAD_OUT_IT;
e07e6e58
NC
23339 return FAIL;
23340 }
23341 break;
23342
5ee91343
AV
23343 case INSIDE_VPT_INSN:
23344 if (now_pred.type == SCALAR_PRED)
23345 {
23346 /* Case 2: In an IT block, with a VPT code: error: must be in a
23347 VPT block. */
23348 inst.error = BAD_OUT_VPT;
23349 return FAIL;
23350 }
23351 /* Case 5: In a VPT block, with a VPT code: OK! */
23352 else if (cond != inst.cond)
23353 {
23354 inst.error = BAD_VPT_COND;
23355 return FAIL;
23356 }
23357 break;
e07e6e58
NC
23358 case INSIDE_IT_LAST_INSN:
23359 case IF_INSIDE_IT_LAST_INSN:
5ee91343
AV
23360 if (now_pred.type == VECTOR_PRED || inst.cond > COND_ALWAYS)
23361 {
23362 /* Case 4: In a VPT block, with an IT code: syntax error. */
23363 /* Case 11: In an IT block, with a VPT code: syntax error. */
23364 inst.error = BAD_SYNTAX;
23365 return FAIL;
23366 }
23367 else if (cond != inst.cond)
e07e6e58
NC
23368 {
23369 inst.error = BAD_IT_COND;
23370 return FAIL;
23371 }
23372 if (!is_last)
23373 {
23374 inst.error = BAD_BRANCH;
23375 return FAIL;
23376 }
23377 break;
23378
23379 case NEUTRAL_IT_INSN:
5ee91343
AV
23380 /* The BKPT instruction is unconditional even in a IT or VPT
23381 block. */
e07e6e58
NC
23382 break;
23383
23384 case IT_INSN:
5ee91343
AV
23385 if (now_pred.type == SCALAR_PRED)
23386 {
23387 inst.error = BAD_IT_IT;
23388 return FAIL;
23389 }
23390 /* fall through. */
23391 case VPT_INSN:
23392 if (inst.cond == COND_ALWAYS)
23393 {
23394 /* Executing a VPT/VPST instruction inside an IT block or a
23395 VPT/VPST/IT instruction inside a VPT block is UNPREDICTABLE.
23396 */
23397 if (now_pred.type == SCALAR_PRED)
23398 as_tsktsk (MVE_NOT_IT);
23399 else
23400 as_tsktsk (MVE_NOT_VPT);
23401 return SUCCESS;
23402 }
23403 else
23404 {
23405 /* VPT/VPST do not accept condition codes. */
23406 inst.error = BAD_SYNTAX;
23407 return FAIL;
23408 }
e07e6e58 23409 }
5ee91343 23410 }
e07e6e58
NC
23411 break;
23412 }
23413
23414 return SUCCESS;
23415}
23416
5a01bb1d
MGD
23417struct depr_insn_mask
23418{
23419 unsigned long pattern;
23420 unsigned long mask;
23421 const char* description;
23422};
23423
23424/* List of 16-bit instruction patterns deprecated in an IT block in
23425 ARMv8. */
23426static const struct depr_insn_mask depr_it_insns[] = {
23427 { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
23428 { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
23429 { 0xa000, 0xb800, N_("ADR") },
23430 { 0x4800, 0xf800, N_("Literal loads") },
23431 { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
23432 { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
c8de034b
JW
23433 /* NOTE: 0x00dd is not the real encoding, instead, it is the 'tvalue'
23434 field in asm_opcode. 'tvalue' is used at the stage this check happen. */
23435 { 0x00dd, 0x7fff, N_("ADD/SUB sp, sp #imm") },
5a01bb1d
MGD
23436 { 0, 0, NULL }
23437};
23438
e07e6e58
NC
23439static void
23440it_fsm_post_encode (void)
23441{
23442 int is_last;
23443
5ee91343
AV
23444 if (!now_pred.state_handled)
23445 handle_pred_state ();
e07e6e58 23446
5ee91343 23447 if (now_pred.insn_cond
24f19ccb 23448 && warn_on_restrict_it
5ee91343 23449 && !now_pred.warn_deprecated
5a01bb1d 23450 && warn_on_deprecated
164446e0
AF
23451 && (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)
23452 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8r))
df9909b8 23453 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m))
5a01bb1d
MGD
23454 {
23455 if (inst.instruction >= 0x10000)
23456 {
5c3696f8 23457 as_tsktsk (_("IT blocks containing 32-bit Thumb instructions are "
df9909b8 23458 "performance deprecated in ARMv8-A and ARMv8-R"));
5b7c81bd 23459 now_pred.warn_deprecated = true;
5a01bb1d
MGD
23460 }
23461 else
23462 {
23463 const struct depr_insn_mask *p = depr_it_insns;
23464
23465 while (p->mask != 0)
23466 {
23467 if ((inst.instruction & p->mask) == p->pattern)
23468 {
df9909b8
TP
23469 as_tsktsk (_("IT blocks containing 16-bit Thumb "
23470 "instructions of the following class are "
23471 "performance deprecated in ARMv8-A and "
23472 "ARMv8-R: %s"), p->description);
5b7c81bd 23473 now_pred.warn_deprecated = true;
5a01bb1d
MGD
23474 break;
23475 }
23476
23477 ++p;
23478 }
23479 }
23480
5ee91343 23481 if (now_pred.block_length > 1)
5a01bb1d 23482 {
5c3696f8 23483 as_tsktsk (_("IT blocks containing more than one conditional "
df9909b8
TP
23484 "instruction are performance deprecated in ARMv8-A and "
23485 "ARMv8-R"));
5b7c81bd 23486 now_pred.warn_deprecated = true;
5a01bb1d
MGD
23487 }
23488 }
23489
5ee91343
AV
23490 is_last = (now_pred.mask == 0x10);
23491 if (is_last)
23492 {
23493 now_pred.state = OUTSIDE_PRED_BLOCK;
23494 now_pred.mask = 0;
23495 }
e07e6e58
NC
23496}
23497
23498static void
23499force_automatic_it_block_close (void)
23500{
5ee91343 23501 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
e07e6e58
NC
23502 {
23503 close_automatic_it_block ();
5ee91343
AV
23504 now_pred.state = OUTSIDE_PRED_BLOCK;
23505 now_pred.mask = 0;
e07e6e58
NC
23506 }
23507}
23508
23509static int
5ee91343 23510in_pred_block (void)
e07e6e58 23511{
5ee91343
AV
23512 if (!now_pred.state_handled)
23513 handle_pred_state ();
e07e6e58 23514
5ee91343 23515 return now_pred.state != OUTSIDE_PRED_BLOCK;
e07e6e58
NC
23516}
23517
ff8646ee
TP
23518/* Whether OPCODE only has T32 encoding. Since this function is only used by
23519 t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed
23520 here, hence the "known" in the function name. */
fc289b0a 23521
5b7c81bd 23522static bool
ff8646ee 23523known_t32_only_insn (const struct asm_opcode *opcode)
fc289b0a
TP
23524{
23525 /* Original Thumb-1 wide instruction. */
23526 if (opcode->tencode == do_t_blx
23527 || opcode->tencode == do_t_branch23
23528 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
23529 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
5b7c81bd 23530 return true;
fc289b0a 23531
16a1fa25
TP
23532 /* Wide-only instruction added to ARMv8-M Baseline. */
23533 if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m_m_only)
ff8646ee
TP
23534 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics)
23535 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m)
23536 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div))
5b7c81bd 23537 return true;
ff8646ee 23538
5b7c81bd 23539 return false;
ff8646ee
TP
23540}
23541
23542/* Whether wide instruction variant can be used if available for a valid OPCODE
23543 in ARCH. */
23544
5b7c81bd 23545static bool
ff8646ee
TP
23546t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode)
23547{
23548 if (known_t32_only_insn (opcode))
5b7c81bd 23549 return true;
ff8646ee
TP
23550
23551 /* Instruction with narrow and wide encoding added to ARMv8-M. Availability
23552 of variant T3 of B.W is checked in do_t_branch. */
23553 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
23554 && opcode->tencode == do_t_branch)
5b7c81bd 23555 return true;
ff8646ee 23556
bada4342
JW
23557 /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */
23558 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
23559 && opcode->tencode == do_t_mov_cmp
23560 /* Make sure CMP instruction is not affected. */
23561 && opcode->aencode == do_mov)
5b7c81bd 23562 return true;
bada4342 23563
ff8646ee
TP
23564 /* Wide instruction variants of all instructions with narrow *and* wide
23565 variants become available with ARMv6t2. Other opcodes are either
23566 narrow-only or wide-only and are thus available if OPCODE is valid. */
23567 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2))
5b7c81bd 23568 return true;
ff8646ee
TP
23569
23570 /* OPCODE with narrow only instruction variant or wide variant not
23571 available. */
5b7c81bd 23572 return false;
fc289b0a
TP
23573}
23574
c19d1205
ZW
23575void
23576md_assemble (char *str)
b99bd4ef 23577{
c19d1205
ZW
23578 char *p = str;
23579 const struct asm_opcode * opcode;
b99bd4ef 23580
c19d1205
ZW
23581 /* Align the previous label if needed. */
23582 if (last_label_seen != NULL)
b99bd4ef 23583 {
c19d1205
ZW
23584 symbol_set_frag (last_label_seen, frag_now);
23585 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
23586 S_SET_SEGMENT (last_label_seen, now_seg);
b99bd4ef
NC
23587 }
23588
c19d1205 23589 memset (&inst, '\0', sizeof (inst));
e2b0ab59
AV
23590 int r;
23591 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
23592 inst.relocs[r].type = BFD_RELOC_UNUSED;
b99bd4ef 23593
c19d1205
ZW
23594 opcode = opcode_lookup (&p);
23595 if (!opcode)
b99bd4ef 23596 {
c19d1205 23597 /* It wasn't an instruction, but it might be a register alias of
dcbf9037 23598 the form alias .req reg, or a Neon .dn/.qn directive. */
c921be7d 23599 if (! create_register_alias (str, p)
477330fc 23600 && ! create_neon_reg_alias (str, p))
c19d1205 23601 as_bad (_("bad instruction `%s'"), str);
b99bd4ef 23602
b99bd4ef
NC
23603 return;
23604 }
23605
278df34e 23606 if (warn_on_deprecated && opcode->tag == OT_cinfix3_deprecated)
5c3696f8 23607 as_tsktsk (_("s suffix on comparison instruction is deprecated"));
088fa78e 23608
037e8744
JB
23609 /* The value which unconditional instructions should have in place of the
23610 condition field. */
7af67752 23611 inst.uncond_value = (opcode->tag == OT_csuffixF) ? 0xf : -1u;
037e8744 23612
c19d1205 23613 if (thumb_mode)
b99bd4ef 23614 {
e74cfd16 23615 arm_feature_set variant;
8f06b2d8
PB
23616
23617 variant = cpu_variant;
23618 /* Only allow coprocessor instructions on Thumb-2 capable devices. */
e74cfd16
PB
23619 if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2))
23620 ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard);
c19d1205 23621 /* Check that this instruction is supported for this CPU. */
62b3e311
PB
23622 if (!opcode->tvariant
23623 || (thumb_mode == 1
23624 && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
b99bd4ef 23625 {
173205ca
TP
23626 if (opcode->tencode == do_t_swi)
23627 as_bad (_("SVC is not permitted on this architecture"));
23628 else
23629 as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
b99bd4ef
NC
23630 return;
23631 }
c19d1205
ZW
23632 if (inst.cond != COND_ALWAYS && !unified_syntax
23633 && opcode->tencode != do_t_branch)
b99bd4ef 23634 {
c19d1205 23635 as_bad (_("Thumb does not support conditional execution"));
b99bd4ef
NC
23636 return;
23637 }
23638
fc289b0a
TP
23639 /* Two things are addressed here:
23640 1) Implicit require narrow instructions on Thumb-1.
23641 This avoids relaxation accidentally introducing Thumb-2
23642 instructions.
23643 2) Reject wide instructions in non Thumb-2 cores.
23644
23645 Only instructions with narrow and wide variants need to be handled
23646 but selecting all non wide-only instructions is easier. */
23647 if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)
ff8646ee 23648 && !t32_insn_ok (variant, opcode))
076d447c 23649 {
fc289b0a
TP
23650 if (inst.size_req == 0)
23651 inst.size_req = 2;
23652 else if (inst.size_req == 4)
752d5da4 23653 {
ff8646ee
TP
23654 if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m))
23655 as_bad (_("selected processor does not support 32bit wide "
23656 "variant of instruction `%s'"), str);
23657 else
23658 as_bad (_("selected processor does not support `%s' in "
23659 "Thumb-2 mode"), str);
fc289b0a 23660 return;
752d5da4 23661 }
076d447c
PB
23662 }
23663
c19d1205
ZW
23664 inst.instruction = opcode->tvalue;
23665
5b7c81bd 23666 if (!parse_operands (p, opcode->operands, /*thumb=*/true))
477330fc 23667 {
5ee91343 23668 /* Prepare the pred_insn_type for those encodings that don't set
477330fc
RM
23669 it. */
23670 it_fsm_pre_encode ();
c19d1205 23671
477330fc 23672 opcode->tencode ();
e07e6e58 23673
477330fc
RM
23674 it_fsm_post_encode ();
23675 }
e27ec89e 23676
0110f2b8 23677 if (!(inst.error || inst.relax))
b99bd4ef 23678 {
9c2799c2 23679 gas_assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
c19d1205
ZW
23680 inst.size = (inst.instruction > 0xffff ? 4 : 2);
23681 if (inst.size_req && inst.size_req != inst.size)
b99bd4ef 23682 {
c19d1205 23683 as_bad (_("cannot honor width suffix -- `%s'"), str);
b99bd4ef
NC
23684 return;
23685 }
23686 }
076d447c
PB
23687
23688 /* Something has gone badly wrong if we try to relax a fixed size
477330fc 23689 instruction. */
9c2799c2 23690 gas_assert (inst.size_req == 0 || !inst.relax);
076d447c 23691
e74cfd16
PB
23692 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
23693 *opcode->tvariant);
ee065d83 23694 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
fc289b0a
TP
23695 set those bits when Thumb-2 32-bit instructions are seen. The impact
23696 of relaxable instructions will be considered later after we finish all
23697 relaxation. */
ff8646ee
TP
23698 if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any))
23699 variant = arm_arch_none;
23700 else
23701 variant = cpu_variant;
23702 if (inst.size == 4 && !t32_insn_ok (variant, opcode))
e74cfd16
PB
23703 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
23704 arm_ext_v6t2);
cd000bff 23705
88714cb8
DG
23706 check_neon_suffixes;
23707
cd000bff 23708 if (!inst.error)
c877a2f2
NC
23709 {
23710 mapping_state (MAP_THUMB);
23711 }
c19d1205 23712 }
3e9e4fcf 23713 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205 23714 {
5b7c81bd 23715 bool is_bx;
845b51d6
PB
23716
23717 /* bx is allowed on v5 cores, and sometimes on v4 cores. */
23718 is_bx = (opcode->aencode == do_bx);
23719
c19d1205 23720 /* Check that this instruction is supported for this CPU. */
845b51d6
PB
23721 if (!(is_bx && fix_v4bx)
23722 && !(opcode->avariant &&
23723 ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)))
b99bd4ef 23724 {
84b52b66 23725 as_bad (_("selected processor does not support `%s' in ARM mode"), str);
c19d1205 23726 return;
b99bd4ef 23727 }
c19d1205 23728 if (inst.size_req)
b99bd4ef 23729 {
c19d1205
ZW
23730 as_bad (_("width suffixes are invalid in ARM mode -- `%s'"), str);
23731 return;
b99bd4ef
NC
23732 }
23733
c19d1205
ZW
23734 inst.instruction = opcode->avalue;
23735 if (opcode->tag == OT_unconditionalF)
eff0bc54 23736 inst.instruction |= 0xFU << 28;
c19d1205
ZW
23737 else
23738 inst.instruction |= inst.cond << 28;
23739 inst.size = INSN_SIZE;
5b7c81bd 23740 if (!parse_operands (p, opcode->operands, /*thumb=*/false))
477330fc
RM
23741 {
23742 it_fsm_pre_encode ();
23743 opcode->aencode ();
23744 it_fsm_post_encode ();
23745 }
ee065d83 23746 /* Arm mode bx is marked as both v4T and v5 because it's still required
477330fc 23747 on a hypothetical non-thumb v5 core. */
845b51d6 23748 if (is_bx)
e74cfd16 23749 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t);
ee065d83 23750 else
e74cfd16
PB
23751 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
23752 *opcode->avariant);
88714cb8
DG
23753
23754 check_neon_suffixes;
23755
cd000bff 23756 if (!inst.error)
c877a2f2
NC
23757 {
23758 mapping_state (MAP_ARM);
23759 }
b99bd4ef 23760 }
3e9e4fcf
JB
23761 else
23762 {
23763 as_bad (_("attempt to use an ARM instruction on a Thumb-only processor "
23764 "-- `%s'"), str);
23765 return;
23766 }
c19d1205
ZW
23767 output_inst (str);
23768}
b99bd4ef 23769
e07e6e58 23770static void
5ee91343 23771check_pred_blocks_finished (void)
e07e6e58
NC
23772{
23773#ifdef OBJ_ELF
23774 asection *sect;
23775
23776 for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
5ee91343
AV
23777 if (seg_info (sect)->tc_segment_info_data.current_pred.state
23778 == MANUAL_PRED_BLOCK)
e07e6e58 23779 {
5ee91343
AV
23780 if (now_pred.type == SCALAR_PRED)
23781 as_warn (_("section '%s' finished with an open IT block."),
23782 sect->name);
23783 else
23784 as_warn (_("section '%s' finished with an open VPT/VPST block."),
23785 sect->name);
e07e6e58
NC
23786 }
23787#else
5ee91343
AV
23788 if (now_pred.state == MANUAL_PRED_BLOCK)
23789 {
23790 if (now_pred.type == SCALAR_PRED)
23791 as_warn (_("file finished with an open IT block."));
23792 else
23793 as_warn (_("file finished with an open VPT/VPST block."));
23794 }
e07e6e58
NC
23795#endif
23796}
23797
c19d1205
ZW
23798/* Various frobbings of labels and their addresses. */
23799
23800void
23801arm_start_line_hook (void)
23802{
23803 last_label_seen = NULL;
b99bd4ef
NC
23804}
23805
c19d1205
ZW
23806void
23807arm_frob_label (symbolS * sym)
b99bd4ef 23808{
c19d1205 23809 last_label_seen = sym;
b99bd4ef 23810
c19d1205 23811 ARM_SET_THUMB (sym, thumb_mode);
b99bd4ef 23812
c19d1205
ZW
23813#if defined OBJ_COFF || defined OBJ_ELF
23814 ARM_SET_INTERWORK (sym, support_interwork);
23815#endif
b99bd4ef 23816
e07e6e58
NC
23817 force_automatic_it_block_close ();
23818
5f4273c7 23819 /* Note - do not allow local symbols (.Lxxx) to be labelled
c19d1205
ZW
23820 as Thumb functions. This is because these labels, whilst
23821 they exist inside Thumb code, are not the entry points for
23822 possible ARM->Thumb calls. Also, these labels can be used
23823 as part of a computed goto or switch statement. eg gcc
23824 can generate code that looks like this:
b99bd4ef 23825
c19d1205
ZW
23826 ldr r2, [pc, .Laaa]
23827 lsl r3, r3, #2
23828 ldr r2, [r3, r2]
23829 mov pc, r2
b99bd4ef 23830
c19d1205
ZW
23831 .Lbbb: .word .Lxxx
23832 .Lccc: .word .Lyyy
23833 ..etc...
23834 .Laaa: .word Lbbb
b99bd4ef 23835
c19d1205
ZW
23836 The first instruction loads the address of the jump table.
23837 The second instruction converts a table index into a byte offset.
23838 The third instruction gets the jump address out of the table.
23839 The fourth instruction performs the jump.
b99bd4ef 23840
c19d1205
ZW
23841 If the address stored at .Laaa is that of a symbol which has the
23842 Thumb_Func bit set, then the linker will arrange for this address
23843 to have the bottom bit set, which in turn would mean that the
23844 address computation performed by the third instruction would end
23845 up with the bottom bit set. Since the ARM is capable of unaligned
23846 word loads, the instruction would then load the incorrect address
23847 out of the jump table, and chaos would ensue. */
23848 if (label_is_thumb_function_name
23849 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
fd361982 23850 && (bfd_section_flags (now_seg) & SEC_CODE) != 0)
b99bd4ef 23851 {
c19d1205
ZW
23852 /* When the address of a Thumb function is taken the bottom
23853 bit of that address should be set. This will allow
23854 interworking between Arm and Thumb functions to work
23855 correctly. */
b99bd4ef 23856
c19d1205 23857 THUMB_SET_FUNC (sym, 1);
b99bd4ef 23858
5b7c81bd 23859 label_is_thumb_function_name = false;
b99bd4ef 23860 }
07a53e5c 23861
07a53e5c 23862 dwarf2_emit_label (sym);
b99bd4ef
NC
23863}
23864
5b7c81bd 23865bool
c19d1205 23866arm_data_in_code (void)
b99bd4ef 23867{
d34049e8 23868 if (thumb_mode && startswith (input_line_pointer + 1, "data:"))
b99bd4ef 23869 {
c19d1205
ZW
23870 *input_line_pointer = '/';
23871 input_line_pointer += 5;
23872 *input_line_pointer = 0;
5b7c81bd 23873 return true;
b99bd4ef
NC
23874 }
23875
5b7c81bd 23876 return false;
b99bd4ef
NC
23877}
23878
c19d1205
ZW
23879char *
23880arm_canonicalize_symbol_name (char * name)
b99bd4ef 23881{
c19d1205 23882 int len;
b99bd4ef 23883
c19d1205
ZW
23884 if (thumb_mode && (len = strlen (name)) > 5
23885 && streq (name + len - 5, "/data"))
23886 *(name + len - 5) = 0;
b99bd4ef 23887
c19d1205 23888 return name;
b99bd4ef 23889}
c19d1205
ZW
23890\f
23891/* Table of all register names defined by default. The user can
23892 define additional names with .req. Note that all register names
23893 should appear in both upper and lowercase variants. Some registers
23894 also have mixed-case names. */
b99bd4ef 23895
5b7c81bd 23896#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, true, 0 }
c19d1205 23897#define REGNUM(p,n,t) REGDEF(p##n, n, t)
5287ad62 23898#define REGNUM2(p,n,t) REGDEF(p##n, 2 * n, t)
c19d1205
ZW
23899#define REGSET(p,t) \
23900 REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
23901 REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
23902 REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
23903 REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
5287ad62
JB
23904#define REGSETH(p,t) \
23905 REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
23906 REGNUM(p,20,t), REGNUM(p,21,t), REGNUM(p,22,t), REGNUM(p,23,t), \
23907 REGNUM(p,24,t), REGNUM(p,25,t), REGNUM(p,26,t), REGNUM(p,27,t), \
23908 REGNUM(p,28,t), REGNUM(p,29,t), REGNUM(p,30,t), REGNUM(p,31,t)
23909#define REGSET2(p,t) \
23910 REGNUM2(p, 0,t), REGNUM2(p, 1,t), REGNUM2(p, 2,t), REGNUM2(p, 3,t), \
23911 REGNUM2(p, 4,t), REGNUM2(p, 5,t), REGNUM2(p, 6,t), REGNUM2(p, 7,t), \
23912 REGNUM2(p, 8,t), REGNUM2(p, 9,t), REGNUM2(p,10,t), REGNUM2(p,11,t), \
23913 REGNUM2(p,12,t), REGNUM2(p,13,t), REGNUM2(p,14,t), REGNUM2(p,15,t)
90ec0d68
MGD
23914#define SPLRBANK(base,bank,t) \
23915 REGDEF(lr_##bank, 768|((base+0)<<16), t), \
23916 REGDEF(sp_##bank, 768|((base+1)<<16), t), \
23917 REGDEF(spsr_##bank, 768|(base<<16)|SPSR_BIT, t), \
23918 REGDEF(LR_##bank, 768|((base+0)<<16), t), \
23919 REGDEF(SP_##bank, 768|((base+1)<<16), t), \
23920 REGDEF(SPSR_##bank, 768|(base<<16)|SPSR_BIT, t)
7ed4c4c5 23921
c19d1205 23922static const struct reg_entry reg_names[] =
7ed4c4c5 23923{
c19d1205
ZW
23924 /* ARM integer registers. */
23925 REGSET(r, RN), REGSET(R, RN),
7ed4c4c5 23926
c19d1205
ZW
23927 /* ATPCS synonyms. */
23928 REGDEF(a1,0,RN), REGDEF(a2,1,RN), REGDEF(a3, 2,RN), REGDEF(a4, 3,RN),
23929 REGDEF(v1,4,RN), REGDEF(v2,5,RN), REGDEF(v3, 6,RN), REGDEF(v4, 7,RN),
23930 REGDEF(v5,8,RN), REGDEF(v6,9,RN), REGDEF(v7,10,RN), REGDEF(v8,11,RN),
7ed4c4c5 23931
c19d1205
ZW
23932 REGDEF(A1,0,RN), REGDEF(A2,1,RN), REGDEF(A3, 2,RN), REGDEF(A4, 3,RN),
23933 REGDEF(V1,4,RN), REGDEF(V2,5,RN), REGDEF(V3, 6,RN), REGDEF(V4, 7,RN),
23934 REGDEF(V5,8,RN), REGDEF(V6,9,RN), REGDEF(V7,10,RN), REGDEF(V8,11,RN),
7ed4c4c5 23935
c19d1205
ZW
23936 /* Well-known aliases. */
23937 REGDEF(wr, 7,RN), REGDEF(sb, 9,RN), REGDEF(sl,10,RN), REGDEF(fp,11,RN),
23938 REGDEF(ip,12,RN), REGDEF(sp,13,RN), REGDEF(lr,14,RN), REGDEF(pc,15,RN),
23939
23940 REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
23941 REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
23942
1b883319
AV
23943 /* Defining the new Zero register from ARMv8.1-M. */
23944 REGDEF(zr,15,ZR),
23945 REGDEF(ZR,15,ZR),
23946
c19d1205
ZW
23947 /* Coprocessor numbers. */
23948 REGSET(p, CP), REGSET(P, CP),
23949
23950 /* Coprocessor register numbers. The "cr" variants are for backward
23951 compatibility. */
23952 REGSET(c, CN), REGSET(C, CN),
23953 REGSET(cr, CN), REGSET(CR, CN),
23954
90ec0d68
MGD
23955 /* ARM banked registers. */
23956 REGDEF(R8_usr,512|(0<<16),RNB), REGDEF(r8_usr,512|(0<<16),RNB),
23957 REGDEF(R9_usr,512|(1<<16),RNB), REGDEF(r9_usr,512|(1<<16),RNB),
23958 REGDEF(R10_usr,512|(2<<16),RNB), REGDEF(r10_usr,512|(2<<16),RNB),
23959 REGDEF(R11_usr,512|(3<<16),RNB), REGDEF(r11_usr,512|(3<<16),RNB),
23960 REGDEF(R12_usr,512|(4<<16),RNB), REGDEF(r12_usr,512|(4<<16),RNB),
23961 REGDEF(SP_usr,512|(5<<16),RNB), REGDEF(sp_usr,512|(5<<16),RNB),
23962 REGDEF(LR_usr,512|(6<<16),RNB), REGDEF(lr_usr,512|(6<<16),RNB),
23963
23964 REGDEF(R8_fiq,512|(8<<16),RNB), REGDEF(r8_fiq,512|(8<<16),RNB),
23965 REGDEF(R9_fiq,512|(9<<16),RNB), REGDEF(r9_fiq,512|(9<<16),RNB),
23966 REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
23967 REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
23968 REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
1472d06f 23969 REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(sp_fiq,512|(13<<16),RNB),
90ec0d68
MGD
23970 REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
23971 REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
23972
23973 SPLRBANK(0,IRQ,RNB), SPLRBANK(0,irq,RNB),
23974 SPLRBANK(2,SVC,RNB), SPLRBANK(2,svc,RNB),
23975 SPLRBANK(4,ABT,RNB), SPLRBANK(4,abt,RNB),
23976 SPLRBANK(6,UND,RNB), SPLRBANK(6,und,RNB),
23977 SPLRBANK(12,MON,RNB), SPLRBANK(12,mon,RNB),
23978 REGDEF(elr_hyp,768|(14<<16),RNB), REGDEF(ELR_hyp,768|(14<<16),RNB),
23979 REGDEF(sp_hyp,768|(15<<16),RNB), REGDEF(SP_hyp,768|(15<<16),RNB),
fa94de6b 23980 REGDEF(spsr_hyp,768|(14<<16)|SPSR_BIT,RNB),
90ec0d68
MGD
23981 REGDEF(SPSR_hyp,768|(14<<16)|SPSR_BIT,RNB),
23982
c19d1205
ZW
23983 /* FPA registers. */
23984 REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
23985 REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
23986
23987 REGNUM(F,0,FN), REGNUM(F,1,FN), REGNUM(F,2,FN), REGNUM(F,3,FN),
23988 REGNUM(F,4,FN), REGNUM(F,5,FN), REGNUM(F,6,FN), REGNUM(F,7, FN),
23989
23990 /* VFP SP registers. */
5287ad62
JB
23991 REGSET(s,VFS), REGSET(S,VFS),
23992 REGSETH(s,VFS), REGSETH(S,VFS),
c19d1205
ZW
23993
23994 /* VFP DP Registers. */
5287ad62
JB
23995 REGSET(d,VFD), REGSET(D,VFD),
23996 /* Extra Neon DP registers. */
23997 REGSETH(d,VFD), REGSETH(D,VFD),
23998
23999 /* Neon QP registers. */
24000 REGSET2(q,NQ), REGSET2(Q,NQ),
c19d1205
ZW
24001
24002 /* VFP control registers. */
24003 REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
24004 REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
cd2cf30b
PB
24005 REGDEF(fpinst,9,VFC), REGDEF(fpinst2,10,VFC),
24006 REGDEF(FPINST,9,VFC), REGDEF(FPINST2,10,VFC),
24007 REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
24008 REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
40c7d507 24009 REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
ba6cd17f
SD
24010 REGDEF(fpscr_nzcvqc,2,VFC), REGDEF(FPSCR_nzcvqc,2,VFC),
24011 REGDEF(vpr,12,VFC), REGDEF(VPR,12,VFC),
24012 REGDEF(fpcxt_ns,14,VFC), REGDEF(FPCXT_NS,14,VFC),
24013 REGDEF(fpcxt_s,15,VFC), REGDEF(FPCXT_S,15,VFC),
ee3272d4
SP
24014 REGDEF(fpcxtns,14,VFC), REGDEF(FPCXTNS,14,VFC),
24015 REGDEF(fpcxts,15,VFC), REGDEF(FPCXTS,15,VFC),
c19d1205
ZW
24016
24017 /* Maverick DSP coprocessor registers. */
24018 REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
24019 REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
24020
24021 REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
24022 REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
24023 REGDEF(dspsc,0,DSPSC),
24024
24025 REGNUM(MVAX,0,MVAX), REGNUM(MVAX,1,MVAX),
24026 REGNUM(MVAX,2,MVAX), REGNUM(MVAX,3,MVAX),
24027 REGDEF(DSPSC,0,DSPSC),
24028
24029 /* iWMMXt data registers - p0, c0-15. */
24030 REGSET(wr,MMXWR), REGSET(wR,MMXWR), REGSET(WR, MMXWR),
24031
24032 /* iWMMXt control registers - p1, c0-3. */
24033 REGDEF(wcid, 0,MMXWC), REGDEF(wCID, 0,MMXWC), REGDEF(WCID, 0,MMXWC),
24034 REGDEF(wcon, 1,MMXWC), REGDEF(wCon, 1,MMXWC), REGDEF(WCON, 1,MMXWC),
24035 REGDEF(wcssf, 2,MMXWC), REGDEF(wCSSF, 2,MMXWC), REGDEF(WCSSF, 2,MMXWC),
24036 REGDEF(wcasf, 3,MMXWC), REGDEF(wCASF, 3,MMXWC), REGDEF(WCASF, 3,MMXWC),
24037
24038 /* iWMMXt scalar (constant/offset) registers - p1, c8-11. */
24039 REGDEF(wcgr0, 8,MMXWCG), REGDEF(wCGR0, 8,MMXWCG), REGDEF(WCGR0, 8,MMXWCG),
24040 REGDEF(wcgr1, 9,MMXWCG), REGDEF(wCGR1, 9,MMXWCG), REGDEF(WCGR1, 9,MMXWCG),
24041 REGDEF(wcgr2,10,MMXWCG), REGDEF(wCGR2,10,MMXWCG), REGDEF(WCGR2,10,MMXWCG),
24042 REGDEF(wcgr3,11,MMXWCG), REGDEF(wCGR3,11,MMXWCG), REGDEF(WCGR3,11,MMXWCG),
24043
24044 /* XScale accumulator registers. */
24045 REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
0264bf6f 24046
3a368c4c
VDN
24047 /* DWARF ABI defines RA_AUTH_CODE to 143. */
24048 REGDEF(ra_auth_code,143,PSEUDO),
c19d1205
ZW
24049};
24050#undef REGDEF
24051#undef REGNUM
24052#undef REGSET
7ed4c4c5 24053
c19d1205
ZW
24054/* Table of all PSR suffixes. Bare "CPSR" and "SPSR" are handled
24055 within psr_required_here. */
24056static const struct asm_psr psrs[] =
24057{
24058 /* Backward compatibility notation. Note that "all" is no longer
24059 truly all possible PSR bits. */
24060 {"all", PSR_c | PSR_f},
24061 {"flg", PSR_f},
24062 {"ctl", PSR_c},
24063
24064 /* Individual flags. */
24065 {"f", PSR_f},
24066 {"c", PSR_c},
24067 {"x", PSR_x},
24068 {"s", PSR_s},
59b42a0d 24069
c19d1205
ZW
24070 /* Combinations of flags. */
24071 {"fs", PSR_f | PSR_s},
24072 {"fx", PSR_f | PSR_x},
24073 {"fc", PSR_f | PSR_c},
24074 {"sf", PSR_s | PSR_f},
24075 {"sx", PSR_s | PSR_x},
24076 {"sc", PSR_s | PSR_c},
24077 {"xf", PSR_x | PSR_f},
24078 {"xs", PSR_x | PSR_s},
24079 {"xc", PSR_x | PSR_c},
24080 {"cf", PSR_c | PSR_f},
24081 {"cs", PSR_c | PSR_s},
24082 {"cx", PSR_c | PSR_x},
24083 {"fsx", PSR_f | PSR_s | PSR_x},
24084 {"fsc", PSR_f | PSR_s | PSR_c},
24085 {"fxs", PSR_f | PSR_x | PSR_s},
24086 {"fxc", PSR_f | PSR_x | PSR_c},
24087 {"fcs", PSR_f | PSR_c | PSR_s},
24088 {"fcx", PSR_f | PSR_c | PSR_x},
24089 {"sfx", PSR_s | PSR_f | PSR_x},
24090 {"sfc", PSR_s | PSR_f | PSR_c},
24091 {"sxf", PSR_s | PSR_x | PSR_f},
24092 {"sxc", PSR_s | PSR_x | PSR_c},
24093 {"scf", PSR_s | PSR_c | PSR_f},
24094 {"scx", PSR_s | PSR_c | PSR_x},
24095 {"xfs", PSR_x | PSR_f | PSR_s},
24096 {"xfc", PSR_x | PSR_f | PSR_c},
24097 {"xsf", PSR_x | PSR_s | PSR_f},
24098 {"xsc", PSR_x | PSR_s | PSR_c},
24099 {"xcf", PSR_x | PSR_c | PSR_f},
24100 {"xcs", PSR_x | PSR_c | PSR_s},
24101 {"cfs", PSR_c | PSR_f | PSR_s},
24102 {"cfx", PSR_c | PSR_f | PSR_x},
24103 {"csf", PSR_c | PSR_s | PSR_f},
24104 {"csx", PSR_c | PSR_s | PSR_x},
24105 {"cxf", PSR_c | PSR_x | PSR_f},
24106 {"cxs", PSR_c | PSR_x | PSR_s},
24107 {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
24108 {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
24109 {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
24110 {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
24111 {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
24112 {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
24113 {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
24114 {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
24115 {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
24116 {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
24117 {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
24118 {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
24119 {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
24120 {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
24121 {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
24122 {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
24123 {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
24124 {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
24125 {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
24126 {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
24127 {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
24128 {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
24129 {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
24130 {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
24131};
24132
62b3e311
PB
24133/* Table of V7M psr names. */
24134static const struct asm_psr v7m_psrs[] =
24135{
1a336194
TP
24136 {"apsr", 0x0 }, {"APSR", 0x0 },
24137 {"iapsr", 0x1 }, {"IAPSR", 0x1 },
24138 {"eapsr", 0x2 }, {"EAPSR", 0x2 },
24139 {"psr", 0x3 }, {"PSR", 0x3 },
24140 {"xpsr", 0x3 }, {"XPSR", 0x3 }, {"xPSR", 3 },
24141 {"ipsr", 0x5 }, {"IPSR", 0x5 },
24142 {"epsr", 0x6 }, {"EPSR", 0x6 },
24143 {"iepsr", 0x7 }, {"IEPSR", 0x7 },
24144 {"msp", 0x8 }, {"MSP", 0x8 },
24145 {"psp", 0x9 }, {"PSP", 0x9 },
24146 {"msplim", 0xa }, {"MSPLIM", 0xa },
24147 {"psplim", 0xb }, {"PSPLIM", 0xb },
24148 {"primask", 0x10}, {"PRIMASK", 0x10},
24149 {"basepri", 0x11}, {"BASEPRI", 0x11},
24150 {"basepri_max", 0x12}, {"BASEPRI_MAX", 0x12},
1a336194
TP
24151 {"faultmask", 0x13}, {"FAULTMASK", 0x13},
24152 {"control", 0x14}, {"CONTROL", 0x14},
24153 {"msp_ns", 0x88}, {"MSP_NS", 0x88},
24154 {"psp_ns", 0x89}, {"PSP_NS", 0x89},
24155 {"msplim_ns", 0x8a}, {"MSPLIM_NS", 0x8a},
24156 {"psplim_ns", 0x8b}, {"PSPLIM_NS", 0x8b},
24157 {"primask_ns", 0x90}, {"PRIMASK_NS", 0x90},
24158 {"basepri_ns", 0x91}, {"BASEPRI_NS", 0x91},
24159 {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
24160 {"control_ns", 0x94}, {"CONTROL_NS", 0x94},
24161 {"sp_ns", 0x98}, {"SP_NS", 0x98 }
62b3e311
PB
24162};
24163
c19d1205
ZW
24164/* Table of all shift-in-operand names. */
24165static const struct asm_shift_name shift_names [] =
b99bd4ef 24166{
c19d1205
ZW
24167 { "asl", SHIFT_LSL }, { "ASL", SHIFT_LSL },
24168 { "lsl", SHIFT_LSL }, { "LSL", SHIFT_LSL },
24169 { "lsr", SHIFT_LSR }, { "LSR", SHIFT_LSR },
24170 { "asr", SHIFT_ASR }, { "ASR", SHIFT_ASR },
24171 { "ror", SHIFT_ROR }, { "ROR", SHIFT_ROR },
f5f10c66
AV
24172 { "rrx", SHIFT_RRX }, { "RRX", SHIFT_RRX },
24173 { "uxtw", SHIFT_UXTW}, { "UXTW", SHIFT_UXTW}
c19d1205 24174};
b99bd4ef 24175
c19d1205
ZW
24176/* Table of all explicit relocation names. */
24177#ifdef OBJ_ELF
24178static struct reloc_entry reloc_names[] =
24179{
24180 { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
24181 { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
24182 { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
24183 { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
24184 { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
24185 { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
24186 { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
24187 { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
24188 { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
24189 { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
b43420e6 24190 { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32},
0855e32b
NS
24191 { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL},
24192 { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC},
477330fc 24193 { "TLSDESC", BFD_RELOC_ARM_TLS_GOTDESC},
0855e32b 24194 { "tlscall", BFD_RELOC_ARM_TLS_CALL},
477330fc 24195 { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
0855e32b 24196 { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
188fd7ae
CL
24197 { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ},
24198 { "gotfuncdesc", BFD_RELOC_ARM_GOTFUNCDESC },
24199 { "GOTFUNCDESC", BFD_RELOC_ARM_GOTFUNCDESC },
24200 { "gotofffuncdesc", BFD_RELOC_ARM_GOTOFFFUNCDESC },
24201 { "GOTOFFFUNCDESC", BFD_RELOC_ARM_GOTOFFFUNCDESC },
24202 { "funcdesc", BFD_RELOC_ARM_FUNCDESC },
5c5a4843
CL
24203 { "FUNCDESC", BFD_RELOC_ARM_FUNCDESC },
24204 { "tlsgd_fdpic", BFD_RELOC_ARM_TLS_GD32_FDPIC }, { "TLSGD_FDPIC", BFD_RELOC_ARM_TLS_GD32_FDPIC },
24205 { "tlsldm_fdpic", BFD_RELOC_ARM_TLS_LDM32_FDPIC }, { "TLSLDM_FDPIC", BFD_RELOC_ARM_TLS_LDM32_FDPIC },
24206 { "gottpoff_fdpic", BFD_RELOC_ARM_TLS_IE32_FDPIC }, { "GOTTPOFF_FDIC", BFD_RELOC_ARM_TLS_IE32_FDPIC },
c19d1205
ZW
24207};
24208#endif
b99bd4ef 24209
5ee91343 24210/* Table of all conditional affixes. */
c19d1205
ZW
24211static const struct asm_cond conds[] =
24212{
24213 {"eq", 0x0},
24214 {"ne", 0x1},
24215 {"cs", 0x2}, {"hs", 0x2},
24216 {"cc", 0x3}, {"ul", 0x3}, {"lo", 0x3},
24217 {"mi", 0x4},
24218 {"pl", 0x5},
24219 {"vs", 0x6},
24220 {"vc", 0x7},
24221 {"hi", 0x8},
24222 {"ls", 0x9},
24223 {"ge", 0xa},
24224 {"lt", 0xb},
24225 {"gt", 0xc},
24226 {"le", 0xd},
24227 {"al", 0xe}
24228};
5ee91343
AV
24229static const struct asm_cond vconds[] =
24230{
24231 {"t", 0xf},
24232 {"e", 0x10}
24233};
bfae80f2 24234
e797f7e0 24235#define UL_BARRIER(L,U,CODE,FEAT) \
823d2571
TG
24236 { L, CODE, ARM_FEATURE_CORE_LOW (FEAT) }, \
24237 { U, CODE, ARM_FEATURE_CORE_LOW (FEAT) }
e797f7e0 24238
62b3e311
PB
24239static struct asm_barrier_opt barrier_opt_names[] =
24240{
e797f7e0
MGD
24241 UL_BARRIER ("sy", "SY", 0xf, ARM_EXT_BARRIER),
24242 UL_BARRIER ("st", "ST", 0xe, ARM_EXT_BARRIER),
24243 UL_BARRIER ("ld", "LD", 0xd, ARM_EXT_V8),
24244 UL_BARRIER ("ish", "ISH", 0xb, ARM_EXT_BARRIER),
24245 UL_BARRIER ("sh", "SH", 0xb, ARM_EXT_BARRIER),
24246 UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER),
24247 UL_BARRIER ("shst", "SHST", 0xa, ARM_EXT_BARRIER),
24248 UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8),
24249 UL_BARRIER ("un", "UN", 0x7, ARM_EXT_BARRIER),
24250 UL_BARRIER ("nsh", "NSH", 0x7, ARM_EXT_BARRIER),
24251 UL_BARRIER ("unst", "UNST", 0x6, ARM_EXT_BARRIER),
24252 UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER),
24253 UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8),
24254 UL_BARRIER ("osh", "OSH", 0x3, ARM_EXT_BARRIER),
24255 UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER),
24256 UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8)
62b3e311
PB
24257};
24258
e797f7e0
MGD
24259#undef UL_BARRIER
24260
c19d1205
ZW
24261/* Table of ARM-format instructions. */
24262
24263/* Macros for gluing together operand strings. N.B. In all cases
24264 other than OPS0, the trailing OP_stop comes from default
24265 zero-initialization of the unspecified elements of the array. */
24266#define OPS0() { OP_stop, }
24267#define OPS1(a) { OP_##a, }
24268#define OPS2(a,b) { OP_##a,OP_##b, }
24269#define OPS3(a,b,c) { OP_##a,OP_##b,OP_##c, }
24270#define OPS4(a,b,c,d) { OP_##a,OP_##b,OP_##c,OP_##d, }
24271#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
24272#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
24273
5be8be5d
DG
24274/* These macros are similar to the OPSn, but do not prepend the OP_ prefix.
24275 This is useful when mixing operands for ARM and THUMB, i.e. using the
24276 MIX_ARM_THUMB_OPERANDS macro.
24277 In order to use these macros, prefix the number of operands with _
24278 e.g. _3. */
24279#define OPS_1(a) { a, }
24280#define OPS_2(a,b) { a,b, }
24281#define OPS_3(a,b,c) { a,b,c, }
24282#define OPS_4(a,b,c,d) { a,b,c,d, }
24283#define OPS_5(a,b,c,d,e) { a,b,c,d,e, }
24284#define OPS_6(a,b,c,d,e,f) { a,b,c,d,e,f, }
24285
c19d1205
ZW
24286/* These macros abstract out the exact format of the mnemonic table and
24287 save some repeated characters. */
24288
24289/* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix. */
24290#define TxCE(mnem, op, top, nops, ops, ae, te) \
21d799b5 24291 { mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
5ee91343 24292 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
24293
24294/* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
24295 a T_MNEM_xyz enumerator. */
24296#define TCE(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24297 TxCE (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 24298#define tCE(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24299 TxCE (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205
ZW
24300
24301/* Second most common sort of mnemonic: has a Thumb variant, takes a conditional
24302 infix after the third character. */
24303#define TxC3(mnem, op, top, nops, ops, ae, te) \
21d799b5 24304 { mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
5ee91343 24305 THUMB_VARIANT, do_##ae, do_##te, 0 }
088fa78e 24306#define TxC3w(mnem, op, top, nops, ops, ae, te) \
21d799b5 24307 { mnem, OPS##nops ops, OT_cinfix3_deprecated, 0x##op, top, ARM_VARIANT, \
5ee91343 24308 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 24309#define TC3(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24310 TxC3 (mnem, aop, 0x##top, nops, ops, ae, te)
088fa78e 24311#define TC3w(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24312 TxC3w (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 24313#define tC3(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24314 TxC3 (mnem, aop, T_MNEM##top, nops, ops, ae, te)
088fa78e 24315#define tC3w(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24316 TxC3w (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205 24317
c19d1205 24318/* Mnemonic that cannot be conditionalized. The ARM condition-code
dfa9f0d5
PB
24319 field is still 0xE. Many of the Thumb variants can be executed
24320 conditionally, so this is checked separately. */
c19d1205 24321#define TUE(mnem, op, top, nops, ops, ae, te) \
21d799b5 24322 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24323 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 24324
dd5181d5
KT
24325/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
24326 Used by mnemonics that have very minimal differences in the encoding for
24327 ARM and Thumb variants and can be handled in a common function. */
24328#define TUEc(mnem, op, top, nops, ops, en) \
24329 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24330 THUMB_VARIANT, do_##en, do_##en, 0 }
dd5181d5 24331
c19d1205
ZW
24332/* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
24333 condition code field. */
24334#define TUF(mnem, op, top, nops, ops, ae, te) \
21d799b5 24335 { mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24336 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
24337
24338/* ARM-only variants of all the above. */
6a86118a 24339#define CE(mnem, op, nops, ops, ae) \
5ee91343 24340 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24341
24342#define C3(mnem, op, nops, ops, ae) \
5ee91343 24343 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 24344
cf3cf39d
TP
24345/* Thumb-only variants of TCE and TUE. */
24346#define ToC(mnem, top, nops, ops, te) \
24347 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
5ee91343 24348 do_##te, 0 }
cf3cf39d
TP
24349
24350#define ToU(mnem, top, nops, ops, te) \
24351 { mnem, OPS##nops ops, OT_unconditional, 0x0, 0x##top, 0, THUMB_VARIANT, \
5ee91343 24352 NULL, do_##te, 0 }
cf3cf39d 24353
4389b29a
AV
24354/* T_MNEM_xyz enumerator variants of ToC. */
24355#define toC(mnem, top, nops, ops, te) \
24356 { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \
5ee91343 24357 do_##te, 0 }
4389b29a 24358
f6b2b12d
AV
24359/* T_MNEM_xyz enumerator variants of ToU. */
24360#define toU(mnem, top, nops, ops, te) \
24361 { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \
5ee91343 24362 NULL, do_##te, 0 }
f6b2b12d 24363
e3cb604e
PB
24364/* Legacy mnemonics that always have conditional infix after the third
24365 character. */
24366#define CL(mnem, op, nops, ops, ae) \
21d799b5 24367 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 24368 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
e3cb604e 24369
8f06b2d8
PB
24370/* Coprocessor instructions. Isomorphic between Arm and Thumb-2. */
24371#define cCE(mnem, op, nops, ops, ae) \
5ee91343 24372 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 24373
57785aa2
AV
24374/* mov instructions that are shared between coprocessor and MVE. */
24375#define mcCE(mnem, op, nops, ops, ae) \
24376 { #mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##ae, 0 }
24377
e3cb604e
PB
24378/* Legacy coprocessor instructions where conditional infix and conditional
24379 suffix are ambiguous. For consistency this includes all FPA instructions,
24380 not just the potentially ambiguous ones. */
24381#define cCL(mnem, op, nops, ops, ae) \
21d799b5 24382 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 24383 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
e3cb604e
PB
24384
24385/* Coprocessor, takes either a suffix or a position-3 infix
24386 (for an FPA corner case). */
24387#define C3E(mnem, op, nops, ops, ae) \
21d799b5 24388 { mnem, OPS##nops ops, OT_csuf_or_in3, \
5ee91343 24389 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 24390
6a86118a 24391#define xCM_(m1, m2, m3, op, nops, ops, ae) \
21d799b5
NC
24392 { m1 #m2 m3, OPS##nops ops, \
24393 sizeof (#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof (m1) - 1, \
5ee91343 24394 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24395
24396#define CM(m1, m2, op, nops, ops, ae) \
e07e6e58
NC
24397 xCM_ (m1, , m2, op, nops, ops, ae), \
24398 xCM_ (m1, eq, m2, op, nops, ops, ae), \
24399 xCM_ (m1, ne, m2, op, nops, ops, ae), \
24400 xCM_ (m1, cs, m2, op, nops, ops, ae), \
24401 xCM_ (m1, hs, m2, op, nops, ops, ae), \
24402 xCM_ (m1, cc, m2, op, nops, ops, ae), \
24403 xCM_ (m1, ul, m2, op, nops, ops, ae), \
24404 xCM_ (m1, lo, m2, op, nops, ops, ae), \
24405 xCM_ (m1, mi, m2, op, nops, ops, ae), \
24406 xCM_ (m1, pl, m2, op, nops, ops, ae), \
24407 xCM_ (m1, vs, m2, op, nops, ops, ae), \
24408 xCM_ (m1, vc, m2, op, nops, ops, ae), \
24409 xCM_ (m1, hi, m2, op, nops, ops, ae), \
24410 xCM_ (m1, ls, m2, op, nops, ops, ae), \
24411 xCM_ (m1, ge, m2, op, nops, ops, ae), \
24412 xCM_ (m1, lt, m2, op, nops, ops, ae), \
24413 xCM_ (m1, gt, m2, op, nops, ops, ae), \
24414 xCM_ (m1, le, m2, op, nops, ops, ae), \
24415 xCM_ (m1, al, m2, op, nops, ops, ae)
6a86118a
NC
24416
24417#define UE(mnem, op, nops, ops, ae) \
5ee91343 24418 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24419
24420#define UF(mnem, op, nops, ops, ae) \
5ee91343 24421 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 24422
5287ad62
JB
24423/* Neon data-processing. ARM versions are unconditional with cond=0xf.
24424 The Thumb and ARM variants are mostly the same (bits 0-23 and 24/28), so we
24425 use the same encoding function for each. */
24426#define NUF(mnem, op, nops, ops, enc) \
24427 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
5ee91343 24428 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
24429
24430/* Neon data processing, version which indirects through neon_enc_tab for
24431 the various overloaded versions of opcodes. */
24432#define nUF(mnem, op, nops, ops, enc) \
21d799b5 24433 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
5ee91343 24434 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
24435
24436/* Neon insn with conditional suffix for the ARM version, non-overloaded
24437 version. */
5ee91343 24438#define NCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
037e8744 24439 { #mnem, OPS##nops ops, tag, 0x##op, 0x##op, ARM_VARIANT, \
5ee91343 24440 THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 24441
037e8744 24442#define NCE(mnem, op, nops, ops, enc) \
5ee91343 24443 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
24444
24445#define NCEF(mnem, op, nops, ops, enc) \
5ee91343 24446 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
037e8744 24447
5287ad62 24448/* Neon insn with conditional suffix for the ARM version, overloaded types. */
5ee91343 24449#define nCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
21d799b5 24450 { #mnem, OPS##nops ops, tag, N_MNEM##op, N_MNEM##op, \
5ee91343 24451 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 24452
037e8744 24453#define nCE(mnem, op, nops, ops, enc) \
5ee91343 24454 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
24455
24456#define nCEF(mnem, op, nops, ops, enc) \
5ee91343
AV
24457 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
24458
24459/* */
24460#define mCEF(mnem, op, nops, ops, enc) \
a302e574 24461 { #mnem, OPS##nops ops, OT_csuffixF, M_MNEM##op, M_MNEM##op, \
5ee91343
AV
24462 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24463
24464
24465/* nCEF but for MVE predicated instructions. */
24466#define mnCEF(mnem, op, nops, ops, enc) \
24467 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
24468
24469/* nCE but for MVE predicated instructions. */
24470#define mnCE(mnem, op, nops, ops, enc) \
24471 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
037e8744 24472
5ee91343
AV
24473/* NUF but for potentially MVE predicated instructions. */
24474#define MNUF(mnem, op, nops, ops, enc) \
24475 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
24476 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24477
24478/* nUF but for potentially MVE predicated instructions. */
24479#define mnUF(mnem, op, nops, ops, enc) \
24480 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
24481 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24482
24483/* ToC but for potentially MVE predicated instructions. */
24484#define mToC(mnem, top, nops, ops, te) \
24485 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
24486 do_##te, 1 }
24487
24488/* NCE but for MVE predicated instructions. */
24489#define MNCE(mnem, op, nops, ops, enc) \
24490 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
24491
24492/* NCEF but for MVE predicated instructions. */
24493#define MNCEF(mnem, op, nops, ops, enc) \
24494 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
c19d1205
ZW
24495#define do_0 0
24496
c19d1205 24497static const struct asm_opcode insns[] =
bfae80f2 24498{
74db7efb
NC
24499#define ARM_VARIANT & arm_ext_v1 /* Core ARM Instructions. */
24500#define THUMB_VARIANT & arm_ext_v4t
21d799b5
NC
24501 tCE("and", 0000000, _and, 3, (RR, oRR, SH), arit, t_arit3c),
24502 tC3("ands", 0100000, _ands, 3, (RR, oRR, SH), arit, t_arit3c),
24503 tCE("eor", 0200000, _eor, 3, (RR, oRR, SH), arit, t_arit3c),
24504 tC3("eors", 0300000, _eors, 3, (RR, oRR, SH), arit, t_arit3c),
24505 tCE("sub", 0400000, _sub, 3, (RR, oRR, SH), arit, t_add_sub),
24506 tC3("subs", 0500000, _subs, 3, (RR, oRR, SH), arit, t_add_sub),
24507 tCE("add", 0800000, _add, 3, (RR, oRR, SHG), arit, t_add_sub),
24508 tC3("adds", 0900000, _adds, 3, (RR, oRR, SHG), arit, t_add_sub),
24509 tCE("adc", 0a00000, _adc, 3, (RR, oRR, SH), arit, t_arit3c),
24510 tC3("adcs", 0b00000, _adcs, 3, (RR, oRR, SH), arit, t_arit3c),
24511 tCE("sbc", 0c00000, _sbc, 3, (RR, oRR, SH), arit, t_arit3),
24512 tC3("sbcs", 0d00000, _sbcs, 3, (RR, oRR, SH), arit, t_arit3),
24513 tCE("orr", 1800000, _orr, 3, (RR, oRR, SH), arit, t_arit3c),
24514 tC3("orrs", 1900000, _orrs, 3, (RR, oRR, SH), arit, t_arit3c),
24515 tCE("bic", 1c00000, _bic, 3, (RR, oRR, SH), arit, t_arit3),
24516 tC3("bics", 1d00000, _bics, 3, (RR, oRR, SH), arit, t_arit3),
c19d1205
ZW
24517
24518 /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
24519 for setting PSR flag bits. They are obsolete in V6 and do not
24520 have Thumb equivalents. */
21d799b5
NC
24521 tCE("tst", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
24522 tC3w("tsts", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
24523 CL("tstp", 110f000, 2, (RR, SH), cmp),
24524 tCE("cmp", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
24525 tC3w("cmps", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
24526 CL("cmpp", 150f000, 2, (RR, SH), cmp),
24527 tCE("cmn", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
24528 tC3w("cmns", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
24529 CL("cmnp", 170f000, 2, (RR, SH), cmp),
24530
24531 tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
72d98d16 24532 tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
21d799b5
NC
24533 tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
24534 tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
24535
24536 tCE("ldr", 4100000, _ldr, 2, (RR, ADDRGLDR),ldst, t_ldst),
5be8be5d
DG
24537 tC3("ldrb", 4500000, _ldrb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
24538 tCE("str", 4000000, _str, _2, (MIX_ARM_THUMB_OPERANDS (OP_RR,
24539 OP_RRnpc),
24540 OP_ADDRGLDR),ldst, t_ldst),
24541 tC3("strb", 4400000, _strb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
21d799b5
NC
24542
24543 tCE("stm", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24544 tC3("stmia", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24545 tC3("stmea", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24546 tCE("ldm", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24547 tC3("ldmia", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24548 tC3("ldmfd", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24549
21d799b5
NC
24550 tCE("b", a000000, _b, 1, (EXPr), branch, t_branch),
24551 TCE("bl", b000000, f000f800, 1, (EXPr), bl, t_branch23),
bfae80f2 24552
c19d1205 24553 /* Pseudo ops. */
21d799b5 24554 tCE("adr", 28f0000, _adr, 2, (RR, EXP), adr, t_adr),
2fc8bdac 24555 C3(adrl, 28f0000, 2, (RR, EXP), adrl),
21d799b5 24556 tCE("nop", 1a00000, _nop, 1, (oI255c), nop, t_nop),
74db7efb 24557 tCE("udf", 7f000f0, _udf, 1, (oIffffb), bkpt, t_udf),
c19d1205
ZW
24558
24559 /* Thumb-compatibility pseudo ops. */
21d799b5
NC
24560 tCE("lsl", 1a00000, _lsl, 3, (RR, oRR, SH), shift, t_shift),
24561 tC3("lsls", 1b00000, _lsls, 3, (RR, oRR, SH), shift, t_shift),
24562 tCE("lsr", 1a00020, _lsr, 3, (RR, oRR, SH), shift, t_shift),
24563 tC3("lsrs", 1b00020, _lsrs, 3, (RR, oRR, SH), shift, t_shift),
24564 tCE("asr", 1a00040, _asr, 3, (RR, oRR, SH), shift, t_shift),
24565 tC3("asrs", 1b00040, _asrs, 3, (RR, oRR, SH), shift, t_shift),
24566 tCE("ror", 1a00060, _ror, 3, (RR, oRR, SH), shift, t_shift),
24567 tC3("rors", 1b00060, _rors, 3, (RR, oRR, SH), shift, t_shift),
24568 tCE("neg", 2600000, _neg, 2, (RR, RR), rd_rn, t_neg),
24569 tC3("negs", 2700000, _negs, 2, (RR, RR), rd_rn, t_neg),
24570 tCE("push", 92d0000, _push, 1, (REGLST), push_pop, t_push_pop),
24571 tCE("pop", 8bd0000, _pop, 1, (REGLST), push_pop, t_push_pop),
c19d1205 24572
16a4cf17 24573 /* These may simplify to neg. */
21d799b5
NC
24574 TCE("rsb", 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
24575 TC3("rsbs", 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
16a4cf17 24576
173205ca
TP
24577#undef THUMB_VARIANT
24578#define THUMB_VARIANT & arm_ext_os
24579
24580 TCE("swi", f000000, df00, 1, (EXPi), swi, t_swi),
24581 TCE("svc", f000000, df00, 1, (EXPi), swi, t_swi),
24582
c921be7d
NC
24583#undef THUMB_VARIANT
24584#define THUMB_VARIANT & arm_ext_v6
24585
21d799b5 24586 TCE("cpy", 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
c19d1205
ZW
24587
24588 /* V1 instructions with no Thumb analogue prior to V6T2. */
c921be7d
NC
24589#undef THUMB_VARIANT
24590#define THUMB_VARIANT & arm_ext_v6t2
24591
21d799b5
NC
24592 TCE("teq", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
24593 TC3w("teqs", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
24594 CL("teqp", 130f000, 2, (RR, SH), cmp),
c19d1205 24595
5be8be5d
DG
24596 TC3("ldrt", 4300000, f8500e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
24597 TC3("ldrbt", 4700000, f8100e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
24598 TC3("strt", 4200000, f8400e00, 2, (RR_npcsp, ADDR), ldstt, t_ldstt),
24599 TC3("strbt", 4600000, f8000e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
c19d1205 24600
21d799b5
NC
24601 TC3("stmdb", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24602 TC3("stmfd", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205 24603
21d799b5
NC
24604 TC3("ldmdb", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24605 TC3("ldmea", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205
ZW
24606
24607 /* V1 instructions with no Thumb analogue at all. */
21d799b5 24608 CE("rsc", 0e00000, 3, (RR, oRR, SH), arit),
c19d1205
ZW
24609 C3(rscs, 0f00000, 3, (RR, oRR, SH), arit),
24610
24611 C3(stmib, 9800000, 2, (RRw, REGLST), ldmstm),
24612 C3(stmfa, 9800000, 2, (RRw, REGLST), ldmstm),
24613 C3(stmda, 8000000, 2, (RRw, REGLST), ldmstm),
24614 C3(stmed, 8000000, 2, (RRw, REGLST), ldmstm),
24615 C3(ldmib, 9900000, 2, (RRw, REGLST), ldmstm),
24616 C3(ldmed, 9900000, 2, (RRw, REGLST), ldmstm),
24617 C3(ldmda, 8100000, 2, (RRw, REGLST), ldmstm),
24618 C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm),
24619
c921be7d
NC
24620#undef ARM_VARIANT
24621#define ARM_VARIANT & arm_ext_v2 /* ARM 2 - multiplies. */
24622#undef THUMB_VARIANT
24623#define THUMB_VARIANT & arm_ext_v4t
24624
21d799b5
NC
24625 tCE("mul", 0000090, _mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
24626 tC3("muls", 0100090, _muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
c19d1205 24627
c921be7d
NC
24628#undef THUMB_VARIANT
24629#define THUMB_VARIANT & arm_ext_v6t2
24630
21d799b5 24631 TCE("mla", 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
c19d1205
ZW
24632 C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
24633
24634 /* Generic coprocessor instructions. */
21d799b5
NC
24635 TCE("cdp", e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
24636 TCE("ldc", c100000, ec100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24637 TC3("ldcl", c500000, ec500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24638 TCE("stc", c000000, ec000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24639 TC3("stcl", c400000, ec400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24640 TCE("mcr", e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
db472d6f 24641 TCE("mrc", e100010, ee100010, 6, (RCP, I7b, APSR_RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 24642
c921be7d
NC
24643#undef ARM_VARIANT
24644#define ARM_VARIANT & arm_ext_v2s /* ARM 3 - swp instructions. */
24645
21d799b5 24646 CE("swp", 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
c19d1205
ZW
24647 C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
24648
c921be7d
NC
24649#undef ARM_VARIANT
24650#define ARM_VARIANT & arm_ext_v3 /* ARM 6 Status register instructions. */
24651#undef THUMB_VARIANT
24652#define THUMB_VARIANT & arm_ext_msr
24653
d2cd1205
JB
24654 TCE("mrs", 1000000, f3e08000, 2, (RRnpc, rPSR), mrs, t_mrs),
24655 TCE("msr", 120f000, f3808000, 2, (wPSR, RR_EXi), msr, t_msr),
c19d1205 24656
c921be7d
NC
24657#undef ARM_VARIANT
24658#define ARM_VARIANT & arm_ext_v3m /* ARM 7M long multiplies. */
24659#undef THUMB_VARIANT
24660#define THUMB_VARIANT & arm_ext_v6t2
24661
21d799b5
NC
24662 TCE("smull", 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24663 CM("smull","s", 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24664 TCE("umull", 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24665 CM("umull","s", 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24666 TCE("smlal", 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24667 CM("smlal","s", 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24668 TCE("umlal", 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24669 CM("umlal","s", 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
c19d1205 24670
c921be7d
NC
24671#undef ARM_VARIANT
24672#define ARM_VARIANT & arm_ext_v4 /* ARM Architecture 4. */
24673#undef THUMB_VARIANT
24674#define THUMB_VARIANT & arm_ext_v4t
24675
5be8be5d
DG
24676 tC3("ldrh", 01000b0, _ldrh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24677 tC3("strh", 00000b0, _strh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24678 tC3("ldrsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24679 tC3("ldrsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
56c0a61f
RE
24680 tC3("ldsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24681 tC3("ldsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
c19d1205 24682
c921be7d
NC
24683#undef ARM_VARIANT
24684#define ARM_VARIANT & arm_ext_v4t_5
24685
c19d1205
ZW
24686 /* ARM Architecture 4T. */
24687 /* Note: bx (and blx) are required on V5, even if the processor does
24688 not support Thumb. */
21d799b5 24689 TCE("bx", 12fff10, 4700, 1, (RR), bx, t_bx),
c19d1205 24690
c921be7d
NC
24691#undef ARM_VARIANT
24692#define ARM_VARIANT & arm_ext_v5 /* ARM Architecture 5T. */
24693#undef THUMB_VARIANT
24694#define THUMB_VARIANT & arm_ext_v5t
24695
c19d1205
ZW
24696 /* Note: blx has 2 variants; the .value coded here is for
24697 BLX(2). Only this variant has conditional execution. */
21d799b5
NC
24698 TCE("blx", 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
24699 TUE("bkpt", 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
c19d1205 24700
c921be7d
NC
24701#undef THUMB_VARIANT
24702#define THUMB_VARIANT & arm_ext_v6t2
24703
21d799b5
NC
24704 TCE("clz", 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
24705 TUF("ldc2", c100000, fc100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24706 TUF("ldc2l", c500000, fc500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24707 TUF("stc2", c000000, fc000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24708 TUF("stc2l", c400000, fc400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24709 TUF("cdp2", e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
24710 TUF("mcr2", e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
24711 TUF("mrc2", e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 24712
c921be7d 24713#undef ARM_VARIANT
74db7efb
NC
24714#define ARM_VARIANT & arm_ext_v5exp /* ARM Architecture 5TExP. */
24715#undef THUMB_VARIANT
24716#define THUMB_VARIANT & arm_ext_v5exp
c921be7d 24717
21d799b5
NC
24718 TCE("smlabb", 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24719 TCE("smlatb", 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24720 TCE("smlabt", 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24721 TCE("smlatt", 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 24722
21d799b5
NC
24723 TCE("smlawb", 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24724 TCE("smlawt", 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 24725
21d799b5
NC
24726 TCE("smlalbb", 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24727 TCE("smlaltb", 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24728 TCE("smlalbt", 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24729 TCE("smlaltt", 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
c19d1205 24730
21d799b5
NC
24731 TCE("smulbb", 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24732 TCE("smultb", 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24733 TCE("smulbt", 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24734 TCE("smultt", 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 24735
21d799b5
NC
24736 TCE("smulwb", 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24737 TCE("smulwt", 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 24738
03ee1b7f
NC
24739 TCE("qadd", 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24740 TCE("qdadd", 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24741 TCE("qsub", 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24742 TCE("qdsub", 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
c19d1205 24743
c921be7d 24744#undef ARM_VARIANT
74db7efb
NC
24745#define ARM_VARIANT & arm_ext_v5e /* ARM Architecture 5TE. */
24746#undef THUMB_VARIANT
24747#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 24748
21d799b5 24749 TUF("pld", 450f000, f810f000, 1, (ADDR), pld, t_pld),
5be8be5d
DG
24750 TC3("ldrd", 00000d0, e8500000, 3, (RRnpc_npcsp, oRRnpc_npcsp, ADDRGLDRS),
24751 ldrd, t_ldstd),
24752 TC3("strd", 00000f0, e8400000, 3, (RRnpc_npcsp, oRRnpc_npcsp,
24753 ADDRGLDRS), ldrd, t_ldstd),
c19d1205 24754
21d799b5
NC
24755 TCE("mcrr", c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
24756 TCE("mrrc", c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
c19d1205 24757
c921be7d
NC
24758#undef ARM_VARIANT
24759#define ARM_VARIANT & arm_ext_v5j /* ARM Architecture 5TEJ. */
24760
21d799b5 24761 TCE("bxj", 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
c19d1205 24762
c921be7d
NC
24763#undef ARM_VARIANT
24764#define ARM_VARIANT & arm_ext_v6 /* ARM V6. */
24765#undef THUMB_VARIANT
24766#define THUMB_VARIANT & arm_ext_v6
24767
21d799b5
NC
24768 TUF("cpsie", 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
24769 TUF("cpsid", 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
24770 tCE("rev", 6bf0f30, _rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24771 tCE("rev16", 6bf0fb0, _rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24772 tCE("revsh", 6ff0fb0, _revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24773 tCE("sxth", 6bf0070, _sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24774 tCE("uxth", 6ff0070, _uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24775 tCE("sxtb", 6af0070, _sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24776 tCE("uxtb", 6ef0070, _uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24777 TUF("setend", 1010000, b650, 1, (ENDI), setend, t_setend),
c19d1205 24778
c921be7d 24779#undef THUMB_VARIANT
ff8646ee 24780#define THUMB_VARIANT & arm_ext_v6t2_v8m
c921be7d 24781
5be8be5d
DG
24782 TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
24783 TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
24784 strex, t_strex),
ff8646ee
TP
24785#undef THUMB_VARIANT
24786#define THUMB_VARIANT & arm_ext_v6t2
24787
21d799b5
NC
24788 TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
24789 TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
62b3e311 24790
21d799b5
NC
24791 TCE("ssat", 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
24792 TCE("usat", 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
62b3e311 24793
9e3c6df6 24794/* ARM V6 not included in V7M. */
c921be7d
NC
24795#undef THUMB_VARIANT
24796#define THUMB_VARIANT & arm_ext_v6_notm
9e3c6df6 24797 TUF("rfeia", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6 24798 TUF("rfe", 8900a00, e990c000, 1, (RRw), rfe, rfe),
9e3c6df6
PB
24799 UF(rfeib, 9900a00, 1, (RRw), rfe),
24800 UF(rfeda, 8100a00, 1, (RRw), rfe),
24801 TUF("rfedb", 9100a00, e810c000, 1, (RRw), rfe, rfe),
24802 TUF("rfefd", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6
RE
24803 UF(rfefa, 8100a00, 1, (RRw), rfe),
24804 TUF("rfeea", 9100a00, e810c000, 1, (RRw), rfe, rfe),
24805 UF(rfeed, 9900a00, 1, (RRw), rfe),
9e3c6df6 24806 TUF("srsia", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
d709e4e6
RE
24807 TUF("srs", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
24808 TUF("srsea", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
9e3c6df6 24809 UF(srsib, 9c00500, 2, (oRRw, I31w), srs),
d709e4e6 24810 UF(srsfa, 9c00500, 2, (oRRw, I31w), srs),
9e3c6df6 24811 UF(srsda, 8400500, 2, (oRRw, I31w), srs),
d709e4e6 24812 UF(srsed, 8400500, 2, (oRRw, I31w), srs),
9e3c6df6 24813 TUF("srsdb", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
d709e4e6 24814 TUF("srsfd", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
941c9cad 24815 TUF("cps", 1020000, f3af8100, 1, (I31b), imm0, t_cps),
c921be7d 24816
9e3c6df6
PB
24817/* ARM V6 not included in V7M (eg. integer SIMD). */
24818#undef THUMB_VARIANT
24819#define THUMB_VARIANT & arm_ext_v6_dsp
21d799b5
NC
24820 TCE("pkhbt", 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
24821 TCE("pkhtb", 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
24822 TCE("qadd16", 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24823 TCE("qadd8", 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24824 TCE("qasx", 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24825 /* Old name for QASX. */
74db7efb 24826 TCE("qaddsubx",6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 24827 TCE("qsax", 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24828 /* Old name for QSAX. */
74db7efb 24829 TCE("qsubaddx",6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24830 TCE("qsub16", 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24831 TCE("qsub8", 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24832 TCE("sadd16", 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24833 TCE("sadd8", 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24834 TCE("sasx", 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24835 /* Old name for SASX. */
74db7efb 24836 TCE("saddsubx",6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24837 TCE("shadd16", 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24838 TCE("shadd8", 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24839 TCE("shasx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24840 /* Old name for SHASX. */
21d799b5 24841 TCE("shaddsubx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24842 TCE("shsax", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24843 /* Old name for SHSAX. */
21d799b5
NC
24844 TCE("shsubaddx", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24845 TCE("shsub16", 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24846 TCE("shsub8", 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24847 TCE("ssax", 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24848 /* Old name for SSAX. */
74db7efb 24849 TCE("ssubaddx",6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24850 TCE("ssub16", 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24851 TCE("ssub8", 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24852 TCE("uadd16", 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24853 TCE("uadd8", 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24854 TCE("uasx", 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24855 /* Old name for UASX. */
74db7efb 24856 TCE("uaddsubx",6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24857 TCE("uhadd16", 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24858 TCE("uhadd8", 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24859 TCE("uhasx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24860 /* Old name for UHASX. */
21d799b5
NC
24861 TCE("uhaddsubx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24862 TCE("uhsax", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24863 /* Old name for UHSAX. */
21d799b5
NC
24864 TCE("uhsubaddx", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24865 TCE("uhsub16", 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24866 TCE("uhsub8", 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24867 TCE("uqadd16", 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24868 TCE("uqadd8", 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24869 TCE("uqasx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24870 /* Old name for UQASX. */
21d799b5
NC
24871 TCE("uqaddsubx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24872 TCE("uqsax", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24873 /* Old name for UQSAX. */
21d799b5
NC
24874 TCE("uqsubaddx", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24875 TCE("uqsub16", 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24876 TCE("uqsub8", 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24877 TCE("usub16", 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24878 TCE("usax", 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24879 /* Old name for USAX. */
74db7efb 24880 TCE("usubaddx",6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 24881 TCE("usub8", 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24882 TCE("sxtah", 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24883 TCE("sxtab16", 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24884 TCE("sxtab", 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24885 TCE("sxtb16", 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24886 TCE("uxtah", 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24887 TCE("uxtab16", 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24888 TCE("uxtab", 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24889 TCE("uxtb16", 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24890 TCE("sel", 6800fb0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24891 TCE("smlad", 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24892 TCE("smladx", 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24893 TCE("smlald", 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24894 TCE("smlaldx", 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24895 TCE("smlsd", 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24896 TCE("smlsdx", 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24897 TCE("smlsld", 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24898 TCE("smlsldx", 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24899 TCE("smmla", 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24900 TCE("smmlar", 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24901 TCE("smmls", 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24902 TCE("smmlsr", 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24903 TCE("smmul", 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24904 TCE("smmulr", 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24905 TCE("smuad", 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24906 TCE("smuadx", 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24907 TCE("smusd", 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24908 TCE("smusdx", 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
21d799b5
NC
24909 TCE("ssat16", 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
24910 TCE("umaal", 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
24911 TCE("usad8", 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24912 TCE("usada8", 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24913 TCE("usat16", 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
c19d1205 24914
c921be7d 24915#undef ARM_VARIANT
55e8aae7 24916#define ARM_VARIANT & arm_ext_v6k_v6t2
c921be7d 24917#undef THUMB_VARIANT
55e8aae7 24918#define THUMB_VARIANT & arm_ext_v6k_v6t2
c921be7d 24919
21d799b5
NC
24920 tCE("yield", 320f001, _yield, 0, (), noargs, t_hint),
24921 tCE("wfe", 320f002, _wfe, 0, (), noargs, t_hint),
24922 tCE("wfi", 320f003, _wfi, 0, (), noargs, t_hint),
24923 tCE("sev", 320f004, _sev, 0, (), noargs, t_hint),
c19d1205 24924
c921be7d
NC
24925#undef THUMB_VARIANT
24926#define THUMB_VARIANT & arm_ext_v6_notm
5be8be5d
DG
24927 TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc_npcsp, oRRnpc_npcsp, RRnpcb),
24928 ldrexd, t_ldrexd),
24929 TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc_npcsp, RRnpc_npcsp, oRRnpc_npcsp,
24930 RRnpcb), strexd, t_strexd),
ebdca51a 24931
c921be7d 24932#undef THUMB_VARIANT
ff8646ee 24933#define THUMB_VARIANT & arm_ext_v6t2_v8m
5be8be5d
DG
24934 TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
24935 rd_rn, rd_rn),
24936 TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
24937 rd_rn, rd_rn),
24938 TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 24939 strex, t_strexbh),
5be8be5d 24940 TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 24941 strex, t_strexbh),
21d799b5 24942 TUF("clrex", 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
c19d1205 24943
c921be7d 24944#undef ARM_VARIANT
f4c65163 24945#define ARM_VARIANT & arm_ext_sec
74db7efb 24946#undef THUMB_VARIANT
f4c65163 24947#define THUMB_VARIANT & arm_ext_sec
c921be7d 24948
21d799b5 24949 TCE("smc", 1600070, f7f08000, 1, (EXPi), smc, t_smc),
c19d1205 24950
90ec0d68
MGD
24951#undef ARM_VARIANT
24952#define ARM_VARIANT & arm_ext_virt
24953#undef THUMB_VARIANT
24954#define THUMB_VARIANT & arm_ext_virt
24955
24956 TCE("hvc", 1400070, f7e08000, 1, (EXPi), hvc, t_hvc),
24957 TCE("eret", 160006e, f3de8f00, 0, (), noargs, noargs),
24958
ddfded2f
MW
24959#undef ARM_VARIANT
24960#define ARM_VARIANT & arm_ext_pan
24961#undef THUMB_VARIANT
24962#define THUMB_VARIANT & arm_ext_pan
24963
24964 TUF("setpan", 1100000, b610, 1, (I7), setpan, t_setpan),
24965
c921be7d 24966#undef ARM_VARIANT
74db7efb 24967#define ARM_VARIANT & arm_ext_v6t2
f4c65163
MGD
24968#undef THUMB_VARIANT
24969#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 24970
21d799b5
NC
24971 TCE("bfc", 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
24972 TCE("bfi", 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
24973 TCE("sbfx", 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
24974 TCE("ubfx", 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
c19d1205 24975
21d799b5 24976 TCE("mls", 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
21d799b5 24977 TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
c19d1205 24978
5be8be5d
DG
24979 TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24980 TC3("ldrsht", 03000f0, f9300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24981 TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24982 TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
c19d1205 24983
91d8b670
JG
24984#undef ARM_VARIANT
24985#define ARM_VARIANT & arm_ext_v3
24986#undef THUMB_VARIANT
24987#define THUMB_VARIANT & arm_ext_v6t2
24988
24989 TUE("csdb", 320f014, f3af8014, 0, (), noargs, t_csdb),
c597cc3d
SD
24990 TUF("ssbb", 57ff040, f3bf8f40, 0, (), noargs, t_csdb),
24991 TUF("pssbb", 57ff044, f3bf8f44, 0, (), noargs, t_csdb),
91d8b670
JG
24992
24993#undef ARM_VARIANT
24994#define ARM_VARIANT & arm_ext_v6t2
ff8646ee
TP
24995#undef THUMB_VARIANT
24996#define THUMB_VARIANT & arm_ext_v6t2_v8m
24997 TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
24998 TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
24999
bf3eeda7 25000 /* Thumb-only instructions. */
74db7efb 25001#undef ARM_VARIANT
bf3eeda7
NS
25002#define ARM_VARIANT NULL
25003 TUE("cbnz", 0, b900, 2, (RR, EXP), 0, t_cbz),
25004 TUE("cbz", 0, b100, 2, (RR, EXP), 0, t_cbz),
c921be7d
NC
25005
25006 /* ARM does not really have an IT instruction, so always allow it.
25007 The opcode is copied from Thumb in order to allow warnings in
25008 -mimplicit-it=[never | arm] modes. */
25009#undef ARM_VARIANT
25010#define ARM_VARIANT & arm_ext_v1
ff8646ee
TP
25011#undef THUMB_VARIANT
25012#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 25013
21d799b5
NC
25014 TUE("it", bf08, bf08, 1, (COND), it, t_it),
25015 TUE("itt", bf0c, bf0c, 1, (COND), it, t_it),
25016 TUE("ite", bf04, bf04, 1, (COND), it, t_it),
25017 TUE("ittt", bf0e, bf0e, 1, (COND), it, t_it),
25018 TUE("itet", bf06, bf06, 1, (COND), it, t_it),
25019 TUE("itte", bf0a, bf0a, 1, (COND), it, t_it),
25020 TUE("itee", bf02, bf02, 1, (COND), it, t_it),
25021 TUE("itttt", bf0f, bf0f, 1, (COND), it, t_it),
25022 TUE("itett", bf07, bf07, 1, (COND), it, t_it),
25023 TUE("ittet", bf0b, bf0b, 1, (COND), it, t_it),
25024 TUE("iteet", bf03, bf03, 1, (COND), it, t_it),
25025 TUE("ittte", bf0d, bf0d, 1, (COND), it, t_it),
25026 TUE("itete", bf05, bf05, 1, (COND), it, t_it),
25027 TUE("ittee", bf09, bf09, 1, (COND), it, t_it),
25028 TUE("iteee", bf01, bf01, 1, (COND), it, t_it),
1c444d06 25029 /* ARM/Thumb-2 instructions with no Thumb-1 equivalent. */
21d799b5
NC
25030 TC3("rrx", 01a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rrx),
25031 TC3("rrxs", 01b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rrx),
c19d1205 25032
92e90b6e 25033 /* Thumb2 only instructions. */
c921be7d
NC
25034#undef ARM_VARIANT
25035#define ARM_VARIANT NULL
92e90b6e 25036
21d799b5
NC
25037 TCE("addw", 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
25038 TCE("subw", 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
25039 TCE("orn", 0, ea600000, 3, (RR, oRR, SH), 0, t_orn),
25040 TCE("orns", 0, ea700000, 3, (RR, oRR, SH), 0, t_orn),
25041 TCE("tbb", 0, e8d0f000, 1, (TB), 0, t_tb),
25042 TCE("tbh", 0, e8d0f010, 1, (TB), 0, t_tb),
92e90b6e 25043
eea54501
MGD
25044 /* Hardware division instructions. */
25045#undef ARM_VARIANT
25046#define ARM_VARIANT & arm_ext_adiv
c921be7d
NC
25047#undef THUMB_VARIANT
25048#define THUMB_VARIANT & arm_ext_div
25049
eea54501
MGD
25050 TCE("sdiv", 710f010, fb90f0f0, 3, (RR, oRR, RR), div, t_div),
25051 TCE("udiv", 730f010, fbb0f0f0, 3, (RR, oRR, RR), div, t_div),
62b3e311 25052
7e806470 25053 /* ARM V6M/V7 instructions. */
c921be7d
NC
25054#undef ARM_VARIANT
25055#define ARM_VARIANT & arm_ext_barrier
25056#undef THUMB_VARIANT
25057#define THUMB_VARIANT & arm_ext_barrier
25058
ccb84d65
JB
25059 TUF("dmb", 57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier, barrier),
25060 TUF("dsb", 57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier, barrier),
25061 TUF("isb", 57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier, barrier),
7e806470 25062
62b3e311 25063 /* ARM V7 instructions. */
c921be7d
NC
25064#undef ARM_VARIANT
25065#define ARM_VARIANT & arm_ext_v7
25066#undef THUMB_VARIANT
25067#define THUMB_VARIANT & arm_ext_v7
25068
21d799b5
NC
25069 TUF("pli", 450f000, f910f000, 1, (ADDR), pli, t_pld),
25070 TCE("dbg", 320f0f0, f3af80f0, 1, (I15), dbg, t_dbg),
62b3e311 25071
74db7efb 25072#undef ARM_VARIANT
60e5ef9f 25073#define ARM_VARIANT & arm_ext_mp
74db7efb 25074#undef THUMB_VARIANT
60e5ef9f
MGD
25075#define THUMB_VARIANT & arm_ext_mp
25076
25077 TUF("pldw", 410f000, f830f000, 1, (ADDR), pld, t_pld),
25078
53c4b28b
MGD
25079 /* AArchv8 instructions. */
25080#undef ARM_VARIANT
25081#define ARM_VARIANT & arm_ext_v8
4ed7ed8d
TP
25082
25083/* Instructions shared between armv8-a and armv8-m. */
53c4b28b 25084#undef THUMB_VARIANT
4ed7ed8d 25085#define THUMB_VARIANT & arm_ext_atomics
53c4b28b 25086
4ed7ed8d
TP
25087 TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25088 TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25089 TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25090 TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
25091 TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
25092 TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
4b8c8c02 25093 TCE("ldaex", 1900e9f, e8d00fef, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
4b8c8c02
RE
25094 TCE("ldaexb", 1d00e9f, e8d00fcf, 2, (RRnpc,RRnpcb), rd_rn, rd_rn),
25095 TCE("ldaexh", 1f00e9f, e8d00fdf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25096 TCE("stlex", 1800e90, e8c00fe0, 3, (RRnpc, RRnpc, RRnpcb),
25097 stlex, t_stlex),
4b8c8c02
RE
25098 TCE("stlexb", 1c00e90, e8c00fc0, 3, (RRnpc, RRnpc, RRnpcb),
25099 stlex, t_stlex),
25100 TCE("stlexh", 1e00e90, e8c00fd0, 3, (RRnpc, RRnpc, RRnpcb),
25101 stlex, t_stlex),
4ed7ed8d
TP
25102#undef THUMB_VARIANT
25103#define THUMB_VARIANT & arm_ext_v8
53c4b28b 25104
4ed7ed8d 25105 tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
4ed7ed8d
TP
25106 TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
25107 ldrexd, t_ldrexd),
25108 TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
25109 strexd, t_strexd),
26417f19
AC
25110#undef THUMB_VARIANT
25111#define THUMB_VARIANT & arm_ext_v8r
25112#undef ARM_VARIANT
25113#define ARM_VARIANT & arm_ext_v8r
25114
25115/* ARMv8-R instructions. */
25116 TUF("dfb", 57ff04c, f3bf8f4c, 0, (), noargs, noargs),
f7dd2fb2
TC
25117
25118/* Defined in V8 but is in undefined encoding space for earlier
25119 architectures. However earlier architectures are required to treat
25120 this instuction as a semihosting trap as well. Hence while not explicitly
25121 defined as such, it is in fact correct to define the instruction for all
25122 architectures. */
25123#undef THUMB_VARIANT
25124#define THUMB_VARIANT & arm_ext_v1
25125#undef ARM_VARIANT
25126#define ARM_VARIANT & arm_ext_v1
25127 TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
25128
8884b720 25129 /* ARMv8 T32 only. */
74db7efb 25130#undef ARM_VARIANT
b79f7053
MGD
25131#define ARM_VARIANT NULL
25132 TUF("dcps1", 0, f78f8001, 0, (), noargs, noargs),
25133 TUF("dcps2", 0, f78f8002, 0, (), noargs, noargs),
25134 TUF("dcps3", 0, f78f8003, 0, (), noargs, noargs),
25135
33399f07
MGD
25136 /* FP for ARMv8. */
25137#undef ARM_VARIANT
a715796b 25138#define ARM_VARIANT & fpu_vfp_ext_armv8xd
33399f07 25139#undef THUMB_VARIANT
a715796b 25140#define THUMB_VARIANT & fpu_vfp_ext_armv8xd
33399f07
MGD
25141
25142 nUF(vseleq, _vseleq, 3, (RVSD, RVSD, RVSD), vsel),
25143 nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD), vsel),
25144 nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD), vsel),
25145 nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD), vsel),
30bdf752 25146 nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ), vrintr),
a710b305
AV
25147 mnCE(vrintz, _vrintr, 2, (RNSDQMQ, oRNSDQMQ), vrintz),
25148 mnCE(vrintx, _vrintr, 2, (RNSDQMQ, oRNSDQMQ), vrintx),
25149 mnUF(vrinta, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrinta),
25150 mnUF(vrintn, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintn),
25151 mnUF(vrintp, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintp),
25152 mnUF(vrintm, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintm),
33399f07 25153
91ff7894
MGD
25154 /* Crypto v1 extensions. */
25155#undef ARM_VARIANT
25156#define ARM_VARIANT & fpu_crypto_ext_armv8
25157#undef THUMB_VARIANT
25158#define THUMB_VARIANT & fpu_crypto_ext_armv8
25159
25160 nUF(aese, _aes, 2, (RNQ, RNQ), aese),
25161 nUF(aesd, _aes, 2, (RNQ, RNQ), aesd),
25162 nUF(aesmc, _aes, 2, (RNQ, RNQ), aesmc),
25163 nUF(aesimc, _aes, 2, (RNQ, RNQ), aesimc),
48adcd8e
MGD
25164 nUF(sha1c, _sha3op, 3, (RNQ, RNQ, RNQ), sha1c),
25165 nUF(sha1p, _sha3op, 3, (RNQ, RNQ, RNQ), sha1p),
25166 nUF(sha1m, _sha3op, 3, (RNQ, RNQ, RNQ), sha1m),
25167 nUF(sha1su0, _sha3op, 3, (RNQ, RNQ, RNQ), sha1su0),
25168 nUF(sha256h, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h),
25169 nUF(sha256h2, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h2),
25170 nUF(sha256su1, _sha3op, 3, (RNQ, RNQ, RNQ), sha256su1),
3c9017d2
MGD
25171 nUF(sha1h, _sha1h, 2, (RNQ, RNQ), sha1h),
25172 nUF(sha1su1, _sha2op, 2, (RNQ, RNQ), sha1su1),
25173 nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
91ff7894 25174
dd5181d5 25175#undef ARM_VARIANT
8b301fbb 25176#define ARM_VARIANT & arm_ext_crc
dd5181d5 25177#undef THUMB_VARIANT
8b301fbb 25178#define THUMB_VARIANT & arm_ext_crc
dd5181d5
KT
25179 TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
25180 TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
25181 TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
25182 TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
25183 TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
25184 TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
25185
105bde57
MW
25186 /* ARMv8.2 RAS extension. */
25187#undef ARM_VARIANT
4d1464f2 25188#define ARM_VARIANT & arm_ext_ras
105bde57 25189#undef THUMB_VARIANT
4d1464f2 25190#define THUMB_VARIANT & arm_ext_ras
105bde57
MW
25191 TUE ("esb", 320f010, f3af8010, 0, (), noargs, noargs),
25192
49e8a725
SN
25193#undef ARM_VARIANT
25194#define ARM_VARIANT & arm_ext_v8_3
25195#undef THUMB_VARIANT
25196#define THUMB_VARIANT & arm_ext_v8_3
25197 NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
25198
c604a79a
JW
25199#undef ARM_VARIANT
25200#define ARM_VARIANT & fpu_neon_ext_dotprod
25201#undef THUMB_VARIANT
25202#define THUMB_VARIANT & fpu_neon_ext_dotprod
25203 NUF (vsdot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_s),
25204 NUF (vudot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_u),
25205
c921be7d
NC
25206#undef ARM_VARIANT
25207#define ARM_VARIANT & fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
53c4b28b
MGD
25208#undef THUMB_VARIANT
25209#define THUMB_VARIANT NULL
c921be7d 25210
21d799b5
NC
25211 cCE("wfs", e200110, 1, (RR), rd),
25212 cCE("rfs", e300110, 1, (RR), rd),
25213 cCE("wfc", e400110, 1, (RR), rd),
25214 cCE("rfc", e500110, 1, (RR), rd),
25215
25216 cCL("ldfs", c100100, 2, (RF, ADDRGLDC), rd_cpaddr),
25217 cCL("ldfd", c108100, 2, (RF, ADDRGLDC), rd_cpaddr),
25218 cCL("ldfe", c500100, 2, (RF, ADDRGLDC), rd_cpaddr),
25219 cCL("ldfp", c508100, 2, (RF, ADDRGLDC), rd_cpaddr),
25220
25221 cCL("stfs", c000100, 2, (RF, ADDRGLDC), rd_cpaddr),
25222 cCL("stfd", c008100, 2, (RF, ADDRGLDC), rd_cpaddr),
25223 cCL("stfe", c400100, 2, (RF, ADDRGLDC), rd_cpaddr),
25224 cCL("stfp", c408100, 2, (RF, ADDRGLDC), rd_cpaddr),
25225
25226 cCL("mvfs", e008100, 2, (RF, RF_IF), rd_rm),
25227 cCL("mvfsp", e008120, 2, (RF, RF_IF), rd_rm),
25228 cCL("mvfsm", e008140, 2, (RF, RF_IF), rd_rm),
25229 cCL("mvfsz", e008160, 2, (RF, RF_IF), rd_rm),
25230 cCL("mvfd", e008180, 2, (RF, RF_IF), rd_rm),
25231 cCL("mvfdp", e0081a0, 2, (RF, RF_IF), rd_rm),
25232 cCL("mvfdm", e0081c0, 2, (RF, RF_IF), rd_rm),
25233 cCL("mvfdz", e0081e0, 2, (RF, RF_IF), rd_rm),
25234 cCL("mvfe", e088100, 2, (RF, RF_IF), rd_rm),
25235 cCL("mvfep", e088120, 2, (RF, RF_IF), rd_rm),
25236 cCL("mvfem", e088140, 2, (RF, RF_IF), rd_rm),
25237 cCL("mvfez", e088160, 2, (RF, RF_IF), rd_rm),
25238
25239 cCL("mnfs", e108100, 2, (RF, RF_IF), rd_rm),
25240 cCL("mnfsp", e108120, 2, (RF, RF_IF), rd_rm),
25241 cCL("mnfsm", e108140, 2, (RF, RF_IF), rd_rm),
25242 cCL("mnfsz", e108160, 2, (RF, RF_IF), rd_rm),
25243 cCL("mnfd", e108180, 2, (RF, RF_IF), rd_rm),
25244 cCL("mnfdp", e1081a0, 2, (RF, RF_IF), rd_rm),
25245 cCL("mnfdm", e1081c0, 2, (RF, RF_IF), rd_rm),
25246 cCL("mnfdz", e1081e0, 2, (RF, RF_IF), rd_rm),
25247 cCL("mnfe", e188100, 2, (RF, RF_IF), rd_rm),
25248 cCL("mnfep", e188120, 2, (RF, RF_IF), rd_rm),
25249 cCL("mnfem", e188140, 2, (RF, RF_IF), rd_rm),
25250 cCL("mnfez", e188160, 2, (RF, RF_IF), rd_rm),
25251
25252 cCL("abss", e208100, 2, (RF, RF_IF), rd_rm),
25253 cCL("abssp", e208120, 2, (RF, RF_IF), rd_rm),
25254 cCL("abssm", e208140, 2, (RF, RF_IF), rd_rm),
25255 cCL("abssz", e208160, 2, (RF, RF_IF), rd_rm),
25256 cCL("absd", e208180, 2, (RF, RF_IF), rd_rm),
25257 cCL("absdp", e2081a0, 2, (RF, RF_IF), rd_rm),
25258 cCL("absdm", e2081c0, 2, (RF, RF_IF), rd_rm),
25259 cCL("absdz", e2081e0, 2, (RF, RF_IF), rd_rm),
25260 cCL("abse", e288100, 2, (RF, RF_IF), rd_rm),
25261 cCL("absep", e288120, 2, (RF, RF_IF), rd_rm),
25262 cCL("absem", e288140, 2, (RF, RF_IF), rd_rm),
25263 cCL("absez", e288160, 2, (RF, RF_IF), rd_rm),
25264
25265 cCL("rnds", e308100, 2, (RF, RF_IF), rd_rm),
25266 cCL("rndsp", e308120, 2, (RF, RF_IF), rd_rm),
25267 cCL("rndsm", e308140, 2, (RF, RF_IF), rd_rm),
25268 cCL("rndsz", e308160, 2, (RF, RF_IF), rd_rm),
25269 cCL("rndd", e308180, 2, (RF, RF_IF), rd_rm),
25270 cCL("rnddp", e3081a0, 2, (RF, RF_IF), rd_rm),
25271 cCL("rnddm", e3081c0, 2, (RF, RF_IF), rd_rm),
25272 cCL("rnddz", e3081e0, 2, (RF, RF_IF), rd_rm),
25273 cCL("rnde", e388100, 2, (RF, RF_IF), rd_rm),
25274 cCL("rndep", e388120, 2, (RF, RF_IF), rd_rm),
25275 cCL("rndem", e388140, 2, (RF, RF_IF), rd_rm),
25276 cCL("rndez", e388160, 2, (RF, RF_IF), rd_rm),
25277
25278 cCL("sqts", e408100, 2, (RF, RF_IF), rd_rm),
25279 cCL("sqtsp", e408120, 2, (RF, RF_IF), rd_rm),
25280 cCL("sqtsm", e408140, 2, (RF, RF_IF), rd_rm),
25281 cCL("sqtsz", e408160, 2, (RF, RF_IF), rd_rm),
25282 cCL("sqtd", e408180, 2, (RF, RF_IF), rd_rm),
25283 cCL("sqtdp", e4081a0, 2, (RF, RF_IF), rd_rm),
25284 cCL("sqtdm", e4081c0, 2, (RF, RF_IF), rd_rm),
25285 cCL("sqtdz", e4081e0, 2, (RF, RF_IF), rd_rm),
25286 cCL("sqte", e488100, 2, (RF, RF_IF), rd_rm),
25287 cCL("sqtep", e488120, 2, (RF, RF_IF), rd_rm),
25288 cCL("sqtem", e488140, 2, (RF, RF_IF), rd_rm),
25289 cCL("sqtez", e488160, 2, (RF, RF_IF), rd_rm),
25290
25291 cCL("logs", e508100, 2, (RF, RF_IF), rd_rm),
25292 cCL("logsp", e508120, 2, (RF, RF_IF), rd_rm),
25293 cCL("logsm", e508140, 2, (RF, RF_IF), rd_rm),
25294 cCL("logsz", e508160, 2, (RF, RF_IF), rd_rm),
25295 cCL("logd", e508180, 2, (RF, RF_IF), rd_rm),
25296 cCL("logdp", e5081a0, 2, (RF, RF_IF), rd_rm),
25297 cCL("logdm", e5081c0, 2, (RF, RF_IF), rd_rm),
25298 cCL("logdz", e5081e0, 2, (RF, RF_IF), rd_rm),
25299 cCL("loge", e588100, 2, (RF, RF_IF), rd_rm),
25300 cCL("logep", e588120, 2, (RF, RF_IF), rd_rm),
25301 cCL("logem", e588140, 2, (RF, RF_IF), rd_rm),
25302 cCL("logez", e588160, 2, (RF, RF_IF), rd_rm),
25303
25304 cCL("lgns", e608100, 2, (RF, RF_IF), rd_rm),
25305 cCL("lgnsp", e608120, 2, (RF, RF_IF), rd_rm),
25306 cCL("lgnsm", e608140, 2, (RF, RF_IF), rd_rm),
25307 cCL("lgnsz", e608160, 2, (RF, RF_IF), rd_rm),
25308 cCL("lgnd", e608180, 2, (RF, RF_IF), rd_rm),
25309 cCL("lgndp", e6081a0, 2, (RF, RF_IF), rd_rm),
25310 cCL("lgndm", e6081c0, 2, (RF, RF_IF), rd_rm),
25311 cCL("lgndz", e6081e0, 2, (RF, RF_IF), rd_rm),
25312 cCL("lgne", e688100, 2, (RF, RF_IF), rd_rm),
25313 cCL("lgnep", e688120, 2, (RF, RF_IF), rd_rm),
25314 cCL("lgnem", e688140, 2, (RF, RF_IF), rd_rm),
25315 cCL("lgnez", e688160, 2, (RF, RF_IF), rd_rm),
25316
25317 cCL("exps", e708100, 2, (RF, RF_IF), rd_rm),
25318 cCL("expsp", e708120, 2, (RF, RF_IF), rd_rm),
25319 cCL("expsm", e708140, 2, (RF, RF_IF), rd_rm),
25320 cCL("expsz", e708160, 2, (RF, RF_IF), rd_rm),
25321 cCL("expd", e708180, 2, (RF, RF_IF), rd_rm),
25322 cCL("expdp", e7081a0, 2, (RF, RF_IF), rd_rm),
25323 cCL("expdm", e7081c0, 2, (RF, RF_IF), rd_rm),
25324 cCL("expdz", e7081e0, 2, (RF, RF_IF), rd_rm),
25325 cCL("expe", e788100, 2, (RF, RF_IF), rd_rm),
25326 cCL("expep", e788120, 2, (RF, RF_IF), rd_rm),
25327 cCL("expem", e788140, 2, (RF, RF_IF), rd_rm),
25328 cCL("expdz", e788160, 2, (RF, RF_IF), rd_rm),
25329
25330 cCL("sins", e808100, 2, (RF, RF_IF), rd_rm),
25331 cCL("sinsp", e808120, 2, (RF, RF_IF), rd_rm),
25332 cCL("sinsm", e808140, 2, (RF, RF_IF), rd_rm),
25333 cCL("sinsz", e808160, 2, (RF, RF_IF), rd_rm),
25334 cCL("sind", e808180, 2, (RF, RF_IF), rd_rm),
25335 cCL("sindp", e8081a0, 2, (RF, RF_IF), rd_rm),
25336 cCL("sindm", e8081c0, 2, (RF, RF_IF), rd_rm),
25337 cCL("sindz", e8081e0, 2, (RF, RF_IF), rd_rm),
25338 cCL("sine", e888100, 2, (RF, RF_IF), rd_rm),
25339 cCL("sinep", e888120, 2, (RF, RF_IF), rd_rm),
25340 cCL("sinem", e888140, 2, (RF, RF_IF), rd_rm),
25341 cCL("sinez", e888160, 2, (RF, RF_IF), rd_rm),
25342
25343 cCL("coss", e908100, 2, (RF, RF_IF), rd_rm),
25344 cCL("cossp", e908120, 2, (RF, RF_IF), rd_rm),
25345 cCL("cossm", e908140, 2, (RF, RF_IF), rd_rm),
25346 cCL("cossz", e908160, 2, (RF, RF_IF), rd_rm),
25347 cCL("cosd", e908180, 2, (RF, RF_IF), rd_rm),
25348 cCL("cosdp", e9081a0, 2, (RF, RF_IF), rd_rm),
25349 cCL("cosdm", e9081c0, 2, (RF, RF_IF), rd_rm),
25350 cCL("cosdz", e9081e0, 2, (RF, RF_IF), rd_rm),
25351 cCL("cose", e988100, 2, (RF, RF_IF), rd_rm),
25352 cCL("cosep", e988120, 2, (RF, RF_IF), rd_rm),
25353 cCL("cosem", e988140, 2, (RF, RF_IF), rd_rm),
25354 cCL("cosez", e988160, 2, (RF, RF_IF), rd_rm),
25355
25356 cCL("tans", ea08100, 2, (RF, RF_IF), rd_rm),
25357 cCL("tansp", ea08120, 2, (RF, RF_IF), rd_rm),
25358 cCL("tansm", ea08140, 2, (RF, RF_IF), rd_rm),
25359 cCL("tansz", ea08160, 2, (RF, RF_IF), rd_rm),
25360 cCL("tand", ea08180, 2, (RF, RF_IF), rd_rm),
25361 cCL("tandp", ea081a0, 2, (RF, RF_IF), rd_rm),
25362 cCL("tandm", ea081c0, 2, (RF, RF_IF), rd_rm),
25363 cCL("tandz", ea081e0, 2, (RF, RF_IF), rd_rm),
25364 cCL("tane", ea88100, 2, (RF, RF_IF), rd_rm),
25365 cCL("tanep", ea88120, 2, (RF, RF_IF), rd_rm),
25366 cCL("tanem", ea88140, 2, (RF, RF_IF), rd_rm),
25367 cCL("tanez", ea88160, 2, (RF, RF_IF), rd_rm),
25368
25369 cCL("asns", eb08100, 2, (RF, RF_IF), rd_rm),
25370 cCL("asnsp", eb08120, 2, (RF, RF_IF), rd_rm),
25371 cCL("asnsm", eb08140, 2, (RF, RF_IF), rd_rm),
25372 cCL("asnsz", eb08160, 2, (RF, RF_IF), rd_rm),
25373 cCL("asnd", eb08180, 2, (RF, RF_IF), rd_rm),
25374 cCL("asndp", eb081a0, 2, (RF, RF_IF), rd_rm),
25375 cCL("asndm", eb081c0, 2, (RF, RF_IF), rd_rm),
25376 cCL("asndz", eb081e0, 2, (RF, RF_IF), rd_rm),
25377 cCL("asne", eb88100, 2, (RF, RF_IF), rd_rm),
25378 cCL("asnep", eb88120, 2, (RF, RF_IF), rd_rm),
25379 cCL("asnem", eb88140, 2, (RF, RF_IF), rd_rm),
25380 cCL("asnez", eb88160, 2, (RF, RF_IF), rd_rm),
25381
25382 cCL("acss", ec08100, 2, (RF, RF_IF), rd_rm),
25383 cCL("acssp", ec08120, 2, (RF, RF_IF), rd_rm),
25384 cCL("acssm", ec08140, 2, (RF, RF_IF), rd_rm),
25385 cCL("acssz", ec08160, 2, (RF, RF_IF), rd_rm),
25386 cCL("acsd", ec08180, 2, (RF, RF_IF), rd_rm),
25387 cCL("acsdp", ec081a0, 2, (RF, RF_IF), rd_rm),
25388 cCL("acsdm", ec081c0, 2, (RF, RF_IF), rd_rm),
25389 cCL("acsdz", ec081e0, 2, (RF, RF_IF), rd_rm),
25390 cCL("acse", ec88100, 2, (RF, RF_IF), rd_rm),
25391 cCL("acsep", ec88120, 2, (RF, RF_IF), rd_rm),
25392 cCL("acsem", ec88140, 2, (RF, RF_IF), rd_rm),
25393 cCL("acsez", ec88160, 2, (RF, RF_IF), rd_rm),
25394
25395 cCL("atns", ed08100, 2, (RF, RF_IF), rd_rm),
25396 cCL("atnsp", ed08120, 2, (RF, RF_IF), rd_rm),
25397 cCL("atnsm", ed08140, 2, (RF, RF_IF), rd_rm),
25398 cCL("atnsz", ed08160, 2, (RF, RF_IF), rd_rm),
25399 cCL("atnd", ed08180, 2, (RF, RF_IF), rd_rm),
25400 cCL("atndp", ed081a0, 2, (RF, RF_IF), rd_rm),
25401 cCL("atndm", ed081c0, 2, (RF, RF_IF), rd_rm),
25402 cCL("atndz", ed081e0, 2, (RF, RF_IF), rd_rm),
25403 cCL("atne", ed88100, 2, (RF, RF_IF), rd_rm),
25404 cCL("atnep", ed88120, 2, (RF, RF_IF), rd_rm),
25405 cCL("atnem", ed88140, 2, (RF, RF_IF), rd_rm),
25406 cCL("atnez", ed88160, 2, (RF, RF_IF), rd_rm),
25407
25408 cCL("urds", ee08100, 2, (RF, RF_IF), rd_rm),
25409 cCL("urdsp", ee08120, 2, (RF, RF_IF), rd_rm),
25410 cCL("urdsm", ee08140, 2, (RF, RF_IF), rd_rm),
25411 cCL("urdsz", ee08160, 2, (RF, RF_IF), rd_rm),
25412 cCL("urdd", ee08180, 2, (RF, RF_IF), rd_rm),
25413 cCL("urddp", ee081a0, 2, (RF, RF_IF), rd_rm),
25414 cCL("urddm", ee081c0, 2, (RF, RF_IF), rd_rm),
25415 cCL("urddz", ee081e0, 2, (RF, RF_IF), rd_rm),
25416 cCL("urde", ee88100, 2, (RF, RF_IF), rd_rm),
25417 cCL("urdep", ee88120, 2, (RF, RF_IF), rd_rm),
25418 cCL("urdem", ee88140, 2, (RF, RF_IF), rd_rm),
25419 cCL("urdez", ee88160, 2, (RF, RF_IF), rd_rm),
25420
25421 cCL("nrms", ef08100, 2, (RF, RF_IF), rd_rm),
25422 cCL("nrmsp", ef08120, 2, (RF, RF_IF), rd_rm),
25423 cCL("nrmsm", ef08140, 2, (RF, RF_IF), rd_rm),
25424 cCL("nrmsz", ef08160, 2, (RF, RF_IF), rd_rm),
25425 cCL("nrmd", ef08180, 2, (RF, RF_IF), rd_rm),
25426 cCL("nrmdp", ef081a0, 2, (RF, RF_IF), rd_rm),
25427 cCL("nrmdm", ef081c0, 2, (RF, RF_IF), rd_rm),
25428 cCL("nrmdz", ef081e0, 2, (RF, RF_IF), rd_rm),
25429 cCL("nrme", ef88100, 2, (RF, RF_IF), rd_rm),
25430 cCL("nrmep", ef88120, 2, (RF, RF_IF), rd_rm),
25431 cCL("nrmem", ef88140, 2, (RF, RF_IF), rd_rm),
25432 cCL("nrmez", ef88160, 2, (RF, RF_IF), rd_rm),
25433
25434 cCL("adfs", e000100, 3, (RF, RF, RF_IF), rd_rn_rm),
25435 cCL("adfsp", e000120, 3, (RF, RF, RF_IF), rd_rn_rm),
25436 cCL("adfsm", e000140, 3, (RF, RF, RF_IF), rd_rn_rm),
25437 cCL("adfsz", e000160, 3, (RF, RF, RF_IF), rd_rn_rm),
25438 cCL("adfd", e000180, 3, (RF, RF, RF_IF), rd_rn_rm),
25439 cCL("adfdp", e0001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25440 cCL("adfdm", e0001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25441 cCL("adfdz", e0001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25442 cCL("adfe", e080100, 3, (RF, RF, RF_IF), rd_rn_rm),
25443 cCL("adfep", e080120, 3, (RF, RF, RF_IF), rd_rn_rm),
25444 cCL("adfem", e080140, 3, (RF, RF, RF_IF), rd_rn_rm),
25445 cCL("adfez", e080160, 3, (RF, RF, RF_IF), rd_rn_rm),
25446
25447 cCL("sufs", e200100, 3, (RF, RF, RF_IF), rd_rn_rm),
25448 cCL("sufsp", e200120, 3, (RF, RF, RF_IF), rd_rn_rm),
25449 cCL("sufsm", e200140, 3, (RF, RF, RF_IF), rd_rn_rm),
25450 cCL("sufsz", e200160, 3, (RF, RF, RF_IF), rd_rn_rm),
25451 cCL("sufd", e200180, 3, (RF, RF, RF_IF), rd_rn_rm),
25452 cCL("sufdp", e2001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25453 cCL("sufdm", e2001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25454 cCL("sufdz", e2001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25455 cCL("sufe", e280100, 3, (RF, RF, RF_IF), rd_rn_rm),
25456 cCL("sufep", e280120, 3, (RF, RF, RF_IF), rd_rn_rm),
25457 cCL("sufem", e280140, 3, (RF, RF, RF_IF), rd_rn_rm),
25458 cCL("sufez", e280160, 3, (RF, RF, RF_IF), rd_rn_rm),
25459
25460 cCL("rsfs", e300100, 3, (RF, RF, RF_IF), rd_rn_rm),
25461 cCL("rsfsp", e300120, 3, (RF, RF, RF_IF), rd_rn_rm),
25462 cCL("rsfsm", e300140, 3, (RF, RF, RF_IF), rd_rn_rm),
25463 cCL("rsfsz", e300160, 3, (RF, RF, RF_IF), rd_rn_rm),
25464 cCL("rsfd", e300180, 3, (RF, RF, RF_IF), rd_rn_rm),
25465 cCL("rsfdp", e3001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25466 cCL("rsfdm", e3001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25467 cCL("rsfdz", e3001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25468 cCL("rsfe", e380100, 3, (RF, RF, RF_IF), rd_rn_rm),
25469 cCL("rsfep", e380120, 3, (RF, RF, RF_IF), rd_rn_rm),
25470 cCL("rsfem", e380140, 3, (RF, RF, RF_IF), rd_rn_rm),
25471 cCL("rsfez", e380160, 3, (RF, RF, RF_IF), rd_rn_rm),
25472
25473 cCL("mufs", e100100, 3, (RF, RF, RF_IF), rd_rn_rm),
25474 cCL("mufsp", e100120, 3, (RF, RF, RF_IF), rd_rn_rm),
25475 cCL("mufsm", e100140, 3, (RF, RF, RF_IF), rd_rn_rm),
25476 cCL("mufsz", e100160, 3, (RF, RF, RF_IF), rd_rn_rm),
25477 cCL("mufd", e100180, 3, (RF, RF, RF_IF), rd_rn_rm),
25478 cCL("mufdp", e1001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25479 cCL("mufdm", e1001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25480 cCL("mufdz", e1001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25481 cCL("mufe", e180100, 3, (RF, RF, RF_IF), rd_rn_rm),
25482 cCL("mufep", e180120, 3, (RF, RF, RF_IF), rd_rn_rm),
25483 cCL("mufem", e180140, 3, (RF, RF, RF_IF), rd_rn_rm),
25484 cCL("mufez", e180160, 3, (RF, RF, RF_IF), rd_rn_rm),
25485
25486 cCL("dvfs", e400100, 3, (RF, RF, RF_IF), rd_rn_rm),
25487 cCL("dvfsp", e400120, 3, (RF, RF, RF_IF), rd_rn_rm),
25488 cCL("dvfsm", e400140, 3, (RF, RF, RF_IF), rd_rn_rm),
25489 cCL("dvfsz", e400160, 3, (RF, RF, RF_IF), rd_rn_rm),
25490 cCL("dvfd", e400180, 3, (RF, RF, RF_IF), rd_rn_rm),
25491 cCL("dvfdp", e4001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25492 cCL("dvfdm", e4001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25493 cCL("dvfdz", e4001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25494 cCL("dvfe", e480100, 3, (RF, RF, RF_IF), rd_rn_rm),
25495 cCL("dvfep", e480120, 3, (RF, RF, RF_IF), rd_rn_rm),
25496 cCL("dvfem", e480140, 3, (RF, RF, RF_IF), rd_rn_rm),
25497 cCL("dvfez", e480160, 3, (RF, RF, RF_IF), rd_rn_rm),
25498
25499 cCL("rdfs", e500100, 3, (RF, RF, RF_IF), rd_rn_rm),
25500 cCL("rdfsp", e500120, 3, (RF, RF, RF_IF), rd_rn_rm),
25501 cCL("rdfsm", e500140, 3, (RF, RF, RF_IF), rd_rn_rm),
25502 cCL("rdfsz", e500160, 3, (RF, RF, RF_IF), rd_rn_rm),
25503 cCL("rdfd", e500180, 3, (RF, RF, RF_IF), rd_rn_rm),
25504 cCL("rdfdp", e5001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25505 cCL("rdfdm", e5001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25506 cCL("rdfdz", e5001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25507 cCL("rdfe", e580100, 3, (RF, RF, RF_IF), rd_rn_rm),
25508 cCL("rdfep", e580120, 3, (RF, RF, RF_IF), rd_rn_rm),
25509 cCL("rdfem", e580140, 3, (RF, RF, RF_IF), rd_rn_rm),
25510 cCL("rdfez", e580160, 3, (RF, RF, RF_IF), rd_rn_rm),
25511
25512 cCL("pows", e600100, 3, (RF, RF, RF_IF), rd_rn_rm),
25513 cCL("powsp", e600120, 3, (RF, RF, RF_IF), rd_rn_rm),
25514 cCL("powsm", e600140, 3, (RF, RF, RF_IF), rd_rn_rm),
25515 cCL("powsz", e600160, 3, (RF, RF, RF_IF), rd_rn_rm),
25516 cCL("powd", e600180, 3, (RF, RF, RF_IF), rd_rn_rm),
25517 cCL("powdp", e6001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25518 cCL("powdm", e6001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25519 cCL("powdz", e6001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25520 cCL("powe", e680100, 3, (RF, RF, RF_IF), rd_rn_rm),
25521 cCL("powep", e680120, 3, (RF, RF, RF_IF), rd_rn_rm),
25522 cCL("powem", e680140, 3, (RF, RF, RF_IF), rd_rn_rm),
25523 cCL("powez", e680160, 3, (RF, RF, RF_IF), rd_rn_rm),
25524
25525 cCL("rpws", e700100, 3, (RF, RF, RF_IF), rd_rn_rm),
25526 cCL("rpwsp", e700120, 3, (RF, RF, RF_IF), rd_rn_rm),
25527 cCL("rpwsm", e700140, 3, (RF, RF, RF_IF), rd_rn_rm),
25528 cCL("rpwsz", e700160, 3, (RF, RF, RF_IF), rd_rn_rm),
25529 cCL("rpwd", e700180, 3, (RF, RF, RF_IF), rd_rn_rm),
25530 cCL("rpwdp", e7001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25531 cCL("rpwdm", e7001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25532 cCL("rpwdz", e7001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25533 cCL("rpwe", e780100, 3, (RF, RF, RF_IF), rd_rn_rm),
25534 cCL("rpwep", e780120, 3, (RF, RF, RF_IF), rd_rn_rm),
25535 cCL("rpwem", e780140, 3, (RF, RF, RF_IF), rd_rn_rm),
25536 cCL("rpwez", e780160, 3, (RF, RF, RF_IF), rd_rn_rm),
25537
25538 cCL("rmfs", e800100, 3, (RF, RF, RF_IF), rd_rn_rm),
25539 cCL("rmfsp", e800120, 3, (RF, RF, RF_IF), rd_rn_rm),
25540 cCL("rmfsm", e800140, 3, (RF, RF, RF_IF), rd_rn_rm),
25541 cCL("rmfsz", e800160, 3, (RF, RF, RF_IF), rd_rn_rm),
25542 cCL("rmfd", e800180, 3, (RF, RF, RF_IF), rd_rn_rm),
25543 cCL("rmfdp", e8001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25544 cCL("rmfdm", e8001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25545 cCL("rmfdz", e8001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25546 cCL("rmfe", e880100, 3, (RF, RF, RF_IF), rd_rn_rm),
25547 cCL("rmfep", e880120, 3, (RF, RF, RF_IF), rd_rn_rm),
25548 cCL("rmfem", e880140, 3, (RF, RF, RF_IF), rd_rn_rm),
25549 cCL("rmfez", e880160, 3, (RF, RF, RF_IF), rd_rn_rm),
25550
25551 cCL("fmls", e900100, 3, (RF, RF, RF_IF), rd_rn_rm),
25552 cCL("fmlsp", e900120, 3, (RF, RF, RF_IF), rd_rn_rm),
25553 cCL("fmlsm", e900140, 3, (RF, RF, RF_IF), rd_rn_rm),
25554 cCL("fmlsz", e900160, 3, (RF, RF, RF_IF), rd_rn_rm),
25555 cCL("fmld", e900180, 3, (RF, RF, RF_IF), rd_rn_rm),
25556 cCL("fmldp", e9001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25557 cCL("fmldm", e9001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25558 cCL("fmldz", e9001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25559 cCL("fmle", e980100, 3, (RF, RF, RF_IF), rd_rn_rm),
25560 cCL("fmlep", e980120, 3, (RF, RF, RF_IF), rd_rn_rm),
25561 cCL("fmlem", e980140, 3, (RF, RF, RF_IF), rd_rn_rm),
25562 cCL("fmlez", e980160, 3, (RF, RF, RF_IF), rd_rn_rm),
25563
25564 cCL("fdvs", ea00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25565 cCL("fdvsp", ea00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25566 cCL("fdvsm", ea00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25567 cCL("fdvsz", ea00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25568 cCL("fdvd", ea00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25569 cCL("fdvdp", ea001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25570 cCL("fdvdm", ea001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25571 cCL("fdvdz", ea001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25572 cCL("fdve", ea80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25573 cCL("fdvep", ea80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25574 cCL("fdvem", ea80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25575 cCL("fdvez", ea80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25576
25577 cCL("frds", eb00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25578 cCL("frdsp", eb00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25579 cCL("frdsm", eb00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25580 cCL("frdsz", eb00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25581 cCL("frdd", eb00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25582 cCL("frddp", eb001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25583 cCL("frddm", eb001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25584 cCL("frddz", eb001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25585 cCL("frde", eb80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25586 cCL("frdep", eb80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25587 cCL("frdem", eb80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25588 cCL("frdez", eb80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25589
25590 cCL("pols", ec00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25591 cCL("polsp", ec00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25592 cCL("polsm", ec00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25593 cCL("polsz", ec00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25594 cCL("pold", ec00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25595 cCL("poldp", ec001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25596 cCL("poldm", ec001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25597 cCL("poldz", ec001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25598 cCL("pole", ec80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25599 cCL("polep", ec80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25600 cCL("polem", ec80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25601 cCL("polez", ec80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25602
25603 cCE("cmf", e90f110, 2, (RF, RF_IF), fpa_cmp),
25604 C3E("cmfe", ed0f110, 2, (RF, RF_IF), fpa_cmp),
25605 cCE("cnf", eb0f110, 2, (RF, RF_IF), fpa_cmp),
25606 C3E("cnfe", ef0f110, 2, (RF, RF_IF), fpa_cmp),
25607
25608 cCL("flts", e000110, 2, (RF, RR), rn_rd),
25609 cCL("fltsp", e000130, 2, (RF, RR), rn_rd),
25610 cCL("fltsm", e000150, 2, (RF, RR), rn_rd),
25611 cCL("fltsz", e000170, 2, (RF, RR), rn_rd),
25612 cCL("fltd", e000190, 2, (RF, RR), rn_rd),
25613 cCL("fltdp", e0001b0, 2, (RF, RR), rn_rd),
25614 cCL("fltdm", e0001d0, 2, (RF, RR), rn_rd),
25615 cCL("fltdz", e0001f0, 2, (RF, RR), rn_rd),
25616 cCL("flte", e080110, 2, (RF, RR), rn_rd),
25617 cCL("fltep", e080130, 2, (RF, RR), rn_rd),
25618 cCL("fltem", e080150, 2, (RF, RR), rn_rd),
25619 cCL("fltez", e080170, 2, (RF, RR), rn_rd),
b99bd4ef 25620
c19d1205
ZW
25621 /* The implementation of the FIX instruction is broken on some
25622 assemblers, in that it accepts a precision specifier as well as a
25623 rounding specifier, despite the fact that this is meaningless.
25624 To be more compatible, we accept it as well, though of course it
25625 does not set any bits. */
21d799b5
NC
25626 cCE("fix", e100110, 2, (RR, RF), rd_rm),
25627 cCL("fixp", e100130, 2, (RR, RF), rd_rm),
25628 cCL("fixm", e100150, 2, (RR, RF), rd_rm),
25629 cCL("fixz", e100170, 2, (RR, RF), rd_rm),
25630 cCL("fixsp", e100130, 2, (RR, RF), rd_rm),
25631 cCL("fixsm", e100150, 2, (RR, RF), rd_rm),
25632 cCL("fixsz", e100170, 2, (RR, RF), rd_rm),
25633 cCL("fixdp", e100130, 2, (RR, RF), rd_rm),
25634 cCL("fixdm", e100150, 2, (RR, RF), rd_rm),
25635 cCL("fixdz", e100170, 2, (RR, RF), rd_rm),
25636 cCL("fixep", e100130, 2, (RR, RF), rd_rm),
25637 cCL("fixem", e100150, 2, (RR, RF), rd_rm),
25638 cCL("fixez", e100170, 2, (RR, RF), rd_rm),
bfae80f2 25639
c19d1205 25640 /* Instructions that were new with the real FPA, call them V2. */
c921be7d
NC
25641#undef ARM_VARIANT
25642#define ARM_VARIANT & fpu_fpa_ext_v2
25643
21d799b5
NC
25644 cCE("lfm", c100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25645 cCL("lfmfd", c900200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25646 cCL("lfmea", d100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25647 cCE("sfm", c000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25648 cCL("sfmfd", d000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25649 cCL("sfmea", c800200, 3, (RF, I4b, ADDR), fpa_ldmstm),
c19d1205 25650
c921be7d
NC
25651#undef ARM_VARIANT
25652#define ARM_VARIANT & fpu_vfp_ext_v1xd /* VFP V1xD (single precision). */
ba6cd17f
SD
25653#undef THUMB_VARIANT
25654#define THUMB_VARIANT & arm_ext_v6t2
25655 mcCE(vmrs, ef00a10, 2, (APSR_RR, RVC), vmrs),
25656 mcCE(vmsr, ee00a10, 2, (RVC, RR), vmsr),
ef8f595f
MI
25657 mcCE(fldd, d100b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
25658 mcCE(fstd, d000b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
25659 mcCE(flds, d100a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
25660 mcCE(fsts, d000a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
90e9955a
SP
25661
25662 /* Memory operations. */
25663 mcCE(fldmias, c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
25664 mcCE(fldmdbs, d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25665 mcCE(fstmias, c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
25666 mcCE(fstmdbs, d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
ba6cd17f 25667#undef THUMB_VARIANT
c921be7d 25668
c19d1205 25669 /* Moves and type conversions. */
21d799b5
NC
25670 cCE("fmstat", ef1fa10, 0, (), noargs),
25671 cCE("fsitos", eb80ac0, 2, (RVS, RVS), vfp_sp_monadic),
25672 cCE("fuitos", eb80a40, 2, (RVS, RVS), vfp_sp_monadic),
25673 cCE("ftosis", ebd0a40, 2, (RVS, RVS), vfp_sp_monadic),
25674 cCE("ftosizs", ebd0ac0, 2, (RVS, RVS), vfp_sp_monadic),
25675 cCE("ftouis", ebc0a40, 2, (RVS, RVS), vfp_sp_monadic),
25676 cCE("ftouizs", ebc0ac0, 2, (RVS, RVS), vfp_sp_monadic),
25677 cCE("fmrx", ef00a10, 2, (RR, RVC), rd_rn),
25678 cCE("fmxr", ee00a10, 2, (RVC, RR), rn_rd),
c19d1205
ZW
25679
25680 /* Memory operations. */
55881a11 25681 cCE("fldmfds", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
55881a11
MGD
25682 cCE("fldmeas", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25683 cCE("fldmiax", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25684 cCE("fldmfdx", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25685 cCE("fldmdbx", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
25686 cCE("fldmeax", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
55881a11 25687 cCE("fstmeas", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
55881a11
MGD
25688 cCE("fstmfds", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25689 cCE("fstmiax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25690 cCE("fstmeax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25691 cCE("fstmdbx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
25692 cCE("fstmfdx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
bfae80f2 25693
c19d1205 25694 /* Monadic operations. */
21d799b5
NC
25695 cCE("fabss", eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
25696 cCE("fnegs", eb10a40, 2, (RVS, RVS), vfp_sp_monadic),
25697 cCE("fsqrts", eb10ac0, 2, (RVS, RVS), vfp_sp_monadic),
c19d1205
ZW
25698
25699 /* Dyadic operations. */
21d799b5
NC
25700 cCE("fadds", e300a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25701 cCE("fsubs", e300a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25702 cCE("fmuls", e200a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25703 cCE("fdivs", e800a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25704 cCE("fmacs", e000a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25705 cCE("fmscs", e100a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25706 cCE("fnmuls", e200a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25707 cCE("fnmacs", e000a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25708 cCE("fnmscs", e100a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
b99bd4ef 25709
c19d1205 25710 /* Comparisons. */
21d799b5
NC
25711 cCE("fcmps", eb40a40, 2, (RVS, RVS), vfp_sp_monadic),
25712 cCE("fcmpzs", eb50a40, 1, (RVS), vfp_sp_compare_z),
25713 cCE("fcmpes", eb40ac0, 2, (RVS, RVS), vfp_sp_monadic),
25714 cCE("fcmpezs", eb50ac0, 1, (RVS), vfp_sp_compare_z),
b99bd4ef 25715
62f3b8c8
PB
25716 /* Double precision load/store are still present on single precision
25717 implementations. */
55881a11
MGD
25718 cCE("fldmiad", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25719 cCE("fldmfdd", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25720 cCE("fldmdbd", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25721 cCE("fldmead", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25722 cCE("fstmiad", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25723 cCE("fstmead", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25724 cCE("fstmdbd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25725 cCE("fstmfdd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
62f3b8c8 25726
c921be7d
NC
25727#undef ARM_VARIANT
25728#define ARM_VARIANT & fpu_vfp_ext_v1 /* VFP V1 (Double precision). */
25729
c19d1205 25730 /* Moves and type conversions. */
21d799b5
NC
25731 cCE("fcvtds", eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt),
25732 cCE("fcvtsd", eb70bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
25733 cCE("fmdhr", e200b10, 2, (RVD, RR), vfp_dp_rn_rd),
25734 cCE("fmdlr", e000b10, 2, (RVD, RR), vfp_dp_rn_rd),
25735 cCE("fmrdh", e300b10, 2, (RR, RVD), vfp_dp_rd_rn),
25736 cCE("fmrdl", e100b10, 2, (RR, RVD), vfp_dp_rd_rn),
25737 cCE("fsitod", eb80bc0, 2, (RVD, RVS), vfp_dp_sp_cvt),
25738 cCE("fuitod", eb80b40, 2, (RVD, RVS), vfp_dp_sp_cvt),
25739 cCE("ftosid", ebd0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
25740 cCE("ftosizd", ebd0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
25741 cCE("ftouid", ebc0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
25742 cCE("ftouizd", ebc0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
c19d1205 25743
c19d1205 25744 /* Monadic operations. */
21d799b5
NC
25745 cCE("fabsd", eb00bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
25746 cCE("fnegd", eb10b40, 2, (RVD, RVD), vfp_dp_rd_rm),
25747 cCE("fsqrtd", eb10bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
c19d1205
ZW
25748
25749 /* Dyadic operations. */
21d799b5
NC
25750 cCE("faddd", e300b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25751 cCE("fsubd", e300b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25752 cCE("fmuld", e200b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25753 cCE("fdivd", e800b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25754 cCE("fmacd", e000b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25755 cCE("fmscd", e100b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25756 cCE("fnmuld", e200b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25757 cCE("fnmacd", e000b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25758 cCE("fnmscd", e100b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
b99bd4ef 25759
c19d1205 25760 /* Comparisons. */
21d799b5
NC
25761 cCE("fcmpd", eb40b40, 2, (RVD, RVD), vfp_dp_rd_rm),
25762 cCE("fcmpzd", eb50b40, 1, (RVD), vfp_dp_rd),
25763 cCE("fcmped", eb40bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
25764 cCE("fcmpezd", eb50bc0, 1, (RVD), vfp_dp_rd),
c19d1205 25765
037e8744
JB
25766/* Instructions which may belong to either the Neon or VFP instruction sets.
25767 Individual encoder functions perform additional architecture checks. */
c921be7d
NC
25768#undef ARM_VARIANT
25769#define ARM_VARIANT & fpu_vfp_ext_v1xd
ef8f595f
MI
25770#undef THUMB_VARIANT
25771#define THUMB_VARIANT & arm_ext_v6t2
25772
25773 NCE(vldm, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25774 NCE(vldmia, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25775 NCE(vldmdb, d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25776 NCE(vstm, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25777 NCE(vstmia, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25778 NCE(vstmdb, d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25779
25780 NCE(vpop, 0, 1, (VRSDLST), vfp_nsyn_pop),
25781 NCE(vpush, 0, 1, (VRSDLST), vfp_nsyn_push),
25782
c921be7d
NC
25783#undef THUMB_VARIANT
25784#define THUMB_VARIANT & fpu_vfp_ext_v1xd
25785
037e8744
JB
25786 /* These mnemonics are unique to VFP. */
25787 NCE(vsqrt, 0, 2, (RVSD, RVSD), vfp_nsyn_sqrt),
25788 NCE(vdiv, 0, 3, (RVSD, RVSD, RVSD), vfp_nsyn_div),
21d799b5
NC
25789 nCE(vnmul, _vnmul, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
25790 nCE(vnmla, _vnmla, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
25791 nCE(vnmls, _vnmls, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
037e8744
JB
25792 NCE(vcvtz, 0, 2, (RVSD, RVSD), vfp_nsyn_cvtz),
25793
25794 /* Mnemonics shared by Neon and VFP. */
21d799b5 25795 nCEF(vmls, _vmls, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
037e8744 25796
dd9634d9 25797 mnCEF(vcvt, _vcvt, 3, (RNSDQMQ, RNSDQMQ, oI32z), neon_cvt),
e3e535bc 25798 nCEF(vcvtr, _vcvt, 2, (RNSDQ, RNSDQ), neon_cvtr),
dd9634d9
AV
25799 MNCEF(vcvtb, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtb),
25800 MNCEF(vcvtt, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtt),
f31fef98 25801
037e8744
JB
25802
25803 /* NOTE: All VMOV encoding is special-cased! */
037e8744
JB
25804 NCE(vmovq, 0, 1, (VMOV), neon_mov),
25805
32c36c3c
AV
25806#undef THUMB_VARIANT
25807/* Could be either VLDR/VSTR or VLDR/VSTR (system register) which are guarded
25808 by different feature bits. Since we are setting the Thumb guard, we can
25809 require Thumb-1 which makes it a nop guard and set the right feature bit in
25810 do_vldr_vstr (). */
25811#define THUMB_VARIANT & arm_ext_v4t
25812 NCE(vldr, d100b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
25813 NCE(vstr, d000b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
25814
9db2f6b4
RL
25815#undef ARM_VARIANT
25816#define ARM_VARIANT & arm_ext_fp16
25817#undef THUMB_VARIANT
25818#define THUMB_VARIANT & arm_ext_fp16
25819 /* New instructions added from v8.2, allowing the extraction and insertion of
25820 the upper 16 bits of a 32-bit vector register. */
25821 NCE (vmovx, eb00a40, 2, (RVS, RVS), neon_movhf),
25822 NCE (vins, eb00ac0, 2, (RVS, RVS), neon_movhf),
25823
dec41383 25824 /* New backported fma/fms instructions optional in v8.2. */
aab2c27d
MM
25825 NUF (vfmsl, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmsl),
25826 NUF (vfmal, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmal),
dec41383 25827
c921be7d
NC
25828#undef THUMB_VARIANT
25829#define THUMB_VARIANT & fpu_neon_ext_v1
25830#undef ARM_VARIANT
25831#define ARM_VARIANT & fpu_neon_ext_v1
25832
5287ad62
JB
25833 /* Data processing with three registers of the same length. */
25834 /* integer ops, valid types S8 S16 S32 U8 U16 U32. */
25835 NUF(vaba, 0000710, 3, (RNDQ, RNDQ, RNDQ), neon_dyadic_i_su),
25836 NUF(vabaq, 0000710, 3, (RNQ, RNQ, RNQ), neon_dyadic_i_su),
5287ad62 25837 NUF(vhaddq, 0000000, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62 25838 NUF(vrhaddq, 0000100, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62
JB
25839 NUF(vhsubq, 0000200, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
25840 /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62 25841 NUF(vqaddq, 0000010, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
5287ad62 25842 NUF(vqsubq, 0000210, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
627907b7 25843 NUF(vrshlq, 0000500, 3, (RNQ, oRNQ, RNQ), neon_rshl),
627907b7 25844 NUF(vqrshlq, 0000510, 3, (RNQ, oRNQ, RNQ), neon_rshl),
5287ad62 25845 /* If not immediate, fall back to neon_dyadic_i64_su.
5150f0d8
AV
25846 shl should accept I8 I16 I32 I64,
25847 qshl should accept S8 S16 S32 S64 U8 U16 U32 U64. */
25848 nUF(vshlq, _vshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_shl),
25849 nUF(vqshlq, _vqshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_qshl),
5287ad62 25850 /* Logic ops, types optional & ignored. */
4316f0d2 25851 nUF(vandq, _vand, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25852 nUF(vbicq, _vbic, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25853 nUF(vorrq, _vorr, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25854 nUF(vornq, _vorn, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25855 nUF(veorq, _veor, 3, (RNQ, oRNQ, RNQ), neon_logic),
5287ad62
JB
25856 /* Bitfield ops, untyped. */
25857 NUF(vbsl, 1100110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25858 NUF(vbslq, 1100110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
25859 NUF(vbit, 1200110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25860 NUF(vbitq, 1200110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
25861 NUF(vbif, 1300110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25862 NUF(vbifq, 1300110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
cc933301 25863 /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32. */
21d799b5 25864 nUF(vabdq, _vabd, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 25865 nUF(vmaxq, _vmax, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 25866 nUF(vminq, _vmin, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
5287ad62
JB
25867 /* Comparisons. Types S8 S16 S32 U8 U16 U32 F32. Non-immediate versions fall
25868 back to neon_dyadic_if_su. */
21d799b5
NC
25869 nUF(vcge, _vcge, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
25870 nUF(vcgeq, _vcge, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
25871 nUF(vcgt, _vcgt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
25872 nUF(vcgtq, _vcgt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
25873 nUF(vclt, _vclt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
25874 nUF(vcltq, _vclt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
25875 nUF(vcle, _vcle, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
25876 nUF(vcleq, _vcle, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
428e3f1f 25877 /* Comparison. Type I8 I16 I32 F32. */
21d799b5
NC
25878 nUF(vceq, _vceq, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_ceq),
25879 nUF(vceqq, _vceq, 3, (RNQ, oRNQ, RNDQ_I0), neon_ceq),
5287ad62 25880 /* As above, D registers only. */
21d799b5
NC
25881 nUF(vpmax, _vpmax, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
25882 nUF(vpmin, _vpmin, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
5287ad62 25883 /* Int and float variants, signedness unimportant. */
21d799b5
NC
25884 nUF(vmlaq, _vmla, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
25885 nUF(vmlsq, _vmls, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
25886 nUF(vpadd, _vpadd, 3, (RND, oRND, RND), neon_dyadic_if_i_d),
5287ad62 25887 /* Add/sub take types I8 I16 I32 I64 F32. */
21d799b5
NC
25888 nUF(vaddq, _vadd, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
25889 nUF(vsubq, _vsub, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
5287ad62
JB
25890 /* vtst takes sizes 8, 16, 32. */
25891 NUF(vtst, 0000810, 3, (RNDQ, oRNDQ, RNDQ), neon_tst),
25892 NUF(vtstq, 0000810, 3, (RNQ, oRNQ, RNQ), neon_tst),
25893 /* VMUL takes I8 I16 I32 F32 P8. */
21d799b5 25894 nUF(vmulq, _vmul, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mul),
5287ad62 25895 /* VQD{R}MULH takes S16 S32. */
21d799b5 25896 nUF(vqdmulhq, _vqdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
21d799b5 25897 nUF(vqrdmulhq, _vqrdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
5287ad62
JB
25898 NUF(vacge, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
25899 NUF(vacgeq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
25900 NUF(vacgt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
25901 NUF(vacgtq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
92559b5b
PB
25902 NUF(vaclt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
25903 NUF(vacltq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
25904 NUF(vacle, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
25905 NUF(vacleq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
5287ad62
JB
25906 NUF(vrecps, 0000f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
25907 NUF(vrecpsq, 0000f10, 3, (RNQ, oRNQ, RNQ), neon_step),
25908 NUF(vrsqrts, 0200f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
25909 NUF(vrsqrtsq, 0200f10, 3, (RNQ, oRNQ, RNQ), neon_step),
d6b4b13e 25910 /* ARM v8.1 extension. */
643afb90
MW
25911 nUF (vqrdmlahq, _vqrdmlah, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
25912 nUF (vqrdmlsh, _vqrdmlsh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
25913 nUF (vqrdmlshq, _vqrdmlsh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
5287ad62
JB
25914
25915 /* Two address, int/float. Types S8 S16 S32 F32. */
5287ad62 25916 NUF(vabsq, 1b10300, 2, (RNQ, RNQ), neon_abs_neg),
5287ad62
JB
25917 NUF(vnegq, 1b10380, 2, (RNQ, RNQ), neon_abs_neg),
25918
25919 /* Data processing with two registers and a shift amount. */
25920 /* Right shifts, and variants with rounding.
25921 Types accepted S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62 25922 NUF(vshrq, 0800010, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
5287ad62
JB
25923 NUF(vrshrq, 0800210, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
25924 NUF(vsra, 0800110, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
25925 NUF(vsraq, 0800110, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
25926 NUF(vrsra, 0800310, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
25927 NUF(vrsraq, 0800310, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
25928 /* Shift and insert. Sizes accepted 8 16 32 64. */
5287ad62 25929 NUF(vsliq, 1800510, 3, (RNQ, oRNQ, I63), neon_sli),
5287ad62
JB
25930 NUF(vsriq, 1800410, 3, (RNQ, oRNQ, I64), neon_sri),
25931 /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62
JB
25932 NUF(vqshluq, 1800610, 3, (RNQ, oRNQ, I63), neon_qshlu_imm),
25933 /* Right shift immediate, saturating & narrowing, with rounding variants.
25934 Types accepted S16 S32 S64 U16 U32 U64. */
25935 NUF(vqshrn, 0800910, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
25936 NUF(vqrshrn, 0800950, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
25937 /* As above, unsigned. Types accepted S16 S32 S64. */
25938 NUF(vqshrun, 0800810, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
25939 NUF(vqrshrun, 0800850, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
25940 /* Right shift narrowing. Types accepted I16 I32 I64. */
25941 NUF(vshrn, 0800810, 3, (RND, RNQ, I32z), neon_rshift_narrow),
25942 NUF(vrshrn, 0800850, 3, (RND, RNQ, I32z), neon_rshift_narrow),
25943 /* Special case. Types S8 S16 S32 U8 U16 U32. Handles max shift variant. */
21d799b5 25944 nUF(vshll, _vshll, 3, (RNQ, RND, I32), neon_shll),
5287ad62 25945 /* CVT with optional immediate for fixed-point variant. */
21d799b5 25946 nUF(vcvtq, _vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
b7fc2769 25947
4316f0d2 25948 nUF(vmvnq, _vmvn, 2, (RNQ, RNDQ_Ibig), neon_mvn),
5287ad62
JB
25949
25950 /* Data processing, three registers of different lengths. */
25951 /* Dyadic, long insns. Types S8 S16 S32 U8 U16 U32. */
25952 NUF(vabal, 0800500, 3, (RNQ, RND, RND), neon_abal),
5287ad62
JB
25953 /* If not scalar, fall back to neon_dyadic_long.
25954 Vector types as above, scalar types S16 S32 U16 U32. */
21d799b5
NC
25955 nUF(vmlal, _vmlal, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
25956 nUF(vmlsl, _vmlsl, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
5287ad62
JB
25957 /* Dyadic, widening insns. Types S8 S16 S32 U8 U16 U32. */
25958 NUF(vaddw, 0800100, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
25959 NUF(vsubw, 0800300, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
25960 /* Dyadic, narrowing insns. Types I16 I32 I64. */
25961 NUF(vaddhn, 0800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25962 NUF(vraddhn, 1800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25963 NUF(vsubhn, 0800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25964 NUF(vrsubhn, 1800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25965 /* Saturating doubling multiplies. Types S16 S32. */
21d799b5
NC
25966 nUF(vqdmlal, _vqdmlal, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
25967 nUF(vqdmlsl, _vqdmlsl, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
25968 nUF(vqdmull, _vqdmull, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
5287ad62
JB
25969 /* VMULL. Vector types S8 S16 S32 U8 U16 U32 P8, scalar types
25970 S16 S32 U16 U32. */
21d799b5 25971 nUF(vmull, _vmull, 3, (RNQ, RND, RND_RNSC), neon_vmull),
5287ad62
JB
25972
25973 /* Extract. Size 8. */
3b8d421e
PB
25974 NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I15), neon_ext),
25975 NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I15), neon_ext),
5287ad62
JB
25976
25977 /* Two registers, miscellaneous. */
25978 /* Reverse. Sizes 8 16 32 (must be < size in opcode). */
5287ad62 25979 NUF(vrev64q, 1b00000, 2, (RNQ, RNQ), neon_rev),
5287ad62 25980 NUF(vrev32q, 1b00080, 2, (RNQ, RNQ), neon_rev),
5287ad62
JB
25981 NUF(vrev16q, 1b00100, 2, (RNQ, RNQ), neon_rev),
25982 /* Vector replicate. Sizes 8 16 32. */
21d799b5 25983 nCE(vdupq, _vdup, 2, (RNQ, RR_RNSC), neon_dup),
5287ad62
JB
25984 /* VMOVL. Types S8 S16 S32 U8 U16 U32. */
25985 NUF(vmovl, 0800a10, 2, (RNQ, RND), neon_movl),
25986 /* VMOVN. Types I16 I32 I64. */
21d799b5 25987 nUF(vmovn, _vmovn, 2, (RND, RNQ), neon_movn),
5287ad62 25988 /* VQMOVN. Types S16 S32 S64 U16 U32 U64. */
21d799b5 25989 nUF(vqmovn, _vqmovn, 2, (RND, RNQ), neon_qmovn),
5287ad62 25990 /* VQMOVUN. Types S16 S32 S64. */
21d799b5 25991 nUF(vqmovun, _vqmovun, 2, (RND, RNQ), neon_qmovun),
5287ad62
JB
25992 /* VZIP / VUZP. Sizes 8 16 32. */
25993 NUF(vzip, 1b20180, 2, (RNDQ, RNDQ), neon_zip_uzp),
25994 NUF(vzipq, 1b20180, 2, (RNQ, RNQ), neon_zip_uzp),
25995 NUF(vuzp, 1b20100, 2, (RNDQ, RNDQ), neon_zip_uzp),
25996 NUF(vuzpq, 1b20100, 2, (RNQ, RNQ), neon_zip_uzp),
25997 /* VQABS / VQNEG. Types S8 S16 S32. */
5287ad62 25998 NUF(vqabsq, 1b00700, 2, (RNQ, RNQ), neon_sat_abs_neg),
5287ad62
JB
25999 NUF(vqnegq, 1b00780, 2, (RNQ, RNQ), neon_sat_abs_neg),
26000 /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32. */
26001 NUF(vpadal, 1b00600, 2, (RNDQ, RNDQ), neon_pair_long),
26002 NUF(vpadalq, 1b00600, 2, (RNQ, RNQ), neon_pair_long),
26003 NUF(vpaddl, 1b00200, 2, (RNDQ, RNDQ), neon_pair_long),
26004 NUF(vpaddlq, 1b00200, 2, (RNQ, RNQ), neon_pair_long),
cc933301 26005 /* Reciprocal estimates. Types U32 F16 F32. */
5287ad62
JB
26006 NUF(vrecpe, 1b30400, 2, (RNDQ, RNDQ), neon_recip_est),
26007 NUF(vrecpeq, 1b30400, 2, (RNQ, RNQ), neon_recip_est),
26008 NUF(vrsqrte, 1b30480, 2, (RNDQ, RNDQ), neon_recip_est),
26009 NUF(vrsqrteq, 1b30480, 2, (RNQ, RNQ), neon_recip_est),
26010 /* VCLS. Types S8 S16 S32. */
5287ad62
JB
26011 NUF(vclsq, 1b00400, 2, (RNQ, RNQ), neon_cls),
26012 /* VCLZ. Types I8 I16 I32. */
5287ad62
JB
26013 NUF(vclzq, 1b00480, 2, (RNQ, RNQ), neon_clz),
26014 /* VCNT. Size 8. */
26015 NUF(vcnt, 1b00500, 2, (RNDQ, RNDQ), neon_cnt),
26016 NUF(vcntq, 1b00500, 2, (RNQ, RNQ), neon_cnt),
26017 /* Two address, untyped. */
26018 NUF(vswp, 1b20000, 2, (RNDQ, RNDQ), neon_swp),
26019 NUF(vswpq, 1b20000, 2, (RNQ, RNQ), neon_swp),
26020 /* VTRN. Sizes 8 16 32. */
21d799b5
NC
26021 nUF(vtrn, _vtrn, 2, (RNDQ, RNDQ), neon_trn),
26022 nUF(vtrnq, _vtrn, 2, (RNQ, RNQ), neon_trn),
5287ad62
JB
26023
26024 /* Table lookup. Size 8. */
26025 NUF(vtbl, 1b00800, 3, (RND, NRDLST, RND), neon_tbl_tbx),
26026 NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
26027
c921be7d
NC
26028#undef THUMB_VARIANT
26029#define THUMB_VARIANT & fpu_vfp_v3_or_neon_ext
26030#undef ARM_VARIANT
26031#define ARM_VARIANT & fpu_vfp_v3_or_neon_ext
26032
5287ad62 26033 /* Neon element/structure load/store. */
21d799b5
NC
26034 nUF(vld1, _vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
26035 nUF(vst1, _vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
26036 nUF(vld2, _vld2, 2, (NSTRLST, ADDR), neon_ldx_stx),
26037 nUF(vst2, _vst2, 2, (NSTRLST, ADDR), neon_ldx_stx),
26038 nUF(vld3, _vld3, 2, (NSTRLST, ADDR), neon_ldx_stx),
26039 nUF(vst3, _vst3, 2, (NSTRLST, ADDR), neon_ldx_stx),
26040 nUF(vld4, _vld4, 2, (NSTRLST, ADDR), neon_ldx_stx),
26041 nUF(vst4, _vst4, 2, (NSTRLST, ADDR), neon_ldx_stx),
5287ad62 26042
c921be7d 26043#undef THUMB_VARIANT
74db7efb
NC
26044#define THUMB_VARIANT & fpu_vfp_ext_v3xd
26045#undef ARM_VARIANT
26046#define ARM_VARIANT & fpu_vfp_ext_v3xd
62f3b8c8
PB
26047 cCE("fconsts", eb00a00, 2, (RVS, I255), vfp_sp_const),
26048 cCE("fshtos", eba0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26049 cCE("fsltos", eba0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26050 cCE("fuhtos", ebb0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26051 cCE("fultos", ebb0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26052 cCE("ftoshs", ebe0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26053 cCE("ftosls", ebe0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26054 cCE("ftouhs", ebf0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26055 cCE("ftouls", ebf0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26056
74db7efb 26057#undef THUMB_VARIANT
c921be7d
NC
26058#define THUMB_VARIANT & fpu_vfp_ext_v3
26059#undef ARM_VARIANT
26060#define ARM_VARIANT & fpu_vfp_ext_v3
26061
21d799b5 26062 cCE("fconstd", eb00b00, 2, (RVD, I255), vfp_dp_const),
21d799b5 26063 cCE("fshtod", eba0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26064 cCE("fsltod", eba0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 26065 cCE("fuhtod", ebb0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26066 cCE("fultod", ebb0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 26067 cCE("ftoshd", ebe0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26068 cCE("ftosld", ebe0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 26069 cCE("ftouhd", ebf0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26070 cCE("ftould", ebf0bc0, 2, (RVD, I32), vfp_dp_conv_32),
c19d1205 26071
74db7efb
NC
26072#undef ARM_VARIANT
26073#define ARM_VARIANT & fpu_vfp_ext_fma
26074#undef THUMB_VARIANT
26075#define THUMB_VARIANT & fpu_vfp_ext_fma
aab2c27d 26076 /* Mnemonics shared by Neon, VFP, MVE and BF16. These are included in the
62f3b8c8
PB
26077 VFP FMA variant; NEON and VFP FMA always includes the NEON
26078 FMA instructions. */
d58196e0 26079 mnCEF(vfma, _vfma, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_fmac),
aab2c27d 26080 TUF ("vfmat", c300850, fc300850, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), mve_vfma, mve_vfma),
d58196e0
AV
26081 mnCEF(vfms, _vfms, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), neon_fmac),
26082
62f3b8c8
PB
26083 /* ffmas/ffmad/ffmss/ffmsd are dummy mnemonics to satisfy gas;
26084 the v form should always be used. */
26085 cCE("ffmas", ea00a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
26086 cCE("ffnmas", ea00a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
26087 cCE("ffmad", ea00b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
26088 cCE("ffnmad", ea00b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
26089 nCE(vfnma, _vfnma, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
26090 nCE(vfnms, _vfnms, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
26091
5287ad62 26092#undef THUMB_VARIANT
c921be7d
NC
26093#undef ARM_VARIANT
26094#define ARM_VARIANT & arm_cext_xscale /* Intel XScale extensions. */
26095
21d799b5
NC
26096 cCE("mia", e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26097 cCE("miaph", e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26098 cCE("miabb", e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26099 cCE("miabt", e2d0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26100 cCE("miatb", e2e0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26101 cCE("miatt", e2f0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26102 cCE("mar", c400000, 3, (RXA, RRnpc, RRnpc), xsc_mar),
26103 cCE("mra", c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra),
c19d1205 26104
c921be7d
NC
26105#undef ARM_VARIANT
26106#define ARM_VARIANT & arm_cext_iwmmxt /* Intel Wireless MMX technology. */
26107
21d799b5
NC
26108 cCE("tandcb", e13f130, 1, (RR), iwmmxt_tandorc),
26109 cCE("tandch", e53f130, 1, (RR), iwmmxt_tandorc),
26110 cCE("tandcw", e93f130, 1, (RR), iwmmxt_tandorc),
26111 cCE("tbcstb", e400010, 2, (RIWR, RR), rn_rd),
26112 cCE("tbcsth", e400050, 2, (RIWR, RR), rn_rd),
26113 cCE("tbcstw", e400090, 2, (RIWR, RR), rn_rd),
26114 cCE("textrcb", e130170, 2, (RR, I7), iwmmxt_textrc),
26115 cCE("textrch", e530170, 2, (RR, I7), iwmmxt_textrc),
26116 cCE("textrcw", e930170, 2, (RR, I7), iwmmxt_textrc),
74db7efb
NC
26117 cCE("textrmub",e100070, 3, (RR, RIWR, I7), iwmmxt_textrm),
26118 cCE("textrmuh",e500070, 3, (RR, RIWR, I7), iwmmxt_textrm),
26119 cCE("textrmuw",e900070, 3, (RR, RIWR, I7), iwmmxt_textrm),
26120 cCE("textrmsb",e100078, 3, (RR, RIWR, I7), iwmmxt_textrm),
26121 cCE("textrmsh",e500078, 3, (RR, RIWR, I7), iwmmxt_textrm),
26122 cCE("textrmsw",e900078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21d799b5
NC
26123 cCE("tinsrb", e600010, 3, (RIWR, RR, I7), iwmmxt_tinsr),
26124 cCE("tinsrh", e600050, 3, (RIWR, RR, I7), iwmmxt_tinsr),
26125 cCE("tinsrw", e600090, 3, (RIWR, RR, I7), iwmmxt_tinsr),
26126 cCE("tmcr", e000110, 2, (RIWC_RIWG, RR), rn_rd),
26127 cCE("tmcrr", c400000, 3, (RIWR, RR, RR), rm_rd_rn),
26128 cCE("tmia", e200010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26129 cCE("tmiaph", e280010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26130 cCE("tmiabb", e2c0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26131 cCE("tmiabt", e2d0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26132 cCE("tmiatb", e2e0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26133 cCE("tmiatt", e2f0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
74db7efb
NC
26134 cCE("tmovmskb",e100030, 2, (RR, RIWR), rd_rn),
26135 cCE("tmovmskh",e500030, 2, (RR, RIWR), rd_rn),
26136 cCE("tmovmskw",e900030, 2, (RR, RIWR), rd_rn),
21d799b5
NC
26137 cCE("tmrc", e100110, 2, (RR, RIWC_RIWG), rd_rn),
26138 cCE("tmrrc", c500000, 3, (RR, RR, RIWR), rd_rn_rm),
26139 cCE("torcb", e13f150, 1, (RR), iwmmxt_tandorc),
26140 cCE("torch", e53f150, 1, (RR), iwmmxt_tandorc),
26141 cCE("torcw", e93f150, 1, (RR), iwmmxt_tandorc),
26142 cCE("waccb", e0001c0, 2, (RIWR, RIWR), rd_rn),
26143 cCE("wacch", e4001c0, 2, (RIWR, RIWR), rd_rn),
26144 cCE("waccw", e8001c0, 2, (RIWR, RIWR), rd_rn),
26145 cCE("waddbss", e300180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26146 cCE("waddb", e000180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26147 cCE("waddbus", e100180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26148 cCE("waddhss", e700180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26149 cCE("waddh", e400180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26150 cCE("waddhus", e500180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26151 cCE("waddwss", eb00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26152 cCE("waddw", e800180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26153 cCE("waddwus", e900180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26154 cCE("waligni", e000020, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_waligni),
74db7efb
NC
26155 cCE("walignr0",e800020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26156 cCE("walignr1",e900020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26157 cCE("walignr2",ea00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26158 cCE("walignr3",eb00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
26159 cCE("wand", e200000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26160 cCE("wandn", e300000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26161 cCE("wavg2b", e800000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26162 cCE("wavg2br", e900000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26163 cCE("wavg2h", ec00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26164 cCE("wavg2hr", ed00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26165 cCE("wcmpeqb", e000060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26166 cCE("wcmpeqh", e400060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26167 cCE("wcmpeqw", e800060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
26168 cCE("wcmpgtub",e100060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26169 cCE("wcmpgtuh",e500060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26170 cCE("wcmpgtuw",e900060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26171 cCE("wcmpgtsb",e300060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26172 cCE("wcmpgtsh",e700060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26173 cCE("wcmpgtsw",eb00060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
26174 cCE("wldrb", c100000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26175 cCE("wldrh", c500000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26176 cCE("wldrw", c100100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
26177 cCE("wldrd", c500100, 2, (RIWR, ADDR), iwmmxt_wldstd),
26178 cCE("wmacs", e600100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26179 cCE("wmacsz", e700100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26180 cCE("wmacu", e400100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26181 cCE("wmacuz", e500100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26182 cCE("wmadds", ea00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26183 cCE("wmaddu", e800100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26184 cCE("wmaxsb", e200160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26185 cCE("wmaxsh", e600160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26186 cCE("wmaxsw", ea00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26187 cCE("wmaxub", e000160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26188 cCE("wmaxuh", e400160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26189 cCE("wmaxuw", e800160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26190 cCE("wminsb", e300160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26191 cCE("wminsh", e700160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26192 cCE("wminsw", eb00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26193 cCE("wminub", e100160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26194 cCE("wminuh", e500160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26195 cCE("wminuw", e900160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26196 cCE("wmov", e000000, 2, (RIWR, RIWR), iwmmxt_wmov),
26197 cCE("wmulsm", e300100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26198 cCE("wmulsl", e200100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26199 cCE("wmulum", e100100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26200 cCE("wmulul", e000100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26201 cCE("wor", e000000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
26202 cCE("wpackhss",e700080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26203 cCE("wpackhus",e500080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26204 cCE("wpackwss",eb00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26205 cCE("wpackwus",e900080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26206 cCE("wpackdss",ef00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26207 cCE("wpackdus",ed00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
26208 cCE("wrorh", e700040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26209 cCE("wrorhg", e700148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26210 cCE("wrorw", eb00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26211 cCE("wrorwg", eb00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26212 cCE("wrord", ef00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26213 cCE("wrordg", ef00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26214 cCE("wsadb", e000120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26215 cCE("wsadbz", e100120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26216 cCE("wsadh", e400120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26217 cCE("wsadhz", e500120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26218 cCE("wshufh", e0001e0, 3, (RIWR, RIWR, I255), iwmmxt_wshufh),
26219 cCE("wsllh", e500040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26220 cCE("wsllhg", e500148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26221 cCE("wsllw", e900040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26222 cCE("wsllwg", e900148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26223 cCE("wslld", ed00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26224 cCE("wslldg", ed00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26225 cCE("wsrah", e400040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26226 cCE("wsrahg", e400148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26227 cCE("wsraw", e800040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26228 cCE("wsrawg", e800148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26229 cCE("wsrad", ec00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26230 cCE("wsradg", ec00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26231 cCE("wsrlh", e600040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26232 cCE("wsrlhg", e600148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26233 cCE("wsrlw", ea00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26234 cCE("wsrlwg", ea00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26235 cCE("wsrld", ee00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26236 cCE("wsrldg", ee00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26237 cCE("wstrb", c000000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26238 cCE("wstrh", c400000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26239 cCE("wstrw", c000100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
26240 cCE("wstrd", c400100, 2, (RIWR, ADDR), iwmmxt_wldstd),
26241 cCE("wsubbss", e3001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26242 cCE("wsubb", e0001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26243 cCE("wsubbus", e1001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26244 cCE("wsubhss", e7001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26245 cCE("wsubh", e4001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26246 cCE("wsubhus", e5001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26247 cCE("wsubwss", eb001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26248 cCE("wsubw", e8001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26249 cCE("wsubwus", e9001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26250 cCE("wunpckehub",e0000c0, 2, (RIWR, RIWR), rd_rn),
26251 cCE("wunpckehuh",e4000c0, 2, (RIWR, RIWR), rd_rn),
26252 cCE("wunpckehuw",e8000c0, 2, (RIWR, RIWR), rd_rn),
26253 cCE("wunpckehsb",e2000c0, 2, (RIWR, RIWR), rd_rn),
26254 cCE("wunpckehsh",e6000c0, 2, (RIWR, RIWR), rd_rn),
26255 cCE("wunpckehsw",ea000c0, 2, (RIWR, RIWR), rd_rn),
26256 cCE("wunpckihb", e1000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26257 cCE("wunpckihh", e5000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26258 cCE("wunpckihw", e9000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26259 cCE("wunpckelub",e0000e0, 2, (RIWR, RIWR), rd_rn),
26260 cCE("wunpckeluh",e4000e0, 2, (RIWR, RIWR), rd_rn),
26261 cCE("wunpckeluw",e8000e0, 2, (RIWR, RIWR), rd_rn),
26262 cCE("wunpckelsb",e2000e0, 2, (RIWR, RIWR), rd_rn),
26263 cCE("wunpckelsh",e6000e0, 2, (RIWR, RIWR), rd_rn),
26264 cCE("wunpckelsw",ea000e0, 2, (RIWR, RIWR), rd_rn),
26265 cCE("wunpckilb", e1000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26266 cCE("wunpckilh", e5000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26267 cCE("wunpckilw", e9000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26268 cCE("wxor", e100000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26269 cCE("wzero", e300000, 1, (RIWR), iwmmxt_wzero),
c19d1205 26270
c921be7d
NC
26271#undef ARM_VARIANT
26272#define ARM_VARIANT & arm_cext_iwmmxt2 /* Intel Wireless MMX technology, version 2. */
26273
21d799b5
NC
26274 cCE("torvscb", e12f190, 1, (RR), iwmmxt_tandorc),
26275 cCE("torvsch", e52f190, 1, (RR), iwmmxt_tandorc),
26276 cCE("torvscw", e92f190, 1, (RR), iwmmxt_tandorc),
26277 cCE("wabsb", e2001c0, 2, (RIWR, RIWR), rd_rn),
26278 cCE("wabsh", e6001c0, 2, (RIWR, RIWR), rd_rn),
26279 cCE("wabsw", ea001c0, 2, (RIWR, RIWR), rd_rn),
26280 cCE("wabsdiffb", e1001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26281 cCE("wabsdiffh", e5001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26282 cCE("wabsdiffw", e9001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26283 cCE("waddbhusl", e2001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26284 cCE("waddbhusm", e6001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26285 cCE("waddhc", e600180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26286 cCE("waddwc", ea00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26287 cCE("waddsubhx", ea001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26288 cCE("wavg4", e400000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26289 cCE("wavg4r", e500000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26290 cCE("wmaddsn", ee00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26291 cCE("wmaddsx", eb00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26292 cCE("wmaddun", ec00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26293 cCE("wmaddux", e900100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26294 cCE("wmerge", e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
26295 cCE("wmiabb", e0000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26296 cCE("wmiabt", e1000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26297 cCE("wmiatb", e2000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26298 cCE("wmiatt", e3000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26299 cCE("wmiabbn", e4000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26300 cCE("wmiabtn", e5000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26301 cCE("wmiatbn", e6000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26302 cCE("wmiattn", e7000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26303 cCE("wmiawbb", e800120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26304 cCE("wmiawbt", e900120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26305 cCE("wmiawtb", ea00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26306 cCE("wmiawtt", eb00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26307 cCE("wmiawbbn", ec00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26308 cCE("wmiawbtn", ed00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26309 cCE("wmiawtbn", ee00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26310 cCE("wmiawttn", ef00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26311 cCE("wmulsmr", ef00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26312 cCE("wmulumr", ed00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26313 cCE("wmulwumr", ec000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26314 cCE("wmulwsmr", ee000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26315 cCE("wmulwum", ed000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26316 cCE("wmulwsm", ef000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26317 cCE("wmulwl", eb000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26318 cCE("wqmiabb", e8000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26319 cCE("wqmiabt", e9000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26320 cCE("wqmiatb", ea000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26321 cCE("wqmiatt", eb000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26322 cCE("wqmiabbn", ec000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26323 cCE("wqmiabtn", ed000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26324 cCE("wqmiatbn", ee000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26325 cCE("wqmiattn", ef000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26326 cCE("wqmulm", e100080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26327 cCE("wqmulmr", e300080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26328 cCE("wqmulwm", ec000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26329 cCE("wqmulwmr", ee000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26330 cCE("wsubaddhx", ed001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
2d447fca 26331
c921be7d
NC
26332#undef ARM_VARIANT
26333#define ARM_VARIANT & arm_cext_maverick /* Cirrus Maverick instructions. */
26334
21d799b5
NC
26335 cCE("cfldrs", c100400, 2, (RMF, ADDRGLDC), rd_cpaddr),
26336 cCE("cfldrd", c500400, 2, (RMD, ADDRGLDC), rd_cpaddr),
26337 cCE("cfldr32", c100500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
26338 cCE("cfldr64", c500500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
26339 cCE("cfstrs", c000400, 2, (RMF, ADDRGLDC), rd_cpaddr),
26340 cCE("cfstrd", c400400, 2, (RMD, ADDRGLDC), rd_cpaddr),
26341 cCE("cfstr32", c000500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
26342 cCE("cfstr64", c400500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
26343 cCE("cfmvsr", e000450, 2, (RMF, RR), rn_rd),
26344 cCE("cfmvrs", e100450, 2, (RR, RMF), rd_rn),
26345 cCE("cfmvdlr", e000410, 2, (RMD, RR), rn_rd),
26346 cCE("cfmvrdl", e100410, 2, (RR, RMD), rd_rn),
26347 cCE("cfmvdhr", e000430, 2, (RMD, RR), rn_rd),
26348 cCE("cfmvrdh", e100430, 2, (RR, RMD), rd_rn),
74db7efb
NC
26349 cCE("cfmv64lr",e000510, 2, (RMDX, RR), rn_rd),
26350 cCE("cfmvr64l",e100510, 2, (RR, RMDX), rd_rn),
26351 cCE("cfmv64hr",e000530, 2, (RMDX, RR), rn_rd),
26352 cCE("cfmvr64h",e100530, 2, (RR, RMDX), rd_rn),
26353 cCE("cfmval32",e200440, 2, (RMAX, RMFX), rd_rn),
26354 cCE("cfmv32al",e100440, 2, (RMFX, RMAX), rd_rn),
26355 cCE("cfmvam32",e200460, 2, (RMAX, RMFX), rd_rn),
26356 cCE("cfmv32am",e100460, 2, (RMFX, RMAX), rd_rn),
26357 cCE("cfmvah32",e200480, 2, (RMAX, RMFX), rd_rn),
26358 cCE("cfmv32ah",e100480, 2, (RMFX, RMAX), rd_rn),
21d799b5
NC
26359 cCE("cfmva32", e2004a0, 2, (RMAX, RMFX), rd_rn),
26360 cCE("cfmv32a", e1004a0, 2, (RMFX, RMAX), rd_rn),
26361 cCE("cfmva64", e2004c0, 2, (RMAX, RMDX), rd_rn),
26362 cCE("cfmv64a", e1004c0, 2, (RMDX, RMAX), rd_rn),
74db7efb
NC
26363 cCE("cfmvsc32",e2004e0, 2, (RMDS, RMDX), mav_dspsc),
26364 cCE("cfmv32sc",e1004e0, 2, (RMDX, RMDS), rd),
21d799b5
NC
26365 cCE("cfcpys", e000400, 2, (RMF, RMF), rd_rn),
26366 cCE("cfcpyd", e000420, 2, (RMD, RMD), rd_rn),
26367 cCE("cfcvtsd", e000460, 2, (RMD, RMF), rd_rn),
26368 cCE("cfcvtds", e000440, 2, (RMF, RMD), rd_rn),
74db7efb
NC
26369 cCE("cfcvt32s",e000480, 2, (RMF, RMFX), rd_rn),
26370 cCE("cfcvt32d",e0004a0, 2, (RMD, RMFX), rd_rn),
26371 cCE("cfcvt64s",e0004c0, 2, (RMF, RMDX), rd_rn),
26372 cCE("cfcvt64d",e0004e0, 2, (RMD, RMDX), rd_rn),
26373 cCE("cfcvts32",e100580, 2, (RMFX, RMF), rd_rn),
26374 cCE("cfcvtd32",e1005a0, 2, (RMFX, RMD), rd_rn),
21d799b5
NC
26375 cCE("cftruncs32",e1005c0, 2, (RMFX, RMF), rd_rn),
26376 cCE("cftruncd32",e1005e0, 2, (RMFX, RMD), rd_rn),
74db7efb
NC
26377 cCE("cfrshl32",e000550, 3, (RMFX, RMFX, RR), mav_triple),
26378 cCE("cfrshl64",e000570, 3, (RMDX, RMDX, RR), mav_triple),
21d799b5
NC
26379 cCE("cfsh32", e000500, 3, (RMFX, RMFX, I63s), mav_shift),
26380 cCE("cfsh64", e200500, 3, (RMDX, RMDX, I63s), mav_shift),
26381 cCE("cfcmps", e100490, 3, (RR, RMF, RMF), rd_rn_rm),
26382 cCE("cfcmpd", e1004b0, 3, (RR, RMD, RMD), rd_rn_rm),
26383 cCE("cfcmp32", e100590, 3, (RR, RMFX, RMFX), rd_rn_rm),
26384 cCE("cfcmp64", e1005b0, 3, (RR, RMDX, RMDX), rd_rn_rm),
26385 cCE("cfabss", e300400, 2, (RMF, RMF), rd_rn),
26386 cCE("cfabsd", e300420, 2, (RMD, RMD), rd_rn),
26387 cCE("cfnegs", e300440, 2, (RMF, RMF), rd_rn),
26388 cCE("cfnegd", e300460, 2, (RMD, RMD), rd_rn),
26389 cCE("cfadds", e300480, 3, (RMF, RMF, RMF), rd_rn_rm),
26390 cCE("cfaddd", e3004a0, 3, (RMD, RMD, RMD), rd_rn_rm),
26391 cCE("cfsubs", e3004c0, 3, (RMF, RMF, RMF), rd_rn_rm),
26392 cCE("cfsubd", e3004e0, 3, (RMD, RMD, RMD), rd_rn_rm),
26393 cCE("cfmuls", e100400, 3, (RMF, RMF, RMF), rd_rn_rm),
26394 cCE("cfmuld", e100420, 3, (RMD, RMD, RMD), rd_rn_rm),
26395 cCE("cfabs32", e300500, 2, (RMFX, RMFX), rd_rn),
26396 cCE("cfabs64", e300520, 2, (RMDX, RMDX), rd_rn),
26397 cCE("cfneg32", e300540, 2, (RMFX, RMFX), rd_rn),
26398 cCE("cfneg64", e300560, 2, (RMDX, RMDX), rd_rn),
26399 cCE("cfadd32", e300580, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26400 cCE("cfadd64", e3005a0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26401 cCE("cfsub32", e3005c0, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26402 cCE("cfsub64", e3005e0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26403 cCE("cfmul32", e100500, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26404 cCE("cfmul64", e100520, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26405 cCE("cfmac32", e100540, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26406 cCE("cfmsc32", e100560, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
74db7efb
NC
26407 cCE("cfmadd32",e000600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
26408 cCE("cfmsub32",e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21d799b5
NC
26409 cCE("cfmadda32", e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
26410 cCE("cfmsuba32", e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
4ed7ed8d 26411
7fadb25d
SD
26412 /* ARMv8.5-A instructions. */
26413#undef ARM_VARIANT
26414#define ARM_VARIANT & arm_ext_sb
26415#undef THUMB_VARIANT
26416#define THUMB_VARIANT & arm_ext_sb
26417 TUF("sb", 57ff070, f3bf8f70, 0, (), noargs, noargs),
26418
dad0c3bf
SD
26419#undef ARM_VARIANT
26420#define ARM_VARIANT & arm_ext_predres
26421#undef THUMB_VARIANT
26422#define THUMB_VARIANT & arm_ext_predres
26423 CE("cfprctx", e070f93, 1, (RRnpc), rd),
26424 CE("dvprctx", e070fb3, 1, (RRnpc), rd),
26425 CE("cpprctx", e070ff3, 1, (RRnpc), rd),
26426
16a1fa25 26427 /* ARMv8-M instructions. */
4ed7ed8d
TP
26428#undef ARM_VARIANT
26429#define ARM_VARIANT NULL
26430#undef THUMB_VARIANT
26431#define THUMB_VARIANT & arm_ext_v8m
cf3cf39d
TP
26432 ToU("sg", e97fe97f, 0, (), noargs),
26433 ToC("blxns", 4784, 1, (RRnpc), t_blx),
26434 ToC("bxns", 4704, 1, (RRnpc), t_bx),
26435 ToC("tt", e840f000, 2, (RRnpc, RRnpc), tt),
26436 ToC("ttt", e840f040, 2, (RRnpc, RRnpc), tt),
26437 ToC("tta", e840f080, 2, (RRnpc, RRnpc), tt),
26438 ToC("ttat", e840f0c0, 2, (RRnpc, RRnpc), tt),
16a1fa25
TP
26439
26440 /* FP for ARMv8-M Mainline. Enabled for ARMv8-M Mainline because the
26441 instructions behave as nop if no VFP is present. */
26442#undef THUMB_VARIANT
26443#define THUMB_VARIANT & arm_ext_v8m_main
cf3cf39d
TP
26444 ToC("vlldm", ec300a00, 1, (RRnpc), rn),
26445 ToC("vlstm", ec200a00, 1, (RRnpc), rn),
4389b29a
AV
26446
26447 /* Armv8.1-M Mainline instructions. */
26448#undef THUMB_VARIANT
26449#define THUMB_VARIANT & arm_ext_v8_1m_main
e43ca2cb 26450 toU("aut", _aut, 3, (R12, LR, SP), t_pacbti),
be05908c 26451 toU("autg", _autg, 3, (RR, RR, RR), t_pacbti_nonop),
3751264c 26452 ToU("bti", f3af800f, 0, (), noargs),
e07352fa 26453 toU("bxaut", _bxaut, 3, (RR, RR, RR), t_pacbti_nonop),
ce537a7d 26454 toU("pac", _pac, 3, (R12, LR, SP), t_pacbti),
f1e1d7f3 26455 toU("pacbti", _pacbti, 3, (R12, LR, SP), t_pacbti),
5c43020d 26456 toU("pacg", _pacg, 3, (RR, RR, RR), t_pacbti_pacg),
e39c1607
SD
26457 toU("cinc", _cinc, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26458 toU("cinv", _cinv, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26459 toU("cneg", _cneg, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26460 toU("csel", _csel, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26461 toU("csetm", _csetm, 2, (RRnpcsp, COND), t_cond),
26462 toU("cset", _cset, 2, (RRnpcsp, COND), t_cond),
26463 toU("csinc", _csinc, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26464 toU("csinv", _csinv, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26465 toU("csneg", _csneg, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26466
4389b29a 26467 toC("bf", _bf, 2, (EXPs, EXPs), t_branch_future),
f6b2b12d 26468 toU("bfcsel", _bfcsel, 4, (EXPs, EXPs, EXPs, COND), t_branch_future),
f1c7f421 26469 toC("bfx", _bfx, 2, (EXPs, RRnpcsp), t_branch_future),
65d1bc05 26470 toC("bfl", _bfl, 2, (EXPs, EXPs), t_branch_future),
f1c7f421 26471 toC("bflx", _bflx, 2, (EXPs, RRnpcsp), t_branch_future),
60f993ce
AV
26472
26473 toU("dls", _dls, 2, (LR, RRnpcsp), t_loloop),
26474 toU("wls", _wls, 3, (LR, RRnpcsp, EXP), t_loloop),
26475 toU("le", _le, 2, (oLR, EXP), t_loloop),
4b5a202f 26476
efd6b359 26477 ToC("clrm", e89f0000, 1, (CLRMLST), t_clrm),
5ee91343
AV
26478 ToC("vscclrm", ec9f0a00, 1, (VRSDVLST), t_vscclrm),
26479
26480#undef THUMB_VARIANT
26481#define THUMB_VARIANT & mve_ext
23d00a41
SD
26482 ToC("lsll", ea50010d, 3, (RRe, RRo, RRnpcsp_I32), mve_scalar_shift),
26483 ToC("lsrl", ea50011f, 3, (RRe, RRo, I32), mve_scalar_shift),
26484 ToC("asrl", ea50012d, 3, (RRe, RRo, RRnpcsp_I32), mve_scalar_shift),
08132bdd
SP
26485 ToC("uqrshll", ea51010d, 4, (RRe, RRo, I48_I64, RRnpcsp), mve_scalar_shift1),
26486 ToC("sqrshrl", ea51012d, 4, (RRe, RRo, I48_I64, RRnpcsp), mve_scalar_shift1),
23d00a41
SD
26487 ToC("uqshll", ea51010f, 3, (RRe, RRo, I32), mve_scalar_shift),
26488 ToC("urshrl", ea51011f, 3, (RRe, RRo, I32), mve_scalar_shift),
26489 ToC("srshrl", ea51012f, 3, (RRe, RRo, I32), mve_scalar_shift),
26490 ToC("sqshll", ea51013f, 3, (RRe, RRo, I32), mve_scalar_shift),
26491 ToC("uqrshl", ea500f0d, 2, (RRnpcsp, RRnpcsp), mve_scalar_shift),
26492 ToC("sqrshr", ea500f2d, 2, (RRnpcsp, RRnpcsp), mve_scalar_shift),
26493 ToC("uqshl", ea500f0f, 2, (RRnpcsp, I32), mve_scalar_shift),
26494 ToC("urshr", ea500f1f, 2, (RRnpcsp, I32), mve_scalar_shift),
26495 ToC("srshr", ea500f2f, 2, (RRnpcsp, I32), mve_scalar_shift),
26496 ToC("sqshl", ea500f3f, 2, (RRnpcsp, I32), mve_scalar_shift),
1b883319
AV
26497
26498 ToC("vpt", ee410f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26499 ToC("vptt", ee018f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26500 ToC("vpte", ee418f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26501 ToC("vpttt", ee014f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26502 ToC("vptte", ee01cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26503 ToC("vptet", ee41cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26504 ToC("vptee", ee414f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26505 ToC("vptttt", ee012f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26506 ToC("vpttte", ee016f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26507 ToC("vpttet", ee01ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26508 ToC("vpttee", ee01af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26509 ToC("vptett", ee41af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26510 ToC("vptete", ee41ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26511 ToC("vpteet", ee416f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26512 ToC("vpteee", ee412f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26513
5ee91343
AV
26514 ToC("vpst", fe710f4d, 0, (), mve_vpt),
26515 ToC("vpstt", fe318f4d, 0, (), mve_vpt),
26516 ToC("vpste", fe718f4d, 0, (), mve_vpt),
26517 ToC("vpsttt", fe314f4d, 0, (), mve_vpt),
26518 ToC("vpstte", fe31cf4d, 0, (), mve_vpt),
26519 ToC("vpstet", fe71cf4d, 0, (), mve_vpt),
26520 ToC("vpstee", fe714f4d, 0, (), mve_vpt),
26521 ToC("vpstttt", fe312f4d, 0, (), mve_vpt),
26522 ToC("vpsttte", fe316f4d, 0, (), mve_vpt),
26523 ToC("vpsttet", fe31ef4d, 0, (), mve_vpt),
26524 ToC("vpsttee", fe31af4d, 0, (), mve_vpt),
26525 ToC("vpstett", fe71af4d, 0, (), mve_vpt),
26526 ToC("vpstete", fe71ef4d, 0, (), mve_vpt),
26527 ToC("vpsteet", fe716f4d, 0, (), mve_vpt),
26528 ToC("vpsteee", fe712f4d, 0, (), mve_vpt),
26529
a302e574 26530 /* MVE and MVE FP only. */
7df54120 26531 mToC("vhcadd", ee000f00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vhcadd),
efd0b310 26532 mCEF(vctp, _vctp, 1, (RRnpc), mve_vctp),
c2dafc2a
AV
26533 mCEF(vadc, _vadc, 3, (RMQ, RMQ, RMQ), mve_vadc),
26534 mCEF(vadci, _vadci, 3, (RMQ, RMQ, RMQ), mve_vadc),
26535 mToC("vsbc", fe300f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
26536 mToC("vsbci", fe301f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
886e1c73 26537 mCEF(vmullb, _vmullb, 3, (RMQ, RMQ, RMQ), mve_vmull),
a302e574
AV
26538 mCEF(vabav, _vabav, 3, (RRnpcsp, RMQ, RMQ), mve_vabav),
26539 mCEF(vmladav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26540 mCEF(vmladava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26541 mCEF(vmladavx, _vmladavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
26542 mCEF(vmladavax, _vmladavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
26543 mCEF(vmlav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26544 mCEF(vmlava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26545 mCEF(vmlsdav, _vmlsdav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26546 mCEF(vmlsdava, _vmlsdava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26547 mCEF(vmlsdavx, _vmlsdavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
26548 mCEF(vmlsdavax, _vmlsdavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
26549
35c228db
AV
26550 mCEF(vst20, _vst20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26551 mCEF(vst21, _vst21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26552 mCEF(vst40, _vst40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26553 mCEF(vst41, _vst41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26554 mCEF(vst42, _vst42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26555 mCEF(vst43, _vst43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26556 mCEF(vld20, _vld20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26557 mCEF(vld21, _vld21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26558 mCEF(vld40, _vld40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26559 mCEF(vld41, _vld41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26560 mCEF(vld42, _vld42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26561 mCEF(vld43, _vld43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
f5f10c66
AV
26562 mCEF(vstrb, _vstrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26563 mCEF(vstrh, _vstrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26564 mCEF(vstrw, _vstrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26565 mCEF(vstrd, _vstrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26566 mCEF(vldrb, _vldrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26567 mCEF(vldrh, _vldrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26568 mCEF(vldrw, _vldrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26569 mCEF(vldrd, _vldrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
35c228db 26570
57785aa2
AV
26571 mCEF(vmovnt, _vmovnt, 2, (RMQ, RMQ), mve_movn),
26572 mCEF(vmovnb, _vmovnb, 2, (RMQ, RMQ), mve_movn),
c2dafc2a 26573 mCEF(vbrsr, _vbrsr, 3, (RMQ, RMQ, RR), mve_vbrsr),
26c1e780
AV
26574 mCEF(vaddlv, _vaddlv, 3, (RRe, RRo, RMQ), mve_vaddlv),
26575 mCEF(vaddlva, _vaddlva, 3, (RRe, RRo, RMQ), mve_vaddlv),
26576 mCEF(vaddv, _vaddv, 2, (RRe, RMQ), mve_vaddv),
26577 mCEF(vaddva, _vaddva, 2, (RRe, RMQ), mve_vaddv),
b409bdb6
AV
26578 mCEF(vddup, _vddup, 3, (RMQ, RRe, EXPi), mve_viddup),
26579 mCEF(vdwdup, _vdwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
26580 mCEF(vidup, _vidup, 3, (RMQ, RRe, EXPi), mve_viddup),
26581 mCEF(viwdup, _viwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
935295b5
AV
26582 mToC("vmaxa", ee330e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
26583 mToC("vmina", ee331e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
13ccd4c0
AV
26584 mCEF(vmaxv, _vmaxv, 2, (RR, RMQ), mve_vmaxv),
26585 mCEF(vmaxav, _vmaxav, 2, (RR, RMQ), mve_vmaxv),
26586 mCEF(vminv, _vminv, 2, (RR, RMQ), mve_vmaxv),
26587 mCEF(vminav, _vminav, 2, (RR, RMQ), mve_vmaxv),
57785aa2 26588
93925576
AV
26589 mCEF(vmlaldav, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26590 mCEF(vmlaldava, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26591 mCEF(vmlaldavx, _vmlaldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26592 mCEF(vmlaldavax, _vmlaldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26593 mCEF(vmlalv, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26594 mCEF(vmlalva, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26595 mCEF(vmlsldav, _vmlsldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26596 mCEF(vmlsldava, _vmlsldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26597 mCEF(vmlsldavx, _vmlsldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26598 mCEF(vmlsldavax, _vmlsldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26599 mToC("vrmlaldavh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26600 mToC("vrmlaldavha",ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26601 mCEF(vrmlaldavhx, _vrmlaldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26602 mCEF(vrmlaldavhax, _vrmlaldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26603 mToC("vrmlalvh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26604 mToC("vrmlalvha", ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26605 mCEF(vrmlsldavh, _vrmlsldavh, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26606 mCEF(vrmlsldavha, _vrmlsldavha, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26607 mCEF(vrmlsldavhx, _vrmlsldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26608 mCEF(vrmlsldavhax, _vrmlsldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26609
2d78f95b
AV
26610 mToC("vmlas", ee011e40, 3, (RMQ, RMQ, RR), mve_vmlas),
26611 mToC("vmulh", ee010e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
26612 mToC("vrmulh", ee011e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
3063888e
AV
26613 mToC("vpnot", fe310f4d, 0, (), mve_vpnot),
26614 mToC("vpsel", fe310f01, 3, (RMQ, RMQ, RMQ), mve_vpsel),
2d78f95b 26615
8b8b22a4
AV
26616 mToC("vqdmladh", ee000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26617 mToC("vqdmladhx", ee001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26618 mToC("vqrdmladh", ee000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26619 mToC("vqrdmladhx",ee001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26620 mToC("vqdmlsdh", fe000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26621 mToC("vqdmlsdhx", fe001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26622 mToC("vqrdmlsdh", fe000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26623 mToC("vqrdmlsdhx",fe001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
42b16635
AV
26624 mToC("vqdmlah", ee000e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
26625 mToC("vqdmlash", ee001e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
26626 mToC("vqrdmlash", ee001e40, 3, (RMQ, RMQ, RR), mve_vqdmlah),
35d1cfc2
AV
26627 mToC("vqdmullt", ee301f00, 3, (RMQ, RMQ, RMQRR), mve_vqdmull),
26628 mToC("vqdmullb", ee300f00, 3, (RMQ, RMQ, RMQRR), mve_vqdmull),
1be7aba3
AV
26629 mCEF(vqmovnt, _vqmovnt, 2, (RMQ, RMQ), mve_vqmovn),
26630 mCEF(vqmovnb, _vqmovnb, 2, (RMQ, RMQ), mve_vqmovn),
26631 mCEF(vqmovunt, _vqmovunt, 2, (RMQ, RMQ), mve_vqmovn),
26632 mCEF(vqmovunb, _vqmovunb, 2, (RMQ, RMQ), mve_vqmovn),
8b8b22a4 26633
4aa88b50
AV
26634 mCEF(vshrnt, _vshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26635 mCEF(vshrnb, _vshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26636 mCEF(vrshrnt, _vrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26637 mCEF(vrshrnb, _vrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26638 mCEF(vqshrnt, _vqrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26639 mCEF(vqshrnb, _vqrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26640 mCEF(vqshrunt, _vqrshrunt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26641 mCEF(vqshrunb, _vqrshrunb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26642 mCEF(vqrshrnt, _vqrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26643 mCEF(vqrshrnb, _vqrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26644 mCEF(vqrshrunt, _vqrshrunt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26645 mCEF(vqrshrunb, _vqrshrunb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26646
acca5630
AV
26647 mToC("vshlc", eea00fc0, 3, (RMQ, RR, I32z), mve_vshlc),
26648 mToC("vshllt", ee201e00, 3, (RMQ, RMQ, I32), mve_vshll),
26649 mToC("vshllb", ee200e00, 3, (RMQ, RMQ, I32), mve_vshll),
26650
1f6234a3
AV
26651 toU("dlstp", _dlstp, 2, (LR, RR), t_loloop),
26652 toU("wlstp", _wlstp, 3, (LR, RR, EXP), t_loloop),
26653 toU("letp", _letp, 2, (LR, EXP), t_loloop),
26654 toU("lctp", _lctp, 0, (), t_loloop),
26655
5d281bf0
AV
26656#undef THUMB_VARIANT
26657#define THUMB_VARIANT & mve_fp_ext
26658 mToC("vcmul", ee300e00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vcmul),
f30ee27c 26659 mToC("vfmas", ee311e40, 3, (RMQ, RMQ, RR), mve_vfmas),
935295b5
AV
26660 mToC("vmaxnma", ee3f0e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
26661 mToC("vminnma", ee3f1e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
8cd78170
AV
26662 mToC("vmaxnmv", eeee0f00, 2, (RR, RMQ), mve_vmaxnmv),
26663 mToC("vmaxnmav",eeec0f00, 2, (RR, RMQ), mve_vmaxnmv),
26664 mToC("vminnmv", eeee0f80, 2, (RR, RMQ), mve_vmaxnmv),
26665 mToC("vminnmav",eeec0f80, 2, (RR, RMQ), mve_vmaxnmv),
5d281bf0 26666
5ee91343 26667#undef ARM_VARIANT
57785aa2 26668#define ARM_VARIANT & fpu_vfp_ext_v1
5ee91343
AV
26669#undef THUMB_VARIANT
26670#define THUMB_VARIANT & arm_ext_v6t2
26671
57785aa2
AV
26672 mcCE(fcpyd, eb00b40, 2, (RVD, RVD), vfp_dp_rd_rm),
26673
26674#undef ARM_VARIANT
26675#define ARM_VARIANT & fpu_vfp_ext_v1xd
26676
48f4d8ce
AV
26677 mnCEF(vmla, _vmla, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mac_maybe_scalar),
26678 mnCEF(vmul, _vmul, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mul),
57785aa2
AV
26679 MNCE(vmov, 0, 1, (VMOV), neon_mov),
26680 mcCE(fmrs, e100a10, 2, (RR, RVS), vfp_reg_from_sp),
26681 mcCE(fmsr, e000a10, 2, (RVS, RR), vfp_sp_from_reg),
26682 mcCE(fcpys, eb00a40, 2, (RVS, RVS), vfp_sp_monadic),
26683
886e1c73
AV
26684 mCEF(vmullt, _vmullt, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ), mve_vmull),
26685 mnCEF(vadd, _vadd, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
26686 mnCEF(vsub, _vsub, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
5ee91343 26687
485dee97
AV
26688 MNCEF(vabs, 1b10300, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
26689 MNCEF(vneg, 1b10380, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
26690
57785aa2
AV
26691 mCEF(vmovlt, _vmovlt, 1, (VMOV), mve_movl),
26692 mCEF(vmovlb, _vmovlb, 1, (VMOV), mve_movl),
26693
1b883319
AV
26694 mnCE(vcmp, _vcmp, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
26695 mnCE(vcmpe, _vcmpe, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
26696
57785aa2
AV
26697#undef ARM_VARIANT
26698#define ARM_VARIANT & fpu_vfp_ext_v2
26699
26700 mcCE(fmsrr, c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
26701 mcCE(fmrrs, c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
26702 mcCE(fmdrr, c400b10, 3, (RVD, RR, RR), vfp_dp_rm_rd_rn),
26703 mcCE(fmrrd, c500b10, 3, (RR, RR, RVD), vfp_dp_rd_rn_rm),
26704
dd9634d9
AV
26705#undef ARM_VARIANT
26706#define ARM_VARIANT & fpu_vfp_ext_armv8xd
26707 mnUF(vcvta, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvta),
26708 mnUF(vcvtp, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtp),
26709 mnUF(vcvtn, _vcvta, 3, (RNSDQMQ, oRNSDQMQ, oI32z), neon_cvtn),
26710 mnUF(vcvtm, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtm),
935295b5
AV
26711 mnUF(vmaxnm, _vmaxnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
26712 mnUF(vminnm, _vminnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
dd9634d9
AV
26713
26714#undef ARM_VARIANT
5ee91343 26715#define ARM_VARIANT & fpu_neon_ext_v1
f601a00c 26716 mnUF(vabd, _vabd, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
5ee91343 26717 mnUF(vabdl, _vabdl, 3, (RNQMQ, RNDMQ, RNDMQ), neon_dyadic_long),
66d1f7cc
AV
26718 mnUF(vaddl, _vaddl, 3, (RNSDQMQ, oRNSDMQ, RNSDMQR), neon_dyadic_long),
26719 mnUF(vsubl, _vsubl, 3, (RNSDQMQ, oRNSDMQ, RNSDMQR), neon_dyadic_long),
f601a00c
AV
26720 mnUF(vand, _vand, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26721 mnUF(vbic, _vbic, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26722 mnUF(vorr, _vorr, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26723 mnUF(vorn, _vorn, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26724 mnUF(veor, _veor, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_logic),
f30ee27c
AV
26725 MNUF(vcls, 1b00400, 2, (RNDQMQ, RNDQMQ), neon_cls),
26726 MNUF(vclz, 1b00480, 2, (RNDQMQ, RNDQMQ), neon_clz),
b409bdb6 26727 mnCE(vdup, _vdup, 2, (RNDQMQ, RR_RNSC), neon_dup),
7df54120
AV
26728 MNUF(vhadd, 00000000, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
26729 MNUF(vrhadd, 00000100, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_i_su),
26730 MNUF(vhsub, 00000200, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
935295b5
AV
26731 mnUF(vmin, _vmin, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
26732 mnUF(vmax, _vmax, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
a8465a06
AV
26733 MNUF(vqadd, 0000010, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
26734 MNUF(vqsub, 0000210, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
1a186d29
AV
26735 mnUF(vmvn, _vmvn, 2, (RNDQMQ, RNDQMQ_Ibig), neon_mvn),
26736 MNUF(vqabs, 1b00700, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
26737 MNUF(vqneg, 1b00780, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
42b16635
AV
26738 mnUF(vqrdmlah, _vqrdmlah,3, (RNDQMQ, oRNDQMQ, RNDQ_RNSC_RR), neon_qrdmlah),
26739 mnUF(vqdmulh, _vqdmulh, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
26740 mnUF(vqrdmulh, _vqrdmulh,3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
1be7aba3
AV
26741 MNUF(vqrshl, 0000510, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
26742 MNUF(vrshl, 0000500, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
4401c241
AV
26743 MNUF(vshr, 0800010, 3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
26744 MNUF(vrshr, 0800210, 3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
26745 MNUF(vsli, 1800510, 3, (RNDQMQ, oRNDQMQ, I63), neon_sli),
26746 MNUF(vsri, 1800410, 3, (RNDQMQ, oRNDQMQ, I64z), neon_sri),
26747 MNUF(vrev64, 1b00000, 2, (RNDQMQ, RNDQMQ), neon_rev),
26748 MNUF(vrev32, 1b00080, 2, (RNDQMQ, RNDQMQ), neon_rev),
26749 MNUF(vrev16, 1b00100, 2, (RNDQMQ, RNDQMQ), neon_rev),
5150f0d8
AV
26750 mnUF(vshl, _vshl, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_shl),
26751 mnUF(vqshl, _vqshl, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_qshl),
26752 MNUF(vqshlu, 1800610, 3, (RNDQMQ, oRNDQMQ, I63), neon_qshlu_imm),
5d281bf0
AV
26753
26754#undef ARM_VARIANT
26755#define ARM_VARIANT & arm_ext_v8_3
26756#undef THUMB_VARIANT
26757#define THUMB_VARIANT & arm_ext_v6t2_v8m
26758 MNUF (vcadd, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ, EXPi), vcadd),
26759 MNUF (vcmla, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ_RNSC, EXPi), vcmla),
aab2c27d
MM
26760
26761#undef ARM_VARIANT
26762#define ARM_VARIANT &arm_ext_bf16
26763#undef THUMB_VARIANT
26764#define THUMB_VARIANT &arm_ext_bf16
26765 TUF ("vdot", c000d00, fc000d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), vdot, vdot),
26766 TUF ("vmmla", c000c40, fc000c40, 3, (RNQ, RNQ, RNQ), vmmla, vmmla),
26767 TUF ("vfmab", c300810, fc300810, 3, (RNDQ, RNDQ, RNDQ_RNSC), bfloat_vfma, bfloat_vfma),
26768
26769#undef ARM_VARIANT
26770#define ARM_VARIANT &arm_ext_i8mm
26771#undef THUMB_VARIANT
26772#define THUMB_VARIANT &arm_ext_i8mm
26773 TUF ("vsmmla", c200c40, fc200c40, 3, (RNQ, RNQ, RNQ), vsmmla, vsmmla),
26774 TUF ("vummla", c200c50, fc200c50, 3, (RNQ, RNQ, RNQ), vummla, vummla),
616ce08e 26775 TUF ("vusmmla", ca00c40, fca00c40, 3, (RNQ, RNQ, RNQ), vsmmla, vsmmla),
aab2c27d
MM
26776 TUF ("vusdot", c800d00, fc800d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), vusdot, vusdot),
26777 TUF ("vsudot", c800d10, fc800d10, 3, (RNDQ, RNDQ, RNSC), vsudot, vsudot),
4934a27c
MM
26778
26779#undef ARM_VARIANT
26780#undef THUMB_VARIANT
26781#define THUMB_VARIANT &arm_ext_cde
26782 ToC ("cx1", ee000000, 3, (RCP, APSR_RR, I8191), cx1),
26783 ToC ("cx1a", fe000000, 3, (RCP, APSR_RR, I8191), cx1a),
26784 ToC ("cx1d", ee000040, 4, (RCP, RR, APSR_RR, I8191), cx1d),
26785 ToC ("cx1da", fe000040, 4, (RCP, RR, APSR_RR, I8191), cx1da),
26786
26787 ToC ("cx2", ee400000, 4, (RCP, APSR_RR, APSR_RR, I511), cx2),
26788 ToC ("cx2a", fe400000, 4, (RCP, APSR_RR, APSR_RR, I511), cx2a),
26789 ToC ("cx2d", ee400040, 5, (RCP, RR, APSR_RR, APSR_RR, I511), cx2d),
26790 ToC ("cx2da", fe400040, 5, (RCP, RR, APSR_RR, APSR_RR, I511), cx2da),
26791
26792 ToC ("cx3", ee800000, 5, (RCP, APSR_RR, APSR_RR, APSR_RR, I63), cx3),
26793 ToC ("cx3a", fe800000, 5, (RCP, APSR_RR, APSR_RR, APSR_RR, I63), cx3a),
26794 ToC ("cx3d", ee800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3d),
26795 ToC ("cx3da", fe800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3da),
5aae9ae9
MM
26796
26797 mToC ("vcx1", ec200000, 3, (RCP, RNSDMQ, I4095), vcx1),
26798 mToC ("vcx1a", fc200000, 3, (RCP, RNSDMQ, I4095), vcx1),
26799
26800 mToC ("vcx2", ec300000, 4, (RCP, RNSDMQ, RNSDMQ, I127), vcx2),
26801 mToC ("vcx2a", fc300000, 4, (RCP, RNSDMQ, RNSDMQ, I127), vcx2),
26802
26803 mToC ("vcx3", ec800000, 5, (RCP, RNSDMQ, RNSDMQ, RNSDMQ, I15), vcx3),
26804 mToC ("vcx3a", fc800000, 5, (RCP, RNSDMQ, RNSDMQ, RNSDMQ, I15), vcx3),
c19d1205 26805};
5aae9ae9 26806
c19d1205
ZW
26807#undef ARM_VARIANT
26808#undef THUMB_VARIANT
26809#undef TCE
c19d1205
ZW
26810#undef TUE
26811#undef TUF
26812#undef TCC
8f06b2d8 26813#undef cCE
e3cb604e
PB
26814#undef cCL
26815#undef C3E
4389b29a 26816#undef C3
c19d1205
ZW
26817#undef CE
26818#undef CM
4389b29a 26819#undef CL
c19d1205
ZW
26820#undef UE
26821#undef UF
26822#undef UT
5287ad62
JB
26823#undef NUF
26824#undef nUF
26825#undef NCE
26826#undef nCE
c19d1205
ZW
26827#undef OPS0
26828#undef OPS1
26829#undef OPS2
26830#undef OPS3
26831#undef OPS4
26832#undef OPS5
26833#undef OPS6
26834#undef do_0
4389b29a
AV
26835#undef ToC
26836#undef toC
26837#undef ToU
f6b2b12d 26838#undef toU
c19d1205
ZW
26839\f
26840/* MD interface: bits in the object file. */
bfae80f2 26841
c19d1205
ZW
26842/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
26843 for use in the a.out file, and stores them in the array pointed to by buf.
26844 This knows about the endian-ness of the target machine and does
26845 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
26846 2 (short) and 4 (long) Floating numbers are put out as a series of
26847 LITTLENUMS (shorts, here at least). */
b99bd4ef 26848
c19d1205
ZW
26849void
26850md_number_to_chars (char * buf, valueT val, int n)
26851{
26852 if (target_big_endian)
26853 number_to_chars_bigendian (buf, val, n);
26854 else
26855 number_to_chars_littleendian (buf, val, n);
bfae80f2
RE
26856}
26857
c19d1205
ZW
26858static valueT
26859md_chars_to_number (char * buf, int n)
bfae80f2 26860{
c19d1205
ZW
26861 valueT result = 0;
26862 unsigned char * where = (unsigned char *) buf;
bfae80f2 26863
c19d1205 26864 if (target_big_endian)
b99bd4ef 26865 {
c19d1205
ZW
26866 while (n--)
26867 {
26868 result <<= 8;
26869 result |= (*where++ & 255);
26870 }
b99bd4ef 26871 }
c19d1205 26872 else
b99bd4ef 26873 {
c19d1205
ZW
26874 while (n--)
26875 {
26876 result <<= 8;
26877 result |= (where[n] & 255);
26878 }
bfae80f2 26879 }
b99bd4ef 26880
c19d1205 26881 return result;
bfae80f2 26882}
b99bd4ef 26883
c19d1205 26884/* MD interface: Sections. */
b99bd4ef 26885
fa94de6b
RM
26886/* Calculate the maximum variable size (i.e., excluding fr_fix)
26887 that an rs_machine_dependent frag may reach. */
26888
26889unsigned int
26890arm_frag_max_var (fragS *fragp)
26891{
26892 /* We only use rs_machine_dependent for variable-size Thumb instructions,
26893 which are either THUMB_SIZE (2) or INSN_SIZE (4).
26894
26895 Note that we generate relaxable instructions even for cases that don't
26896 really need it, like an immediate that's a trivial constant. So we're
26897 overestimating the instruction size for some of those cases. Rather
26898 than putting more intelligence here, it would probably be better to
26899 avoid generating a relaxation frag in the first place when it can be
26900 determined up front that a short instruction will suffice. */
26901
26902 gas_assert (fragp->fr_type == rs_machine_dependent);
26903 return INSN_SIZE;
26904}
26905
0110f2b8
PB
26906/* Estimate the size of a frag before relaxing. Assume everything fits in
26907 2 bytes. */
26908
c19d1205 26909int
0110f2b8 26910md_estimate_size_before_relax (fragS * fragp,
c19d1205
ZW
26911 segT segtype ATTRIBUTE_UNUSED)
26912{
0110f2b8
PB
26913 fragp->fr_var = 2;
26914 return 2;
26915}
26916
26917/* Convert a machine dependent frag. */
26918
26919void
26920md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
26921{
26922 unsigned long insn;
26923 unsigned long old_op;
26924 char *buf;
26925 expressionS exp;
26926 fixS *fixp;
26927 int reloc_type;
26928 int pc_rel;
26929 int opcode;
26930
26931 buf = fragp->fr_literal + fragp->fr_fix;
26932
26933 old_op = bfd_get_16(abfd, buf);
5f4273c7
NC
26934 if (fragp->fr_symbol)
26935 {
0110f2b8
PB
26936 exp.X_op = O_symbol;
26937 exp.X_add_symbol = fragp->fr_symbol;
5f4273c7
NC
26938 }
26939 else
26940 {
0110f2b8 26941 exp.X_op = O_constant;
5f4273c7 26942 }
0110f2b8
PB
26943 exp.X_add_number = fragp->fr_offset;
26944 opcode = fragp->fr_subtype;
26945 switch (opcode)
26946 {
26947 case T_MNEM_ldr_pc:
26948 case T_MNEM_ldr_pc2:
26949 case T_MNEM_ldr_sp:
26950 case T_MNEM_str_sp:
26951 case T_MNEM_ldr:
26952 case T_MNEM_ldrb:
26953 case T_MNEM_ldrh:
26954 case T_MNEM_str:
26955 case T_MNEM_strb:
26956 case T_MNEM_strh:
26957 if (fragp->fr_var == 4)
26958 {
5f4273c7 26959 insn = THUMB_OP32 (opcode);
0110f2b8
PB
26960 if ((old_op >> 12) == 4 || (old_op >> 12) == 9)
26961 {
26962 insn |= (old_op & 0x700) << 4;
26963 }
26964 else
26965 {
26966 insn |= (old_op & 7) << 12;
26967 insn |= (old_op & 0x38) << 13;
26968 }
26969 insn |= 0x00000c00;
26970 put_thumb32_insn (buf, insn);
26971 reloc_type = BFD_RELOC_ARM_T32_OFFSET_IMM;
26972 }
26973 else
26974 {
26975 reloc_type = BFD_RELOC_ARM_THUMB_OFFSET;
26976 }
26977 pc_rel = (opcode == T_MNEM_ldr_pc2);
26978 break;
26979 case T_MNEM_adr:
d3e52e12
TC
26980 /* Thumb bits should be set in the frag handling so we process them
26981 after all symbols have been seen. PR gas/25235. */
26982 if (exp.X_op == O_symbol
26983 && exp.X_add_symbol != NULL
26984 && S_IS_DEFINED (exp.X_add_symbol)
26985 && THUMB_IS_FUNC (exp.X_add_symbol))
26986 exp.X_add_number |= 1;
26987
0110f2b8
PB
26988 if (fragp->fr_var == 4)
26989 {
26990 insn = THUMB_OP32 (opcode);
26991 insn |= (old_op & 0xf0) << 4;
26992 put_thumb32_insn (buf, insn);
26993 reloc_type = BFD_RELOC_ARM_T32_ADD_PC12;
26994 }
26995 else
26996 {
26997 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
26998 exp.X_add_number -= 4;
26999 }
27000 pc_rel = 1;
27001 break;
27002 case T_MNEM_mov:
27003 case T_MNEM_movs:
27004 case T_MNEM_cmp:
27005 case T_MNEM_cmn:
27006 if (fragp->fr_var == 4)
27007 {
27008 int r0off = (opcode == T_MNEM_mov
27009 || opcode == T_MNEM_movs) ? 0 : 8;
27010 insn = THUMB_OP32 (opcode);
27011 insn = (insn & 0xe1ffffff) | 0x10000000;
27012 insn |= (old_op & 0x700) << r0off;
27013 put_thumb32_insn (buf, insn);
27014 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
27015 }
27016 else
27017 {
27018 reloc_type = BFD_RELOC_ARM_THUMB_IMM;
27019 }
27020 pc_rel = 0;
27021 break;
27022 case T_MNEM_b:
27023 if (fragp->fr_var == 4)
27024 {
27025 insn = THUMB_OP32(opcode);
27026 put_thumb32_insn (buf, insn);
27027 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH25;
27028 }
27029 else
27030 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH12;
27031 pc_rel = 1;
27032 break;
27033 case T_MNEM_bcond:
27034 if (fragp->fr_var == 4)
27035 {
27036 insn = THUMB_OP32(opcode);
27037 insn |= (old_op & 0xf00) << 14;
27038 put_thumb32_insn (buf, insn);
27039 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH20;
27040 }
27041 else
27042 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH9;
27043 pc_rel = 1;
27044 break;
27045 case T_MNEM_add_sp:
27046 case T_MNEM_add_pc:
27047 case T_MNEM_inc_sp:
27048 case T_MNEM_dec_sp:
27049 if (fragp->fr_var == 4)
27050 {
27051 /* ??? Choose between add and addw. */
27052 insn = THUMB_OP32 (opcode);
27053 insn |= (old_op & 0xf0) << 4;
27054 put_thumb32_insn (buf, insn);
16805f35
PB
27055 if (opcode == T_MNEM_add_pc)
27056 reloc_type = BFD_RELOC_ARM_T32_IMM12;
27057 else
27058 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
0110f2b8
PB
27059 }
27060 else
27061 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
27062 pc_rel = 0;
27063 break;
27064
27065 case T_MNEM_addi:
27066 case T_MNEM_addis:
27067 case T_MNEM_subi:
27068 case T_MNEM_subis:
27069 if (fragp->fr_var == 4)
27070 {
27071 insn = THUMB_OP32 (opcode);
27072 insn |= (old_op & 0xf0) << 4;
27073 insn |= (old_op & 0xf) << 16;
27074 put_thumb32_insn (buf, insn);
16805f35
PB
27075 if (insn & (1 << 20))
27076 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
27077 else
27078 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8
PB
27079 }
27080 else
27081 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
27082 pc_rel = 0;
27083 break;
27084 default:
5f4273c7 27085 abort ();
0110f2b8
PB
27086 }
27087 fixp = fix_new_exp (fragp, fragp->fr_fix, fragp->fr_var, &exp, pc_rel,
21d799b5 27088 (enum bfd_reloc_code_real) reloc_type);
0110f2b8
PB
27089 fixp->fx_file = fragp->fr_file;
27090 fixp->fx_line = fragp->fr_line;
27091 fragp->fr_fix += fragp->fr_var;
3cfdb781
TG
27092
27093 /* Set whether we use thumb-2 ISA based on final relaxation results. */
27094 if (thumb_mode && fragp->fr_var == 4 && no_cpu_selected ()
27095 && !ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2))
27096 ARM_MERGE_FEATURE_SETS (arm_arch_used, thumb_arch_used, arm_ext_v6t2);
0110f2b8
PB
27097}
27098
27099/* Return the size of a relaxable immediate operand instruction.
27100 SHIFT and SIZE specify the form of the allowable immediate. */
27101static int
27102relax_immediate (fragS *fragp, int size, int shift)
27103{
27104 offsetT offset;
27105 offsetT mask;
27106 offsetT low;
27107
27108 /* ??? Should be able to do better than this. */
27109 if (fragp->fr_symbol)
27110 return 4;
27111
27112 low = (1 << shift) - 1;
27113 mask = (1 << (shift + size)) - (1 << shift);
27114 offset = fragp->fr_offset;
27115 /* Force misaligned offsets to 32-bit variant. */
27116 if (offset & low)
5e77afaa 27117 return 4;
0110f2b8
PB
27118 if (offset & ~mask)
27119 return 4;
27120 return 2;
27121}
27122
5e77afaa
PB
27123/* Get the address of a symbol during relaxation. */
27124static addressT
5f4273c7 27125relaxed_symbol_addr (fragS *fragp, long stretch)
5e77afaa
PB
27126{
27127 fragS *sym_frag;
27128 addressT addr;
27129 symbolS *sym;
27130
27131 sym = fragp->fr_symbol;
27132 sym_frag = symbol_get_frag (sym);
27133 know (S_GET_SEGMENT (sym) != absolute_section
27134 || sym_frag == &zero_address_frag);
27135 addr = S_GET_VALUE (sym) + fragp->fr_offset;
27136
27137 /* If frag has yet to be reached on this pass, assume it will
27138 move by STRETCH just as we did. If this is not so, it will
27139 be because some frag between grows, and that will force
27140 another pass. */
27141
27142 if (stretch != 0
27143 && sym_frag->relax_marker != fragp->relax_marker)
4396b686
PB
27144 {
27145 fragS *f;
27146
27147 /* Adjust stretch for any alignment frag. Note that if have
27148 been expanding the earlier code, the symbol may be
27149 defined in what appears to be an earlier frag. FIXME:
27150 This doesn't handle the fr_subtype field, which specifies
27151 a maximum number of bytes to skip when doing an
27152 alignment. */
27153 for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
27154 {
27155 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
27156 {
27157 if (stretch < 0)
27158 stretch = - ((- stretch)
27159 & ~ ((1 << (int) f->fr_offset) - 1));
27160 else
27161 stretch &= ~ ((1 << (int) f->fr_offset) - 1);
27162 if (stretch == 0)
27163 break;
27164 }
27165 }
27166 if (f != NULL)
27167 addr += stretch;
27168 }
5e77afaa
PB
27169
27170 return addr;
27171}
27172
0110f2b8
PB
27173/* Return the size of a relaxable adr pseudo-instruction or PC-relative
27174 load. */
27175static int
5e77afaa 27176relax_adr (fragS *fragp, asection *sec, long stretch)
0110f2b8
PB
27177{
27178 addressT addr;
27179 offsetT val;
27180
27181 /* Assume worst case for symbols not known to be in the same section. */
974da60d
NC
27182 if (fragp->fr_symbol == NULL
27183 || !S_IS_DEFINED (fragp->fr_symbol)
77db8e2e 27184 || sec != S_GET_SEGMENT (fragp->fr_symbol)
d3e52e12
TC
27185 || S_IS_WEAK (fragp->fr_symbol)
27186 || THUMB_IS_FUNC (fragp->fr_symbol))
0110f2b8
PB
27187 return 4;
27188
5f4273c7 27189 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
27190 addr = fragp->fr_address + fragp->fr_fix;
27191 addr = (addr + 4) & ~3;
5e77afaa 27192 /* Force misaligned targets to 32-bit variant. */
0110f2b8 27193 if (val & 3)
5e77afaa 27194 return 4;
0110f2b8
PB
27195 val -= addr;
27196 if (val < 0 || val > 1020)
27197 return 4;
27198 return 2;
27199}
27200
27201/* Return the size of a relaxable add/sub immediate instruction. */
27202static int
27203relax_addsub (fragS *fragp, asection *sec)
27204{
27205 char *buf;
27206 int op;
27207
27208 buf = fragp->fr_literal + fragp->fr_fix;
27209 op = bfd_get_16(sec->owner, buf);
27210 if ((op & 0xf) == ((op >> 4) & 0xf))
27211 return relax_immediate (fragp, 8, 0);
27212 else
27213 return relax_immediate (fragp, 3, 0);
27214}
27215
e83a675f
RE
27216/* Return TRUE iff the definition of symbol S could be pre-empted
27217 (overridden) at link or load time. */
5b7c81bd 27218static bool
e83a675f
RE
27219symbol_preemptible (symbolS *s)
27220{
27221 /* Weak symbols can always be pre-empted. */
27222 if (S_IS_WEAK (s))
5b7c81bd 27223 return true;
e83a675f
RE
27224
27225 /* Non-global symbols cannot be pre-empted. */
27226 if (! S_IS_EXTERNAL (s))
5b7c81bd 27227 return false;
e83a675f
RE
27228
27229#ifdef OBJ_ELF
27230 /* In ELF, a global symbol can be marked protected, or private. In that
27231 case it can't be pre-empted (other definitions in the same link unit
27232 would violate the ODR). */
27233 if (ELF_ST_VISIBILITY (S_GET_OTHER (s)) > STV_DEFAULT)
5b7c81bd 27234 return false;
e83a675f
RE
27235#endif
27236
27237 /* Other global symbols might be pre-empted. */
5b7c81bd 27238 return true;
e83a675f 27239}
0110f2b8
PB
27240
27241/* Return the size of a relaxable branch instruction. BITS is the
27242 size of the offset field in the narrow instruction. */
27243
27244static int
5e77afaa 27245relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
0110f2b8
PB
27246{
27247 addressT addr;
27248 offsetT val;
27249 offsetT limit;
27250
27251 /* Assume worst case for symbols not known to be in the same section. */
5f4273c7 27252 if (!S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
27253 || sec != S_GET_SEGMENT (fragp->fr_symbol)
27254 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
27255 return 4;
27256
267bf995 27257#ifdef OBJ_ELF
e83a675f 27258 /* A branch to a function in ARM state will require interworking. */
267bf995
RR
27259 if (S_IS_DEFINED (fragp->fr_symbol)
27260 && ARM_IS_FUNC (fragp->fr_symbol))
27261 return 4;
e83a675f 27262#endif
0d9b4b55 27263
e83a675f 27264 if (symbol_preemptible (fragp->fr_symbol))
0d9b4b55 27265 return 4;
267bf995 27266
5f4273c7 27267 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
27268 addr = fragp->fr_address + fragp->fr_fix + 4;
27269 val -= addr;
27270
27271 /* Offset is a signed value *2 */
27272 limit = 1 << bits;
27273 if (val >= limit || val < -limit)
27274 return 4;
27275 return 2;
27276}
27277
27278
27279/* Relax a machine dependent frag. This returns the amount by which
27280 the current size of the frag should change. */
27281
27282int
5e77afaa 27283arm_relax_frag (asection *sec, fragS *fragp, long stretch)
0110f2b8
PB
27284{
27285 int oldsize;
27286 int newsize;
27287
27288 oldsize = fragp->fr_var;
27289 switch (fragp->fr_subtype)
27290 {
27291 case T_MNEM_ldr_pc2:
5f4273c7 27292 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
27293 break;
27294 case T_MNEM_ldr_pc:
27295 case T_MNEM_ldr_sp:
27296 case T_MNEM_str_sp:
5f4273c7 27297 newsize = relax_immediate (fragp, 8, 2);
0110f2b8
PB
27298 break;
27299 case T_MNEM_ldr:
27300 case T_MNEM_str:
5f4273c7 27301 newsize = relax_immediate (fragp, 5, 2);
0110f2b8
PB
27302 break;
27303 case T_MNEM_ldrh:
27304 case T_MNEM_strh:
5f4273c7 27305 newsize = relax_immediate (fragp, 5, 1);
0110f2b8
PB
27306 break;
27307 case T_MNEM_ldrb:
27308 case T_MNEM_strb:
5f4273c7 27309 newsize = relax_immediate (fragp, 5, 0);
0110f2b8
PB
27310 break;
27311 case T_MNEM_adr:
5f4273c7 27312 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
27313 break;
27314 case T_MNEM_mov:
27315 case T_MNEM_movs:
27316 case T_MNEM_cmp:
27317 case T_MNEM_cmn:
5f4273c7 27318 newsize = relax_immediate (fragp, 8, 0);
0110f2b8
PB
27319 break;
27320 case T_MNEM_b:
5f4273c7 27321 newsize = relax_branch (fragp, sec, 11, stretch);
0110f2b8
PB
27322 break;
27323 case T_MNEM_bcond:
5f4273c7 27324 newsize = relax_branch (fragp, sec, 8, stretch);
0110f2b8
PB
27325 break;
27326 case T_MNEM_add_sp:
27327 case T_MNEM_add_pc:
27328 newsize = relax_immediate (fragp, 8, 2);
27329 break;
27330 case T_MNEM_inc_sp:
27331 case T_MNEM_dec_sp:
27332 newsize = relax_immediate (fragp, 7, 2);
27333 break;
27334 case T_MNEM_addi:
27335 case T_MNEM_addis:
27336 case T_MNEM_subi:
27337 case T_MNEM_subis:
27338 newsize = relax_addsub (fragp, sec);
27339 break;
27340 default:
5f4273c7 27341 abort ();
0110f2b8 27342 }
5e77afaa
PB
27343
27344 fragp->fr_var = newsize;
27345 /* Freeze wide instructions that are at or before the same location as
27346 in the previous pass. This avoids infinite loops.
5f4273c7
NC
27347 Don't freeze them unconditionally because targets may be artificially
27348 misaligned by the expansion of preceding frags. */
5e77afaa 27349 if (stretch <= 0 && newsize > 2)
0110f2b8 27350 {
0110f2b8 27351 md_convert_frag (sec->owner, sec, fragp);
5f4273c7 27352 frag_wane (fragp);
0110f2b8 27353 }
5e77afaa 27354
0110f2b8 27355 return newsize - oldsize;
c19d1205 27356}
b99bd4ef 27357
c19d1205 27358/* Round up a section size to the appropriate boundary. */
b99bd4ef 27359
c19d1205
ZW
27360valueT
27361md_section_align (segT segment ATTRIBUTE_UNUSED,
27362 valueT size)
27363{
6844c0cc 27364 return size;
bfae80f2 27365}
b99bd4ef 27366
c19d1205
ZW
27367/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
27368 of an rs_align_code fragment. */
27369
27370void
27371arm_handle_align (fragS * fragP)
bfae80f2 27372{
d9235011 27373 static unsigned char const arm_noop[2][2][4] =
e7495e45
NS
27374 {
27375 { /* ARMv1 */
27376 {0x00, 0x00, 0xa0, 0xe1}, /* LE */
27377 {0xe1, 0xa0, 0x00, 0x00}, /* BE */
27378 },
27379 { /* ARMv6k */
27380 {0x00, 0xf0, 0x20, 0xe3}, /* LE */
27381 {0xe3, 0x20, 0xf0, 0x00}, /* BE */
27382 },
27383 };
d9235011 27384 static unsigned char const thumb_noop[2][2][2] =
e7495e45
NS
27385 {
27386 { /* Thumb-1 */
27387 {0xc0, 0x46}, /* LE */
27388 {0x46, 0xc0}, /* BE */
27389 },
27390 { /* Thumb-2 */
27391 {0x00, 0xbf}, /* LE */
27392 {0xbf, 0x00} /* BE */
27393 }
27394 };
d9235011 27395 static unsigned char const wide_thumb_noop[2][4] =
e7495e45
NS
27396 { /* Wide Thumb-2 */
27397 {0xaf, 0xf3, 0x00, 0x80}, /* LE */
27398 {0xf3, 0xaf, 0x80, 0x00}, /* BE */
27399 };
c921be7d 27400
e7495e45 27401 unsigned bytes, fix, noop_size;
c19d1205 27402 char * p;
d9235011
TS
27403 const unsigned char * noop;
27404 const unsigned char *narrow_noop = NULL;
cd000bff
DJ
27405#ifdef OBJ_ELF
27406 enum mstate state;
27407#endif
bfae80f2 27408
c19d1205 27409 if (fragP->fr_type != rs_align_code)
bfae80f2
RE
27410 return;
27411
c19d1205
ZW
27412 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
27413 p = fragP->fr_literal + fragP->fr_fix;
27414 fix = 0;
bfae80f2 27415
c19d1205
ZW
27416 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
27417 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
bfae80f2 27418
cd000bff 27419 gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
8dc2430f 27420
cd000bff 27421 if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
a737bd4d 27422 {
7f78eb34
JW
27423 if (ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
27424 ? selected_cpu : arm_arch_none, arm_ext_v6t2))
e7495e45
NS
27425 {
27426 narrow_noop = thumb_noop[1][target_big_endian];
27427 noop = wide_thumb_noop[target_big_endian];
27428 }
c19d1205 27429 else
e7495e45
NS
27430 noop = thumb_noop[0][target_big_endian];
27431 noop_size = 2;
cd000bff
DJ
27432#ifdef OBJ_ELF
27433 state = MAP_THUMB;
27434#endif
7ed4c4c5
NC
27435 }
27436 else
27437 {
7f78eb34
JW
27438 noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
27439 ? selected_cpu : arm_arch_none,
27440 arm_ext_v6k) != 0]
e7495e45
NS
27441 [target_big_endian];
27442 noop_size = 4;
cd000bff
DJ
27443#ifdef OBJ_ELF
27444 state = MAP_ARM;
27445#endif
7ed4c4c5 27446 }
c921be7d 27447
e7495e45 27448 fragP->fr_var = noop_size;
c921be7d 27449
c19d1205 27450 if (bytes & (noop_size - 1))
7ed4c4c5 27451 {
c19d1205 27452 fix = bytes & (noop_size - 1);
cd000bff
DJ
27453#ifdef OBJ_ELF
27454 insert_data_mapping_symbol (state, fragP->fr_fix, fragP, fix);
27455#endif
c19d1205
ZW
27456 memset (p, 0, fix);
27457 p += fix;
27458 bytes -= fix;
a737bd4d 27459 }
a737bd4d 27460
e7495e45
NS
27461 if (narrow_noop)
27462 {
27463 if (bytes & noop_size)
27464 {
27465 /* Insert a narrow noop. */
27466 memcpy (p, narrow_noop, noop_size);
27467 p += noop_size;
27468 bytes -= noop_size;
27469 fix += noop_size;
27470 }
27471
27472 /* Use wide noops for the remainder */
27473 noop_size = 4;
27474 }
27475
c19d1205 27476 while (bytes >= noop_size)
a737bd4d 27477 {
c19d1205
ZW
27478 memcpy (p, noop, noop_size);
27479 p += noop_size;
27480 bytes -= noop_size;
27481 fix += noop_size;
a737bd4d
NC
27482 }
27483
c19d1205 27484 fragP->fr_fix += fix;
a737bd4d
NC
27485}
27486
c19d1205
ZW
27487/* Called from md_do_align. Used to create an alignment
27488 frag in a code section. */
27489
27490void
27491arm_frag_align_code (int n, int max)
bfae80f2 27492{
c19d1205 27493 char * p;
7ed4c4c5 27494
c19d1205 27495 /* We assume that there will never be a requirement
6ec8e702 27496 to support alignments greater than MAX_MEM_FOR_RS_ALIGN_CODE bytes. */
c19d1205 27497 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
6ec8e702
NC
27498 {
27499 char err_msg[128];
27500
fa94de6b 27501 sprintf (err_msg,
477330fc
RM
27502 _("alignments greater than %d bytes not supported in .text sections."),
27503 MAX_MEM_FOR_RS_ALIGN_CODE + 1);
20203fb9 27504 as_fatal ("%s", err_msg);
6ec8e702 27505 }
bfae80f2 27506
c19d1205
ZW
27507 p = frag_var (rs_align_code,
27508 MAX_MEM_FOR_RS_ALIGN_CODE,
27509 1,
27510 (relax_substateT) max,
27511 (symbolS *) NULL,
27512 (offsetT) n,
27513 (char *) NULL);
27514 *p = 0;
27515}
bfae80f2 27516
8dc2430f
NC
27517/* Perform target specific initialisation of a frag.
27518 Note - despite the name this initialisation is not done when the frag
27519 is created, but only when its type is assigned. A frag can be created
27520 and used a long time before its type is set, so beware of assuming that
33eaf5de 27521 this initialisation is performed first. */
bfae80f2 27522
cd000bff
DJ
27523#ifndef OBJ_ELF
27524void
27525arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
27526{
27527 /* Record whether this frag is in an ARM or a THUMB area. */
2e98972e 27528 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
cd000bff
DJ
27529}
27530
27531#else /* OBJ_ELF is defined. */
c19d1205 27532void
cd000bff 27533arm_init_frag (fragS * fragP, int max_chars)
c19d1205 27534{
5b7c81bd 27535 bool frag_thumb_mode;
b968d18a 27536
8dc2430f
NC
27537 /* If the current ARM vs THUMB mode has not already
27538 been recorded into this frag then do so now. */
cd000bff 27539 if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
b968d18a
JW
27540 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
27541
e8d84ca1
NC
27542 /* PR 21809: Do not set a mapping state for debug sections
27543 - it just confuses other tools. */
fd361982 27544 if (bfd_section_flags (now_seg) & SEC_DEBUGGING)
e8d84ca1
NC
27545 return;
27546
b968d18a 27547 frag_thumb_mode = fragP->tc_frag_data.thumb_mode ^ MODE_RECORDED;
cd000bff 27548
f9c1b181
RL
27549 /* Record a mapping symbol for alignment frags. We will delete this
27550 later if the alignment ends up empty. */
27551 switch (fragP->fr_type)
27552 {
27553 case rs_align:
27554 case rs_align_test:
27555 case rs_fill:
27556 mapping_state_2 (MAP_DATA, max_chars);
27557 break;
27558 case rs_align_code:
b968d18a 27559 mapping_state_2 (frag_thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
f9c1b181
RL
27560 break;
27561 default:
27562 break;
cd000bff 27563 }
bfae80f2
RE
27564}
27565
c19d1205
ZW
27566/* When we change sections we need to issue a new mapping symbol. */
27567
27568void
27569arm_elf_change_section (void)
bfae80f2 27570{
c19d1205
ZW
27571 /* Link an unlinked unwind index table section to the .text section. */
27572 if (elf_section_type (now_seg) == SHT_ARM_EXIDX
27573 && elf_linked_to_section (now_seg) == NULL)
27574 elf_linked_to_section (now_seg) = text_section;
bfae80f2
RE
27575}
27576
c19d1205
ZW
27577int
27578arm_elf_section_type (const char * str, size_t len)
e45d0630 27579{
d34049e8 27580 if (len == 5 && startswith (str, "exidx"))
c19d1205 27581 return SHT_ARM_EXIDX;
e45d0630 27582
c19d1205
ZW
27583 return -1;
27584}
27585\f
27586/* Code to deal with unwinding tables. */
e45d0630 27587
c19d1205 27588static void add_unwind_adjustsp (offsetT);
e45d0630 27589
5f4273c7 27590/* Generate any deferred unwind frame offset. */
e45d0630 27591
bfae80f2 27592static void
c19d1205 27593flush_pending_unwind (void)
bfae80f2 27594{
c19d1205 27595 offsetT offset;
bfae80f2 27596
c19d1205
ZW
27597 offset = unwind.pending_offset;
27598 unwind.pending_offset = 0;
27599 if (offset != 0)
27600 add_unwind_adjustsp (offset);
bfae80f2
RE
27601}
27602
c19d1205
ZW
27603/* Add an opcode to this list for this function. Two-byte opcodes should
27604 be passed as op[0] << 8 | op[1]. The list of opcodes is built in reverse
27605 order. */
27606
bfae80f2 27607static void
c19d1205 27608add_unwind_opcode (valueT op, int length)
bfae80f2 27609{
c19d1205
ZW
27610 /* Add any deferred stack adjustment. */
27611 if (unwind.pending_offset)
27612 flush_pending_unwind ();
bfae80f2 27613
c19d1205 27614 unwind.sp_restored = 0;
bfae80f2 27615
c19d1205 27616 if (unwind.opcode_count + length > unwind.opcode_alloc)
bfae80f2 27617 {
c19d1205
ZW
27618 unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
27619 if (unwind.opcodes)
325801bd
TS
27620 unwind.opcodes = XRESIZEVEC (unsigned char, unwind.opcodes,
27621 unwind.opcode_alloc);
c19d1205 27622 else
325801bd 27623 unwind.opcodes = XNEWVEC (unsigned char, unwind.opcode_alloc);
bfae80f2 27624 }
c19d1205 27625 while (length > 0)
bfae80f2 27626 {
c19d1205
ZW
27627 length--;
27628 unwind.opcodes[unwind.opcode_count] = op & 0xff;
27629 op >>= 8;
27630 unwind.opcode_count++;
bfae80f2 27631 }
bfae80f2
RE
27632}
27633
c19d1205
ZW
27634/* Add unwind opcodes to adjust the stack pointer. */
27635
bfae80f2 27636static void
c19d1205 27637add_unwind_adjustsp (offsetT offset)
bfae80f2 27638{
c19d1205 27639 valueT op;
bfae80f2 27640
c19d1205 27641 if (offset > 0x200)
bfae80f2 27642 {
c19d1205
ZW
27643 /* We need at most 5 bytes to hold a 32-bit value in a uleb128. */
27644 char bytes[5];
27645 int n;
27646 valueT o;
bfae80f2 27647
c19d1205
ZW
27648 /* Long form: 0xb2, uleb128. */
27649 /* This might not fit in a word so add the individual bytes,
27650 remembering the list is built in reverse order. */
27651 o = (valueT) ((offset - 0x204) >> 2);
27652 if (o == 0)
27653 add_unwind_opcode (0, 1);
bfae80f2 27654
c19d1205
ZW
27655 /* Calculate the uleb128 encoding of the offset. */
27656 n = 0;
27657 while (o)
27658 {
27659 bytes[n] = o & 0x7f;
27660 o >>= 7;
27661 if (o)
27662 bytes[n] |= 0x80;
27663 n++;
27664 }
27665 /* Add the insn. */
27666 for (; n; n--)
27667 add_unwind_opcode (bytes[n - 1], 1);
27668 add_unwind_opcode (0xb2, 1);
27669 }
27670 else if (offset > 0x100)
bfae80f2 27671 {
c19d1205
ZW
27672 /* Two short opcodes. */
27673 add_unwind_opcode (0x3f, 1);
27674 op = (offset - 0x104) >> 2;
27675 add_unwind_opcode (op, 1);
bfae80f2 27676 }
c19d1205
ZW
27677 else if (offset > 0)
27678 {
27679 /* Short opcode. */
27680 op = (offset - 4) >> 2;
27681 add_unwind_opcode (op, 1);
27682 }
27683 else if (offset < 0)
bfae80f2 27684 {
c19d1205
ZW
27685 offset = -offset;
27686 while (offset > 0x100)
bfae80f2 27687 {
c19d1205
ZW
27688 add_unwind_opcode (0x7f, 1);
27689 offset -= 0x100;
bfae80f2 27690 }
c19d1205
ZW
27691 op = ((offset - 4) >> 2) | 0x40;
27692 add_unwind_opcode (op, 1);
bfae80f2 27693 }
bfae80f2
RE
27694}
27695
c19d1205 27696/* Finish the list of unwind opcodes for this function. */
0198d5e6 27697
c19d1205
ZW
27698static void
27699finish_unwind_opcodes (void)
bfae80f2 27700{
c19d1205 27701 valueT op;
bfae80f2 27702
c19d1205 27703 if (unwind.fp_used)
bfae80f2 27704 {
708587a4 27705 /* Adjust sp as necessary. */
c19d1205
ZW
27706 unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
27707 flush_pending_unwind ();
bfae80f2 27708
c19d1205
ZW
27709 /* After restoring sp from the frame pointer. */
27710 op = 0x90 | unwind.fp_reg;
27711 add_unwind_opcode (op, 1);
27712 }
27713 else
27714 flush_pending_unwind ();
bfae80f2
RE
27715}
27716
bfae80f2 27717
c19d1205
ZW
27718/* Start an exception table entry. If idx is nonzero this is an index table
27719 entry. */
bfae80f2
RE
27720
27721static void
c19d1205 27722start_unwind_section (const segT text_seg, int idx)
bfae80f2 27723{
c19d1205
ZW
27724 const char * text_name;
27725 const char * prefix;
27726 const char * prefix_once;
a8c4d40b 27727 struct elf_section_match match;
c19d1205 27728 char * sec_name;
c19d1205
ZW
27729 int type;
27730 int flags;
27731 int linkonce;
bfae80f2 27732
c19d1205 27733 if (idx)
bfae80f2 27734 {
c19d1205
ZW
27735 prefix = ELF_STRING_ARM_unwind;
27736 prefix_once = ELF_STRING_ARM_unwind_once;
27737 type = SHT_ARM_EXIDX;
bfae80f2 27738 }
c19d1205 27739 else
bfae80f2 27740 {
c19d1205
ZW
27741 prefix = ELF_STRING_ARM_unwind_info;
27742 prefix_once = ELF_STRING_ARM_unwind_info_once;
27743 type = SHT_PROGBITS;
bfae80f2
RE
27744 }
27745
c19d1205
ZW
27746 text_name = segment_name (text_seg);
27747 if (streq (text_name, ".text"))
27748 text_name = "";
27749
d34049e8 27750 if (startswith (text_name, ".gnu.linkonce.t."))
bfae80f2 27751 {
c19d1205
ZW
27752 prefix = prefix_once;
27753 text_name += strlen (".gnu.linkonce.t.");
bfae80f2
RE
27754 }
27755
29a2809e 27756 sec_name = concat (prefix, text_name, (char *) NULL);
bfae80f2 27757
c19d1205
ZW
27758 flags = SHF_ALLOC;
27759 linkonce = 0;
a8c4d40b 27760 memset (&match, 0, sizeof (match));
bfae80f2 27761
c19d1205
ZW
27762 /* Handle COMDAT group. */
27763 if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
bfae80f2 27764 {
a8c4d40b
L
27765 match.group_name = elf_group_name (text_seg);
27766 if (match.group_name == NULL)
c19d1205 27767 {
bd3ba5d1 27768 as_bad (_("Group section `%s' has no group signature"),
c19d1205
ZW
27769 segment_name (text_seg));
27770 ignore_rest_of_line ();
27771 return;
27772 }
27773 flags |= SHF_GROUP;
27774 linkonce = 1;
bfae80f2
RE
27775 }
27776
a8c4d40b 27777 obj_elf_change_section (sec_name, type, flags, 0, &match,
a91e1603 27778 linkonce, 0);
bfae80f2 27779
5f4273c7 27780 /* Set the section link for index tables. */
c19d1205
ZW
27781 if (idx)
27782 elf_linked_to_section (now_seg) = text_seg;
bfae80f2
RE
27783}
27784
bfae80f2 27785
c19d1205
ZW
27786/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
27787 personality routine data. Returns zero, or the index table value for
cad0da33 27788 an inline entry. */
c19d1205
ZW
27789
27790static valueT
27791create_unwind_entry (int have_data)
bfae80f2 27792{
c19d1205
ZW
27793 int size;
27794 addressT where;
27795 char *ptr;
27796 /* The current word of data. */
27797 valueT data;
27798 /* The number of bytes left in this word. */
27799 int n;
bfae80f2 27800
c19d1205 27801 finish_unwind_opcodes ();
bfae80f2 27802
c19d1205
ZW
27803 /* Remember the current text section. */
27804 unwind.saved_seg = now_seg;
27805 unwind.saved_subseg = now_subseg;
bfae80f2 27806
c19d1205 27807 start_unwind_section (now_seg, 0);
bfae80f2 27808
c19d1205 27809 if (unwind.personality_routine == NULL)
bfae80f2 27810 {
c19d1205
ZW
27811 if (unwind.personality_index == -2)
27812 {
27813 if (have_data)
5f4273c7 27814 as_bad (_("handlerdata in cantunwind frame"));
c19d1205
ZW
27815 return 1; /* EXIDX_CANTUNWIND. */
27816 }
bfae80f2 27817
c19d1205
ZW
27818 /* Use a default personality routine if none is specified. */
27819 if (unwind.personality_index == -1)
27820 {
27821 if (unwind.opcode_count > 3)
27822 unwind.personality_index = 1;
27823 else
27824 unwind.personality_index = 0;
27825 }
bfae80f2 27826
c19d1205
ZW
27827 /* Space for the personality routine entry. */
27828 if (unwind.personality_index == 0)
27829 {
27830 if (unwind.opcode_count > 3)
b43e801e
AM
27831 {
27832 as_bad (_("too many unwind opcodes for personality routine 0"));
27833 return 1;
27834 }
bfae80f2 27835
c19d1205
ZW
27836 if (!have_data)
27837 {
27838 /* All the data is inline in the index table. */
27839 data = 0x80;
27840 n = 3;
27841 while (unwind.opcode_count > 0)
27842 {
27843 unwind.opcode_count--;
27844 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
27845 n--;
27846 }
bfae80f2 27847
c19d1205
ZW
27848 /* Pad with "finish" opcodes. */
27849 while (n--)
27850 data = (data << 8) | 0xb0;
bfae80f2 27851
c19d1205
ZW
27852 return data;
27853 }
27854 size = 0;
27855 }
27856 else
27857 /* We get two opcodes "free" in the first word. */
27858 size = unwind.opcode_count - 2;
27859 }
27860 else
5011093d 27861 {
cad0da33
NC
27862 /* PR 16765: Missing or misplaced unwind directives can trigger this. */
27863 if (unwind.personality_index != -1)
27864 {
27865 as_bad (_("attempt to recreate an unwind entry"));
27866 return 1;
27867 }
5011093d
NC
27868
27869 /* An extra byte is required for the opcode count. */
27870 size = unwind.opcode_count + 1;
27871 }
bfae80f2 27872
c19d1205
ZW
27873 size = (size + 3) >> 2;
27874 if (size > 0xff)
b43e801e
AM
27875 {
27876 as_bad (_("too many unwind opcodes"));
27877 return 1;
27878 }
bfae80f2 27879
c19d1205
ZW
27880 frag_align (2, 0, 0);
27881 record_alignment (now_seg, 2);
27882 unwind.table_entry = expr_build_dot ();
27883
27884 /* Allocate the table entry. */
27885 ptr = frag_more ((size << 2) + 4);
74929e7b
NC
27886 /* PR 13449: Zero the table entries in case some of them are not used. */
27887 memset (ptr, 0, (size << 2) + 4);
c19d1205 27888 where = frag_now_fix () - ((size << 2) + 4);
bfae80f2 27889
c19d1205 27890 switch (unwind.personality_index)
bfae80f2 27891 {
c19d1205
ZW
27892 case -1:
27893 /* ??? Should this be a PLT generating relocation? */
27894 /* Custom personality routine. */
27895 fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
27896 BFD_RELOC_ARM_PREL31);
bfae80f2 27897
c19d1205
ZW
27898 where += 4;
27899 ptr += 4;
bfae80f2 27900
c19d1205 27901 /* Set the first byte to the number of additional words. */
5011093d 27902 data = size > 0 ? size - 1 : 0;
c19d1205
ZW
27903 n = 3;
27904 break;
bfae80f2 27905
c19d1205
ZW
27906 /* ABI defined personality routines. */
27907 case 0:
27908 /* Three opcodes bytes are packed into the first word. */
27909 data = 0x80;
27910 n = 3;
27911 break;
bfae80f2 27912
c19d1205
ZW
27913 case 1:
27914 case 2:
27915 /* The size and first two opcode bytes go in the first word. */
27916 data = ((0x80 + unwind.personality_index) << 8) | size;
27917 n = 2;
27918 break;
bfae80f2 27919
c19d1205
ZW
27920 default:
27921 /* Should never happen. */
27922 abort ();
27923 }
bfae80f2 27924
c19d1205
ZW
27925 /* Pack the opcodes into words (MSB first), reversing the list at the same
27926 time. */
27927 while (unwind.opcode_count > 0)
27928 {
27929 if (n == 0)
27930 {
27931 md_number_to_chars (ptr, data, 4);
27932 ptr += 4;
27933 n = 4;
27934 data = 0;
27935 }
27936 unwind.opcode_count--;
27937 n--;
27938 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
27939 }
27940
27941 /* Finish off the last word. */
27942 if (n < 4)
27943 {
27944 /* Pad with "finish" opcodes. */
27945 while (n--)
27946 data = (data << 8) | 0xb0;
27947
27948 md_number_to_chars (ptr, data, 4);
27949 }
27950
27951 if (!have_data)
27952 {
27953 /* Add an empty descriptor if there is no user-specified data. */
27954 ptr = frag_more (4);
27955 md_number_to_chars (ptr, 0, 4);
27956 }
27957
27958 return 0;
bfae80f2
RE
27959}
27960
f0927246
NC
27961/* Initialize the DWARF-2 unwind information for this procedure. */
27962
27963void
27964tc_arm_frame_initial_instructions (void)
27965{
27966 cfi_add_CFA_def_cfa (REG_SP, 0);
27967}
27968#endif /* OBJ_ELF */
27969
c19d1205
ZW
27970/* Convert REGNAME to a DWARF-2 register number. */
27971
27972int
1df69f4f 27973tc_arm_regname_to_dw2regnum (char *regname)
bfae80f2 27974{
1df69f4f 27975 int reg = arm_reg_parse (&regname, REG_TYPE_RN);
1f5afe1c
NC
27976 if (reg != FAIL)
27977 return reg;
c19d1205 27978
1f5afe1c
NC
27979 /* PR 16694: Allow VFP registers as well. */
27980 reg = arm_reg_parse (&regname, REG_TYPE_VFS);
27981 if (reg != FAIL)
27982 return 64 + reg;
c19d1205 27983
1f5afe1c
NC
27984 reg = arm_reg_parse (&regname, REG_TYPE_VFD);
27985 if (reg != FAIL)
27986 return reg + 256;
27987
e90f28a7
VDN
27988 reg = arm_reg_parse (&regname, REG_TYPE_PSEUDO);
27989 if (reg != FAIL)
27990 return reg;
27991
0198d5e6 27992 return FAIL;
bfae80f2
RE
27993}
27994
f0927246 27995#ifdef TE_PE
c19d1205 27996void
f0927246 27997tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
bfae80f2 27998{
91d6fa6a 27999 expressionS exp;
bfae80f2 28000
91d6fa6a
NC
28001 exp.X_op = O_secrel;
28002 exp.X_add_symbol = symbol;
28003 exp.X_add_number = 0;
28004 emit_expr (&exp, size);
f0927246
NC
28005}
28006#endif
bfae80f2 28007
c19d1205 28008/* MD interface: Symbol and relocation handling. */
bfae80f2 28009
2fc8bdac
ZW
28010/* Return the address within the segment that a PC-relative fixup is
28011 relative to. For ARM, PC-relative fixups applied to instructions
28012 are generally relative to the location of the fixup plus 8 bytes.
28013 Thumb branches are offset by 4, and Thumb loads relative to PC
28014 require special handling. */
bfae80f2 28015
c19d1205 28016long
2fc8bdac 28017md_pcrel_from_section (fixS * fixP, segT seg)
bfae80f2 28018{
2fc8bdac
ZW
28019 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
28020
28021 /* If this is pc-relative and we are going to emit a relocation
28022 then we just want to put out any pipeline compensation that the linker
53baae48
NC
28023 will need. Otherwise we want to use the calculated base.
28024 For WinCE we skip the bias for externals as well, since this
28025 is how the MS ARM-CE assembler behaves and we want to be compatible. */
5f4273c7 28026 if (fixP->fx_pcrel
2fc8bdac 28027 && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
53baae48
NC
28028 || (arm_force_relocation (fixP)
28029#ifdef TE_WINCE
28030 && !S_IS_EXTERNAL (fixP->fx_addsy)
28031#endif
28032 )))
2fc8bdac 28033 base = 0;
bfae80f2 28034
267bf995 28035
c19d1205 28036 switch (fixP->fx_r_type)
bfae80f2 28037 {
2fc8bdac
ZW
28038 /* PC relative addressing on the Thumb is slightly odd as the
28039 bottom two bits of the PC are forced to zero for the
28040 calculation. This happens *after* application of the
28041 pipeline offset. However, Thumb adrl already adjusts for
28042 this, so we need not do it again. */
c19d1205 28043 case BFD_RELOC_ARM_THUMB_ADD:
2fc8bdac 28044 return base & ~3;
c19d1205
ZW
28045
28046 case BFD_RELOC_ARM_THUMB_OFFSET:
28047 case BFD_RELOC_ARM_T32_OFFSET_IMM:
e9f89963 28048 case BFD_RELOC_ARM_T32_ADD_PC12:
8f06b2d8 28049 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
2fc8bdac 28050 return (base + 4) & ~3;
c19d1205 28051
2fc8bdac 28052 /* Thumb branches are simply offset by +4. */
e12437dc 28053 case BFD_RELOC_THUMB_PCREL_BRANCH5:
2fc8bdac
ZW
28054 case BFD_RELOC_THUMB_PCREL_BRANCH7:
28055 case BFD_RELOC_THUMB_PCREL_BRANCH9:
28056 case BFD_RELOC_THUMB_PCREL_BRANCH12:
28057 case BFD_RELOC_THUMB_PCREL_BRANCH20:
2fc8bdac 28058 case BFD_RELOC_THUMB_PCREL_BRANCH25:
f6b2b12d 28059 case BFD_RELOC_THUMB_PCREL_BFCSEL:
e5d6e09e 28060 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 28061 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 28062 case BFD_RELOC_ARM_THUMB_BF13:
60f993ce 28063 case BFD_RELOC_ARM_THUMB_LOOP12:
2fc8bdac 28064 return base + 4;
bfae80f2 28065
267bf995 28066 case BFD_RELOC_THUMB_PCREL_BRANCH23:
486499d0
CL
28067 if (fixP->fx_addsy
28068 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28069 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995 28070 && ARM_IS_FUNC (fixP->fx_addsy)
477330fc
RM
28071 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28072 base = fixP->fx_where + fixP->fx_frag->fr_address;
267bf995
RR
28073 return base + 4;
28074
00adf2d4
JB
28075 /* BLX is like branches above, but forces the low two bits of PC to
28076 zero. */
486499d0
CL
28077 case BFD_RELOC_THUMB_PCREL_BLX:
28078 if (fixP->fx_addsy
28079 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28080 && !S_FORCE_RELOC (fixP->fx_addsy, true)
477330fc
RM
28081 && THUMB_IS_FUNC (fixP->fx_addsy)
28082 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28083 base = fixP->fx_where + fixP->fx_frag->fr_address;
00adf2d4
JB
28084 return (base + 4) & ~3;
28085
2fc8bdac
ZW
28086 /* ARM mode branches are offset by +8. However, the Windows CE
28087 loader expects the relocation not to take this into account. */
267bf995 28088 case BFD_RELOC_ARM_PCREL_BLX:
486499d0
CL
28089 if (fixP->fx_addsy
28090 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28091 && !S_FORCE_RELOC (fixP->fx_addsy, true)
477330fc
RM
28092 && ARM_IS_FUNC (fixP->fx_addsy)
28093 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28094 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 28095 return base + 8;
267bf995 28096
486499d0
CL
28097 case BFD_RELOC_ARM_PCREL_CALL:
28098 if (fixP->fx_addsy
28099 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28100 && !S_FORCE_RELOC (fixP->fx_addsy, true)
477330fc
RM
28101 && THUMB_IS_FUNC (fixP->fx_addsy)
28102 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28103 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 28104 return base + 8;
267bf995 28105
2fc8bdac 28106 case BFD_RELOC_ARM_PCREL_BRANCH:
39b41c9c 28107 case BFD_RELOC_ARM_PCREL_JUMP:
2fc8bdac 28108 case BFD_RELOC_ARM_PLT32:
c19d1205 28109#ifdef TE_WINCE
5f4273c7 28110 /* When handling fixups immediately, because we have already
477330fc 28111 discovered the value of a symbol, or the address of the frag involved
53baae48 28112 we must account for the offset by +8, as the OS loader will never see the reloc.
477330fc
RM
28113 see fixup_segment() in write.c
28114 The S_IS_EXTERNAL test handles the case of global symbols.
28115 Those need the calculated base, not just the pipe compensation the linker will need. */
53baae48
NC
28116 if (fixP->fx_pcrel
28117 && fixP->fx_addsy != NULL
28118 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28119 && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP)))
28120 return base + 8;
2fc8bdac 28121 return base;
c19d1205 28122#else
2fc8bdac 28123 return base + 8;
c19d1205 28124#endif
2fc8bdac 28125
267bf995 28126
2fc8bdac
ZW
28127 /* ARM mode loads relative to PC are also offset by +8. Unlike
28128 branches, the Windows CE loader *does* expect the relocation
28129 to take this into account. */
28130 case BFD_RELOC_ARM_OFFSET_IMM:
28131 case BFD_RELOC_ARM_OFFSET_IMM8:
28132 case BFD_RELOC_ARM_HWLITERAL:
28133 case BFD_RELOC_ARM_LITERAL:
28134 case BFD_RELOC_ARM_CP_OFF_IMM:
28135 return base + 8;
28136
28137
28138 /* Other PC-relative relocations are un-offset. */
28139 default:
28140 return base;
28141 }
bfae80f2
RE
28142}
28143
5b7c81bd 28144static bool flag_warn_syms = true;
8b2d793c 28145
5b7c81bd 28146bool
ae8714c2 28147arm_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char * name)
bfae80f2 28148{
8b2d793c
NC
28149 /* PR 18347 - Warn if the user attempts to create a symbol with the same
28150 name as an ARM instruction. Whilst strictly speaking it is allowed, it
28151 does mean that the resulting code might be very confusing to the reader.
28152 Also this warning can be triggered if the user omits an operand before
28153 an immediate address, eg:
28154
28155 LDR =foo
28156
28157 GAS treats this as an assignment of the value of the symbol foo to a
28158 symbol LDR, and so (without this code) it will not issue any kind of
28159 warning or error message.
28160
28161 Note - ARM instructions are case-insensitive but the strings in the hash
28162 table are all stored in lower case, so we must first ensure that name is
ae8714c2
NC
28163 lower case too. */
28164 if (flag_warn_syms && arm_ops_hsh)
8b2d793c
NC
28165 {
28166 char * nbuf = strdup (name);
28167 char * p;
28168
28169 for (p = nbuf; *p; p++)
28170 *p = TOLOWER (*p);
629310ab 28171 if (str_hash_find (arm_ops_hsh, nbuf) != NULL)
8b2d793c 28172 {
629310ab 28173 static htab_t already_warned = NULL;
8b2d793c
NC
28174
28175 if (already_warned == NULL)
629310ab 28176 already_warned = str_htab_create ();
8b2d793c 28177 /* Only warn about the symbol once. To keep the code
629310ab 28178 simple we let str_hash_insert do the lookup for us. */
d3be5dab
AM
28179 if (str_hash_insert (already_warned, nbuf, NULL, 0) == NULL)
28180 as_warn (_("[-mwarn-syms]: Assignment makes a symbol match an ARM instruction: %s"), name);
8b2d793c
NC
28181 }
28182 else
28183 free (nbuf);
28184 }
3739860c 28185
5b7c81bd 28186 return false;
ae8714c2
NC
28187}
28188
28189/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
28190 Otherwise we have no need to default values of symbols. */
28191
28192symbolS *
28193md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
28194{
28195#ifdef OBJ_ELF
28196 if (name[0] == '_' && name[1] == 'G'
28197 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
28198 {
28199 if (!GOT_symbol)
28200 {
28201 if (symbol_find (name))
28202 as_bad (_("GOT already in the symbol table"));
28203
28204 GOT_symbol = symbol_new (name, undefined_section,
e01e1cee 28205 &zero_address_frag, 0);
ae8714c2
NC
28206 }
28207
28208 return GOT_symbol;
28209 }
28210#endif
28211
c921be7d 28212 return NULL;
bfae80f2
RE
28213}
28214
55cf6793 28215/* Subroutine of md_apply_fix. Check to see if an immediate can be
c19d1205
ZW
28216 computed as two separate immediate values, added together. We
28217 already know that this value cannot be computed by just one ARM
28218 instruction. */
28219
28220static unsigned int
28221validate_immediate_twopart (unsigned int val,
28222 unsigned int * highpart)
bfae80f2 28223{
c19d1205
ZW
28224 unsigned int a;
28225 unsigned int i;
bfae80f2 28226
c19d1205
ZW
28227 for (i = 0; i < 32; i += 2)
28228 if (((a = rotate_left (val, i)) & 0xff) != 0)
28229 {
28230 if (a & 0xff00)
28231 {
28232 if (a & ~ 0xffff)
28233 continue;
28234 * highpart = (a >> 8) | ((i + 24) << 7);
28235 }
28236 else if (a & 0xff0000)
28237 {
28238 if (a & 0xff000000)
28239 continue;
28240 * highpart = (a >> 16) | ((i + 16) << 7);
28241 }
28242 else
28243 {
9c2799c2 28244 gas_assert (a & 0xff000000);
c19d1205
ZW
28245 * highpart = (a >> 24) | ((i + 8) << 7);
28246 }
bfae80f2 28247
c19d1205
ZW
28248 return (a & 0xff) | (i << 7);
28249 }
bfae80f2 28250
c19d1205 28251 return FAIL;
bfae80f2
RE
28252}
28253
c19d1205
ZW
28254static int
28255validate_offset_imm (unsigned int val, int hwse)
28256{
28257 if ((hwse && val > 255) || val > 4095)
28258 return FAIL;
28259 return val;
28260}
bfae80f2 28261
55cf6793 28262/* Subroutine of md_apply_fix. Do those data_ops which can take a
c19d1205
ZW
28263 negative immediate constant by altering the instruction. A bit of
28264 a hack really.
28265 MOV <-> MVN
28266 AND <-> BIC
28267 ADC <-> SBC
28268 by inverting the second operand, and
28269 ADD <-> SUB
28270 CMP <-> CMN
28271 by negating the second operand. */
bfae80f2 28272
c19d1205
ZW
28273static int
28274negate_data_op (unsigned long * instruction,
28275 unsigned long value)
bfae80f2 28276{
c19d1205
ZW
28277 int op, new_inst;
28278 unsigned long negated, inverted;
bfae80f2 28279
c19d1205
ZW
28280 negated = encode_arm_immediate (-value);
28281 inverted = encode_arm_immediate (~value);
bfae80f2 28282
c19d1205
ZW
28283 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
28284 switch (op)
bfae80f2 28285 {
c19d1205
ZW
28286 /* First negates. */
28287 case OPCODE_SUB: /* ADD <-> SUB */
28288 new_inst = OPCODE_ADD;
28289 value = negated;
28290 break;
bfae80f2 28291
c19d1205
ZW
28292 case OPCODE_ADD:
28293 new_inst = OPCODE_SUB;
28294 value = negated;
28295 break;
bfae80f2 28296
c19d1205
ZW
28297 case OPCODE_CMP: /* CMP <-> CMN */
28298 new_inst = OPCODE_CMN;
28299 value = negated;
28300 break;
bfae80f2 28301
c19d1205
ZW
28302 case OPCODE_CMN:
28303 new_inst = OPCODE_CMP;
28304 value = negated;
28305 break;
bfae80f2 28306
c19d1205
ZW
28307 /* Now Inverted ops. */
28308 case OPCODE_MOV: /* MOV <-> MVN */
28309 new_inst = OPCODE_MVN;
28310 value = inverted;
28311 break;
bfae80f2 28312
c19d1205
ZW
28313 case OPCODE_MVN:
28314 new_inst = OPCODE_MOV;
28315 value = inverted;
28316 break;
bfae80f2 28317
c19d1205
ZW
28318 case OPCODE_AND: /* AND <-> BIC */
28319 new_inst = OPCODE_BIC;
28320 value = inverted;
28321 break;
bfae80f2 28322
c19d1205
ZW
28323 case OPCODE_BIC:
28324 new_inst = OPCODE_AND;
28325 value = inverted;
28326 break;
bfae80f2 28327
c19d1205
ZW
28328 case OPCODE_ADC: /* ADC <-> SBC */
28329 new_inst = OPCODE_SBC;
28330 value = inverted;
28331 break;
bfae80f2 28332
c19d1205
ZW
28333 case OPCODE_SBC:
28334 new_inst = OPCODE_ADC;
28335 value = inverted;
28336 break;
bfae80f2 28337
c19d1205
ZW
28338 /* We cannot do anything. */
28339 default:
28340 return FAIL;
b99bd4ef
NC
28341 }
28342
c19d1205
ZW
28343 if (value == (unsigned) FAIL)
28344 return FAIL;
28345
28346 *instruction &= OPCODE_MASK;
28347 *instruction |= new_inst << DATA_OP_SHIFT;
28348 return value;
b99bd4ef
NC
28349}
28350
ef8d22e6
PB
28351/* Like negate_data_op, but for Thumb-2. */
28352
28353static unsigned int
7af67752 28354thumb32_negate_data_op (valueT *instruction, unsigned int value)
ef8d22e6 28355{
7af67752
AM
28356 unsigned int op, new_inst;
28357 unsigned int rd;
16dd5e42 28358 unsigned int negated, inverted;
ef8d22e6
PB
28359
28360 negated = encode_thumb32_immediate (-value);
28361 inverted = encode_thumb32_immediate (~value);
28362
28363 rd = (*instruction >> 8) & 0xf;
28364 op = (*instruction >> T2_DATA_OP_SHIFT) & 0xf;
28365 switch (op)
28366 {
28367 /* ADD <-> SUB. Includes CMP <-> CMN. */
28368 case T2_OPCODE_SUB:
28369 new_inst = T2_OPCODE_ADD;
28370 value = negated;
28371 break;
28372
28373 case T2_OPCODE_ADD:
28374 new_inst = T2_OPCODE_SUB;
28375 value = negated;
28376 break;
28377
28378 /* ORR <-> ORN. Includes MOV <-> MVN. */
28379 case T2_OPCODE_ORR:
28380 new_inst = T2_OPCODE_ORN;
28381 value = inverted;
28382 break;
28383
28384 case T2_OPCODE_ORN:
28385 new_inst = T2_OPCODE_ORR;
28386 value = inverted;
28387 break;
28388
28389 /* AND <-> BIC. TST has no inverted equivalent. */
28390 case T2_OPCODE_AND:
28391 new_inst = T2_OPCODE_BIC;
28392 if (rd == 15)
28393 value = FAIL;
28394 else
28395 value = inverted;
28396 break;
28397
28398 case T2_OPCODE_BIC:
28399 new_inst = T2_OPCODE_AND;
28400 value = inverted;
28401 break;
28402
28403 /* ADC <-> SBC */
28404 case T2_OPCODE_ADC:
28405 new_inst = T2_OPCODE_SBC;
28406 value = inverted;
28407 break;
28408
28409 case T2_OPCODE_SBC:
28410 new_inst = T2_OPCODE_ADC;
28411 value = inverted;
28412 break;
28413
28414 /* We cannot do anything. */
28415 default:
28416 return FAIL;
28417 }
28418
16dd5e42 28419 if (value == (unsigned int)FAIL)
ef8d22e6
PB
28420 return FAIL;
28421
28422 *instruction &= T2_OPCODE_MASK;
28423 *instruction |= new_inst << T2_DATA_OP_SHIFT;
28424 return value;
28425}
28426
8f06b2d8 28427/* Read a 32-bit thumb instruction from buf. */
0198d5e6 28428
8f06b2d8
PB
28429static unsigned long
28430get_thumb32_insn (char * buf)
28431{
28432 unsigned long insn;
28433 insn = md_chars_to_number (buf, THUMB_SIZE) << 16;
28434 insn |= md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28435
28436 return insn;
28437}
28438
a8bc6c78
PB
28439/* We usually want to set the low bit on the address of thumb function
28440 symbols. In particular .word foo - . should have the low bit set.
28441 Generic code tries to fold the difference of two symbols to
28442 a constant. Prevent this and force a relocation when the first symbols
28443 is a thumb function. */
c921be7d 28444
5b7c81bd 28445bool
a8bc6c78
PB
28446arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
28447{
28448 if (op == O_subtract
28449 && l->X_op == O_symbol
28450 && r->X_op == O_symbol
28451 && THUMB_IS_FUNC (l->X_add_symbol))
28452 {
28453 l->X_op = O_subtract;
28454 l->X_op_symbol = r->X_add_symbol;
28455 l->X_add_number -= r->X_add_number;
5b7c81bd 28456 return true;
a8bc6c78 28457 }
c921be7d 28458
a8bc6c78 28459 /* Process as normal. */
5b7c81bd 28460 return false;
a8bc6c78
PB
28461}
28462
4a42ebbc
RR
28463/* Encode Thumb2 unconditional branches and calls. The encoding
28464 for the 2 are identical for the immediate values. */
28465
28466static void
28467encode_thumb2_b_bl_offset (char * buf, offsetT value)
28468{
28469#define T2I1I2MASK ((1 << 13) | (1 << 11))
28470 offsetT newval;
28471 offsetT newval2;
28472 addressT S, I1, I2, lo, hi;
28473
28474 S = (value >> 24) & 0x01;
28475 I1 = (value >> 23) & 0x01;
28476 I2 = (value >> 22) & 0x01;
28477 hi = (value >> 12) & 0x3ff;
fa94de6b 28478 lo = (value >> 1) & 0x7ff;
4a42ebbc
RR
28479 newval = md_chars_to_number (buf, THUMB_SIZE);
28480 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28481 newval |= (S << 10) | hi;
28482 newval2 &= ~T2I1I2MASK;
28483 newval2 |= (((I1 ^ S) << 13) | ((I2 ^ S) << 11) | lo) ^ T2I1I2MASK;
28484 md_number_to_chars (buf, newval, THUMB_SIZE);
28485 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
28486}
28487
c19d1205 28488void
55cf6793 28489md_apply_fix (fixS * fixP,
c19d1205
ZW
28490 valueT * valP,
28491 segT seg)
28492{
7af67752
AM
28493 valueT value = * valP;
28494 valueT newval;
c19d1205
ZW
28495 unsigned int newimm;
28496 unsigned long temp;
28497 int sign;
28498 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
b99bd4ef 28499
9c2799c2 28500 gas_assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
b99bd4ef 28501
c19d1205 28502 /* Note whether this will delete the relocation. */
4962c51a 28503
c19d1205
ZW
28504 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
28505 fixP->fx_done = 1;
b99bd4ef 28506
adbaf948 28507 /* On a 64-bit host, silently truncate 'value' to 32 bits for
5f4273c7 28508 consistency with the behaviour on 32-bit hosts. Remember value
adbaf948
ZW
28509 for emit_reloc. */
28510 value &= 0xffffffff;
28511 value ^= 0x80000000;
5f4273c7 28512 value -= 0x80000000;
adbaf948
ZW
28513
28514 *valP = value;
c19d1205 28515 fixP->fx_addnumber = value;
b99bd4ef 28516
adbaf948
ZW
28517 /* Same treatment for fixP->fx_offset. */
28518 fixP->fx_offset &= 0xffffffff;
28519 fixP->fx_offset ^= 0x80000000;
28520 fixP->fx_offset -= 0x80000000;
28521
c19d1205 28522 switch (fixP->fx_r_type)
b99bd4ef 28523 {
c19d1205
ZW
28524 case BFD_RELOC_NONE:
28525 /* This will need to go in the object file. */
28526 fixP->fx_done = 0;
28527 break;
b99bd4ef 28528
c19d1205
ZW
28529 case BFD_RELOC_ARM_IMMEDIATE:
28530 /* We claim that this fixup has been processed here,
28531 even if in fact we generate an error because we do
28532 not have a reloc for it, so tc_gen_reloc will reject it. */
28533 fixP->fx_done = 1;
b99bd4ef 28534
77db8e2e 28535 if (fixP->fx_addsy)
b99bd4ef 28536 {
77db8e2e 28537 const char *msg = 0;
b99bd4ef 28538
77db8e2e
NC
28539 if (! S_IS_DEFINED (fixP->fx_addsy))
28540 msg = _("undefined symbol %s used as an immediate value");
28541 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
28542 msg = _("symbol %s is in a different section");
28543 else if (S_IS_WEAK (fixP->fx_addsy))
28544 msg = _("symbol %s is weak and may be overridden later");
28545
28546 if (msg)
28547 {
28548 as_bad_where (fixP->fx_file, fixP->fx_line,
28549 msg, S_GET_NAME (fixP->fx_addsy));
28550 break;
28551 }
42e5fcbf
AS
28552 }
28553
c19d1205
ZW
28554 temp = md_chars_to_number (buf, INSN_SIZE);
28555
5e73442d 28556 /* If the offset is negative, we should use encoding A2 for ADR. */
7af67752 28557 if ((temp & 0xfff0000) == 0x28f0000 && (offsetT) value < 0)
5e73442d
SL
28558 newimm = negate_data_op (&temp, value);
28559 else
28560 {
28561 newimm = encode_arm_immediate (value);
28562
28563 /* If the instruction will fail, see if we can fix things up by
28564 changing the opcode. */
28565 if (newimm == (unsigned int) FAIL)
28566 newimm = negate_data_op (&temp, value);
bada4342
JW
28567 /* MOV accepts both ARM modified immediate (A1 encoding) and
28568 UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
28569 When disassembling, MOV is preferred when there is no encoding
28570 overlap. */
28571 if (newimm == (unsigned int) FAIL
28572 && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
28573 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
28574 && !((temp >> SBIT_SHIFT) & 0x1)
7af67752 28575 && value <= 0xffff)
bada4342
JW
28576 {
28577 /* Clear bits[23:20] to change encoding from A1 to A2. */
28578 temp &= 0xff0fffff;
28579 /* Encoding high 4bits imm. Code below will encode the remaining
28580 low 12bits. */
28581 temp |= (value & 0x0000f000) << 4;
28582 newimm = value & 0x00000fff;
28583 }
5e73442d
SL
28584 }
28585
28586 if (newimm == (unsigned int) FAIL)
b99bd4ef 28587 {
c19d1205
ZW
28588 as_bad_where (fixP->fx_file, fixP->fx_line,
28589 _("invalid constant (%lx) after fixup"),
28590 (unsigned long) value);
28591 break;
b99bd4ef 28592 }
b99bd4ef 28593
c19d1205
ZW
28594 newimm |= (temp & 0xfffff000);
28595 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
28596 break;
b99bd4ef 28597
c19d1205
ZW
28598 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
28599 {
28600 unsigned int highpart = 0;
28601 unsigned int newinsn = 0xe1a00000; /* nop. */
b99bd4ef 28602
77db8e2e 28603 if (fixP->fx_addsy)
42e5fcbf 28604 {
77db8e2e 28605 const char *msg = 0;
42e5fcbf 28606
77db8e2e
NC
28607 if (! S_IS_DEFINED (fixP->fx_addsy))
28608 msg = _("undefined symbol %s used as an immediate value");
28609 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
28610 msg = _("symbol %s is in a different section");
28611 else if (S_IS_WEAK (fixP->fx_addsy))
28612 msg = _("symbol %s is weak and may be overridden later");
42e5fcbf 28613
77db8e2e
NC
28614 if (msg)
28615 {
28616 as_bad_where (fixP->fx_file, fixP->fx_line,
28617 msg, S_GET_NAME (fixP->fx_addsy));
28618 break;
28619 }
28620 }
fa94de6b 28621
c19d1205
ZW
28622 newimm = encode_arm_immediate (value);
28623 temp = md_chars_to_number (buf, INSN_SIZE);
b99bd4ef 28624
c19d1205
ZW
28625 /* If the instruction will fail, see if we can fix things up by
28626 changing the opcode. */
28627 if (newimm == (unsigned int) FAIL
28628 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
28629 {
28630 /* No ? OK - try using two ADD instructions to generate
28631 the value. */
28632 newimm = validate_immediate_twopart (value, & highpart);
b99bd4ef 28633
c19d1205
ZW
28634 /* Yes - then make sure that the second instruction is
28635 also an add. */
28636 if (newimm != (unsigned int) FAIL)
28637 newinsn = temp;
28638 /* Still No ? Try using a negated value. */
28639 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
28640 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
28641 /* Otherwise - give up. */
28642 else
28643 {
28644 as_bad_where (fixP->fx_file, fixP->fx_line,
28645 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
28646 (long) value);
28647 break;
28648 }
b99bd4ef 28649
c19d1205
ZW
28650 /* Replace the first operand in the 2nd instruction (which
28651 is the PC) with the destination register. We have
28652 already added in the PC in the first instruction and we
28653 do not want to do it again. */
28654 newinsn &= ~ 0xf0000;
28655 newinsn |= ((newinsn & 0x0f000) << 4);
28656 }
b99bd4ef 28657
c19d1205
ZW
28658 newimm |= (temp & 0xfffff000);
28659 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
b99bd4ef 28660
c19d1205
ZW
28661 highpart |= (newinsn & 0xfffff000);
28662 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
28663 }
28664 break;
b99bd4ef 28665
c19d1205 28666 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
28667 if (!fixP->fx_done && seg->use_rela_p)
28668 value = 0;
1a0670f3 28669 /* Fall through. */
00a97672 28670
c19d1205 28671 case BFD_RELOC_ARM_LITERAL:
7af67752 28672 sign = (offsetT) value > 0;
b99bd4ef 28673
7af67752 28674 if ((offsetT) value < 0)
c19d1205 28675 value = - value;
b99bd4ef 28676
c19d1205 28677 if (validate_offset_imm (value, 0) == FAIL)
f03698e6 28678 {
c19d1205
ZW
28679 if (fixP->fx_r_type == BFD_RELOC_ARM_LITERAL)
28680 as_bad_where (fixP->fx_file, fixP->fx_line,
28681 _("invalid literal constant: pool needs to be closer"));
28682 else
28683 as_bad_where (fixP->fx_file, fixP->fx_line,
28684 _("bad immediate value for offset (%ld)"),
28685 (long) value);
28686 break;
f03698e6
RE
28687 }
28688
c19d1205 28689 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
28690 if (value == 0)
28691 newval &= 0xfffff000;
28692 else
28693 {
28694 newval &= 0xff7ff000;
28695 newval |= value | (sign ? INDEX_UP : 0);
28696 }
c19d1205
ZW
28697 md_number_to_chars (buf, newval, INSN_SIZE);
28698 break;
b99bd4ef 28699
c19d1205
ZW
28700 case BFD_RELOC_ARM_OFFSET_IMM8:
28701 case BFD_RELOC_ARM_HWLITERAL:
7af67752 28702 sign = (offsetT) value > 0;
b99bd4ef 28703
7af67752 28704 if ((offsetT) value < 0)
c19d1205 28705 value = - value;
b99bd4ef 28706
c19d1205 28707 if (validate_offset_imm (value, 1) == FAIL)
b99bd4ef 28708 {
c19d1205
ZW
28709 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
28710 as_bad_where (fixP->fx_file, fixP->fx_line,
28711 _("invalid literal constant: pool needs to be closer"));
28712 else
427d0db6
RM
28713 as_bad_where (fixP->fx_file, fixP->fx_line,
28714 _("bad immediate value for 8-bit offset (%ld)"),
28715 (long) value);
c19d1205 28716 break;
b99bd4ef
NC
28717 }
28718
c19d1205 28719 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
28720 if (value == 0)
28721 newval &= 0xfffff0f0;
28722 else
28723 {
28724 newval &= 0xff7ff0f0;
28725 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
28726 }
c19d1205
ZW
28727 md_number_to_chars (buf, newval, INSN_SIZE);
28728 break;
b99bd4ef 28729
c19d1205 28730 case BFD_RELOC_ARM_T32_OFFSET_U8:
7af67752 28731 if (value > 1020 || value % 4 != 0)
c19d1205
ZW
28732 as_bad_where (fixP->fx_file, fixP->fx_line,
28733 _("bad immediate value for offset (%ld)"), (long) value);
28734 value /= 4;
b99bd4ef 28735
c19d1205 28736 newval = md_chars_to_number (buf+2, THUMB_SIZE);
c19d1205
ZW
28737 newval |= value;
28738 md_number_to_chars (buf+2, newval, THUMB_SIZE);
28739 break;
b99bd4ef 28740
c19d1205
ZW
28741 case BFD_RELOC_ARM_T32_OFFSET_IMM:
28742 /* This is a complicated relocation used for all varieties of Thumb32
28743 load/store instruction with immediate offset:
28744
28745 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
477330fc 28746 *4, optional writeback(W)
c19d1205
ZW
28747 (doubleword load/store)
28748
28749 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
28750 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
28751 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
28752 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
28753 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
28754
28755 Uppercase letters indicate bits that are already encoded at
28756 this point. Lowercase letters are our problem. For the
28757 second block of instructions, the secondary opcode nybble
28758 (bits 8..11) is present, and bit 23 is zero, even if this is
28759 a PC-relative operation. */
28760 newval = md_chars_to_number (buf, THUMB_SIZE);
28761 newval <<= 16;
28762 newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
b99bd4ef 28763
c19d1205 28764 if ((newval & 0xf0000000) == 0xe0000000)
b99bd4ef 28765 {
c19d1205 28766 /* Doubleword load/store: 8-bit offset, scaled by 4. */
7af67752 28767 if ((offsetT) value >= 0)
c19d1205
ZW
28768 newval |= (1 << 23);
28769 else
28770 value = -value;
28771 if (value % 4 != 0)
28772 {
28773 as_bad_where (fixP->fx_file, fixP->fx_line,
28774 _("offset not a multiple of 4"));
28775 break;
28776 }
28777 value /= 4;
216d22bc 28778 if (value > 0xff)
c19d1205
ZW
28779 {
28780 as_bad_where (fixP->fx_file, fixP->fx_line,
28781 _("offset out of range"));
28782 break;
28783 }
28784 newval &= ~0xff;
b99bd4ef 28785 }
c19d1205 28786 else if ((newval & 0x000f0000) == 0x000f0000)
b99bd4ef 28787 {
c19d1205 28788 /* PC-relative, 12-bit offset. */
7af67752 28789 if ((offsetT) value >= 0)
c19d1205
ZW
28790 newval |= (1 << 23);
28791 else
28792 value = -value;
216d22bc 28793 if (value > 0xfff)
c19d1205
ZW
28794 {
28795 as_bad_where (fixP->fx_file, fixP->fx_line,
28796 _("offset out of range"));
28797 break;
28798 }
28799 newval &= ~0xfff;
b99bd4ef 28800 }
c19d1205 28801 else if ((newval & 0x00000100) == 0x00000100)
b99bd4ef 28802 {
c19d1205 28803 /* Writeback: 8-bit, +/- offset. */
7af67752 28804 if ((offsetT) value >= 0)
c19d1205
ZW
28805 newval |= (1 << 9);
28806 else
28807 value = -value;
216d22bc 28808 if (value > 0xff)
c19d1205
ZW
28809 {
28810 as_bad_where (fixP->fx_file, fixP->fx_line,
28811 _("offset out of range"));
28812 break;
28813 }
28814 newval &= ~0xff;
b99bd4ef 28815 }
c19d1205 28816 else if ((newval & 0x00000f00) == 0x00000e00)
b99bd4ef 28817 {
c19d1205 28818 /* T-instruction: positive 8-bit offset. */
7af67752 28819 if (value > 0xff)
b99bd4ef 28820 {
c19d1205
ZW
28821 as_bad_where (fixP->fx_file, fixP->fx_line,
28822 _("offset out of range"));
28823 break;
b99bd4ef 28824 }
c19d1205
ZW
28825 newval &= ~0xff;
28826 newval |= value;
b99bd4ef
NC
28827 }
28828 else
b99bd4ef 28829 {
c19d1205 28830 /* Positive 12-bit or negative 8-bit offset. */
7af67752
AM
28831 unsigned int limit;
28832 if ((offsetT) value >= 0)
b99bd4ef 28833 {
c19d1205
ZW
28834 newval |= (1 << 23);
28835 limit = 0xfff;
28836 }
28837 else
28838 {
28839 value = -value;
28840 limit = 0xff;
28841 }
28842 if (value > limit)
28843 {
28844 as_bad_where (fixP->fx_file, fixP->fx_line,
28845 _("offset out of range"));
28846 break;
b99bd4ef 28847 }
c19d1205 28848 newval &= ~limit;
b99bd4ef 28849 }
b99bd4ef 28850
c19d1205
ZW
28851 newval |= value;
28852 md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
28853 md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
28854 break;
404ff6b5 28855
c19d1205
ZW
28856 case BFD_RELOC_ARM_SHIFT_IMM:
28857 newval = md_chars_to_number (buf, INSN_SIZE);
7af67752 28858 if (value > 32
c19d1205
ZW
28859 || (value == 32
28860 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
28861 {
28862 as_bad_where (fixP->fx_file, fixP->fx_line,
28863 _("shift expression is too large"));
28864 break;
28865 }
404ff6b5 28866
c19d1205
ZW
28867 if (value == 0)
28868 /* Shifts of zero must be done as lsl. */
28869 newval &= ~0x60;
28870 else if (value == 32)
28871 value = 0;
28872 newval &= 0xfffff07f;
28873 newval |= (value & 0x1f) << 7;
28874 md_number_to_chars (buf, newval, INSN_SIZE);
28875 break;
404ff6b5 28876
c19d1205 28877 case BFD_RELOC_ARM_T32_IMMEDIATE:
16805f35 28878 case BFD_RELOC_ARM_T32_ADD_IMM:
92e90b6e 28879 case BFD_RELOC_ARM_T32_IMM12:
e9f89963 28880 case BFD_RELOC_ARM_T32_ADD_PC12:
c19d1205
ZW
28881 /* We claim that this fixup has been processed here,
28882 even if in fact we generate an error because we do
28883 not have a reloc for it, so tc_gen_reloc will reject it. */
28884 fixP->fx_done = 1;
404ff6b5 28885
c19d1205
ZW
28886 if (fixP->fx_addsy
28887 && ! S_IS_DEFINED (fixP->fx_addsy))
28888 {
28889 as_bad_where (fixP->fx_file, fixP->fx_line,
28890 _("undefined symbol %s used as an immediate value"),
28891 S_GET_NAME (fixP->fx_addsy));
28892 break;
28893 }
404ff6b5 28894
c19d1205
ZW
28895 newval = md_chars_to_number (buf, THUMB_SIZE);
28896 newval <<= 16;
28897 newval |= md_chars_to_number (buf+2, THUMB_SIZE);
404ff6b5 28898
16805f35 28899 newimm = FAIL;
bada4342
JW
28900 if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
28901 /* ARMv8-M Baseline MOV will reach here, but it doesn't support
28902 Thumb2 modified immediate encoding (T2). */
28903 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
16805f35 28904 || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
ef8d22e6
PB
28905 {
28906 newimm = encode_thumb32_immediate (value);
28907 if (newimm == (unsigned int) FAIL)
28908 newimm = thumb32_negate_data_op (&newval, value);
28909 }
bada4342 28910 if (newimm == (unsigned int) FAIL)
92e90b6e 28911 {
bada4342 28912 if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
e9f89963 28913 {
bada4342
JW
28914 /* Turn add/sum into addw/subw. */
28915 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
28916 newval = (newval & 0xfeffffff) | 0x02000000;
28917 /* No flat 12-bit imm encoding for addsw/subsw. */
28918 if ((newval & 0x00100000) == 0)
40f246e3 28919 {
bada4342 28920 /* 12 bit immediate for addw/subw. */
7af67752 28921 if ((offsetT) value < 0)
bada4342
JW
28922 {
28923 value = -value;
28924 newval ^= 0x00a00000;
28925 }
28926 if (value > 0xfff)
28927 newimm = (unsigned int) FAIL;
28928 else
28929 newimm = value;
28930 }
28931 }
28932 else
28933 {
28934 /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
28935 UINT16 (T3 encoding), MOVW only accepts UINT16. When
28936 disassembling, MOV is preferred when there is no encoding
db7bf105 28937 overlap. */
bada4342 28938 if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
db7bf105
NC
28939 /* NOTE: MOV uses the ORR opcode in Thumb 2 mode
28940 but with the Rn field [19:16] set to 1111. */
28941 && (((newval >> 16) & 0xf) == 0xf)
bada4342
JW
28942 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
28943 && !((newval >> T2_SBIT_SHIFT) & 0x1)
7af67752 28944 && value <= 0xffff)
bada4342
JW
28945 {
28946 /* Toggle bit[25] to change encoding from T2 to T3. */
28947 newval ^= 1 << 25;
28948 /* Clear bits[19:16]. */
28949 newval &= 0xfff0ffff;
28950 /* Encoding high 4bits imm. Code below will encode the
28951 remaining low 12bits. */
28952 newval |= (value & 0x0000f000) << 4;
28953 newimm = value & 0x00000fff;
40f246e3 28954 }
e9f89963 28955 }
92e90b6e 28956 }
cc8a6dd0 28957
c19d1205 28958 if (newimm == (unsigned int)FAIL)
3631a3c8 28959 {
c19d1205
ZW
28960 as_bad_where (fixP->fx_file, fixP->fx_line,
28961 _("invalid constant (%lx) after fixup"),
28962 (unsigned long) value);
28963 break;
3631a3c8
NC
28964 }
28965
c19d1205
ZW
28966 newval |= (newimm & 0x800) << 15;
28967 newval |= (newimm & 0x700) << 4;
28968 newval |= (newimm & 0x0ff);
cc8a6dd0 28969
c19d1205
ZW
28970 md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
28971 md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
28972 break;
a737bd4d 28973
3eb17e6b 28974 case BFD_RELOC_ARM_SMC:
7af67752 28975 if (value > 0xf)
c19d1205 28976 as_bad_where (fixP->fx_file, fixP->fx_line,
3eb17e6b 28977 _("invalid smc expression"));
ba85f98c 28978
2fc8bdac 28979 newval = md_chars_to_number (buf, INSN_SIZE);
ba85f98c 28980 newval |= (value & 0xf);
c19d1205
ZW
28981 md_number_to_chars (buf, newval, INSN_SIZE);
28982 break;
a737bd4d 28983
90ec0d68 28984 case BFD_RELOC_ARM_HVC:
7af67752 28985 if (value > 0xffff)
90ec0d68
MGD
28986 as_bad_where (fixP->fx_file, fixP->fx_line,
28987 _("invalid hvc expression"));
28988 newval = md_chars_to_number (buf, INSN_SIZE);
28989 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
28990 md_number_to_chars (buf, newval, INSN_SIZE);
28991 break;
28992
c19d1205 28993 case BFD_RELOC_ARM_SWI:
adbaf948 28994 if (fixP->tc_fix_data != 0)
c19d1205 28995 {
7af67752 28996 if (value > 0xff)
c19d1205
ZW
28997 as_bad_where (fixP->fx_file, fixP->fx_line,
28998 _("invalid swi expression"));
2fc8bdac 28999 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205
ZW
29000 newval |= value;
29001 md_number_to_chars (buf, newval, THUMB_SIZE);
29002 }
29003 else
29004 {
7af67752 29005 if (value > 0x00ffffff)
c19d1205
ZW
29006 as_bad_where (fixP->fx_file, fixP->fx_line,
29007 _("invalid swi expression"));
2fc8bdac 29008 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
29009 newval |= value;
29010 md_number_to_chars (buf, newval, INSN_SIZE);
29011 }
29012 break;
a737bd4d 29013
c19d1205 29014 case BFD_RELOC_ARM_MULTI:
7af67752 29015 if (value > 0xffff)
c19d1205
ZW
29016 as_bad_where (fixP->fx_file, fixP->fx_line,
29017 _("invalid expression in load/store multiple"));
29018 newval = value | md_chars_to_number (buf, INSN_SIZE);
29019 md_number_to_chars (buf, newval, INSN_SIZE);
29020 break;
a737bd4d 29021
c19d1205 29022#ifdef OBJ_ELF
39b41c9c 29023 case BFD_RELOC_ARM_PCREL_CALL:
267bf995
RR
29024
29025 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
29026 && fixP->fx_addsy
5b7c81bd 29027 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29028 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29029 && THUMB_IS_FUNC (fixP->fx_addsy))
29030 /* Flip the bl to blx. This is a simple flip
29031 bit here because we generate PCREL_CALL for
29032 unconditional bls. */
29033 {
29034 newval = md_chars_to_number (buf, INSN_SIZE);
29035 newval = newval | 0x10000000;
29036 md_number_to_chars (buf, newval, INSN_SIZE);
29037 temp = 1;
29038 fixP->fx_done = 1;
29039 }
39b41c9c
PB
29040 else
29041 temp = 3;
29042 goto arm_branch_common;
29043
29044 case BFD_RELOC_ARM_PCREL_JUMP:
267bf995
RR
29045 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
29046 && fixP->fx_addsy
5b7c81bd 29047 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29048 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29049 && THUMB_IS_FUNC (fixP->fx_addsy))
29050 {
29051 /* This would map to a bl<cond>, b<cond>,
29052 b<always> to a Thumb function. We
29053 need to force a relocation for this particular
29054 case. */
29055 newval = md_chars_to_number (buf, INSN_SIZE);
29056 fixP->fx_done = 0;
29057 }
1a0670f3 29058 /* Fall through. */
267bf995 29059
2fc8bdac 29060 case BFD_RELOC_ARM_PLT32:
c19d1205 29061#endif
39b41c9c
PB
29062 case BFD_RELOC_ARM_PCREL_BRANCH:
29063 temp = 3;
29064 goto arm_branch_common;
a737bd4d 29065
39b41c9c 29066 case BFD_RELOC_ARM_PCREL_BLX:
267bf995 29067
39b41c9c 29068 temp = 1;
267bf995
RR
29069 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
29070 && fixP->fx_addsy
5b7c81bd 29071 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29072 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29073 && ARM_IS_FUNC (fixP->fx_addsy))
29074 {
29075 /* Flip the blx to a bl and warn. */
29076 const char *name = S_GET_NAME (fixP->fx_addsy);
29077 newval = 0xeb000000;
29078 as_warn_where (fixP->fx_file, fixP->fx_line,
29079 _("blx to '%s' an ARM ISA state function changed to bl"),
29080 name);
29081 md_number_to_chars (buf, newval, INSN_SIZE);
29082 temp = 3;
29083 fixP->fx_done = 1;
29084 }
29085
29086#ifdef OBJ_ELF
29087 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
477330fc 29088 fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
267bf995
RR
29089#endif
29090
39b41c9c 29091 arm_branch_common:
c19d1205 29092 /* We are going to store value (shifted right by two) in the
39b41c9c
PB
29093 instruction, in a 24 bit, signed field. Bits 26 through 32 either
29094 all clear or all set and bit 0 must be clear. For B/BL bit 1 must
de194d85 29095 also be clear. */
39b41c9c 29096 if (value & temp)
c19d1205 29097 as_bad_where (fixP->fx_file, fixP->fx_line,
2fc8bdac 29098 _("misaligned branch destination"));
7af67752
AM
29099 if ((value & 0xfe000000) != 0
29100 && (value & 0xfe000000) != 0xfe000000)
08f10d51 29101 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 29102
2fc8bdac 29103 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 29104 {
2fc8bdac
ZW
29105 newval = md_chars_to_number (buf, INSN_SIZE);
29106 newval |= (value >> 2) & 0x00ffffff;
7ae2971b
PB
29107 /* Set the H bit on BLX instructions. */
29108 if (temp == 1)
29109 {
29110 if (value & 2)
29111 newval |= 0x01000000;
29112 else
29113 newval &= ~0x01000000;
29114 }
2fc8bdac 29115 md_number_to_chars (buf, newval, INSN_SIZE);
c19d1205 29116 }
c19d1205 29117 break;
a737bd4d 29118
25fe350b
MS
29119 case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CBZ */
29120 /* CBZ can only branch forward. */
a737bd4d 29121
738755b0 29122 /* Attempts to use CBZ to branch to the next instruction
477330fc
RM
29123 (which, strictly speaking, are prohibited) will be turned into
29124 no-ops.
738755b0
MS
29125
29126 FIXME: It may be better to remove the instruction completely and
29127 perform relaxation. */
7af67752 29128 if ((offsetT) value == -2)
2fc8bdac
ZW
29129 {
29130 newval = md_chars_to_number (buf, THUMB_SIZE);
738755b0 29131 newval = 0xbf00; /* NOP encoding T1 */
2fc8bdac
ZW
29132 md_number_to_chars (buf, newval, THUMB_SIZE);
29133 }
738755b0
MS
29134 else
29135 {
29136 if (value & ~0x7e)
08f10d51 29137 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
738755b0 29138
477330fc 29139 if (fixP->fx_done || !seg->use_rela_p)
738755b0
MS
29140 {
29141 newval = md_chars_to_number (buf, THUMB_SIZE);
29142 newval |= ((value & 0x3e) << 2) | ((value & 0x40) << 3);
29143 md_number_to_chars (buf, newval, THUMB_SIZE);
29144 }
29145 }
c19d1205 29146 break;
a737bd4d 29147
c19d1205 29148 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
e8f8842d 29149 if (out_of_range_p (value, 8))
08f10d51 29150 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 29151
2fc8bdac
ZW
29152 if (fixP->fx_done || !seg->use_rela_p)
29153 {
29154 newval = md_chars_to_number (buf, THUMB_SIZE);
29155 newval |= (value & 0x1ff) >> 1;
29156 md_number_to_chars (buf, newval, THUMB_SIZE);
29157 }
c19d1205 29158 break;
a737bd4d 29159
c19d1205 29160 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
e8f8842d 29161 if (out_of_range_p (value, 11))
08f10d51 29162 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 29163
2fc8bdac
ZW
29164 if (fixP->fx_done || !seg->use_rela_p)
29165 {
29166 newval = md_chars_to_number (buf, THUMB_SIZE);
29167 newval |= (value & 0xfff) >> 1;
29168 md_number_to_chars (buf, newval, THUMB_SIZE);
29169 }
c19d1205 29170 break;
a737bd4d 29171
e8f8842d 29172 /* This relocation is misnamed, it should be BRANCH21. */
c19d1205 29173 case BFD_RELOC_THUMB_PCREL_BRANCH20:
267bf995
RR
29174 if (fixP->fx_addsy
29175 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29176 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29177 && ARM_IS_FUNC (fixP->fx_addsy)
29178 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
29179 {
29180 /* Force a relocation for a branch 20 bits wide. */
29181 fixP->fx_done = 0;
29182 }
e8f8842d 29183 if (out_of_range_p (value, 20))
2fc8bdac
ZW
29184 as_bad_where (fixP->fx_file, fixP->fx_line,
29185 _("conditional branch out of range"));
404ff6b5 29186
2fc8bdac
ZW
29187 if (fixP->fx_done || !seg->use_rela_p)
29188 {
29189 offsetT newval2;
29190 addressT S, J1, J2, lo, hi;
404ff6b5 29191
2fc8bdac
ZW
29192 S = (value & 0x00100000) >> 20;
29193 J2 = (value & 0x00080000) >> 19;
29194 J1 = (value & 0x00040000) >> 18;
29195 hi = (value & 0x0003f000) >> 12;
29196 lo = (value & 0x00000ffe) >> 1;
6c43fab6 29197
2fc8bdac
ZW
29198 newval = md_chars_to_number (buf, THUMB_SIZE);
29199 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29200 newval |= (S << 10) | hi;
29201 newval2 |= (J1 << 13) | (J2 << 11) | lo;
29202 md_number_to_chars (buf, newval, THUMB_SIZE);
29203 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
29204 }
c19d1205 29205 break;
6c43fab6 29206
c19d1205 29207 case BFD_RELOC_THUMB_PCREL_BLX:
267bf995
RR
29208 /* If there is a blx from a thumb state function to
29209 another thumb function flip this to a bl and warn
29210 about it. */
29211
29212 if (fixP->fx_addsy
5b7c81bd 29213 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29214 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29215 && THUMB_IS_FUNC (fixP->fx_addsy))
29216 {
29217 const char *name = S_GET_NAME (fixP->fx_addsy);
29218 as_warn_where (fixP->fx_file, fixP->fx_line,
29219 _("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
29220 name);
29221 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29222 newval = newval | 0x1000;
29223 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
29224 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
29225 fixP->fx_done = 1;
29226 }
29227
29228
29229 goto thumb_bl_common;
29230
c19d1205 29231 case BFD_RELOC_THUMB_PCREL_BRANCH23:
267bf995
RR
29232 /* A bl from Thumb state ISA to an internal ARM state function
29233 is converted to a blx. */
29234 if (fixP->fx_addsy
29235 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29236 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29237 && ARM_IS_FUNC (fixP->fx_addsy)
29238 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
29239 {
29240 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29241 newval = newval & ~0x1000;
29242 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
29243 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
29244 fixP->fx_done = 1;
29245 }
29246
29247 thumb_bl_common:
29248
2fc8bdac
ZW
29249 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
29250 /* For a BLX instruction, make sure that the relocation is rounded up
29251 to a word boundary. This follows the semantics of the instruction
29252 which specifies that bit 1 of the target address will come from bit
29253 1 of the base address. */
d406f3e4
JB
29254 value = (value + 3) & ~ 3;
29255
29256#ifdef OBJ_ELF
29257 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
29258 && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
29259 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
29260#endif
404ff6b5 29261
e8f8842d 29262 if (out_of_range_p (value, 22))
2b2f5df9 29263 {
fc289b0a 29264 if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)))
2b2f5df9 29265 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
e8f8842d 29266 else if (out_of_range_p (value, 24))
2b2f5df9
NC
29267 as_bad_where (fixP->fx_file, fixP->fx_line,
29268 _("Thumb2 branch out of range"));
29269 }
4a42ebbc
RR
29270
29271 if (fixP->fx_done || !seg->use_rela_p)
29272 encode_thumb2_b_bl_offset (buf, value);
29273
c19d1205 29274 break;
404ff6b5 29275
c19d1205 29276 case BFD_RELOC_THUMB_PCREL_BRANCH25:
e8f8842d 29277 if (out_of_range_p (value, 24))
08f10d51 29278 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
6c43fab6 29279
2fc8bdac 29280 if (fixP->fx_done || !seg->use_rela_p)
4a42ebbc 29281 encode_thumb2_b_bl_offset (buf, value);
6c43fab6 29282
2fc8bdac 29283 break;
a737bd4d 29284
2fc8bdac
ZW
29285 case BFD_RELOC_8:
29286 if (fixP->fx_done || !seg->use_rela_p)
4b1a927e 29287 *buf = value;
c19d1205 29288 break;
a737bd4d 29289
c19d1205 29290 case BFD_RELOC_16:
2fc8bdac 29291 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 29292 md_number_to_chars (buf, value, 2);
c19d1205 29293 break;
a737bd4d 29294
c19d1205 29295#ifdef OBJ_ELF
0855e32b
NS
29296 case BFD_RELOC_ARM_TLS_CALL:
29297 case BFD_RELOC_ARM_THM_TLS_CALL:
29298 case BFD_RELOC_ARM_TLS_DESCSEQ:
29299 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
0855e32b 29300 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205
ZW
29301 case BFD_RELOC_ARM_TLS_GD32:
29302 case BFD_RELOC_ARM_TLS_LE32:
29303 case BFD_RELOC_ARM_TLS_IE32:
29304 case BFD_RELOC_ARM_TLS_LDM32:
29305 case BFD_RELOC_ARM_TLS_LDO32:
29306 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4b1a927e 29307 break;
6c43fab6 29308
5c5a4843
CL
29309 /* Same handling as above, but with the arm_fdpic guard. */
29310 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
29311 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
29312 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
29313 if (arm_fdpic)
29314 {
29315 S_SET_THREAD_LOCAL (fixP->fx_addsy);
29316 }
29317 else
29318 {
29319 as_bad_where (fixP->fx_file, fixP->fx_line,
29320 _("Relocation supported only in FDPIC mode"));
29321 }
29322 break;
29323
c19d1205
ZW
29324 case BFD_RELOC_ARM_GOT32:
29325 case BFD_RELOC_ARM_GOTOFF:
c19d1205 29326 break;
b43420e6
NC
29327
29328 case BFD_RELOC_ARM_GOT_PREL:
29329 if (fixP->fx_done || !seg->use_rela_p)
477330fc 29330 md_number_to_chars (buf, value, 4);
b43420e6
NC
29331 break;
29332
9a6f4e97
NS
29333 case BFD_RELOC_ARM_TARGET2:
29334 /* TARGET2 is not partial-inplace, so we need to write the
477330fc
RM
29335 addend here for REL targets, because it won't be written out
29336 during reloc processing later. */
9a6f4e97
NS
29337 if (fixP->fx_done || !seg->use_rela_p)
29338 md_number_to_chars (buf, fixP->fx_offset, 4);
29339 break;
188fd7ae
CL
29340
29341 /* Relocations for FDPIC. */
29342 case BFD_RELOC_ARM_GOTFUNCDESC:
29343 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
29344 case BFD_RELOC_ARM_FUNCDESC:
29345 if (arm_fdpic)
29346 {
29347 if (fixP->fx_done || !seg->use_rela_p)
29348 md_number_to_chars (buf, 0, 4);
29349 }
29350 else
29351 {
29352 as_bad_where (fixP->fx_file, fixP->fx_line,
29353 _("Relocation supported only in FDPIC mode"));
29354 }
29355 break;
c19d1205 29356#endif
6c43fab6 29357
c19d1205
ZW
29358 case BFD_RELOC_RVA:
29359 case BFD_RELOC_32:
29360 case BFD_RELOC_ARM_TARGET1:
29361 case BFD_RELOC_ARM_ROSEGREL32:
29362 case BFD_RELOC_ARM_SBREL32:
29363 case BFD_RELOC_32_PCREL:
f0927246
NC
29364#ifdef TE_PE
29365 case BFD_RELOC_32_SECREL:
29366#endif
2fc8bdac 29367 if (fixP->fx_done || !seg->use_rela_p)
53baae48
NC
29368#ifdef TE_WINCE
29369 /* For WinCE we only do this for pcrel fixups. */
29370 if (fixP->fx_done || fixP->fx_pcrel)
29371#endif
29372 md_number_to_chars (buf, value, 4);
c19d1205 29373 break;
6c43fab6 29374
c19d1205
ZW
29375#ifdef OBJ_ELF
29376 case BFD_RELOC_ARM_PREL31:
2fc8bdac 29377 if (fixP->fx_done || !seg->use_rela_p)
c19d1205
ZW
29378 {
29379 newval = md_chars_to_number (buf, 4) & 0x80000000;
29380 if ((value ^ (value >> 1)) & 0x40000000)
29381 {
29382 as_bad_where (fixP->fx_file, fixP->fx_line,
29383 _("rel31 relocation overflow"));
29384 }
29385 newval |= value & 0x7fffffff;
29386 md_number_to_chars (buf, newval, 4);
29387 }
29388 break;
c19d1205 29389#endif
a737bd4d 29390
c19d1205 29391 case BFD_RELOC_ARM_CP_OFF_IMM:
8f06b2d8 29392 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
32c36c3c 29393 case BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM:
9db2f6b4
RL
29394 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
29395 newval = md_chars_to_number (buf, INSN_SIZE);
29396 else
29397 newval = get_thumb32_insn (buf);
29398 if ((newval & 0x0f200f00) == 0x0d000900)
29399 {
29400 /* This is a fp16 vstr/vldr. The immediate offset in the mnemonic
7af67752 29401 has permitted values that are multiples of 2, in the range -510
9db2f6b4 29402 to 510. */
7af67752 29403 if (value + 510 > 510 + 510 || (value & 1))
9db2f6b4
RL
29404 as_bad_where (fixP->fx_file, fixP->fx_line,
29405 _("co-processor offset out of range"));
29406 }
32c36c3c
AV
29407 else if ((newval & 0xfe001f80) == 0xec000f80)
29408 {
7af67752 29409 if (value + 511 > 512 + 511 || (value & 3))
32c36c3c
AV
29410 as_bad_where (fixP->fx_file, fixP->fx_line,
29411 _("co-processor offset out of range"));
29412 }
7af67752 29413 else if (value + 1023 > 1023 + 1023 || (value & 3))
c19d1205
ZW
29414 as_bad_where (fixP->fx_file, fixP->fx_line,
29415 _("co-processor offset out of range"));
29416 cp_off_common:
7af67752
AM
29417 sign = (offsetT) value > 0;
29418 if ((offsetT) value < 0)
c19d1205 29419 value = -value;
8f06b2d8
PB
29420 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
29421 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
29422 newval = md_chars_to_number (buf, INSN_SIZE);
29423 else
29424 newval = get_thumb32_insn (buf);
26d97720 29425 if (value == 0)
32c36c3c
AV
29426 {
29427 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
29428 newval &= 0xffffff80;
29429 else
29430 newval &= 0xffffff00;
29431 }
26d97720
NS
29432 else
29433 {
32c36c3c
AV
29434 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
29435 newval &= 0xff7fff80;
29436 else
29437 newval &= 0xff7fff00;
9db2f6b4
RL
29438 if ((newval & 0x0f200f00) == 0x0d000900)
29439 {
29440 /* This is a fp16 vstr/vldr.
29441
29442 It requires the immediate offset in the instruction is shifted
29443 left by 1 to be a half-word offset.
29444
29445 Here, left shift by 1 first, and later right shift by 2
29446 should get the right offset. */
29447 value <<= 1;
29448 }
26d97720
NS
29449 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
29450 }
8f06b2d8
PB
29451 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
29452 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
29453 md_number_to_chars (buf, newval, INSN_SIZE);
29454 else
29455 put_thumb32_insn (buf, newval);
c19d1205 29456 break;
a737bd4d 29457
c19d1205 29458 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
8f06b2d8 29459 case BFD_RELOC_ARM_T32_CP_OFF_IMM_S2:
7af67752 29460 if (value + 255 > 255 + 255)
c19d1205
ZW
29461 as_bad_where (fixP->fx_file, fixP->fx_line,
29462 _("co-processor offset out of range"));
df7849c5 29463 value *= 4;
c19d1205 29464 goto cp_off_common;
6c43fab6 29465
c19d1205
ZW
29466 case BFD_RELOC_ARM_THUMB_OFFSET:
29467 newval = md_chars_to_number (buf, THUMB_SIZE);
29468 /* Exactly what ranges, and where the offset is inserted depends
29469 on the type of instruction, we can establish this from the
29470 top 4 bits. */
29471 switch (newval >> 12)
29472 {
29473 case 4: /* PC load. */
29474 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
29475 forced to zero for these loads; md_pcrel_from has already
29476 compensated for this. */
29477 if (value & 3)
29478 as_bad_where (fixP->fx_file, fixP->fx_line,
29479 _("invalid offset, target not word aligned (0x%08lX)"),
0359e808
NC
29480 (((unsigned long) fixP->fx_frag->fr_address
29481 + (unsigned long) fixP->fx_where) & ~3)
29482 + (unsigned long) value);
749479c8
AO
29483 else if (get_recorded_alignment (seg) < 2)
29484 as_warn_where (fixP->fx_file, fixP->fx_line,
29485 _("section does not have enough alignment to ensure safe PC-relative loads"));
a737bd4d 29486
c19d1205
ZW
29487 if (value & ~0x3fc)
29488 as_bad_where (fixP->fx_file, fixP->fx_line,
29489 _("invalid offset, value too big (0x%08lX)"),
29490 (long) value);
a737bd4d 29491
c19d1205
ZW
29492 newval |= value >> 2;
29493 break;
a737bd4d 29494
c19d1205
ZW
29495 case 9: /* SP load/store. */
29496 if (value & ~0x3fc)
29497 as_bad_where (fixP->fx_file, fixP->fx_line,
29498 _("invalid offset, value too big (0x%08lX)"),
29499 (long) value);
29500 newval |= value >> 2;
29501 break;
6c43fab6 29502
c19d1205
ZW
29503 case 6: /* Word load/store. */
29504 if (value & ~0x7c)
29505 as_bad_where (fixP->fx_file, fixP->fx_line,
29506 _("invalid offset, value too big (0x%08lX)"),
29507 (long) value);
29508 newval |= value << 4; /* 6 - 2. */
29509 break;
a737bd4d 29510
c19d1205
ZW
29511 case 7: /* Byte load/store. */
29512 if (value & ~0x1f)
29513 as_bad_where (fixP->fx_file, fixP->fx_line,
29514 _("invalid offset, value too big (0x%08lX)"),
29515 (long) value);
29516 newval |= value << 6;
29517 break;
a737bd4d 29518
c19d1205
ZW
29519 case 8: /* Halfword load/store. */
29520 if (value & ~0x3e)
29521 as_bad_where (fixP->fx_file, fixP->fx_line,
29522 _("invalid offset, value too big (0x%08lX)"),
29523 (long) value);
29524 newval |= value << 5; /* 6 - 1. */
29525 break;
a737bd4d 29526
c19d1205
ZW
29527 default:
29528 as_bad_where (fixP->fx_file, fixP->fx_line,
29529 "Unable to process relocation for thumb opcode: %lx",
29530 (unsigned long) newval);
29531 break;
29532 }
29533 md_number_to_chars (buf, newval, THUMB_SIZE);
29534 break;
a737bd4d 29535
c19d1205
ZW
29536 case BFD_RELOC_ARM_THUMB_ADD:
29537 /* This is a complicated relocation, since we use it for all of
29538 the following immediate relocations:
a737bd4d 29539
c19d1205
ZW
29540 3bit ADD/SUB
29541 8bit ADD/SUB
29542 9bit ADD/SUB SP word-aligned
29543 10bit ADD PC/SP word-aligned
a737bd4d 29544
c19d1205
ZW
29545 The type of instruction being processed is encoded in the
29546 instruction field:
a737bd4d 29547
c19d1205
ZW
29548 0x8000 SUB
29549 0x00F0 Rd
29550 0x000F Rs
29551 */
29552 newval = md_chars_to_number (buf, THUMB_SIZE);
29553 {
29554 int rd = (newval >> 4) & 0xf;
29555 int rs = newval & 0xf;
29556 int subtract = !!(newval & 0x8000);
a737bd4d 29557
c19d1205
ZW
29558 /* Check for HI regs, only very restricted cases allowed:
29559 Adjusting SP, and using PC or SP to get an address. */
29560 if ((rd > 7 && (rd != REG_SP || rs != REG_SP))
29561 || (rs > 7 && rs != REG_SP && rs != REG_PC))
29562 as_bad_where (fixP->fx_file, fixP->fx_line,
29563 _("invalid Hi register with immediate"));
a737bd4d 29564
c19d1205 29565 /* If value is negative, choose the opposite instruction. */
7af67752 29566 if ((offsetT) value < 0)
c19d1205
ZW
29567 {
29568 value = -value;
29569 subtract = !subtract;
7af67752 29570 if ((offsetT) value < 0)
c19d1205
ZW
29571 as_bad_where (fixP->fx_file, fixP->fx_line,
29572 _("immediate value out of range"));
29573 }
a737bd4d 29574
c19d1205
ZW
29575 if (rd == REG_SP)
29576 {
75c11999 29577 if (value & ~0x1fc)
c19d1205
ZW
29578 as_bad_where (fixP->fx_file, fixP->fx_line,
29579 _("invalid immediate for stack address calculation"));
29580 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
29581 newval |= value >> 2;
29582 }
29583 else if (rs == REG_PC || rs == REG_SP)
29584 {
c12d2c9d
NC
29585 /* PR gas/18541. If the addition is for a defined symbol
29586 within range of an ADR instruction then accept it. */
29587 if (subtract
29588 && value == 4
29589 && fixP->fx_addsy != NULL)
29590 {
29591 subtract = 0;
29592
29593 if (! S_IS_DEFINED (fixP->fx_addsy)
29594 || S_GET_SEGMENT (fixP->fx_addsy) != seg
29595 || S_IS_WEAK (fixP->fx_addsy))
29596 {
29597 as_bad_where (fixP->fx_file, fixP->fx_line,
29598 _("address calculation needs a strongly defined nearby symbol"));
29599 }
29600 else
29601 {
29602 offsetT v = fixP->fx_where + fixP->fx_frag->fr_address;
29603
29604 /* Round up to the next 4-byte boundary. */
29605 if (v & 3)
29606 v = (v + 3) & ~ 3;
29607 else
29608 v += 4;
29609 v = S_GET_VALUE (fixP->fx_addsy) - v;
29610
29611 if (v & ~0x3fc)
29612 {
29613 as_bad_where (fixP->fx_file, fixP->fx_line,
29614 _("symbol too far away"));
29615 }
29616 else
29617 {
29618 fixP->fx_done = 1;
29619 value = v;
29620 }
29621 }
29622 }
29623
c19d1205
ZW
29624 if (subtract || value & ~0x3fc)
29625 as_bad_where (fixP->fx_file, fixP->fx_line,
29626 _("invalid immediate for address calculation (value = 0x%08lX)"),
5fc177c8 29627 (unsigned long) (subtract ? - value : value));
c19d1205
ZW
29628 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
29629 newval |= rd << 8;
29630 newval |= value >> 2;
29631 }
29632 else if (rs == rd)
29633 {
29634 if (value & ~0xff)
29635 as_bad_where (fixP->fx_file, fixP->fx_line,
29636 _("immediate value out of range"));
29637 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
29638 newval |= (rd << 8) | value;
29639 }
29640 else
29641 {
29642 if (value & ~0x7)
29643 as_bad_where (fixP->fx_file, fixP->fx_line,
29644 _("immediate value out of range"));
29645 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
29646 newval |= rd | (rs << 3) | (value << 6);
29647 }
29648 }
29649 md_number_to_chars (buf, newval, THUMB_SIZE);
29650 break;
a737bd4d 29651
c19d1205
ZW
29652 case BFD_RELOC_ARM_THUMB_IMM:
29653 newval = md_chars_to_number (buf, THUMB_SIZE);
7af67752 29654 if (value > 255)
c19d1205 29655 as_bad_where (fixP->fx_file, fixP->fx_line,
4e6e072b 29656 _("invalid immediate: %ld is out of range"),
c19d1205
ZW
29657 (long) value);
29658 newval |= value;
29659 md_number_to_chars (buf, newval, THUMB_SIZE);
29660 break;
a737bd4d 29661
c19d1205
ZW
29662 case BFD_RELOC_ARM_THUMB_SHIFT:
29663 /* 5bit shift value (0..32). LSL cannot take 32. */
29664 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf83f;
29665 temp = newval & 0xf800;
7af67752 29666 if (value > 32 || (value == 32 && temp == T_OPCODE_LSL_I))
c19d1205
ZW
29667 as_bad_where (fixP->fx_file, fixP->fx_line,
29668 _("invalid shift value: %ld"), (long) value);
29669 /* Shifts of zero must be encoded as LSL. */
29670 if (value == 0)
29671 newval = (newval & 0x003f) | T_OPCODE_LSL_I;
29672 /* Shifts of 32 are encoded as zero. */
29673 else if (value == 32)
29674 value = 0;
29675 newval |= value << 6;
29676 md_number_to_chars (buf, newval, THUMB_SIZE);
29677 break;
a737bd4d 29678
c19d1205
ZW
29679 case BFD_RELOC_VTABLE_INHERIT:
29680 case BFD_RELOC_VTABLE_ENTRY:
29681 fixP->fx_done = 0;
29682 return;
6c43fab6 29683
b6895b4f
PB
29684 case BFD_RELOC_ARM_MOVW:
29685 case BFD_RELOC_ARM_MOVT:
29686 case BFD_RELOC_ARM_THUMB_MOVW:
29687 case BFD_RELOC_ARM_THUMB_MOVT:
29688 if (fixP->fx_done || !seg->use_rela_p)
29689 {
29690 /* REL format relocations are limited to a 16-bit addend. */
29691 if (!fixP->fx_done)
29692 {
7af67752 29693 if (value + 0x8000 > 0x7fff + 0x8000)
b6895b4f 29694 as_bad_where (fixP->fx_file, fixP->fx_line,
ff5075ca 29695 _("offset out of range"));
b6895b4f
PB
29696 }
29697 else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT
29698 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
29699 {
29700 value >>= 16;
29701 }
29702
29703 if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
29704 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
29705 {
29706 newval = get_thumb32_insn (buf);
29707 newval &= 0xfbf08f00;
29708 newval |= (value & 0xf000) << 4;
29709 newval |= (value & 0x0800) << 15;
29710 newval |= (value & 0x0700) << 4;
29711 newval |= (value & 0x00ff);
29712 put_thumb32_insn (buf, newval);
29713 }
29714 else
29715 {
29716 newval = md_chars_to_number (buf, 4);
29717 newval &= 0xfff0f000;
29718 newval |= value & 0x0fff;
29719 newval |= (value & 0xf000) << 4;
29720 md_number_to_chars (buf, newval, 4);
29721 }
29722 }
29723 return;
29724
72d98d16
MG
29725 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
29726 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
29727 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
29728 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
29729 gas_assert (!fixP->fx_done);
29730 {
29731 bfd_vma insn;
5b7c81bd 29732 bool is_mov;
72d98d16
MG
29733 bfd_vma encoded_addend = value;
29734
29735 /* Check that addend can be encoded in instruction. */
7af67752 29736 if (!seg->use_rela_p && value > 255)
72d98d16
MG
29737 as_bad_where (fixP->fx_file, fixP->fx_line,
29738 _("the offset 0x%08lX is not representable"),
29739 (unsigned long) encoded_addend);
29740
29741 /* Extract the instruction. */
29742 insn = md_chars_to_number (buf, THUMB_SIZE);
29743 is_mov = (insn & 0xf800) == 0x2000;
29744
29745 /* Encode insn. */
29746 if (is_mov)
29747 {
29748 if (!seg->use_rela_p)
29749 insn |= encoded_addend;
29750 }
29751 else
29752 {
29753 int rd, rs;
29754
29755 /* Extract the instruction. */
29756 /* Encoding is the following
29757 0x8000 SUB
29758 0x00F0 Rd
29759 0x000F Rs
29760 */
29761 /* The following conditions must be true :
29762 - ADD
29763 - Rd == Rs
29764 - Rd <= 7
29765 */
29766 rd = (insn >> 4) & 0xf;
29767 rs = insn & 0xf;
29768 if ((insn & 0x8000) || (rd != rs) || rd > 7)
29769 as_bad_where (fixP->fx_file, fixP->fx_line,
29770 _("Unable to process relocation for thumb opcode: %lx"),
29771 (unsigned long) insn);
29772
29773 /* Encode as ADD immediate8 thumb 1 code. */
29774 insn = 0x3000 | (rd << 8);
29775
29776 /* Place the encoded addend into the first 8 bits of the
29777 instruction. */
29778 if (!seg->use_rela_p)
29779 insn |= encoded_addend;
29780 }
29781
29782 /* Update the instruction. */
29783 md_number_to_chars (buf, insn, THUMB_SIZE);
29784 }
29785 break;
29786
4962c51a
MS
29787 case BFD_RELOC_ARM_ALU_PC_G0_NC:
29788 case BFD_RELOC_ARM_ALU_PC_G0:
29789 case BFD_RELOC_ARM_ALU_PC_G1_NC:
29790 case BFD_RELOC_ARM_ALU_PC_G1:
29791 case BFD_RELOC_ARM_ALU_PC_G2:
29792 case BFD_RELOC_ARM_ALU_SB_G0_NC:
29793 case BFD_RELOC_ARM_ALU_SB_G0:
29794 case BFD_RELOC_ARM_ALU_SB_G1_NC:
29795 case BFD_RELOC_ARM_ALU_SB_G1:
29796 case BFD_RELOC_ARM_ALU_SB_G2:
9c2799c2 29797 gas_assert (!fixP->fx_done);
4962c51a
MS
29798 if (!seg->use_rela_p)
29799 {
477330fc
RM
29800 bfd_vma insn;
29801 bfd_vma encoded_addend;
7af67752 29802 bfd_vma addend_abs = llabs ((offsetT) value);
477330fc
RM
29803
29804 /* Check that the absolute value of the addend can be
29805 expressed as an 8-bit constant plus a rotation. */
29806 encoded_addend = encode_arm_immediate (addend_abs);
29807 if (encoded_addend == (unsigned int) FAIL)
4962c51a 29808 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29809 _("the offset 0x%08lX is not representable"),
29810 (unsigned long) addend_abs);
29811
29812 /* Extract the instruction. */
29813 insn = md_chars_to_number (buf, INSN_SIZE);
29814
29815 /* If the addend is positive, use an ADD instruction.
29816 Otherwise use a SUB. Take care not to destroy the S bit. */
29817 insn &= 0xff1fffff;
7af67752 29818 if ((offsetT) value < 0)
477330fc
RM
29819 insn |= 1 << 22;
29820 else
29821 insn |= 1 << 23;
29822
29823 /* Place the encoded addend into the first 12 bits of the
29824 instruction. */
29825 insn &= 0xfffff000;
29826 insn |= encoded_addend;
29827
29828 /* Update the instruction. */
29829 md_number_to_chars (buf, insn, INSN_SIZE);
4962c51a
MS
29830 }
29831 break;
29832
29833 case BFD_RELOC_ARM_LDR_PC_G0:
29834 case BFD_RELOC_ARM_LDR_PC_G1:
29835 case BFD_RELOC_ARM_LDR_PC_G2:
29836 case BFD_RELOC_ARM_LDR_SB_G0:
29837 case BFD_RELOC_ARM_LDR_SB_G1:
29838 case BFD_RELOC_ARM_LDR_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 12 bits. */
29847 if (addend_abs >= 0x1000)
4962c51a 29848 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29849 _("bad offset 0x%08lX (only 12 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 absolute value of the addend into the first 12 bits
29863 of the instruction. */
29864 insn &= 0xfffff000;
29865 insn |= addend_abs;
29866
29867 /* Update the instruction. */
29868 md_number_to_chars (buf, insn, INSN_SIZE);
29869 }
4962c51a
MS
29870 break;
29871
29872 case BFD_RELOC_ARM_LDRS_PC_G0:
29873 case BFD_RELOC_ARM_LDRS_PC_G1:
29874 case BFD_RELOC_ARM_LDRS_PC_G2:
29875 case BFD_RELOC_ARM_LDRS_SB_G0:
29876 case BFD_RELOC_ARM_LDRS_SB_G1:
29877 case BFD_RELOC_ARM_LDRS_SB_G2:
9c2799c2 29878 gas_assert (!fixP->fx_done);
4962c51a 29879 if (!seg->use_rela_p)
477330fc
RM
29880 {
29881 bfd_vma insn;
7af67752 29882 bfd_vma addend_abs = llabs ((offsetT) value);
4962c51a 29883
477330fc
RM
29884 /* Check that the absolute value of the addend can be
29885 encoded in 8 bits. */
29886 if (addend_abs >= 0x100)
4962c51a 29887 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29888 _("bad offset 0x%08lX (only 8 bits available for the magnitude)"),
29889 (unsigned long) addend_abs);
29890
29891 /* Extract the instruction. */
29892 insn = md_chars_to_number (buf, INSN_SIZE);
29893
29894 /* If the addend is negative, clear bit 23 of the instruction.
29895 Otherwise set it. */
7af67752 29896 if ((offsetT) value < 0)
477330fc
RM
29897 insn &= ~(1 << 23);
29898 else
29899 insn |= 1 << 23;
29900
29901 /* Place the first four bits of the absolute value of the addend
29902 into the first 4 bits of the instruction, and the remaining
29903 four into bits 8 .. 11. */
29904 insn &= 0xfffff0f0;
29905 insn |= (addend_abs & 0xf) | ((addend_abs & 0xf0) << 4);
29906
29907 /* Update the instruction. */
29908 md_number_to_chars (buf, insn, INSN_SIZE);
29909 }
4962c51a
MS
29910 break;
29911
29912 case BFD_RELOC_ARM_LDC_PC_G0:
29913 case BFD_RELOC_ARM_LDC_PC_G1:
29914 case BFD_RELOC_ARM_LDC_PC_G2:
29915 case BFD_RELOC_ARM_LDC_SB_G0:
29916 case BFD_RELOC_ARM_LDC_SB_G1:
29917 case BFD_RELOC_ARM_LDC_SB_G2:
9c2799c2 29918 gas_assert (!fixP->fx_done);
4962c51a 29919 if (!seg->use_rela_p)
477330fc
RM
29920 {
29921 bfd_vma insn;
7af67752 29922 bfd_vma addend_abs = llabs ((offsetT) value);
4962c51a 29923
477330fc
RM
29924 /* Check that the absolute value of the addend is a multiple of
29925 four and, when divided by four, fits in 8 bits. */
29926 if (addend_abs & 0x3)
4962c51a 29927 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29928 _("bad offset 0x%08lX (must be word-aligned)"),
29929 (unsigned long) addend_abs);
4962c51a 29930
477330fc 29931 if ((addend_abs >> 2) > 0xff)
4962c51a 29932 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29933 _("bad offset 0x%08lX (must be an 8-bit number of words)"),
29934 (unsigned long) addend_abs);
29935
29936 /* Extract the instruction. */
29937 insn = md_chars_to_number (buf, INSN_SIZE);
29938
29939 /* If the addend is negative, clear bit 23 of the instruction.
29940 Otherwise set it. */
7af67752 29941 if ((offsetT) value < 0)
477330fc
RM
29942 insn &= ~(1 << 23);
29943 else
29944 insn |= 1 << 23;
29945
29946 /* Place the addend (divided by four) into the first eight
29947 bits of the instruction. */
29948 insn &= 0xfffffff0;
29949 insn |= addend_abs >> 2;
29950
29951 /* Update the instruction. */
29952 md_number_to_chars (buf, insn, INSN_SIZE);
29953 }
4962c51a
MS
29954 break;
29955
e12437dc
AV
29956 case BFD_RELOC_THUMB_PCREL_BRANCH5:
29957 if (fixP->fx_addsy
29958 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29959 && !S_FORCE_RELOC (fixP->fx_addsy, true)
e12437dc
AV
29960 && ARM_IS_FUNC (fixP->fx_addsy)
29961 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29962 {
29963 /* Force a relocation for a branch 5 bits wide. */
29964 fixP->fx_done = 0;
29965 }
5b7c81bd 29966 if (v8_1_branch_value_check (value, 5, false) == FAIL)
e12437dc
AV
29967 as_bad_where (fixP->fx_file, fixP->fx_line,
29968 BAD_BRANCH_OFF);
29969
29970 if (fixP->fx_done || !seg->use_rela_p)
29971 {
29972 addressT boff = value >> 1;
29973
29974 newval = md_chars_to_number (buf, THUMB_SIZE);
29975 newval |= (boff << 7);
29976 md_number_to_chars (buf, newval, THUMB_SIZE);
29977 }
29978 break;
29979
f6b2b12d
AV
29980 case BFD_RELOC_THUMB_PCREL_BFCSEL:
29981 if (fixP->fx_addsy
29982 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29983 && !S_FORCE_RELOC (fixP->fx_addsy, true)
f6b2b12d
AV
29984 && ARM_IS_FUNC (fixP->fx_addsy)
29985 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29986 {
29987 fixP->fx_done = 0;
29988 }
7af67752 29989 if ((value & ~0x7f) && ((value & ~0x3f) != (valueT) ~0x3f))
f6b2b12d
AV
29990 as_bad_where (fixP->fx_file, fixP->fx_line,
29991 _("branch out of range"));
29992
29993 if (fixP->fx_done || !seg->use_rela_p)
29994 {
29995 newval = md_chars_to_number (buf, THUMB_SIZE);
29996
29997 addressT boff = ((newval & 0x0780) >> 7) << 1;
29998 addressT diff = value - boff;
29999
30000 if (diff == 4)
30001 {
30002 newval |= 1 << 1; /* T bit. */
30003 }
30004 else if (diff != 2)
30005 {
30006 as_bad_where (fixP->fx_file, fixP->fx_line,
30007 _("out of range label-relative fixup value"));
30008 }
30009 md_number_to_chars (buf, newval, THUMB_SIZE);
30010 }
30011 break;
30012
e5d6e09e
AV
30013 case BFD_RELOC_ARM_THUMB_BF17:
30014 if (fixP->fx_addsy
30015 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 30016 && !S_FORCE_RELOC (fixP->fx_addsy, true)
e5d6e09e
AV
30017 && ARM_IS_FUNC (fixP->fx_addsy)
30018 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
30019 {
30020 /* Force a relocation for a branch 17 bits wide. */
30021 fixP->fx_done = 0;
30022 }
30023
5b7c81bd 30024 if (v8_1_branch_value_check (value, 17, true) == FAIL)
e5d6e09e
AV
30025 as_bad_where (fixP->fx_file, fixP->fx_line,
30026 BAD_BRANCH_OFF);
30027
30028 if (fixP->fx_done || !seg->use_rela_p)
30029 {
30030 offsetT newval2;
30031 addressT immA, immB, immC;
30032
30033 immA = (value & 0x0001f000) >> 12;
30034 immB = (value & 0x00000ffc) >> 2;
30035 immC = (value & 0x00000002) >> 1;
30036
30037 newval = md_chars_to_number (buf, THUMB_SIZE);
30038 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30039 newval |= immA;
30040 newval2 |= (immC << 11) | (immB << 1);
30041 md_number_to_chars (buf, newval, THUMB_SIZE);
30042 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
30043 }
30044 break;
30045
1caf72a5
AV
30046 case BFD_RELOC_ARM_THUMB_BF19:
30047 if (fixP->fx_addsy
30048 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 30049 && !S_FORCE_RELOC (fixP->fx_addsy, true)
1caf72a5
AV
30050 && ARM_IS_FUNC (fixP->fx_addsy)
30051 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
30052 {
30053 /* Force a relocation for a branch 19 bits wide. */
30054 fixP->fx_done = 0;
30055 }
30056
5b7c81bd 30057 if (v8_1_branch_value_check (value, 19, true) == FAIL)
1caf72a5
AV
30058 as_bad_where (fixP->fx_file, fixP->fx_line,
30059 BAD_BRANCH_OFF);
30060
30061 if (fixP->fx_done || !seg->use_rela_p)
30062 {
30063 offsetT newval2;
30064 addressT immA, immB, immC;
30065
30066 immA = (value & 0x0007f000) >> 12;
30067 immB = (value & 0x00000ffc) >> 2;
30068 immC = (value & 0x00000002) >> 1;
30069
30070 newval = md_chars_to_number (buf, THUMB_SIZE);
30071 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30072 newval |= immA;
30073 newval2 |= (immC << 11) | (immB << 1);
30074 md_number_to_chars (buf, newval, THUMB_SIZE);
30075 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
30076 }
30077 break;
30078
1889da70
AV
30079 case BFD_RELOC_ARM_THUMB_BF13:
30080 if (fixP->fx_addsy
30081 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 30082 && !S_FORCE_RELOC (fixP->fx_addsy, true)
1889da70
AV
30083 && ARM_IS_FUNC (fixP->fx_addsy)
30084 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
30085 {
30086 /* Force a relocation for a branch 13 bits wide. */
30087 fixP->fx_done = 0;
30088 }
30089
5b7c81bd 30090 if (v8_1_branch_value_check (value, 13, true) == FAIL)
1889da70
AV
30091 as_bad_where (fixP->fx_file, fixP->fx_line,
30092 BAD_BRANCH_OFF);
30093
30094 if (fixP->fx_done || !seg->use_rela_p)
30095 {
30096 offsetT newval2;
30097 addressT immA, immB, immC;
30098
30099 immA = (value & 0x00001000) >> 12;
30100 immB = (value & 0x00000ffc) >> 2;
30101 immC = (value & 0x00000002) >> 1;
30102
30103 newval = md_chars_to_number (buf, THUMB_SIZE);
30104 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30105 newval |= immA;
30106 newval2 |= (immC << 11) | (immB << 1);
30107 md_number_to_chars (buf, newval, THUMB_SIZE);
30108 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
30109 }
30110 break;
30111
60f993ce
AV
30112 case BFD_RELOC_ARM_THUMB_LOOP12:
30113 if (fixP->fx_addsy
30114 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 30115 && !S_FORCE_RELOC (fixP->fx_addsy, true)
60f993ce
AV
30116 && ARM_IS_FUNC (fixP->fx_addsy)
30117 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
30118 {
30119 /* Force a relocation for a branch 12 bits wide. */
30120 fixP->fx_done = 0;
30121 }
30122
30123 bfd_vma insn = get_thumb32_insn (buf);
1f6234a3 30124 /* le lr, <label>, le <label> or letp lr, <label> */
60f993ce 30125 if (((insn & 0xffffffff) == 0xf00fc001)
1f6234a3
AV
30126 || ((insn & 0xffffffff) == 0xf02fc001)
30127 || ((insn & 0xffffffff) == 0xf01fc001))
60f993ce
AV
30128 value = -value;
30129
5b7c81bd 30130 if (v8_1_branch_value_check (value, 12, false) == FAIL)
60f993ce
AV
30131 as_bad_where (fixP->fx_file, fixP->fx_line,
30132 BAD_BRANCH_OFF);
30133 if (fixP->fx_done || !seg->use_rela_p)
30134 {
30135 addressT imml, immh;
30136
30137 immh = (value & 0x00000ffc) >> 2;
30138 imml = (value & 0x00000002) >> 1;
30139
30140 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30141 newval |= (imml << 11) | (immh << 1);
30142 md_number_to_chars (buf + THUMB_SIZE, newval, THUMB_SIZE);
30143 }
30144 break;
30145
845b51d6
PB
30146 case BFD_RELOC_ARM_V4BX:
30147 /* This will need to go in the object file. */
30148 fixP->fx_done = 0;
30149 break;
30150
c19d1205
ZW
30151 case BFD_RELOC_UNUSED:
30152 default:
30153 as_bad_where (fixP->fx_file, fixP->fx_line,
30154 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
30155 }
6c43fab6
RE
30156}
30157
c19d1205
ZW
30158/* Translate internal representation of relocation info to BFD target
30159 format. */
a737bd4d 30160
c19d1205 30161arelent *
00a97672 30162tc_gen_reloc (asection *section, fixS *fixp)
a737bd4d 30163{
c19d1205
ZW
30164 arelent * reloc;
30165 bfd_reloc_code_real_type code;
a737bd4d 30166
325801bd 30167 reloc = XNEW (arelent);
a737bd4d 30168
325801bd 30169 reloc->sym_ptr_ptr = XNEW (asymbol *);
c19d1205
ZW
30170 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
30171 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
a737bd4d 30172
2fc8bdac 30173 if (fixp->fx_pcrel)
00a97672
RS
30174 {
30175 if (section->use_rela_p)
30176 fixp->fx_offset -= md_pcrel_from_section (fixp, section);
30177 else
30178 fixp->fx_offset = reloc->address;
30179 }
c19d1205 30180 reloc->addend = fixp->fx_offset;
a737bd4d 30181
c19d1205 30182 switch (fixp->fx_r_type)
a737bd4d 30183 {
c19d1205
ZW
30184 case BFD_RELOC_8:
30185 if (fixp->fx_pcrel)
30186 {
30187 code = BFD_RELOC_8_PCREL;
30188 break;
30189 }
1a0670f3 30190 /* Fall through. */
a737bd4d 30191
c19d1205
ZW
30192 case BFD_RELOC_16:
30193 if (fixp->fx_pcrel)
30194 {
30195 code = BFD_RELOC_16_PCREL;
30196 break;
30197 }
1a0670f3 30198 /* Fall through. */
6c43fab6 30199
c19d1205
ZW
30200 case BFD_RELOC_32:
30201 if (fixp->fx_pcrel)
30202 {
30203 code = BFD_RELOC_32_PCREL;
30204 break;
30205 }
1a0670f3 30206 /* Fall through. */
a737bd4d 30207
b6895b4f
PB
30208 case BFD_RELOC_ARM_MOVW:
30209 if (fixp->fx_pcrel)
30210 {
30211 code = BFD_RELOC_ARM_MOVW_PCREL;
30212 break;
30213 }
1a0670f3 30214 /* Fall through. */
b6895b4f
PB
30215
30216 case BFD_RELOC_ARM_MOVT:
30217 if (fixp->fx_pcrel)
30218 {
30219 code = BFD_RELOC_ARM_MOVT_PCREL;
30220 break;
30221 }
1a0670f3 30222 /* Fall through. */
b6895b4f
PB
30223
30224 case BFD_RELOC_ARM_THUMB_MOVW:
30225 if (fixp->fx_pcrel)
30226 {
30227 code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
30228 break;
30229 }
1a0670f3 30230 /* Fall through. */
b6895b4f
PB
30231
30232 case BFD_RELOC_ARM_THUMB_MOVT:
30233 if (fixp->fx_pcrel)
30234 {
30235 code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
30236 break;
30237 }
1a0670f3 30238 /* Fall through. */
b6895b4f 30239
c19d1205
ZW
30240 case BFD_RELOC_NONE:
30241 case BFD_RELOC_ARM_PCREL_BRANCH:
30242 case BFD_RELOC_ARM_PCREL_BLX:
30243 case BFD_RELOC_RVA:
30244 case BFD_RELOC_THUMB_PCREL_BRANCH7:
30245 case BFD_RELOC_THUMB_PCREL_BRANCH9:
30246 case BFD_RELOC_THUMB_PCREL_BRANCH12:
30247 case BFD_RELOC_THUMB_PCREL_BRANCH20:
30248 case BFD_RELOC_THUMB_PCREL_BRANCH23:
30249 case BFD_RELOC_THUMB_PCREL_BRANCH25:
c19d1205
ZW
30250 case BFD_RELOC_VTABLE_ENTRY:
30251 case BFD_RELOC_VTABLE_INHERIT:
f0927246
NC
30252#ifdef TE_PE
30253 case BFD_RELOC_32_SECREL:
30254#endif
c19d1205
ZW
30255 code = fixp->fx_r_type;
30256 break;
a737bd4d 30257
00adf2d4
JB
30258 case BFD_RELOC_THUMB_PCREL_BLX:
30259#ifdef OBJ_ELF
30260 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
30261 code = BFD_RELOC_THUMB_PCREL_BRANCH23;
30262 else
30263#endif
30264 code = BFD_RELOC_THUMB_PCREL_BLX;
30265 break;
30266
c19d1205
ZW
30267 case BFD_RELOC_ARM_LITERAL:
30268 case BFD_RELOC_ARM_HWLITERAL:
30269 /* If this is called then the a literal has
30270 been referenced across a section boundary. */
30271 as_bad_where (fixp->fx_file, fixp->fx_line,
30272 _("literal referenced across section boundary"));
30273 return NULL;
a737bd4d 30274
c19d1205 30275#ifdef OBJ_ELF
0855e32b
NS
30276 case BFD_RELOC_ARM_TLS_CALL:
30277 case BFD_RELOC_ARM_THM_TLS_CALL:
30278 case BFD_RELOC_ARM_TLS_DESCSEQ:
30279 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
c19d1205
ZW
30280 case BFD_RELOC_ARM_GOT32:
30281 case BFD_RELOC_ARM_GOTOFF:
b43420e6 30282 case BFD_RELOC_ARM_GOT_PREL:
c19d1205
ZW
30283 case BFD_RELOC_ARM_PLT32:
30284 case BFD_RELOC_ARM_TARGET1:
30285 case BFD_RELOC_ARM_ROSEGREL32:
30286 case BFD_RELOC_ARM_SBREL32:
30287 case BFD_RELOC_ARM_PREL31:
30288 case BFD_RELOC_ARM_TARGET2:
c19d1205 30289 case BFD_RELOC_ARM_TLS_LDO32:
39b41c9c
PB
30290 case BFD_RELOC_ARM_PCREL_CALL:
30291 case BFD_RELOC_ARM_PCREL_JUMP:
4962c51a
MS
30292 case BFD_RELOC_ARM_ALU_PC_G0_NC:
30293 case BFD_RELOC_ARM_ALU_PC_G0:
30294 case BFD_RELOC_ARM_ALU_PC_G1_NC:
30295 case BFD_RELOC_ARM_ALU_PC_G1:
30296 case BFD_RELOC_ARM_ALU_PC_G2:
30297 case BFD_RELOC_ARM_LDR_PC_G0:
30298 case BFD_RELOC_ARM_LDR_PC_G1:
30299 case BFD_RELOC_ARM_LDR_PC_G2:
30300 case BFD_RELOC_ARM_LDRS_PC_G0:
30301 case BFD_RELOC_ARM_LDRS_PC_G1:
30302 case BFD_RELOC_ARM_LDRS_PC_G2:
30303 case BFD_RELOC_ARM_LDC_PC_G0:
30304 case BFD_RELOC_ARM_LDC_PC_G1:
30305 case BFD_RELOC_ARM_LDC_PC_G2:
30306 case BFD_RELOC_ARM_ALU_SB_G0_NC:
30307 case BFD_RELOC_ARM_ALU_SB_G0:
30308 case BFD_RELOC_ARM_ALU_SB_G1_NC:
30309 case BFD_RELOC_ARM_ALU_SB_G1:
30310 case BFD_RELOC_ARM_ALU_SB_G2:
30311 case BFD_RELOC_ARM_LDR_SB_G0:
30312 case BFD_RELOC_ARM_LDR_SB_G1:
30313 case BFD_RELOC_ARM_LDR_SB_G2:
30314 case BFD_RELOC_ARM_LDRS_SB_G0:
30315 case BFD_RELOC_ARM_LDRS_SB_G1:
30316 case BFD_RELOC_ARM_LDRS_SB_G2:
30317 case BFD_RELOC_ARM_LDC_SB_G0:
30318 case BFD_RELOC_ARM_LDC_SB_G1:
30319 case BFD_RELOC_ARM_LDC_SB_G2:
845b51d6 30320 case BFD_RELOC_ARM_V4BX:
72d98d16
MG
30321 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
30322 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
30323 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
30324 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
188fd7ae
CL
30325 case BFD_RELOC_ARM_GOTFUNCDESC:
30326 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
30327 case BFD_RELOC_ARM_FUNCDESC:
e5d6e09e 30328 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 30329 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 30330 case BFD_RELOC_ARM_THUMB_BF13:
c19d1205
ZW
30331 code = fixp->fx_r_type;
30332 break;
a737bd4d 30333
0855e32b 30334 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205 30335 case BFD_RELOC_ARM_TLS_GD32:
5c5a4843 30336 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
75c11999 30337 case BFD_RELOC_ARM_TLS_LE32:
c19d1205 30338 case BFD_RELOC_ARM_TLS_IE32:
5c5a4843 30339 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
c19d1205 30340 case BFD_RELOC_ARM_TLS_LDM32:
5c5a4843 30341 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
c19d1205
ZW
30342 /* BFD will include the symbol's address in the addend.
30343 But we don't want that, so subtract it out again here. */
30344 if (!S_IS_COMMON (fixp->fx_addsy))
30345 reloc->addend -= (*reloc->sym_ptr_ptr)->value;
30346 code = fixp->fx_r_type;
30347 break;
30348#endif
a737bd4d 30349
c19d1205
ZW
30350 case BFD_RELOC_ARM_IMMEDIATE:
30351 as_bad_where (fixp->fx_file, fixp->fx_line,
30352 _("internal relocation (type: IMMEDIATE) not fixed up"));
30353 return NULL;
a737bd4d 30354
c19d1205
ZW
30355 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
30356 as_bad_where (fixp->fx_file, fixp->fx_line,
30357 _("ADRL used for a symbol not defined in the same file"));
30358 return NULL;
a737bd4d 30359
e12437dc 30360 case BFD_RELOC_THUMB_PCREL_BRANCH5:
f6b2b12d 30361 case BFD_RELOC_THUMB_PCREL_BFCSEL:
60f993ce 30362 case BFD_RELOC_ARM_THUMB_LOOP12:
e12437dc
AV
30363 as_bad_where (fixp->fx_file, fixp->fx_line,
30364 _("%s used for a symbol not defined in the same file"),
30365 bfd_get_reloc_code_name (fixp->fx_r_type));
30366 return NULL;
30367
c19d1205 30368 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
30369 if (section->use_rela_p)
30370 {
30371 code = fixp->fx_r_type;
30372 break;
30373 }
30374
c19d1205
ZW
30375 if (fixp->fx_addsy != NULL
30376 && !S_IS_DEFINED (fixp->fx_addsy)
30377 && S_IS_LOCAL (fixp->fx_addsy))
a737bd4d 30378 {
c19d1205
ZW
30379 as_bad_where (fixp->fx_file, fixp->fx_line,
30380 _("undefined local label `%s'"),
30381 S_GET_NAME (fixp->fx_addsy));
30382 return NULL;
a737bd4d
NC
30383 }
30384
c19d1205
ZW
30385 as_bad_where (fixp->fx_file, fixp->fx_line,
30386 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
30387 return NULL;
a737bd4d 30388
c19d1205
ZW
30389 default:
30390 {
e0471c16 30391 const char * type;
6c43fab6 30392
c19d1205
ZW
30393 switch (fixp->fx_r_type)
30394 {
30395 case BFD_RELOC_NONE: type = "NONE"; break;
30396 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
30397 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
3eb17e6b 30398 case BFD_RELOC_ARM_SMC: type = "SMC"; break;
c19d1205
ZW
30399 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
30400 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
30401 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
db187cb9 30402 case BFD_RELOC_ARM_T32_OFFSET_IMM: type = "T32_OFFSET_IMM"; break;
8f06b2d8 30403 case BFD_RELOC_ARM_T32_CP_OFF_IMM: type = "T32_CP_OFF_IMM"; break;
c19d1205
ZW
30404 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
30405 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
30406 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
30407 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
30408 default: type = _("<unknown>"); break;
30409 }
30410 as_bad_where (fixp->fx_file, fixp->fx_line,
30411 _("cannot represent %s relocation in this object file format"),
30412 type);
30413 return NULL;
30414 }
a737bd4d 30415 }
6c43fab6 30416
c19d1205
ZW
30417#ifdef OBJ_ELF
30418 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
30419 && GOT_symbol
30420 && fixp->fx_addsy == GOT_symbol)
30421 {
30422 code = BFD_RELOC_ARM_GOTPC;
30423 reloc->addend = fixp->fx_offset = reloc->address;
30424 }
30425#endif
6c43fab6 30426
c19d1205 30427 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6c43fab6 30428
c19d1205
ZW
30429 if (reloc->howto == NULL)
30430 {
30431 as_bad_where (fixp->fx_file, fixp->fx_line,
30432 _("cannot represent %s relocation in this object file format"),
30433 bfd_get_reloc_code_name (code));
30434 return NULL;
30435 }
6c43fab6 30436
c19d1205
ZW
30437 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
30438 vtable entry to be used in the relocation's section offset. */
30439 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
30440 reloc->address = fixp->fx_offset;
6c43fab6 30441
c19d1205 30442 return reloc;
6c43fab6
RE
30443}
30444
c19d1205 30445/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6c43fab6 30446
c19d1205
ZW
30447void
30448cons_fix_new_arm (fragS * frag,
30449 int where,
30450 int size,
62ebcb5c
AM
30451 expressionS * exp,
30452 bfd_reloc_code_real_type reloc)
6c43fab6 30453{
c19d1205 30454 int pcrel = 0;
6c43fab6 30455
c19d1205
ZW
30456 /* Pick a reloc.
30457 FIXME: @@ Should look at CPU word size. */
30458 switch (size)
30459 {
30460 case 1:
62ebcb5c 30461 reloc = BFD_RELOC_8;
c19d1205
ZW
30462 break;
30463 case 2:
62ebcb5c 30464 reloc = BFD_RELOC_16;
c19d1205
ZW
30465 break;
30466 case 4:
30467 default:
62ebcb5c 30468 reloc = BFD_RELOC_32;
c19d1205
ZW
30469 break;
30470 case 8:
62ebcb5c 30471 reloc = BFD_RELOC_64;
c19d1205
ZW
30472 break;
30473 }
6c43fab6 30474
f0927246
NC
30475#ifdef TE_PE
30476 if (exp->X_op == O_secrel)
30477 {
30478 exp->X_op = O_symbol;
62ebcb5c 30479 reloc = BFD_RELOC_32_SECREL;
f0927246
NC
30480 }
30481#endif
30482
62ebcb5c 30483 fix_new_exp (frag, where, size, exp, pcrel, reloc);
c19d1205 30484}
6c43fab6 30485
4343666d 30486#if defined (OBJ_COFF)
c19d1205
ZW
30487void
30488arm_validate_fix (fixS * fixP)
6c43fab6 30489{
c19d1205
ZW
30490 /* If the destination of the branch is a defined symbol which does not have
30491 the THUMB_FUNC attribute, then we must be calling a function which has
30492 the (interfacearm) attribute. We look for the Thumb entry point to that
30493 function and change the branch to refer to that function instead. */
30494 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
30495 && fixP->fx_addsy != NULL
30496 && S_IS_DEFINED (fixP->fx_addsy)
30497 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6c43fab6 30498 {
c19d1205 30499 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6c43fab6 30500 }
c19d1205
ZW
30501}
30502#endif
6c43fab6 30503
267bf995 30504
c19d1205
ZW
30505int
30506arm_force_relocation (struct fix * fixp)
30507{
30508#if defined (OBJ_COFF) && defined (TE_PE)
30509 if (fixp->fx_r_type == BFD_RELOC_RVA)
30510 return 1;
30511#endif
6c43fab6 30512
267bf995
RR
30513 /* In case we have a call or a branch to a function in ARM ISA mode from
30514 a thumb function or vice-versa force the relocation. These relocations
30515 are cleared off for some cores that might have blx and simple transformations
30516 are possible. */
30517
30518#ifdef OBJ_ELF
30519 switch (fixp->fx_r_type)
30520 {
30521 case BFD_RELOC_ARM_PCREL_JUMP:
30522 case BFD_RELOC_ARM_PCREL_CALL:
30523 case BFD_RELOC_THUMB_PCREL_BLX:
30524 if (THUMB_IS_FUNC (fixp->fx_addsy))
30525 return 1;
30526 break;
30527
30528 case BFD_RELOC_ARM_PCREL_BLX:
30529 case BFD_RELOC_THUMB_PCREL_BRANCH25:
30530 case BFD_RELOC_THUMB_PCREL_BRANCH20:
30531 case BFD_RELOC_THUMB_PCREL_BRANCH23:
30532 if (ARM_IS_FUNC (fixp->fx_addsy))
30533 return 1;
30534 break;
30535
30536 default:
30537 break;
30538 }
30539#endif
30540
b5884301
PB
30541 /* Resolve these relocations even if the symbol is extern or weak.
30542 Technically this is probably wrong due to symbol preemption.
30543 In practice these relocations do not have enough range to be useful
30544 at dynamic link time, and some code (e.g. in the Linux kernel)
30545 expects these references to be resolved. */
c19d1205
ZW
30546 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
30547 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
b5884301 30548 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM8
0110f2b8 30549 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
b5884301
PB
30550 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
30551 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2
30552 || fixp->fx_r_type == BFD_RELOC_ARM_THUMB_OFFSET
b59d128a 30553 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH12
16805f35 30554 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
0110f2b8
PB
30555 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
30556 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
b5884301
PB
30557 || fixp->fx_r_type == BFD_RELOC_ARM_T32_OFFSET_IMM
30558 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12
30559 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM
30560 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM_S2)
c19d1205 30561 return 0;
a737bd4d 30562
4962c51a
MS
30563 /* Always leave these relocations for the linker. */
30564 if ((fixp->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
30565 && fixp->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
30566 || fixp->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
30567 return 1;
30568
f0291e4c
PB
30569 /* Always generate relocations against function symbols. */
30570 if (fixp->fx_r_type == BFD_RELOC_32
30571 && fixp->fx_addsy
30572 && (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION))
30573 return 1;
30574
c19d1205 30575 return generic_force_reloc (fixp);
404ff6b5
AH
30576}
30577
0ffdc86c 30578#if defined (OBJ_ELF) || defined (OBJ_COFF)
e28387c3
PB
30579/* Relocations against function names must be left unadjusted,
30580 so that the linker can use this information to generate interworking
30581 stubs. The MIPS version of this function
c19d1205
ZW
30582 also prevents relocations that are mips-16 specific, but I do not
30583 know why it does this.
404ff6b5 30584
c19d1205
ZW
30585 FIXME:
30586 There is one other problem that ought to be addressed here, but
30587 which currently is not: Taking the address of a label (rather
30588 than a function) and then later jumping to that address. Such
30589 addresses also ought to have their bottom bit set (assuming that
30590 they reside in Thumb code), but at the moment they will not. */
404ff6b5 30591
5b7c81bd 30592bool
c19d1205 30593arm_fix_adjustable (fixS * fixP)
404ff6b5 30594{
c19d1205
ZW
30595 if (fixP->fx_addsy == NULL)
30596 return 1;
404ff6b5 30597
e28387c3
PB
30598 /* Preserve relocations against symbols with function type. */
30599 if (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION)
5b7c81bd 30600 return false;
e28387c3 30601
c19d1205
ZW
30602 if (THUMB_IS_FUNC (fixP->fx_addsy)
30603 && fixP->fx_subsy == NULL)
5b7c81bd 30604 return false;
a737bd4d 30605
c19d1205
ZW
30606 /* We need the symbol name for the VTABLE entries. */
30607 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
30608 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5b7c81bd 30609 return false;
404ff6b5 30610
c19d1205
ZW
30611 /* Don't allow symbols to be discarded on GOT related relocs. */
30612 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
30613 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
30614 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
30615 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
5c5a4843 30616 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32_FDPIC
c19d1205
ZW
30617 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
30618 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
5c5a4843 30619 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32_FDPIC
c19d1205 30620 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
5c5a4843 30621 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32_FDPIC
c19d1205 30622 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
0855e32b
NS
30623 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GOTDESC
30624 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
30625 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_CALL
30626 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
30627 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_DESCSEQ
c19d1205 30628 || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
5b7c81bd 30629 return false;
a737bd4d 30630
4962c51a
MS
30631 /* Similarly for group relocations. */
30632 if ((fixP->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
30633 && fixP->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
30634 || fixP->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
5b7c81bd 30635 return false;
4962c51a 30636
79947c54
CD
30637 /* MOVW/MOVT REL relocations have limited offsets, so keep the symbols. */
30638 if (fixP->fx_r_type == BFD_RELOC_ARM_MOVW
30639 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT
30640 || fixP->fx_r_type == BFD_RELOC_ARM_MOVW_PCREL
30641 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT_PCREL
30642 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
30643 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT
30644 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW_PCREL
30645 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
5b7c81bd 30646 return false;
79947c54 30647
72d98d16
MG
30648 /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
30649 offsets, so keep these symbols. */
30650 if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
30651 && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
5b7c81bd 30652 return false;
72d98d16 30653
5b7c81bd 30654 return true;
a737bd4d 30655}
0ffdc86c
NC
30656#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
30657
30658#ifdef OBJ_ELF
c19d1205
ZW
30659const char *
30660elf32_arm_target_format (void)
404ff6b5 30661{
a57d1773 30662#if defined (TE_VXWORKS)
c19d1205
ZW
30663 return (target_big_endian
30664 ? "elf32-bigarm-vxworks"
30665 : "elf32-littlearm-vxworks");
b38cadfb
NC
30666#elif defined (TE_NACL)
30667 return (target_big_endian
30668 ? "elf32-bigarm-nacl"
30669 : "elf32-littlearm-nacl");
c19d1205 30670#else
18a20338
CL
30671 if (arm_fdpic)
30672 {
30673 if (target_big_endian)
30674 return "elf32-bigarm-fdpic";
30675 else
30676 return "elf32-littlearm-fdpic";
30677 }
c19d1205 30678 else
18a20338
CL
30679 {
30680 if (target_big_endian)
30681 return "elf32-bigarm";
30682 else
30683 return "elf32-littlearm";
30684 }
c19d1205 30685#endif
404ff6b5
AH
30686}
30687
c19d1205
ZW
30688void
30689armelf_frob_symbol (symbolS * symp,
30690 int * puntp)
404ff6b5 30691{
c19d1205
ZW
30692 elf_frob_symbol (symp, puntp);
30693}
30694#endif
404ff6b5 30695
c19d1205 30696/* MD interface: Finalization. */
a737bd4d 30697
c19d1205
ZW
30698void
30699arm_cleanup (void)
30700{
30701 literal_pool * pool;
a737bd4d 30702
5ee91343
AV
30703 /* Ensure that all the predication blocks are properly closed. */
30704 check_pred_blocks_finished ();
e07e6e58 30705
c19d1205
ZW
30706 for (pool = list_of_pools; pool; pool = pool->next)
30707 {
5f4273c7 30708 /* Put it at the end of the relevant section. */
c19d1205
ZW
30709 subseg_set (pool->section, pool->sub_section);
30710#ifdef OBJ_ELF
30711 arm_elf_change_section ();
30712#endif
30713 s_ltorg (0);
30714 }
404ff6b5
AH
30715}
30716
cd000bff
DJ
30717#ifdef OBJ_ELF
30718/* Remove any excess mapping symbols generated for alignment frags in
30719 SEC. We may have created a mapping symbol before a zero byte
30720 alignment; remove it if there's a mapping symbol after the
30721 alignment. */
30722static void
30723check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
30724 void *dummy ATTRIBUTE_UNUSED)
30725{
30726 segment_info_type *seginfo = seg_info (sec);
30727 fragS *fragp;
30728
30729 if (seginfo == NULL || seginfo->frchainP == NULL)
30730 return;
30731
30732 for (fragp = seginfo->frchainP->frch_root;
30733 fragp != NULL;
30734 fragp = fragp->fr_next)
30735 {
30736 symbolS *sym = fragp->tc_frag_data.last_map;
30737 fragS *next = fragp->fr_next;
30738
30739 /* Variable-sized frags have been converted to fixed size by
30740 this point. But if this was variable-sized to start with,
30741 there will be a fixed-size frag after it. So don't handle
30742 next == NULL. */
30743 if (sym == NULL || next == NULL)
30744 continue;
30745
30746 if (S_GET_VALUE (sym) < next->fr_address)
30747 /* Not at the end of this frag. */
30748 continue;
30749 know (S_GET_VALUE (sym) == next->fr_address);
30750
30751 do
30752 {
30753 if (next->tc_frag_data.first_map != NULL)
30754 {
30755 /* Next frag starts with a mapping symbol. Discard this
30756 one. */
30757 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
30758 break;
30759 }
30760
30761 if (next->fr_next == NULL)
30762 {
30763 /* This mapping symbol is at the end of the section. Discard
30764 it. */
30765 know (next->fr_fix == 0 && next->fr_var == 0);
30766 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
30767 break;
30768 }
30769
30770 /* As long as we have empty frags without any mapping symbols,
30771 keep looking. */
30772 /* If the next frag is non-empty and does not start with a
30773 mapping symbol, then this mapping symbol is required. */
30774 if (next->fr_address != next->fr_next->fr_address)
30775 break;
30776
30777 next = next->fr_next;
30778 }
30779 while (next != NULL);
30780 }
30781}
30782#endif
30783
c19d1205
ZW
30784/* Adjust the symbol table. This marks Thumb symbols as distinct from
30785 ARM ones. */
404ff6b5 30786
c19d1205
ZW
30787void
30788arm_adjust_symtab (void)
404ff6b5 30789{
c19d1205
ZW
30790#ifdef OBJ_COFF
30791 symbolS * sym;
404ff6b5 30792
c19d1205
ZW
30793 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
30794 {
30795 if (ARM_IS_THUMB (sym))
30796 {
30797 if (THUMB_IS_FUNC (sym))
30798 {
30799 /* Mark the symbol as a Thumb function. */
30800 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
30801 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
30802 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
404ff6b5 30803
c19d1205
ZW
30804 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
30805 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
30806 else
30807 as_bad (_("%s: unexpected function type: %d"),
30808 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
30809 }
30810 else switch (S_GET_STORAGE_CLASS (sym))
30811 {
30812 case C_EXT:
30813 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
30814 break;
30815 case C_STAT:
30816 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
30817 break;
30818 case C_LABEL:
30819 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
30820 break;
30821 default:
30822 /* Do nothing. */
30823 break;
30824 }
30825 }
a737bd4d 30826
c19d1205
ZW
30827 if (ARM_IS_INTERWORK (sym))
30828 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
404ff6b5 30829 }
c19d1205
ZW
30830#endif
30831#ifdef OBJ_ELF
30832 symbolS * sym;
30833 char bind;
404ff6b5 30834
c19d1205 30835 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
404ff6b5 30836 {
c19d1205
ZW
30837 if (ARM_IS_THUMB (sym))
30838 {
30839 elf_symbol_type * elf_sym;
404ff6b5 30840
c19d1205
ZW
30841 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
30842 bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
404ff6b5 30843
b0796911
PB
30844 if (! bfd_is_arm_special_symbol_name (elf_sym->symbol.name,
30845 BFD_ARM_SPECIAL_SYM_TYPE_ANY))
c19d1205
ZW
30846 {
30847 /* If it's a .thumb_func, declare it as so,
30848 otherwise tag label as .code 16. */
30849 if (THUMB_IS_FUNC (sym))
39d911fc
TP
30850 ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
30851 ST_BRANCH_TO_THUMB);
3ba67470 30852 else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
c19d1205
ZW
30853 elf_sym->internal_elf_sym.st_info =
30854 ELF_ST_INFO (bind, STT_ARM_16BIT);
30855 }
30856 }
30857 }
cd000bff
DJ
30858
30859 /* Remove any overlapping mapping symbols generated by alignment frags. */
30860 bfd_map_over_sections (stdoutput, check_mapping_symbols, (char *) 0);
709001e9
MM
30861 /* Now do generic ELF adjustments. */
30862 elf_adjust_symtab ();
c19d1205 30863#endif
404ff6b5
AH
30864}
30865
c19d1205 30866/* MD interface: Initialization. */
404ff6b5 30867
a737bd4d 30868static void
c19d1205 30869set_constant_flonums (void)
a737bd4d 30870{
c19d1205 30871 int i;
404ff6b5 30872
c19d1205
ZW
30873 for (i = 0; i < NUM_FLOAT_VALS; i++)
30874 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
30875 abort ();
a737bd4d 30876}
404ff6b5 30877
3e9e4fcf
JB
30878/* Auto-select Thumb mode if it's the only available instruction set for the
30879 given architecture. */
30880
30881static void
30882autoselect_thumb_from_cpu_variant (void)
30883{
30884 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
30885 opcode_select (16);
30886}
30887
c19d1205
ZW
30888void
30889md_begin (void)
a737bd4d 30890{
c19d1205
ZW
30891 unsigned mach;
30892 unsigned int i;
404ff6b5 30893
f16c3d4f
AM
30894 arm_ops_hsh = str_htab_create ();
30895 arm_cond_hsh = str_htab_create ();
30896 arm_vcond_hsh = str_htab_create ();
30897 arm_shift_hsh = str_htab_create ();
30898 arm_psr_hsh = str_htab_create ();
30899 arm_v7m_psr_hsh = str_htab_create ();
30900 arm_reg_hsh = str_htab_create ();
30901 arm_reloc_hsh = str_htab_create ();
30902 arm_barrier_opt_hsh = str_htab_create ();
c19d1205
ZW
30903
30904 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
629310ab 30905 if (str_hash_find (arm_ops_hsh, insns[i].template_name) == NULL)
fe0e921f 30906 str_hash_insert (arm_ops_hsh, insns[i].template_name, insns + i, 0);
c19d1205 30907 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
fe0e921f 30908 str_hash_insert (arm_cond_hsh, conds[i].template_name, conds + i, 0);
5ee91343 30909 for (i = 0; i < sizeof (vconds) / sizeof (struct asm_cond); i++)
fe0e921f 30910 str_hash_insert (arm_vcond_hsh, vconds[i].template_name, vconds + i, 0);
c19d1205 30911 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
fe0e921f 30912 str_hash_insert (arm_shift_hsh, shift_names[i].name, shift_names + i, 0);
c19d1205 30913 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
fe0e921f 30914 str_hash_insert (arm_psr_hsh, psrs[i].template_name, psrs + i, 0);
62b3e311 30915 for (i = 0; i < sizeof (v7m_psrs) / sizeof (struct asm_psr); i++)
629310ab 30916 str_hash_insert (arm_v7m_psr_hsh, v7m_psrs[i].template_name,
fe0e921f 30917 v7m_psrs + i, 0);
c19d1205 30918 for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
fe0e921f 30919 str_hash_insert (arm_reg_hsh, reg_names[i].name, reg_names + i, 0);
62b3e311
PB
30920 for (i = 0;
30921 i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
30922 i++)
629310ab 30923 str_hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
fe0e921f 30924 barrier_opt_names + i, 0);
c19d1205 30925#ifdef OBJ_ELF
3da1d841
NC
30926 for (i = 0; i < ARRAY_SIZE (reloc_names); i++)
30927 {
30928 struct reloc_entry * entry = reloc_names + i;
30929
30930 if (arm_is_eabi() && entry->reloc == BFD_RELOC_ARM_PLT32)
30931 /* This makes encode_branch() use the EABI versions of this relocation. */
30932 entry->reloc = BFD_RELOC_UNUSED;
30933
fe0e921f 30934 str_hash_insert (arm_reloc_hsh, entry->name, entry, 0);
3da1d841 30935 }
c19d1205
ZW
30936#endif
30937
30938 set_constant_flonums ();
404ff6b5 30939
c19d1205
ZW
30940 /* Set the cpu variant based on the command-line options. We prefer
30941 -mcpu= over -march= if both are set (as for GCC); and we prefer
30942 -mfpu= over any other way of setting the floating point unit.
30943 Use of legacy options with new options are faulted. */
e74cfd16 30944 if (legacy_cpu)
404ff6b5 30945 {
e74cfd16 30946 if (mcpu_cpu_opt || march_cpu_opt)
c19d1205
ZW
30947 as_bad (_("use of old and new-style options to set CPU type"));
30948
4d354d8b 30949 selected_arch = *legacy_cpu;
404ff6b5 30950 }
4d354d8b
TP
30951 else if (mcpu_cpu_opt)
30952 {
30953 selected_arch = *mcpu_cpu_opt;
30954 selected_ext = *mcpu_ext_opt;
30955 }
30956 else if (march_cpu_opt)
c168ce07 30957 {
4d354d8b
TP
30958 selected_arch = *march_cpu_opt;
30959 selected_ext = *march_ext_opt;
c168ce07 30960 }
4d354d8b 30961 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
404ff6b5 30962
e74cfd16 30963 if (legacy_fpu)
c19d1205 30964 {
e74cfd16 30965 if (mfpu_opt)
c19d1205 30966 as_bad (_("use of old and new-style options to set FPU type"));
03b1477f 30967
4d354d8b 30968 selected_fpu = *legacy_fpu;
03b1477f 30969 }
4d354d8b
TP
30970 else if (mfpu_opt)
30971 selected_fpu = *mfpu_opt;
30972 else
03b1477f 30973 {
45eb4c1b
NS
30974#if !(defined (EABI_DEFAULT) || defined (TE_LINUX) \
30975 || defined (TE_NetBSD) || defined (TE_VXWORKS))
39c2da32
RE
30976 /* Some environments specify a default FPU. If they don't, infer it
30977 from the processor. */
e74cfd16 30978 if (mcpu_fpu_opt)
4d354d8b 30979 selected_fpu = *mcpu_fpu_opt;
e7da50fa 30980 else if (march_fpu_opt)
4d354d8b 30981 selected_fpu = *march_fpu_opt;
39c2da32 30982#else
4d354d8b 30983 selected_fpu = fpu_default;
39c2da32 30984#endif
03b1477f
RE
30985 }
30986
4d354d8b 30987 if (ARM_FEATURE_ZERO (selected_fpu))
03b1477f 30988 {
4d354d8b
TP
30989 if (!no_cpu_selected ())
30990 selected_fpu = fpu_default;
03b1477f 30991 else
4d354d8b 30992 selected_fpu = fpu_arch_fpa;
03b1477f
RE
30993 }
30994
ee065d83 30995#ifdef CPU_DEFAULT
4d354d8b 30996 if (ARM_FEATURE_ZERO (selected_arch))
ee065d83 30997 {
4d354d8b
TP
30998 selected_arch = cpu_default;
30999 selected_cpu = selected_arch;
ee065d83 31000 }
4d354d8b 31001 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
e74cfd16 31002#else
4d354d8b
TP
31003 /* Autodection of feature mode: allow all features in cpu_variant but leave
31004 selected_cpu unset. It will be set in aeabi_set_public_attributes ()
31005 after all instruction have been processed and we can decide what CPU
31006 should be selected. */
31007 if (ARM_FEATURE_ZERO (selected_arch))
31008 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
ee065d83 31009 else
4d354d8b 31010 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 31011#endif
03b1477f 31012
3e9e4fcf
JB
31013 autoselect_thumb_from_cpu_variant ();
31014
e74cfd16 31015 arm_arch_used = thumb_arch_used = arm_arch_none;
ee065d83 31016
f17c130b 31017#if defined OBJ_COFF || defined OBJ_ELF
b99bd4ef 31018 {
7cc69913
NC
31019 unsigned int flags = 0;
31020
31021#if defined OBJ_ELF
31022 flags = meabi_flags;
d507cf36
PB
31023
31024 switch (meabi_flags)
33a392fb 31025 {
d507cf36 31026 case EF_ARM_EABI_UNKNOWN:
7cc69913 31027#endif
d507cf36
PB
31028 /* Set the flags in the private structure. */
31029 if (uses_apcs_26) flags |= F_APCS26;
31030 if (support_interwork) flags |= F_INTERWORK;
31031 if (uses_apcs_float) flags |= F_APCS_FLOAT;
c19d1205 31032 if (pic_code) flags |= F_PIC;
e74cfd16 31033 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_any_hard))
7cc69913
NC
31034 flags |= F_SOFT_FLOAT;
31035
d507cf36
PB
31036 switch (mfloat_abi_opt)
31037 {
31038 case ARM_FLOAT_ABI_SOFT:
31039 case ARM_FLOAT_ABI_SOFTFP:
31040 flags |= F_SOFT_FLOAT;
31041 break;
33a392fb 31042
d507cf36
PB
31043 case ARM_FLOAT_ABI_HARD:
31044 if (flags & F_SOFT_FLOAT)
31045 as_bad (_("hard-float conflicts with specified fpu"));
31046 break;
31047 }
03b1477f 31048
e74cfd16
PB
31049 /* Using pure-endian doubles (even if soft-float). */
31050 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
7cc69913 31051 flags |= F_VFP_FLOAT;
f17c130b 31052
fde78edd 31053#if defined OBJ_ELF
e74cfd16 31054 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_maverick))
d507cf36 31055 flags |= EF_ARM_MAVERICK_FLOAT;
d507cf36
PB
31056 break;
31057
8cb51566 31058 case EF_ARM_EABI_VER4:
3a4a14e9 31059 case EF_ARM_EABI_VER5:
c19d1205 31060 /* No additional flags to set. */
d507cf36
PB
31061 break;
31062
31063 default:
31064 abort ();
31065 }
7cc69913 31066#endif
b99bd4ef
NC
31067 bfd_set_private_flags (stdoutput, flags);
31068
31069 /* We have run out flags in the COFF header to encode the
31070 status of ATPCS support, so instead we create a dummy,
c19d1205 31071 empty, debug section called .arm.atpcs. */
b99bd4ef
NC
31072 if (atpcs)
31073 {
31074 asection * sec;
31075
31076 sec = bfd_make_section (stdoutput, ".arm.atpcs");
31077
31078 if (sec != NULL)
31079 {
fd361982
AM
31080 bfd_set_section_flags (sec, SEC_READONLY | SEC_DEBUGGING);
31081 bfd_set_section_size (sec, 0);
b99bd4ef
NC
31082 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
31083 }
31084 }
7cc69913 31085 }
f17c130b 31086#endif
b99bd4ef
NC
31087
31088 /* Record the CPU type as well. */
2d447fca
JM
31089 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
31090 mach = bfd_mach_arm_iWMMXt2;
31091 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
e16bb312 31092 mach = bfd_mach_arm_iWMMXt;
e74cfd16 31093 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
b99bd4ef 31094 mach = bfd_mach_arm_XScale;
e74cfd16 31095 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick))
fde78edd 31096 mach = bfd_mach_arm_ep9312;
e74cfd16 31097 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5e))
b99bd4ef 31098 mach = bfd_mach_arm_5TE;
e74cfd16 31099 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5))
b99bd4ef 31100 {
e74cfd16 31101 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
31102 mach = bfd_mach_arm_5T;
31103 else
31104 mach = bfd_mach_arm_5;
31105 }
e74cfd16 31106 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4))
b99bd4ef 31107 {
e74cfd16 31108 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
31109 mach = bfd_mach_arm_4T;
31110 else
31111 mach = bfd_mach_arm_4;
31112 }
e74cfd16 31113 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3m))
b99bd4ef 31114 mach = bfd_mach_arm_3M;
e74cfd16
PB
31115 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3))
31116 mach = bfd_mach_arm_3;
31117 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2s))
31118 mach = bfd_mach_arm_2a;
31119 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2))
31120 mach = bfd_mach_arm_2;
31121 else
31122 mach = bfd_mach_arm_unknown;
b99bd4ef
NC
31123
31124 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
31125}
31126
c19d1205 31127/* Command line processing. */
b99bd4ef 31128
c19d1205
ZW
31129/* md_parse_option
31130 Invocation line includes a switch not recognized by the base assembler.
31131 See if it's a processor-specific option.
b99bd4ef 31132
c19d1205
ZW
31133 This routine is somewhat complicated by the need for backwards
31134 compatibility (since older releases of gcc can't be changed).
31135 The new options try to make the interface as compatible as
31136 possible with GCC.
b99bd4ef 31137
c19d1205 31138 New options (supported) are:
b99bd4ef 31139
c19d1205
ZW
31140 -mcpu=<cpu name> Assemble for selected processor
31141 -march=<architecture name> Assemble for selected architecture
31142 -mfpu=<fpu architecture> Assemble for selected FPU.
31143 -EB/-mbig-endian Big-endian
31144 -EL/-mlittle-endian Little-endian
31145 -k Generate PIC code
31146 -mthumb Start in Thumb mode
31147 -mthumb-interwork Code supports ARM/Thumb interworking
b99bd4ef 31148
278df34e 31149 -m[no-]warn-deprecated Warn about deprecated features
8b2d793c 31150 -m[no-]warn-syms Warn when symbols match instructions
267bf995 31151
c19d1205 31152 For now we will also provide support for:
b99bd4ef 31153
c19d1205
ZW
31154 -mapcs-32 32-bit Program counter
31155 -mapcs-26 26-bit Program counter
31156 -macps-float Floats passed in FP registers
31157 -mapcs-reentrant Reentrant code
31158 -matpcs
31159 (sometime these will probably be replaced with -mapcs=<list of options>
31160 and -matpcs=<list of options>)
b99bd4ef 31161
c19d1205
ZW
31162 The remaining options are only supported for back-wards compatibility.
31163 Cpu variants, the arm part is optional:
31164 -m[arm]1 Currently not supported.
31165 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
31166 -m[arm]3 Arm 3 processor
31167 -m[arm]6[xx], Arm 6 processors
31168 -m[arm]7[xx][t][[d]m] Arm 7 processors
31169 -m[arm]8[10] Arm 8 processors
31170 -m[arm]9[20][tdmi] Arm 9 processors
31171 -mstrongarm[110[0]] StrongARM processors
31172 -mxscale XScale processors
31173 -m[arm]v[2345[t[e]]] Arm architectures
31174 -mall All (except the ARM1)
31175 FP variants:
31176 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
31177 -mfpe-old (No float load/store multiples)
31178 -mvfpxd VFP Single precision
31179 -mvfp All VFP
31180 -mno-fpu Disable all floating point instructions
b99bd4ef 31181
c19d1205
ZW
31182 The following CPU names are recognized:
31183 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
31184 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
31185 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
31186 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
31187 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
31188 arm10t arm10e, arm1020t, arm1020e, arm10200e,
31189 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
b99bd4ef 31190
c19d1205 31191 */
b99bd4ef 31192
c19d1205 31193const char * md_shortopts = "m:k";
b99bd4ef 31194
c19d1205
ZW
31195#ifdef ARM_BI_ENDIAN
31196#define OPTION_EB (OPTION_MD_BASE + 0)
31197#define OPTION_EL (OPTION_MD_BASE + 1)
b99bd4ef 31198#else
c19d1205
ZW
31199#if TARGET_BYTES_BIG_ENDIAN
31200#define OPTION_EB (OPTION_MD_BASE + 0)
b99bd4ef 31201#else
c19d1205
ZW
31202#define OPTION_EL (OPTION_MD_BASE + 1)
31203#endif
b99bd4ef 31204#endif
845b51d6 31205#define OPTION_FIX_V4BX (OPTION_MD_BASE + 2)
18a20338 31206#define OPTION_FDPIC (OPTION_MD_BASE + 3)
b99bd4ef 31207
c19d1205 31208struct option md_longopts[] =
b99bd4ef 31209{
c19d1205
ZW
31210#ifdef OPTION_EB
31211 {"EB", no_argument, NULL, OPTION_EB},
31212#endif
31213#ifdef OPTION_EL
31214 {"EL", no_argument, NULL, OPTION_EL},
b99bd4ef 31215#endif
845b51d6 31216 {"fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
18a20338
CL
31217#ifdef OBJ_ELF
31218 {"fdpic", no_argument, NULL, OPTION_FDPIC},
31219#endif
c19d1205
ZW
31220 {NULL, no_argument, NULL, 0}
31221};
b99bd4ef 31222
c19d1205 31223size_t md_longopts_size = sizeof (md_longopts);
b99bd4ef 31224
c19d1205 31225struct arm_option_table
b99bd4ef 31226{
0198d5e6
TC
31227 const char * option; /* Option name to match. */
31228 const char * help; /* Help information. */
31229 int * var; /* Variable to change. */
31230 int value; /* What to change it to. */
31231 const char * deprecated; /* If non-null, print this message. */
c19d1205 31232};
b99bd4ef 31233
c19d1205
ZW
31234struct arm_option_table arm_opts[] =
31235{
31236 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
31237 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
31238 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
31239 &support_interwork, 1, NULL},
31240 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
31241 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
31242 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
31243 1, NULL},
31244 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
31245 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
31246 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
31247 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
31248 NULL},
b99bd4ef 31249
c19d1205
ZW
31250 /* These are recognized by the assembler, but have no affect on code. */
31251 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
31252 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
278df34e
NS
31253
31254 {"mwarn-deprecated", NULL, &warn_on_deprecated, 1, NULL},
31255 {"mno-warn-deprecated", N_("do not warn on use of deprecated feature"),
31256 &warn_on_deprecated, 0, NULL},
24f19ccb
AV
31257
31258 {"mwarn-restrict-it", N_("warn about performance deprecated IT instructions"
31259 " in ARMv8-A and ARMv8-R"), &warn_on_restrict_it, 1, NULL},
31260 {"mno-warn-restrict-it", NULL, &warn_on_restrict_it, 0, NULL},
31261
5b7c81bd
AM
31262 {"mwarn-syms", N_("warn about symbols that match instruction names [default]"), (int *) (& flag_warn_syms), true, NULL},
31263 {"mno-warn-syms", N_("disable warnings about symobls that match instructions"), (int *) (& flag_warn_syms), false, NULL},
e74cfd16
PB
31264 {NULL, NULL, NULL, 0, NULL}
31265};
31266
31267struct arm_legacy_option_table
31268{
0198d5e6
TC
31269 const char * option; /* Option name to match. */
31270 const arm_feature_set ** var; /* Variable to change. */
31271 const arm_feature_set value; /* What to change it to. */
31272 const char * deprecated; /* If non-null, print this message. */
e74cfd16 31273};
b99bd4ef 31274
e74cfd16
PB
31275const struct arm_legacy_option_table arm_legacy_opts[] =
31276{
c19d1205
ZW
31277 /* DON'T add any new processors to this list -- we want the whole list
31278 to go away... Add them to the processors table instead. */
e74cfd16
PB
31279 {"marm1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
31280 {"m1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
31281 {"marm2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
31282 {"m2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
31283 {"marm250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
31284 {"m250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
31285 {"marm3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
31286 {"m3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
31287 {"marm6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
31288 {"m6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
31289 {"marm600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
31290 {"m600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
31291 {"marm610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
31292 {"m610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
31293 {"marm620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
31294 {"m620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
31295 {"marm7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
31296 {"m7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
31297 {"marm70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
31298 {"m70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
31299 {"marm700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
31300 {"m700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
31301 {"marm700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
31302 {"m700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
31303 {"marm710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
31304 {"m710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
31305 {"marm710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
31306 {"m710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
31307 {"marm720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
31308 {"m720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
31309 {"marm7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
31310 {"m7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
31311 {"marm7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
31312 {"m7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
31313 {"marm7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
31314 {"m7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
31315 {"marm7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
31316 {"m7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
31317 {"marm7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
31318 {"m7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
31319 {"marm7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
31320 {"m7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
31321 {"marm7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
31322 {"m7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
31323 {"marm7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
31324 {"m7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
31325 {"marm7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31326 {"m7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31327 {"marm7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31328 {"m7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31329 {"marm710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
31330 {"m710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
31331 {"marm720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
31332 {"m720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
31333 {"marm740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
31334 {"m740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
31335 {"marm8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
31336 {"m8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
31337 {"marm810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
31338 {"m810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
31339 {"marm9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
31340 {"m9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
31341 {"marm9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
31342 {"m9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
31343 {"marm920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
31344 {"m920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
31345 {"marm940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
31346 {"m940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
31347 {"mstrongarm", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
31348 {"mstrongarm110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31349 N_("use -mcpu=strongarm110")},
e74cfd16 31350 {"mstrongarm1100", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31351 N_("use -mcpu=strongarm1100")},
e74cfd16 31352 {"mstrongarm1110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31353 N_("use -mcpu=strongarm1110")},
e74cfd16
PB
31354 {"mxscale", &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
31355 {"miwmmxt", &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
31356 {"mall", &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
7ed4c4c5 31357
c19d1205 31358 /* Architecture variants -- don't add any more to this list either. */
e74cfd16
PB
31359 {"mv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
31360 {"marmv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
31361 {"mv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
31362 {"marmv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
31363 {"mv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
31364 {"marmv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
31365 {"mv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
31366 {"marmv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
31367 {"mv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
31368 {"marmv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
31369 {"mv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
31370 {"marmv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
31371 {"mv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
31372 {"marmv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
31373 {"mv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
31374 {"marmv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
31375 {"mv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
31376 {"marmv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
7ed4c4c5 31377
c19d1205 31378 /* Floating point variants -- don't add any more to this list either. */
0198d5e6
TC
31379 {"mfpe-old", &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
31380 {"mfpa10", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
31381 {"mfpa11", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
31382 {"mno-fpu", &legacy_fpu, ARM_ARCH_NONE,
c19d1205 31383 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
7ed4c4c5 31384
e74cfd16 31385 {NULL, NULL, ARM_ARCH_NONE, NULL}
c19d1205 31386};
7ed4c4c5 31387
c19d1205 31388struct arm_cpu_option_table
7ed4c4c5 31389{
0198d5e6
TC
31390 const char * name;
31391 size_t name_len;
31392 const arm_feature_set value;
31393 const arm_feature_set ext;
c19d1205
ZW
31394 /* For some CPUs we assume an FPU unless the user explicitly sets
31395 -mfpu=... */
0198d5e6 31396 const arm_feature_set default_fpu;
ee065d83
PB
31397 /* The canonical name of the CPU, or NULL to use NAME converted to upper
31398 case. */
0198d5e6 31399 const char * canonical_name;
c19d1205 31400};
7ed4c4c5 31401
c19d1205
ZW
31402/* This list should, at a minimum, contain all the cpu names
31403 recognized by GCC. */
996b5569 31404#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
0198d5e6 31405
e74cfd16 31406static const struct arm_cpu_option_table arm_cpus[] =
c19d1205 31407{
996b5569
TP
31408 ARM_CPU_OPT ("all", NULL, ARM_ANY,
31409 ARM_ARCH_NONE,
31410 FPU_ARCH_FPA),
31411 ARM_CPU_OPT ("arm1", NULL, ARM_ARCH_V1,
31412 ARM_ARCH_NONE,
31413 FPU_ARCH_FPA),
31414 ARM_CPU_OPT ("arm2", NULL, ARM_ARCH_V2,
31415 ARM_ARCH_NONE,
31416 FPU_ARCH_FPA),
31417 ARM_CPU_OPT ("arm250", NULL, ARM_ARCH_V2S,
31418 ARM_ARCH_NONE,
31419 FPU_ARCH_FPA),
31420 ARM_CPU_OPT ("arm3", NULL, ARM_ARCH_V2S,
31421 ARM_ARCH_NONE,
31422 FPU_ARCH_FPA),
31423 ARM_CPU_OPT ("arm6", NULL, ARM_ARCH_V3,
31424 ARM_ARCH_NONE,
31425 FPU_ARCH_FPA),
31426 ARM_CPU_OPT ("arm60", NULL, ARM_ARCH_V3,
31427 ARM_ARCH_NONE,
31428 FPU_ARCH_FPA),
31429 ARM_CPU_OPT ("arm600", NULL, ARM_ARCH_V3,
31430 ARM_ARCH_NONE,
31431 FPU_ARCH_FPA),
31432 ARM_CPU_OPT ("arm610", NULL, ARM_ARCH_V3,
31433 ARM_ARCH_NONE,
31434 FPU_ARCH_FPA),
31435 ARM_CPU_OPT ("arm620", NULL, ARM_ARCH_V3,
31436 ARM_ARCH_NONE,
31437 FPU_ARCH_FPA),
31438 ARM_CPU_OPT ("arm7", NULL, ARM_ARCH_V3,
31439 ARM_ARCH_NONE,
31440 FPU_ARCH_FPA),
31441 ARM_CPU_OPT ("arm7m", NULL, ARM_ARCH_V3M,
31442 ARM_ARCH_NONE,
31443 FPU_ARCH_FPA),
31444 ARM_CPU_OPT ("arm7d", NULL, ARM_ARCH_V3,
31445 ARM_ARCH_NONE,
31446 FPU_ARCH_FPA),
31447 ARM_CPU_OPT ("arm7dm", NULL, ARM_ARCH_V3M,
31448 ARM_ARCH_NONE,
31449 FPU_ARCH_FPA),
31450 ARM_CPU_OPT ("arm7di", NULL, ARM_ARCH_V3,
31451 ARM_ARCH_NONE,
31452 FPU_ARCH_FPA),
31453 ARM_CPU_OPT ("arm7dmi", NULL, ARM_ARCH_V3M,
31454 ARM_ARCH_NONE,
31455 FPU_ARCH_FPA),
31456 ARM_CPU_OPT ("arm70", NULL, ARM_ARCH_V3,
31457 ARM_ARCH_NONE,
31458 FPU_ARCH_FPA),
31459 ARM_CPU_OPT ("arm700", NULL, ARM_ARCH_V3,
31460 ARM_ARCH_NONE,
31461 FPU_ARCH_FPA),
31462 ARM_CPU_OPT ("arm700i", NULL, ARM_ARCH_V3,
31463 ARM_ARCH_NONE,
31464 FPU_ARCH_FPA),
31465 ARM_CPU_OPT ("arm710", NULL, ARM_ARCH_V3,
31466 ARM_ARCH_NONE,
31467 FPU_ARCH_FPA),
31468 ARM_CPU_OPT ("arm710t", NULL, ARM_ARCH_V4T,
31469 ARM_ARCH_NONE,
31470 FPU_ARCH_FPA),
31471 ARM_CPU_OPT ("arm720", NULL, ARM_ARCH_V3,
31472 ARM_ARCH_NONE,
31473 FPU_ARCH_FPA),
31474 ARM_CPU_OPT ("arm720t", NULL, ARM_ARCH_V4T,
31475 ARM_ARCH_NONE,
31476 FPU_ARCH_FPA),
31477 ARM_CPU_OPT ("arm740t", NULL, ARM_ARCH_V4T,
31478 ARM_ARCH_NONE,
31479 FPU_ARCH_FPA),
31480 ARM_CPU_OPT ("arm710c", NULL, ARM_ARCH_V3,
31481 ARM_ARCH_NONE,
31482 FPU_ARCH_FPA),
31483 ARM_CPU_OPT ("arm7100", NULL, ARM_ARCH_V3,
31484 ARM_ARCH_NONE,
31485 FPU_ARCH_FPA),
31486 ARM_CPU_OPT ("arm7500", NULL, ARM_ARCH_V3,
31487 ARM_ARCH_NONE,
31488 FPU_ARCH_FPA),
31489 ARM_CPU_OPT ("arm7500fe", NULL, ARM_ARCH_V3,
31490 ARM_ARCH_NONE,
31491 FPU_ARCH_FPA),
31492 ARM_CPU_OPT ("arm7t", NULL, ARM_ARCH_V4T,
31493 ARM_ARCH_NONE,
31494 FPU_ARCH_FPA),
31495 ARM_CPU_OPT ("arm7tdmi", NULL, ARM_ARCH_V4T,
31496 ARM_ARCH_NONE,
31497 FPU_ARCH_FPA),
31498 ARM_CPU_OPT ("arm7tdmi-s", NULL, ARM_ARCH_V4T,
31499 ARM_ARCH_NONE,
31500 FPU_ARCH_FPA),
31501 ARM_CPU_OPT ("arm8", NULL, ARM_ARCH_V4,
31502 ARM_ARCH_NONE,
31503 FPU_ARCH_FPA),
31504 ARM_CPU_OPT ("arm810", NULL, ARM_ARCH_V4,
31505 ARM_ARCH_NONE,
31506 FPU_ARCH_FPA),
31507 ARM_CPU_OPT ("strongarm", NULL, ARM_ARCH_V4,
31508 ARM_ARCH_NONE,
31509 FPU_ARCH_FPA),
31510 ARM_CPU_OPT ("strongarm1", NULL, ARM_ARCH_V4,
31511 ARM_ARCH_NONE,
31512 FPU_ARCH_FPA),
31513 ARM_CPU_OPT ("strongarm110", NULL, ARM_ARCH_V4,
31514 ARM_ARCH_NONE,
31515 FPU_ARCH_FPA),
31516 ARM_CPU_OPT ("strongarm1100", NULL, ARM_ARCH_V4,
31517 ARM_ARCH_NONE,
31518 FPU_ARCH_FPA),
31519 ARM_CPU_OPT ("strongarm1110", NULL, ARM_ARCH_V4,
31520 ARM_ARCH_NONE,
31521 FPU_ARCH_FPA),
31522 ARM_CPU_OPT ("arm9", NULL, ARM_ARCH_V4T,
31523 ARM_ARCH_NONE,
31524 FPU_ARCH_FPA),
31525 ARM_CPU_OPT ("arm920", "ARM920T", ARM_ARCH_V4T,
31526 ARM_ARCH_NONE,
31527 FPU_ARCH_FPA),
31528 ARM_CPU_OPT ("arm920t", NULL, ARM_ARCH_V4T,
31529 ARM_ARCH_NONE,
31530 FPU_ARCH_FPA),
31531 ARM_CPU_OPT ("arm922t", NULL, ARM_ARCH_V4T,
31532 ARM_ARCH_NONE,
31533 FPU_ARCH_FPA),
31534 ARM_CPU_OPT ("arm940t", NULL, ARM_ARCH_V4T,
31535 ARM_ARCH_NONE,
31536 FPU_ARCH_FPA),
31537 ARM_CPU_OPT ("arm9tdmi", NULL, ARM_ARCH_V4T,
31538 ARM_ARCH_NONE,
31539 FPU_ARCH_FPA),
31540 ARM_CPU_OPT ("fa526", NULL, ARM_ARCH_V4,
31541 ARM_ARCH_NONE,
31542 FPU_ARCH_FPA),
31543 ARM_CPU_OPT ("fa626", NULL, ARM_ARCH_V4,
31544 ARM_ARCH_NONE,
31545 FPU_ARCH_FPA),
31546
c19d1205
ZW
31547 /* For V5 or later processors we default to using VFP; but the user
31548 should really set the FPU type explicitly. */
996b5569
TP
31549 ARM_CPU_OPT ("arm9e-r0", NULL, ARM_ARCH_V5TExP,
31550 ARM_ARCH_NONE,
31551 FPU_ARCH_VFP_V2),
31552 ARM_CPU_OPT ("arm9e", NULL, ARM_ARCH_V5TE,
31553 ARM_ARCH_NONE,
31554 FPU_ARCH_VFP_V2),
31555 ARM_CPU_OPT ("arm926ej", "ARM926EJ-S", ARM_ARCH_V5TEJ,
31556 ARM_ARCH_NONE,
31557 FPU_ARCH_VFP_V2),
31558 ARM_CPU_OPT ("arm926ejs", "ARM926EJ-S", ARM_ARCH_V5TEJ,
31559 ARM_ARCH_NONE,
31560 FPU_ARCH_VFP_V2),
31561 ARM_CPU_OPT ("arm926ej-s", NULL, ARM_ARCH_V5TEJ,
31562 ARM_ARCH_NONE,
31563 FPU_ARCH_VFP_V2),
31564 ARM_CPU_OPT ("arm946e-r0", NULL, ARM_ARCH_V5TExP,
31565 ARM_ARCH_NONE,
31566 FPU_ARCH_VFP_V2),
31567 ARM_CPU_OPT ("arm946e", "ARM946E-S", ARM_ARCH_V5TE,
31568 ARM_ARCH_NONE,
31569 FPU_ARCH_VFP_V2),
31570 ARM_CPU_OPT ("arm946e-s", NULL, ARM_ARCH_V5TE,
31571 ARM_ARCH_NONE,
31572 FPU_ARCH_VFP_V2),
31573 ARM_CPU_OPT ("arm966e-r0", NULL, ARM_ARCH_V5TExP,
31574 ARM_ARCH_NONE,
31575 FPU_ARCH_VFP_V2),
31576 ARM_CPU_OPT ("arm966e", "ARM966E-S", ARM_ARCH_V5TE,
31577 ARM_ARCH_NONE,
31578 FPU_ARCH_VFP_V2),
31579 ARM_CPU_OPT ("arm966e-s", NULL, ARM_ARCH_V5TE,
31580 ARM_ARCH_NONE,
31581 FPU_ARCH_VFP_V2),
31582 ARM_CPU_OPT ("arm968e-s", NULL, ARM_ARCH_V5TE,
31583 ARM_ARCH_NONE,
31584 FPU_ARCH_VFP_V2),
31585 ARM_CPU_OPT ("arm10t", NULL, ARM_ARCH_V5T,
31586 ARM_ARCH_NONE,
31587 FPU_ARCH_VFP_V1),
31588 ARM_CPU_OPT ("arm10tdmi", NULL, ARM_ARCH_V5T,
31589 ARM_ARCH_NONE,
31590 FPU_ARCH_VFP_V1),
31591 ARM_CPU_OPT ("arm10e", NULL, ARM_ARCH_V5TE,
31592 ARM_ARCH_NONE,
31593 FPU_ARCH_VFP_V2),
31594 ARM_CPU_OPT ("arm1020", "ARM1020E", ARM_ARCH_V5TE,
31595 ARM_ARCH_NONE,
31596 FPU_ARCH_VFP_V2),
31597 ARM_CPU_OPT ("arm1020t", NULL, ARM_ARCH_V5T,
31598 ARM_ARCH_NONE,
31599 FPU_ARCH_VFP_V1),
31600 ARM_CPU_OPT ("arm1020e", NULL, ARM_ARCH_V5TE,
31601 ARM_ARCH_NONE,
31602 FPU_ARCH_VFP_V2),
31603 ARM_CPU_OPT ("arm1022e", NULL, ARM_ARCH_V5TE,
31604 ARM_ARCH_NONE,
31605 FPU_ARCH_VFP_V2),
31606 ARM_CPU_OPT ("arm1026ejs", "ARM1026EJ-S", ARM_ARCH_V5TEJ,
31607 ARM_ARCH_NONE,
31608 FPU_ARCH_VFP_V2),
31609 ARM_CPU_OPT ("arm1026ej-s", NULL, ARM_ARCH_V5TEJ,
31610 ARM_ARCH_NONE,
31611 FPU_ARCH_VFP_V2),
31612 ARM_CPU_OPT ("fa606te", NULL, ARM_ARCH_V5TE,
31613 ARM_ARCH_NONE,
31614 FPU_ARCH_VFP_V2),
31615 ARM_CPU_OPT ("fa616te", NULL, ARM_ARCH_V5TE,
31616 ARM_ARCH_NONE,
31617 FPU_ARCH_VFP_V2),
31618 ARM_CPU_OPT ("fa626te", NULL, ARM_ARCH_V5TE,
31619 ARM_ARCH_NONE,
31620 FPU_ARCH_VFP_V2),
31621 ARM_CPU_OPT ("fmp626", NULL, ARM_ARCH_V5TE,
31622 ARM_ARCH_NONE,
31623 FPU_ARCH_VFP_V2),
31624 ARM_CPU_OPT ("fa726te", NULL, ARM_ARCH_V5TE,
31625 ARM_ARCH_NONE,
31626 FPU_ARCH_VFP_V2),
31627 ARM_CPU_OPT ("arm1136js", "ARM1136J-S", ARM_ARCH_V6,
31628 ARM_ARCH_NONE,
31629 FPU_NONE),
31630 ARM_CPU_OPT ("arm1136j-s", NULL, ARM_ARCH_V6,
31631 ARM_ARCH_NONE,
31632 FPU_NONE),
31633 ARM_CPU_OPT ("arm1136jfs", "ARM1136JF-S", ARM_ARCH_V6,
31634 ARM_ARCH_NONE,
31635 FPU_ARCH_VFP_V2),
31636 ARM_CPU_OPT ("arm1136jf-s", NULL, ARM_ARCH_V6,
31637 ARM_ARCH_NONE,
31638 FPU_ARCH_VFP_V2),
31639 ARM_CPU_OPT ("mpcore", "MPCore", ARM_ARCH_V6K,
31640 ARM_ARCH_NONE,
31641 FPU_ARCH_VFP_V2),
31642 ARM_CPU_OPT ("mpcorenovfp", "MPCore", ARM_ARCH_V6K,
31643 ARM_ARCH_NONE,
31644 FPU_NONE),
31645 ARM_CPU_OPT ("arm1156t2-s", NULL, ARM_ARCH_V6T2,
31646 ARM_ARCH_NONE,
31647 FPU_NONE),
31648 ARM_CPU_OPT ("arm1156t2f-s", NULL, ARM_ARCH_V6T2,
31649 ARM_ARCH_NONE,
31650 FPU_ARCH_VFP_V2),
31651 ARM_CPU_OPT ("arm1176jz-s", NULL, ARM_ARCH_V6KZ,
31652 ARM_ARCH_NONE,
31653 FPU_NONE),
31654 ARM_CPU_OPT ("arm1176jzf-s", NULL, ARM_ARCH_V6KZ,
31655 ARM_ARCH_NONE,
31656 FPU_ARCH_VFP_V2),
31657 ARM_CPU_OPT ("cortex-a5", "Cortex-A5", ARM_ARCH_V7A,
31658 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31659 FPU_NONE),
31660 ARM_CPU_OPT ("cortex-a7", "Cortex-A7", ARM_ARCH_V7VE,
31661 ARM_ARCH_NONE,
31662 FPU_ARCH_NEON_VFP_V4),
31663 ARM_CPU_OPT ("cortex-a8", "Cortex-A8", ARM_ARCH_V7A,
31664 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
31665 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
31666 ARM_CPU_OPT ("cortex-a9", "Cortex-A9", ARM_ARCH_V7A,
31667 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31668 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
31669 ARM_CPU_OPT ("cortex-a12", "Cortex-A12", ARM_ARCH_V7VE,
31670 ARM_ARCH_NONE,
31671 FPU_ARCH_NEON_VFP_V4),
31672 ARM_CPU_OPT ("cortex-a15", "Cortex-A15", ARM_ARCH_V7VE,
31673 ARM_ARCH_NONE,
31674 FPU_ARCH_NEON_VFP_V4),
31675 ARM_CPU_OPT ("cortex-a17", "Cortex-A17", ARM_ARCH_V7VE,
31676 ARM_ARCH_NONE,
31677 FPU_ARCH_NEON_VFP_V4),
31678 ARM_CPU_OPT ("cortex-a32", "Cortex-A32", ARM_ARCH_V8A,
8b301fbb 31679 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31680 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31681 ARM_CPU_OPT ("cortex-a35", "Cortex-A35", ARM_ARCH_V8A,
8b301fbb 31682 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31683 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31684 ARM_CPU_OPT ("cortex-a53", "Cortex-A53", ARM_ARCH_V8A,
8b301fbb 31685 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31686 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
31687 ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A,
31688 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 31689 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569 31690 ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A,
8b301fbb 31691 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31692 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31693 ARM_CPU_OPT ("cortex-a72", "Cortex-A72", ARM_ARCH_V8A,
8b301fbb 31694 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31695 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31696 ARM_CPU_OPT ("cortex-a73", "Cortex-A73", ARM_ARCH_V8A,
8b301fbb 31697 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31698 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
31699 ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A,
31700 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 31701 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
7ebd1359 31702 ARM_CPU_OPT ("cortex-a76", "Cortex-A76", ARM_ARCH_V8_2A,
31703 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31704 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
0535e5d7
DZ
31705 ARM_CPU_OPT ("cortex-a76ae", "Cortex-A76AE", ARM_ARCH_V8_2A,
31706 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31707 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
31708 ARM_CPU_OPT ("cortex-a77", "Cortex-A77", ARM_ARCH_V8_2A,
31709 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31710 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
42c36b73
PW
31711 ARM_CPU_OPT ("cortex-a78", "Cortex-A78", ARM_ARCH_V8_2A,
31712 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
31713 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31714 ARM_CPU_OPT ("cortex-a78ae", "Cortex-A78AE", ARM_ARCH_V8_2A,
31715 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
31716 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
1bbda94f
PW
31717 ARM_CPU_OPT ("cortex-a78c", "Cortex-A78C", ARM_ARCH_V8_2A,
31718 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
31719 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
14f45859
PW
31720 ARM_CPU_OPT ("cortex-a710", "Cortex-A710", ARM_ARCH_V9A,
31721 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
31722 | ARM_EXT2_BF16
31723 | ARM_EXT2_I8MM),
31724 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
ef8df4ca
KT
31725 ARM_CPU_OPT ("ares", "Ares", ARM_ARCH_V8_2A,
31726 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31727 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
31728 ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R,
31729 ARM_ARCH_NONE,
31730 FPU_NONE),
31731 ARM_CPU_OPT ("cortex-r4f", "Cortex-R4F", ARM_ARCH_V7R,
31732 ARM_ARCH_NONE,
31733 FPU_ARCH_VFP_V3D16),
31734 ARM_CPU_OPT ("cortex-r5", "Cortex-R5", ARM_ARCH_V7R,
31735 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31736 FPU_NONE),
31737 ARM_CPU_OPT ("cortex-r7", "Cortex-R7", ARM_ARCH_V7R,
31738 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31739 FPU_ARCH_VFP_V3D16),
31740 ARM_CPU_OPT ("cortex-r8", "Cortex-R8", ARM_ARCH_V7R,
31741 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31742 FPU_ARCH_VFP_V3D16),
0cda1e19 31743 ARM_CPU_OPT ("cortex-r52", "Cortex-R52", ARM_ARCH_V8R,
8b301fbb 31744 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
0cda1e19 31745 FPU_ARCH_NEON_VFP_ARMV8),
80cfde76
PW
31746 ARM_CPU_OPT ("cortex-r52plus", "Cortex-R52+", ARM_ARCH_V8R,
31747 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
31748 FPU_ARCH_NEON_VFP_ARMV8),
0535e5d7
DZ
31749 ARM_CPU_OPT ("cortex-m35p", "Cortex-M35P", ARM_ARCH_V8M_MAIN,
31750 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
31751 FPU_NONE),
996b5569
TP
31752 ARM_CPU_OPT ("cortex-m33", "Cortex-M33", ARM_ARCH_V8M_MAIN,
31753 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
31754 FPU_NONE),
31755 ARM_CPU_OPT ("cortex-m23", "Cortex-M23", ARM_ARCH_V8M_BASE,
31756 ARM_ARCH_NONE,
31757 FPU_NONE),
31758 ARM_CPU_OPT ("cortex-m7", "Cortex-M7", ARM_ARCH_V7EM,
31759 ARM_ARCH_NONE,
31760 FPU_NONE),
31761 ARM_CPU_OPT ("cortex-m4", "Cortex-M4", ARM_ARCH_V7EM,
31762 ARM_ARCH_NONE,
31763 FPU_NONE),
31764 ARM_CPU_OPT ("cortex-m3", "Cortex-M3", ARM_ARCH_V7M,
31765 ARM_ARCH_NONE,
31766 FPU_NONE),
31767 ARM_CPU_OPT ("cortex-m1", "Cortex-M1", ARM_ARCH_V6SM,
31768 ARM_ARCH_NONE,
31769 FPU_NONE),
31770 ARM_CPU_OPT ("cortex-m0", "Cortex-M0", ARM_ARCH_V6SM,
31771 ARM_ARCH_NONE,
31772 FPU_NONE),
31773 ARM_CPU_OPT ("cortex-m0plus", "Cortex-M0+", ARM_ARCH_V6SM,
31774 ARM_ARCH_NONE,
31775 FPU_NONE),
394e9bf6 31776 ARM_CPU_OPT ("cortex-x1", "Cortex-X1", ARM_ARCH_V8_2A,
a417e439 31777 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
394e9bf6 31778 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
cafdb713
SP
31779 ARM_CPU_OPT ("cortex-x1c", "Cortex-X1C", ARM_ARCH_V8_2A,
31780 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
31781 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
996b5569 31782 ARM_CPU_OPT ("exynos-m1", "Samsung Exynos M1", ARM_ARCH_V8A,
8b301fbb 31783 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31784 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
83f43c83
KT
31785 ARM_CPU_OPT ("neoverse-n1", "Neoverse N1", ARM_ARCH_V8_2A,
31786 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31787 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
f3034e25
AC
31788 ARM_CPU_OPT ("neoverse-n2", "Neoverse N2", ARM_ARCH_V8_5A,
31789 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
31790 | ARM_EXT2_BF16
31791 | ARM_EXT2_I8MM),
31792 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4),
6eee0315 31793 ARM_CPU_OPT ("neoverse-v1", "Neoverse V1", ARM_ARCH_V8_4A,
9bede61c
AC
31794 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
31795 | ARM_EXT2_BF16
31796 | ARM_EXT2_I8MM),
6eee0315 31797 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4),
c19d1205 31798 /* ??? XSCALE is really an architecture. */
996b5569
TP
31799 ARM_CPU_OPT ("xscale", NULL, ARM_ARCH_XSCALE,
31800 ARM_ARCH_NONE,
31801 FPU_ARCH_VFP_V2),
31802
c19d1205 31803 /* ??? iwmmxt is not a processor. */
996b5569
TP
31804 ARM_CPU_OPT ("iwmmxt", NULL, ARM_ARCH_IWMMXT,
31805 ARM_ARCH_NONE,
31806 FPU_ARCH_VFP_V2),
31807 ARM_CPU_OPT ("iwmmxt2", NULL, ARM_ARCH_IWMMXT2,
31808 ARM_ARCH_NONE,
31809 FPU_ARCH_VFP_V2),
31810 ARM_CPU_OPT ("i80200", NULL, ARM_ARCH_XSCALE,
31811 ARM_ARCH_NONE,
31812 FPU_ARCH_VFP_V2),
31813
0198d5e6 31814 /* Maverick. */
996b5569
TP
31815 ARM_CPU_OPT ("ep9312", "ARM920T",
31816 ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
31817 ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
31818
da4339ed 31819 /* Marvell processors. */
996b5569
TP
31820 ARM_CPU_OPT ("marvell-pj4", NULL, ARM_ARCH_V7A,
31821 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31822 FPU_ARCH_VFP_V3D16),
31823 ARM_CPU_OPT ("marvell-whitney", NULL, ARM_ARCH_V7A,
31824 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31825 FPU_ARCH_NEON_VFP_V4),
da4339ed 31826
996b5569
TP
31827 /* APM X-Gene family. */
31828 ARM_CPU_OPT ("xgene1", "APM X-Gene 1", ARM_ARCH_V8A,
31829 ARM_ARCH_NONE,
31830 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31831 ARM_CPU_OPT ("xgene2", "APM X-Gene 2", ARM_ARCH_V8A,
8b301fbb 31832 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31833 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31834
31835 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 31836};
f3bad469 31837#undef ARM_CPU_OPT
7ed4c4c5 31838
34ef62f4
AV
31839struct arm_ext_table
31840{
31841 const char * name;
31842 size_t name_len;
31843 const arm_feature_set merge;
31844 const arm_feature_set clear;
31845};
31846
c19d1205 31847struct arm_arch_option_table
7ed4c4c5 31848{
34ef62f4
AV
31849 const char * name;
31850 size_t name_len;
31851 const arm_feature_set value;
31852 const arm_feature_set default_fpu;
31853 const struct arm_ext_table * ext_table;
31854};
31855
31856/* Used to add support for +E and +noE extension. */
31857#define ARM_EXT(E, M, C) { E, sizeof (E) - 1, M, C }
31858/* Used to add support for a +E extension. */
31859#define ARM_ADD(E, M) { E, sizeof(E) - 1, M, ARM_ARCH_NONE }
31860/* Used to add support for a +noE extension. */
31861#define ARM_REMOVE(E, C) { E, sizeof(E) -1, ARM_ARCH_NONE, C }
31862
31863#define ALL_FP ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_FP16_FML, \
31864 ~0 & ~FPU_ENDIAN_PURE)
31865
31866static const struct arm_ext_table armv5te_ext_table[] =
31867{
31868 ARM_EXT ("fp", FPU_ARCH_VFP_V2, ALL_FP),
31869 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31870};
31871
31872static const struct arm_ext_table armv7_ext_table[] =
31873{
31874 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31875 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31876};
31877
31878static const struct arm_ext_table armv7ve_ext_table[] =
31879{
31880 ARM_EXT ("fp", FPU_ARCH_VFP_V4D16, ALL_FP),
31881 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16),
31882 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
31883 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31884 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
31885 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), /* Alias for +fp. */
31886 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
31887
31888 ARM_EXT ("simd", FPU_ARCH_NEON_VFP_V4,
31889 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
31890
31891 /* Aliases for +simd. */
31892 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
31893
31894 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31895 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31896 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
31897
31898 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31899};
31900
31901static const struct arm_ext_table armv7a_ext_table[] =
31902{
31903 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31904 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
31905 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
31906 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31907 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
31908 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16),
31909 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
31910
31911 ARM_EXT ("simd", FPU_ARCH_VFP_V3_PLUS_NEON_V1,
31912 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
31913
31914 /* Aliases for +simd. */
31915 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31916 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31917
31918 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
31919 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
31920
31921 ARM_ADD ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP)),
31922 ARM_ADD ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC)),
31923 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31924};
31925
31926static const struct arm_ext_table armv7r_ext_table[] =
31927{
31928 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V3xD),
31929 ARM_ADD ("vfpv3xd", FPU_ARCH_VFP_V3xD), /* Alias for +fp.sp. */
31930 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31931 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
31932 ARM_ADD ("vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16),
31933 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31934 ARM_EXT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
31935 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV)),
31936 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31937};
31938
31939static const struct arm_ext_table armv7em_ext_table[] =
31940{
31941 ARM_EXT ("fp", FPU_ARCH_VFP_V4_SP_D16, ALL_FP),
31942 /* Alias for +fp, used to be known as fpv4-sp-d16. */
31943 ARM_ADD ("vfpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16),
31944 ARM_ADD ("fpv5", FPU_ARCH_VFP_V5_SP_D16),
31945 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
31946 ARM_ADD ("fpv5-d16", FPU_ARCH_VFP_V5D16),
31947 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31948};
31949
31950static const struct arm_ext_table armv8a_ext_table[] =
31951{
8b301fbb 31952 ARM_ADD ("crc", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC)),
34ef62f4
AV
31953 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
31954 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
31955 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31956
31957 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31958 should use the +simd option to turn on FP. */
31959 ARM_REMOVE ("fp", ALL_FP),
31960 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31961 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31962 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31963};
31964
31965
31966static const struct arm_ext_table armv81a_ext_table[] =
31967{
31968 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
31969 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
31970 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31971
31972 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31973 should use the +simd option to turn on FP. */
31974 ARM_REMOVE ("fp", ALL_FP),
31975 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31976 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31977 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31978};
31979
31980static const struct arm_ext_table armv82a_ext_table[] =
31981{
31982 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
31983 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_2_FP16),
31984 ARM_ADD ("fp16fml", FPU_ARCH_NEON_VFP_ARMV8_2_FP16FML),
616ce08e
MM
31985 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
31986 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
31987 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
31988 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31989 ARM_ADD ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31990
31991 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31992 should use the +simd option to turn on FP. */
31993 ARM_REMOVE ("fp", ALL_FP),
31994 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31995 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31996 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31997};
31998
31999static const struct arm_ext_table armv84a_ext_table[] =
32000{
32001 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
32002 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
616ce08e
MM
32003 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
32004 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
32005 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
32006 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
32007
32008 /* Armv8-a does not allow an FP implementation without SIMD, so the user
32009 should use the +simd option to turn on FP. */
32010 ARM_REMOVE ("fp", ALL_FP),
32011 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
32012 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
32013 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32014};
32015
32016static const struct arm_ext_table armv85a_ext_table[] =
32017{
32018 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
32019 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
616ce08e
MM
32020 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
32021 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
32022 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
32023 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
32024
32025 /* Armv8-a does not allow an FP implementation without SIMD, so the user
32026 should use the +simd option to turn on FP. */
32027 ARM_REMOVE ("fp", ALL_FP),
32028 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32029};
32030
aab2c27d
MM
32031static const struct arm_ext_table armv86a_ext_table[] =
32032{
616ce08e 32033 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
aab2c27d
MM
32034 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32035};
32036
b3e4d932
RS
32037#define armv87a_ext_table armv86a_ext_table
32038#define armv88a_ext_table armv87a_ext_table
32039
3197e593
PW
32040static const struct arm_ext_table armv9a_ext_table[] =
32041{
32042 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
32043 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
32044 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
32045 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
32046 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
32047 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
32048
32049 /* Armv9-a does not allow an FP implementation without SIMD, so the user
32050 should use the +simd option to turn on FP. */
32051 ARM_REMOVE ("fp", ALL_FP),
32052 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32053};
32054
a2b1ea81
RS
32055#define armv91a_ext_table armv86a_ext_table
32056#define armv92a_ext_table armv91a_ext_table
32057#define armv93a_ext_table armv92a_ext_table
32058
4934a27c
MM
32059#define CDE_EXTENSIONS \
32060 ARM_ADD ("cdecp0", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE0)), \
32061 ARM_ADD ("cdecp1", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE1)), \
32062 ARM_ADD ("cdecp2", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE2)), \
32063 ARM_ADD ("cdecp3", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE3)), \
32064 ARM_ADD ("cdecp4", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE4)), \
32065 ARM_ADD ("cdecp5", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE5)), \
32066 ARM_ADD ("cdecp6", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE6)), \
32067 ARM_ADD ("cdecp7", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE7))
32068
34ef62f4
AV
32069static const struct arm_ext_table armv8m_main_ext_table[] =
32070{
92169145
AV
32071 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP),
32072 ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP)),
34ef62f4
AV
32073 ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP),
32074 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
4934a27c 32075 CDE_EXTENSIONS,
34ef62f4
AV
32076 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32077};
32078
92169145 32079
e0991585
AV
32080static const struct arm_ext_table armv8_1m_main_ext_table[] =
32081{
92169145
AV
32082 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP),
32083 ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP)),
e0991585
AV
32084 ARM_EXT ("fp",
32085 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
32086 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA),
32087 ALL_FP),
32088 ARM_ADD ("fp.dp",
32089 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
32090 FPU_VFP_V5D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
92169145 32091 ARM_EXT ("mve", ARM_FEATURE (ARM_AEXT_V8M_MAIN_DSP, ARM_EXT2_MVE, 0),
2da2eaf4 32092 ARM_FEATURE_CORE_HIGH (ARM_EXT2_MVE | ARM_EXT2_MVE_FP)),
a7ad558c 32093 ARM_ADD ("mve.fp",
92169145
AV
32094 ARM_FEATURE (ARM_AEXT_V8M_MAIN_DSP,
32095 ARM_EXT2_FP16_INST | ARM_EXT2_MVE | ARM_EXT2_MVE_FP,
2da2eaf4 32096 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
4934a27c 32097 CDE_EXTENSIONS,
5a0c7a81 32098 ARM_ADD ("pacbti", ARM_FEATURE_CORE_HIGH_HIGH (ARM_AEXT3_V8_1M_MAIN_PACBTI)),
e0991585
AV
32099 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32100};
32101
4934a27c
MM
32102#undef CDE_EXTENSIONS
32103
34ef62f4
AV
32104static const struct arm_ext_table armv8r_ext_table[] =
32105{
8b301fbb 32106 ARM_ADD ("crc", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC)),
34ef62f4
AV
32107 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
32108 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
32109 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
32110 ARM_REMOVE ("fp", ALL_FP),
32111 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V5_SP_D16),
32112 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
c19d1205 32113};
7ed4c4c5 32114
c19d1205
ZW
32115/* This list should, at a minimum, contain all the architecture names
32116 recognized by GCC. */
34ef62f4
AV
32117#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF, NULL }
32118#define ARM_ARCH_OPT2(N, V, DF, ext) \
32119 { N, sizeof (N) - 1, V, DF, ext##_ext_table }
0198d5e6 32120
e74cfd16 32121static const struct arm_arch_option_table arm_archs[] =
c19d1205 32122{
497d849d
TP
32123 ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
32124 ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
32125 ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
32126 ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
32127 ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
32128 ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
32129 ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
32130 ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
32131 ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
32132 ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
32133 ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
32134 ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
32135 ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
32136 ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
34ef62f4
AV
32137 ARM_ARCH_OPT2 ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP, armv5te),
32138 ARM_ARCH_OPT2 ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP, armv5te),
32139 ARM_ARCH_OPT2 ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP, armv5te),
32140 ARM_ARCH_OPT2 ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
32141 ARM_ARCH_OPT2 ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
32142 ARM_ARCH_OPT2 ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP, armv5te),
32143 ARM_ARCH_OPT2 ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP, armv5te),
f33026a9
MW
32144 /* The official spelling of this variant is ARMv6KZ, the name "armv6zk" is
32145 kept to preserve existing behaviour. */
34ef62f4
AV
32146 ARM_ARCH_OPT2 ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
32147 ARM_ARCH_OPT2 ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
32148 ARM_ARCH_OPT2 ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP, armv5te),
32149 ARM_ARCH_OPT2 ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP, armv5te),
32150 ARM_ARCH_OPT2 ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP, armv5te),
f33026a9
MW
32151 /* The official spelling of this variant is ARMv6KZ, the name "armv6zkt2" is
32152 kept to preserve existing behaviour. */
34ef62f4
AV
32153 ARM_ARCH_OPT2 ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
32154 ARM_ARCH_OPT2 ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
497d849d
TP
32155 ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
32156 ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
34ef62f4 32157 ARM_ARCH_OPT2 ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP, armv7),
c450d570
PB
32158 /* The official spelling of the ARMv7 profile variants is the dashed form.
32159 Accept the non-dashed form for compatibility with old toolchains. */
34ef62f4
AV
32160 ARM_ARCH_OPT2 ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
32161 ARM_ARCH_OPT2 ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP, armv7ve),
32162 ARM_ARCH_OPT2 ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 32163 ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4
AV
32164 ARM_ARCH_OPT2 ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
32165 ARM_ARCH_OPT2 ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 32166 ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4 32167 ARM_ARCH_OPT2 ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP, armv7em),
497d849d 32168 ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP),
34ef62f4
AV
32169 ARM_ARCH_OPT2 ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP,
32170 armv8m_main),
e0991585
AV
32171 ARM_ARCH_OPT2 ("armv8.1-m.main", ARM_ARCH_V8_1M_MAIN, FPU_ARCH_VFP,
32172 armv8_1m_main),
34ef62f4
AV
32173 ARM_ARCH_OPT2 ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP, armv8a),
32174 ARM_ARCH_OPT2 ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP, armv81a),
32175 ARM_ARCH_OPT2 ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP, armv82a),
32176 ARM_ARCH_OPT2 ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP, armv82a),
32177 ARM_ARCH_OPT2 ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP, armv8r),
32178 ARM_ARCH_OPT2 ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP, armv84a),
32179 ARM_ARCH_OPT2 ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP, armv85a),
aab2c27d 32180 ARM_ARCH_OPT2 ("armv8.6-a", ARM_ARCH_V8_6A, FPU_ARCH_VFP, armv86a),
b3e4d932
RS
32181 ARM_ARCH_OPT2 ("armv8.7-a", ARM_ARCH_V8_7A, FPU_ARCH_VFP, armv87a),
32182 ARM_ARCH_OPT2 ("armv8.8-a", ARM_ARCH_V8_8A, FPU_ARCH_VFP, armv88a),
a2b1ea81
RS
32183 ARM_ARCH_OPT2 ("armv9-a", ARM_ARCH_V9A, FPU_ARCH_VFP, armv9a),
32184 ARM_ARCH_OPT2 ("armv9.1-a", ARM_ARCH_V9_1A, FPU_ARCH_VFP, armv91a),
32185 ARM_ARCH_OPT2 ("armv9.2-a", ARM_ARCH_V9_2A, FPU_ARCH_VFP, armv92a),
32186 ARM_ARCH_OPT2 ("armv9.3-a", ARM_ARCH_V9_2A, FPU_ARCH_VFP, armv93a),
497d849d
TP
32187 ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
32188 ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
32189 ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP),
34ef62f4 32190 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 32191};
f3bad469 32192#undef ARM_ARCH_OPT
7ed4c4c5 32193
69133863 32194/* ISA extensions in the co-processor and main instruction set space. */
0198d5e6 32195
69133863 32196struct arm_option_extension_value_table
c19d1205 32197{
0198d5e6
TC
32198 const char * name;
32199 size_t name_len;
32200 const arm_feature_set merge_value;
32201 const arm_feature_set clear_value;
d942732e
TP
32202 /* List of architectures for which an extension is available. ARM_ARCH_NONE
32203 indicates that an extension is available for all architectures while
32204 ARM_ANY marks an empty entry. */
0198d5e6 32205 const arm_feature_set allowed_archs[2];
c19d1205 32206};
7ed4c4c5 32207
0198d5e6
TC
32208/* The following table must be in alphabetical order with a NULL last entry. */
32209
d942732e
TP
32210#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
32211#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
0198d5e6 32212
34ef62f4
AV
32213/* DEPRECATED: Refrain from using this table to add any new extensions, instead
32214 use the context sensitive approach using arm_ext_table's. */
69133863 32215static const struct arm_option_extension_value_table arm_extensions[] =
c19d1205 32216{
8b301fbb
MI
32217 ARM_EXT_OPT ("crc", ARM_FEATURE_CORE_HIGH(ARM_EXT2_CRC),
32218 ARM_FEATURE_CORE_HIGH(ARM_EXT2_CRC),
823d2571 32219 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
bca38921 32220 ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
823d2571
TG
32221 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
32222 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
c604a79a
JW
32223 ARM_EXT_OPT ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8,
32224 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
32225 ARM_ARCH_V8_2A),
15afaa63
TP
32226 ARM_EXT_OPT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
32227 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
32228 ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
823d2571
TG
32229 ARM_EXT_OPT ("fp", FPU_ARCH_VFP_ARMV8, ARM_FEATURE_COPROC (FPU_VFP_ARMV8),
32230 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
b8ec4e87
JW
32231 ARM_EXT_OPT ("fp16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
32232 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
32233 ARM_ARCH_V8_2A),
01f48020
TC
32234 ARM_EXT_OPT ("fp16fml", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
32235 | ARM_EXT2_FP16_FML),
32236 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
32237 | ARM_EXT2_FP16_FML),
32238 ARM_ARCH_V8_2A),
d942732e 32239 ARM_EXT_OPT2 ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
823d2571 32240 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
d942732e
TP
32241 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
32242 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
3d030cdb
TP
32243 /* Duplicate entry for the purpose of allowing ARMv7 to match in presence of
32244 Thumb divide instruction. Due to this having the same name as the
32245 previous entry, this will be ignored when doing command-line parsing and
32246 only considered by build attribute selection code. */
32247 ARM_EXT_OPT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
32248 ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
32249 ARM_FEATURE_CORE_LOW (ARM_EXT_V7)),
823d2571 32250 ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
d942732e 32251 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
823d2571 32252 ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
d942732e 32253 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ARCH_NONE),
823d2571 32254 ARM_EXT_OPT ("maverick", ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK),
d942732e
TP
32255 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ARCH_NONE),
32256 ARM_EXT_OPT2 ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
823d2571 32257 ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
d942732e
TP
32258 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
32259 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
823d2571
TG
32260 ARM_EXT_OPT ("os", ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
32261 ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
32262 ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
ddfded2f
MW
32263 ARM_EXT_OPT ("pan", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
32264 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
ced40572 32265 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
dad0c3bf
SD
32266 ARM_EXT_OPT ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
32267 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
32268 ARM_ARCH_V8A),
4d1464f2
MW
32269 ARM_EXT_OPT ("ras", ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
32270 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
ced40572 32271 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
643afb90
MW
32272 ARM_EXT_OPT ("rdma", FPU_ARCH_NEON_VFP_ARMV8_1,
32273 ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
ced40572 32274 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
7fadb25d
SD
32275 ARM_EXT_OPT ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
32276 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
32277 ARM_ARCH_V8A),
d942732e 32278 ARM_EXT_OPT2 ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
823d2571 32279 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
d942732e
TP
32280 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
32281 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
643afb90
MW
32282 ARM_EXT_OPT ("simd", FPU_ARCH_NEON_VFP_ARMV8,
32283 ARM_FEATURE_COPROC (FPU_NEON_ARMV8),
32284 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
823d2571
TG
32285 ARM_EXT_OPT ("virt", ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT | ARM_EXT_ADIV
32286 | ARM_EXT_DIV),
32287 ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT),
32288 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
32289 ARM_EXT_OPT ("xscale",ARM_FEATURE_COPROC (ARM_CEXT_XSCALE),
d942732e
TP
32290 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ARCH_NONE),
32291 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, { ARM_ARCH_NONE, ARM_ARCH_NONE } }
69133863 32292};
f3bad469 32293#undef ARM_EXT_OPT
69133863
MGD
32294
32295/* ISA floating-point and Advanced SIMD extensions. */
32296struct arm_option_fpu_value_table
32297{
0198d5e6
TC
32298 const char * name;
32299 const arm_feature_set value;
c19d1205 32300};
7ed4c4c5 32301
c19d1205
ZW
32302/* This list should, at a minimum, contain all the fpu names
32303 recognized by GCC. */
69133863 32304static const struct arm_option_fpu_value_table arm_fpus[] =
c19d1205
ZW
32305{
32306 {"softfpa", FPU_NONE},
32307 {"fpe", FPU_ARCH_FPE},
32308 {"fpe2", FPU_ARCH_FPE},
32309 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
32310 {"fpa", FPU_ARCH_FPA},
32311 {"fpa10", FPU_ARCH_FPA},
32312 {"fpa11", FPU_ARCH_FPA},
32313 {"arm7500fe", FPU_ARCH_FPA},
32314 {"softvfp", FPU_ARCH_VFP},
32315 {"softvfp+vfp", FPU_ARCH_VFP_V2},
32316 {"vfp", FPU_ARCH_VFP_V2},
32317 {"vfp9", FPU_ARCH_VFP_V2},
d5e0ba9c 32318 {"vfp3", FPU_ARCH_VFP_V3}, /* Undocumented, use vfpv3. */
c19d1205
ZW
32319 {"vfp10", FPU_ARCH_VFP_V2},
32320 {"vfp10-r0", FPU_ARCH_VFP_V1},
32321 {"vfpxd", FPU_ARCH_VFP_V1xD},
b1cc4aeb
PB
32322 {"vfpv2", FPU_ARCH_VFP_V2},
32323 {"vfpv3", FPU_ARCH_VFP_V3},
62f3b8c8 32324 {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16},
b1cc4aeb 32325 {"vfpv3-d16", FPU_ARCH_VFP_V3D16},
62f3b8c8
PB
32326 {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16},
32327 {"vfpv3xd", FPU_ARCH_VFP_V3xD},
32328 {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16},
c19d1205
ZW
32329 {"arm1020t", FPU_ARCH_VFP_V1},
32330 {"arm1020e", FPU_ARCH_VFP_V2},
d5e0ba9c 32331 {"arm1136jfs", FPU_ARCH_VFP_V2}, /* Undocumented, use arm1136jf-s. */
c19d1205
ZW
32332 {"arm1136jf-s", FPU_ARCH_VFP_V2},
32333 {"maverick", FPU_ARCH_MAVERICK},
d5e0ba9c 32334 {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
d3375ddd 32335 {"neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
8e79c3df 32336 {"neon-fp16", FPU_ARCH_NEON_FP16},
62f3b8c8
PB
32337 {"vfpv4", FPU_ARCH_VFP_V4},
32338 {"vfpv4-d16", FPU_ARCH_VFP_V4D16},
ada65aa3 32339 {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16},
a715796b
TG
32340 {"fpv5-d16", FPU_ARCH_VFP_V5D16},
32341 {"fpv5-sp-d16", FPU_ARCH_VFP_V5_SP_D16},
62f3b8c8 32342 {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4},
bca38921
MGD
32343 {"fp-armv8", FPU_ARCH_VFP_ARMV8},
32344 {"neon-fp-armv8", FPU_ARCH_NEON_VFP_ARMV8},
32345 {"crypto-neon-fp-armv8",
32346 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8},
d6b4b13e 32347 {"neon-fp-armv8.1", FPU_ARCH_NEON_VFP_ARMV8_1},
081e4c7d
MW
32348 {"crypto-neon-fp-armv8.1",
32349 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1},
e74cfd16
PB
32350 {NULL, ARM_ARCH_NONE}
32351};
32352
32353struct arm_option_value_table
32354{
e0471c16 32355 const char *name;
e74cfd16 32356 long value;
c19d1205 32357};
7ed4c4c5 32358
e74cfd16 32359static const struct arm_option_value_table arm_float_abis[] =
c19d1205
ZW
32360{
32361 {"hard", ARM_FLOAT_ABI_HARD},
32362 {"softfp", ARM_FLOAT_ABI_SOFTFP},
32363 {"soft", ARM_FLOAT_ABI_SOFT},
e74cfd16 32364 {NULL, 0}
c19d1205 32365};
7ed4c4c5 32366
c19d1205 32367#ifdef OBJ_ELF
3a4a14e9 32368/* We only know how to output GNU and ver 4/5 (AAELF) formats. */
e74cfd16 32369static const struct arm_option_value_table arm_eabis[] =
c19d1205
ZW
32370{
32371 {"gnu", EF_ARM_EABI_UNKNOWN},
32372 {"4", EF_ARM_EABI_VER4},
3a4a14e9 32373 {"5", EF_ARM_EABI_VER5},
e74cfd16 32374 {NULL, 0}
c19d1205
ZW
32375};
32376#endif
7ed4c4c5 32377
c19d1205
ZW
32378struct arm_long_option_table
32379{
5b7c81bd
AM
32380 const char *option; /* Substring to match. */
32381 const char *help; /* Help information. */
32382 bool (*func) (const char *subopt); /* Function to decode sub-option. */
32383 const char *deprecated; /* If non-null, print this message. */
c19d1205 32384};
7ed4c4c5 32385
5b7c81bd 32386static bool
c168ce07 32387arm_parse_extension (const char *str, const arm_feature_set *opt_set,
34ef62f4
AV
32388 arm_feature_set *ext_set,
32389 const struct arm_ext_table *ext_table)
7ed4c4c5 32390{
69133863 32391 /* We insist on extensions being specified in alphabetical order, and with
fa94de6b
RM
32392 extensions being added before being removed. We achieve this by having
32393 the global ARM_EXTENSIONS table in alphabetical order, and using the
69133863 32394 ADDING_VALUE variable to indicate whether we are adding an extension (1)
fa94de6b 32395 or removing it (0) and only allowing it to change in the order
69133863
MGD
32396 -1 -> 1 -> 0. */
32397 const struct arm_option_extension_value_table * opt = NULL;
d942732e 32398 const arm_feature_set arm_any = ARM_ANY;
69133863
MGD
32399 int adding_value = -1;
32400
c19d1205 32401 while (str != NULL && *str != 0)
7ed4c4c5 32402 {
82b8a785 32403 const char *ext;
f3bad469 32404 size_t len;
7ed4c4c5 32405
c19d1205
ZW
32406 if (*str != '+')
32407 {
32408 as_bad (_("invalid architectural extension"));
5b7c81bd 32409 return false;
c19d1205 32410 }
7ed4c4c5 32411
c19d1205
ZW
32412 str++;
32413 ext = strchr (str, '+');
7ed4c4c5 32414
c19d1205 32415 if (ext != NULL)
f3bad469 32416 len = ext - str;
c19d1205 32417 else
f3bad469 32418 len = strlen (str);
7ed4c4c5 32419
d34049e8 32420 if (len >= 2 && startswith (str, "no"))
69133863
MGD
32421 {
32422 if (adding_value != 0)
32423 {
32424 adding_value = 0;
32425 opt = arm_extensions;
32426 }
32427
f3bad469 32428 len -= 2;
69133863
MGD
32429 str += 2;
32430 }
f3bad469 32431 else if (len > 0)
69133863
MGD
32432 {
32433 if (adding_value == -1)
32434 {
32435 adding_value = 1;
32436 opt = arm_extensions;
32437 }
32438 else if (adding_value != 1)
32439 {
32440 as_bad (_("must specify extensions to add before specifying "
32441 "those to remove"));
5b7c81bd 32442 return false;
69133863
MGD
32443 }
32444 }
32445
f3bad469 32446 if (len == 0)
c19d1205
ZW
32447 {
32448 as_bad (_("missing architectural extension"));
5b7c81bd 32449 return false;
c19d1205 32450 }
7ed4c4c5 32451
69133863
MGD
32452 gas_assert (adding_value != -1);
32453 gas_assert (opt != NULL);
32454
34ef62f4
AV
32455 if (ext_table != NULL)
32456 {
32457 const struct arm_ext_table * ext_opt = ext_table;
5b7c81bd 32458 bool found = false;
34ef62f4
AV
32459 for (; ext_opt->name != NULL; ext_opt++)
32460 if (ext_opt->name_len == len
32461 && strncmp (ext_opt->name, str, len) == 0)
32462 {
32463 if (adding_value)
32464 {
32465 if (ARM_FEATURE_ZERO (ext_opt->merge))
32466 /* TODO: Option not supported. When we remove the
32467 legacy table this case should error out. */
32468 continue;
32469
32470 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, ext_opt->merge);
32471 }
32472 else
32473 {
32474 if (ARM_FEATURE_ZERO (ext_opt->clear))
32475 /* TODO: Option not supported. When we remove the
32476 legacy table this case should error out. */
32477 continue;
32478 ARM_CLEAR_FEATURE (*ext_set, *ext_set, ext_opt->clear);
32479 }
5b7c81bd 32480 found = true;
34ef62f4
AV
32481 break;
32482 }
32483 if (found)
32484 {
32485 str = ext;
32486 continue;
32487 }
32488 }
32489
69133863
MGD
32490 /* Scan over the options table trying to find an exact match. */
32491 for (; opt->name != NULL; opt++)
f3bad469 32492 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32493 {
d942732e
TP
32494 int i, nb_allowed_archs =
32495 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
69133863 32496 /* Check we can apply the extension to this architecture. */
d942732e
TP
32497 for (i = 0; i < nb_allowed_archs; i++)
32498 {
32499 /* Empty entry. */
32500 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
32501 continue;
c168ce07 32502 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set))
d942732e
TP
32503 break;
32504 }
32505 if (i == nb_allowed_archs)
69133863
MGD
32506 {
32507 as_bad (_("extension does not apply to the base architecture"));
5b7c81bd 32508 return false;
69133863
MGD
32509 }
32510
32511 /* Add or remove the extension. */
32512 if (adding_value)
4d354d8b 32513 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value);
69133863 32514 else
4d354d8b 32515 ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value);
69133863 32516
3d030cdb
TP
32517 /* Allowing Thumb division instructions for ARMv7 in autodetection
32518 rely on this break so that duplicate extensions (extensions
32519 with the same name as a previous extension in the list) are not
32520 considered for command-line parsing. */
c19d1205
ZW
32521 break;
32522 }
7ed4c4c5 32523
c19d1205
ZW
32524 if (opt->name == NULL)
32525 {
69133863
MGD
32526 /* Did we fail to find an extension because it wasn't specified in
32527 alphabetical order, or because it does not exist? */
32528
32529 for (opt = arm_extensions; opt->name != NULL; opt++)
f3bad469 32530 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
69133863
MGD
32531 break;
32532
32533 if (opt->name == NULL)
32534 as_bad (_("unknown architectural extension `%s'"), str);
32535 else
32536 as_bad (_("architectural extensions must be specified in "
32537 "alphabetical order"));
32538
5b7c81bd 32539 return false;
c19d1205 32540 }
69133863
MGD
32541 else
32542 {
32543 /* We should skip the extension we've just matched the next time
32544 round. */
32545 opt++;
32546 }
7ed4c4c5 32547
c19d1205
ZW
32548 str = ext;
32549 };
7ed4c4c5 32550
5b7c81bd 32551 return true;
c19d1205 32552}
7ed4c4c5 32553
5b7c81bd 32554static bool
5312fe52
BW
32555arm_parse_fp16_opt (const char *str)
32556{
32557 if (strcasecmp (str, "ieee") == 0)
32558 fp16_format = ARM_FP16_FORMAT_IEEE;
32559 else if (strcasecmp (str, "alternative") == 0)
32560 fp16_format = ARM_FP16_FORMAT_ALTERNATIVE;
32561 else
32562 {
32563 as_bad (_("unrecognised float16 format \"%s\""), str);
5b7c81bd 32564 return false;
5312fe52
BW
32565 }
32566
5b7c81bd 32567 return true;
5312fe52
BW
32568}
32569
5b7c81bd 32570static bool
17b9d67d 32571arm_parse_cpu (const char *str)
7ed4c4c5 32572{
f3bad469 32573 const struct arm_cpu_option_table *opt;
82b8a785 32574 const char *ext = strchr (str, '+');
f3bad469 32575 size_t len;
7ed4c4c5 32576
c19d1205 32577 if (ext != NULL)
f3bad469 32578 len = ext - str;
7ed4c4c5 32579 else
f3bad469 32580 len = strlen (str);
7ed4c4c5 32581
f3bad469 32582 if (len == 0)
7ed4c4c5 32583 {
c19d1205 32584 as_bad (_("missing cpu name `%s'"), str);
5b7c81bd 32585 return false;
7ed4c4c5
NC
32586 }
32587
c19d1205 32588 for (opt = arm_cpus; opt->name != NULL; opt++)
f3bad469 32589 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32590 {
c168ce07 32591 mcpu_cpu_opt = &opt->value;
4d354d8b
TP
32592 if (mcpu_ext_opt == NULL)
32593 mcpu_ext_opt = XNEW (arm_feature_set);
32594 *mcpu_ext_opt = opt->ext;
e74cfd16 32595 mcpu_fpu_opt = &opt->default_fpu;
ee065d83 32596 if (opt->canonical_name)
ef8e6722
JW
32597 {
32598 gas_assert (sizeof selected_cpu_name > strlen (opt->canonical_name));
32599 strcpy (selected_cpu_name, opt->canonical_name);
32600 }
ee065d83
PB
32601 else
32602 {
f3bad469 32603 size_t i;
c921be7d 32604
ef8e6722
JW
32605 if (len >= sizeof selected_cpu_name)
32606 len = (sizeof selected_cpu_name) - 1;
32607
f3bad469 32608 for (i = 0; i < len; i++)
ee065d83
PB
32609 selected_cpu_name[i] = TOUPPER (opt->name[i]);
32610 selected_cpu_name[i] = 0;
32611 }
7ed4c4c5 32612
c19d1205 32613 if (ext != NULL)
34ef62f4 32614 return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt, NULL);
7ed4c4c5 32615
5b7c81bd 32616 return true;
c19d1205 32617 }
7ed4c4c5 32618
c19d1205 32619 as_bad (_("unknown cpu `%s'"), str);
5b7c81bd 32620 return false;
7ed4c4c5
NC
32621}
32622
5b7c81bd 32623static bool
17b9d67d 32624arm_parse_arch (const char *str)
7ed4c4c5 32625{
e74cfd16 32626 const struct arm_arch_option_table *opt;
82b8a785 32627 const char *ext = strchr (str, '+');
f3bad469 32628 size_t len;
7ed4c4c5 32629
c19d1205 32630 if (ext != NULL)
f3bad469 32631 len = ext - str;
7ed4c4c5 32632 else
f3bad469 32633 len = strlen (str);
7ed4c4c5 32634
f3bad469 32635 if (len == 0)
7ed4c4c5 32636 {
c19d1205 32637 as_bad (_("missing architecture name `%s'"), str);
5b7c81bd 32638 return false;
7ed4c4c5
NC
32639 }
32640
c19d1205 32641 for (opt = arm_archs; opt->name != NULL; opt++)
f3bad469 32642 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32643 {
e74cfd16 32644 march_cpu_opt = &opt->value;
4d354d8b
TP
32645 if (march_ext_opt == NULL)
32646 march_ext_opt = XNEW (arm_feature_set);
32647 *march_ext_opt = arm_arch_none;
e74cfd16 32648 march_fpu_opt = &opt->default_fpu;
e20f9590 32649 selected_ctx_ext_table = opt->ext_table;
5f4273c7 32650 strcpy (selected_cpu_name, opt->name);
7ed4c4c5 32651
c19d1205 32652 if (ext != NULL)
34ef62f4
AV
32653 return arm_parse_extension (ext, march_cpu_opt, march_ext_opt,
32654 opt->ext_table);
7ed4c4c5 32655
5b7c81bd 32656 return true;
c19d1205
ZW
32657 }
32658
32659 as_bad (_("unknown architecture `%s'\n"), str);
5b7c81bd 32660 return false;
7ed4c4c5 32661}
eb043451 32662
5b7c81bd 32663static bool
17b9d67d 32664arm_parse_fpu (const char * str)
c19d1205 32665{
69133863 32666 const struct arm_option_fpu_value_table * opt;
b99bd4ef 32667
c19d1205
ZW
32668 for (opt = arm_fpus; opt->name != NULL; opt++)
32669 if (streq (opt->name, str))
32670 {
e74cfd16 32671 mfpu_opt = &opt->value;
5b7c81bd 32672 return true;
c19d1205 32673 }
b99bd4ef 32674
c19d1205 32675 as_bad (_("unknown floating point format `%s'\n"), str);
5b7c81bd 32676 return false;
c19d1205
ZW
32677}
32678
5b7c81bd 32679static bool
17b9d67d 32680arm_parse_float_abi (const char * str)
b99bd4ef 32681{
e74cfd16 32682 const struct arm_option_value_table * opt;
b99bd4ef 32683
c19d1205
ZW
32684 for (opt = arm_float_abis; opt->name != NULL; opt++)
32685 if (streq (opt->name, str))
32686 {
32687 mfloat_abi_opt = opt->value;
5b7c81bd 32688 return true;
c19d1205 32689 }
cc8a6dd0 32690
c19d1205 32691 as_bad (_("unknown floating point abi `%s'\n"), str);
5b7c81bd 32692 return false;
c19d1205 32693}
b99bd4ef 32694
c19d1205 32695#ifdef OBJ_ELF
5b7c81bd 32696static bool
17b9d67d 32697arm_parse_eabi (const char * str)
c19d1205 32698{
e74cfd16 32699 const struct arm_option_value_table *opt;
cc8a6dd0 32700
c19d1205
ZW
32701 for (opt = arm_eabis; opt->name != NULL; opt++)
32702 if (streq (opt->name, str))
32703 {
32704 meabi_flags = opt->value;
5b7c81bd 32705 return true;
c19d1205
ZW
32706 }
32707 as_bad (_("unknown EABI `%s'\n"), str);
5b7c81bd 32708 return false;
c19d1205
ZW
32709}
32710#endif
cc8a6dd0 32711
5b7c81bd 32712static bool
17b9d67d 32713arm_parse_it_mode (const char * str)
e07e6e58 32714{
5b7c81bd 32715 bool ret = true;
e07e6e58
NC
32716
32717 if (streq ("arm", str))
32718 implicit_it_mode = IMPLICIT_IT_MODE_ARM;
32719 else if (streq ("thumb", str))
32720 implicit_it_mode = IMPLICIT_IT_MODE_THUMB;
32721 else if (streq ("always", str))
32722 implicit_it_mode = IMPLICIT_IT_MODE_ALWAYS;
32723 else if (streq ("never", str))
32724 implicit_it_mode = IMPLICIT_IT_MODE_NEVER;
32725 else
32726 {
32727 as_bad (_("unknown implicit IT mode `%s', should be "\
477330fc 32728 "arm, thumb, always, or never."), str);
5b7c81bd 32729 ret = false;
e07e6e58
NC
32730 }
32731
32732 return ret;
32733}
32734
5b7c81bd 32735static bool
17b9d67d 32736arm_ccs_mode (const char * unused ATTRIBUTE_UNUSED)
2e6976a8 32737{
5b7c81bd 32738 codecomposer_syntax = true;
2e6976a8
DG
32739 arm_comment_chars[0] = ';';
32740 arm_line_separator_chars[0] = 0;
5b7c81bd 32741 return true;
2e6976a8
DG
32742}
32743
c19d1205
ZW
32744struct arm_long_option_table arm_long_opts[] =
32745{
32746 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
32747 arm_parse_cpu, NULL},
32748 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
32749 arm_parse_arch, NULL},
32750 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
32751 arm_parse_fpu, NULL},
32752 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
32753 arm_parse_float_abi, NULL},
32754#ifdef OBJ_ELF
7fac0536 32755 {"meabi=", N_("<ver>\t\t assemble for eabi version <ver>"),
c19d1205
ZW
32756 arm_parse_eabi, NULL},
32757#endif
e07e6e58
NC
32758 {"mimplicit-it=", N_("<mode>\t controls implicit insertion of IT instructions"),
32759 arm_parse_it_mode, NULL},
2e6976a8
DG
32760 {"mccs", N_("\t\t\t TI CodeComposer Studio syntax compatibility mode"),
32761 arm_ccs_mode, NULL},
5312fe52
BW
32762 {"mfp16-format=",
32763 N_("[ieee|alternative]\n\
32764 set the encoding for half precision floating point "
32765 "numbers to IEEE\n\
32766 or Arm alternative format."),
32767 arm_parse_fp16_opt, NULL },
c19d1205
ZW
32768 {NULL, NULL, 0, NULL}
32769};
cc8a6dd0 32770
c19d1205 32771int
17b9d67d 32772md_parse_option (int c, const char * arg)
c19d1205
ZW
32773{
32774 struct arm_option_table *opt;
e74cfd16 32775 const struct arm_legacy_option_table *fopt;
c19d1205 32776 struct arm_long_option_table *lopt;
b99bd4ef 32777
c19d1205 32778 switch (c)
b99bd4ef 32779 {
c19d1205
ZW
32780#ifdef OPTION_EB
32781 case OPTION_EB:
32782 target_big_endian = 1;
32783 break;
32784#endif
cc8a6dd0 32785
c19d1205
ZW
32786#ifdef OPTION_EL
32787 case OPTION_EL:
32788 target_big_endian = 0;
32789 break;
32790#endif
b99bd4ef 32791
845b51d6 32792 case OPTION_FIX_V4BX:
5b7c81bd 32793 fix_v4bx = true;
845b51d6
PB
32794 break;
32795
18a20338
CL
32796#ifdef OBJ_ELF
32797 case OPTION_FDPIC:
5b7c81bd 32798 arm_fdpic = true;
18a20338
CL
32799 break;
32800#endif /* OBJ_ELF */
32801
c19d1205
ZW
32802 case 'a':
32803 /* Listing option. Just ignore these, we don't support additional
32804 ones. */
32805 return 0;
b99bd4ef 32806
c19d1205
ZW
32807 default:
32808 for (opt = arm_opts; opt->option != NULL; opt++)
32809 {
32810 if (c == opt->option[0]
32811 && ((arg == NULL && opt->option[1] == 0)
32812 || streq (arg, opt->option + 1)))
32813 {
c19d1205 32814 /* If the option is deprecated, tell the user. */
278df34e 32815 if (warn_on_deprecated && opt->deprecated != NULL)
c19d1205
ZW
32816 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
32817 arg ? arg : "", _(opt->deprecated));
b99bd4ef 32818
c19d1205
ZW
32819 if (opt->var != NULL)
32820 *opt->var = opt->value;
cc8a6dd0 32821
c19d1205
ZW
32822 return 1;
32823 }
32824 }
b99bd4ef 32825
e74cfd16
PB
32826 for (fopt = arm_legacy_opts; fopt->option != NULL; fopt++)
32827 {
32828 if (c == fopt->option[0]
32829 && ((arg == NULL && fopt->option[1] == 0)
32830 || streq (arg, fopt->option + 1)))
32831 {
e74cfd16 32832 /* If the option is deprecated, tell the user. */
278df34e 32833 if (warn_on_deprecated && fopt->deprecated != NULL)
e74cfd16
PB
32834 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
32835 arg ? arg : "", _(fopt->deprecated));
e74cfd16
PB
32836
32837 if (fopt->var != NULL)
32838 *fopt->var = &fopt->value;
32839
32840 return 1;
32841 }
32842 }
32843
c19d1205
ZW
32844 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
32845 {
32846 /* These options are expected to have an argument. */
32847 if (c == lopt->option[0]
32848 && arg != NULL
32849 && strncmp (arg, lopt->option + 1,
32850 strlen (lopt->option + 1)) == 0)
32851 {
c19d1205 32852 /* If the option is deprecated, tell the user. */
278df34e 32853 if (warn_on_deprecated && lopt->deprecated != NULL)
c19d1205
ZW
32854 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
32855 _(lopt->deprecated));
b99bd4ef 32856
c19d1205
ZW
32857 /* Call the sup-option parser. */
32858 return lopt->func (arg + strlen (lopt->option) - 1);
32859 }
32860 }
a737bd4d 32861
c19d1205
ZW
32862 return 0;
32863 }
a394c00f 32864
c19d1205
ZW
32865 return 1;
32866}
a394c00f 32867
c19d1205
ZW
32868void
32869md_show_usage (FILE * fp)
a394c00f 32870{
c19d1205
ZW
32871 struct arm_option_table *opt;
32872 struct arm_long_option_table *lopt;
a394c00f 32873
c19d1205 32874 fprintf (fp, _(" ARM-specific assembler options:\n"));
a394c00f 32875
c19d1205
ZW
32876 for (opt = arm_opts; opt->option != NULL; opt++)
32877 if (opt->help != NULL)
32878 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
a394c00f 32879
c19d1205
ZW
32880 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
32881 if (lopt->help != NULL)
32882 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
a394c00f 32883
c19d1205
ZW
32884#ifdef OPTION_EB
32885 fprintf (fp, _("\
32886 -EB assemble code for a big-endian cpu\n"));
a394c00f
NC
32887#endif
32888
c19d1205
ZW
32889#ifdef OPTION_EL
32890 fprintf (fp, _("\
32891 -EL assemble code for a little-endian cpu\n"));
a737bd4d 32892#endif
845b51d6
PB
32893
32894 fprintf (fp, _("\
32895 --fix-v4bx Allow BX in ARMv4 code\n"));
18a20338
CL
32896
32897#ifdef OBJ_ELF
32898 fprintf (fp, _("\
32899 --fdpic generate an FDPIC object file\n"));
32900#endif /* OBJ_ELF */
c19d1205 32901}
ee065d83 32902
ee065d83 32903#ifdef OBJ_ELF
0198d5e6 32904
62b3e311
PB
32905typedef struct
32906{
32907 int val;
32908 arm_feature_set flags;
32909} cpu_arch_ver_table;
32910
2c6b98ea
TP
32911/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
32912 chronologically for architectures, with an exception for ARMv6-M and
32913 ARMv6S-M due to legacy reasons. No new architecture should have a
32914 special case. This allows for build attribute selection results to be
32915 stable when new architectures are added. */
62b3e311
PB
32916static const cpu_arch_ver_table cpu_arch_ver[] =
32917{
031254f2
AV
32918 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V1},
32919 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2},
32920 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2S},
32921 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3},
32922 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3M},
32923 {TAG_CPU_ARCH_V4, ARM_ARCH_V4xM},
32924 {TAG_CPU_ARCH_V4, ARM_ARCH_V4},
32925 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4TxM},
32926 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4T},
32927 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5xM},
32928 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5},
32929 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5TxM},
32930 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5T},
32931 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TExP},
32932 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TE},
32933 {TAG_CPU_ARCH_V5TEJ, ARM_ARCH_V5TEJ},
32934 {TAG_CPU_ARCH_V6, ARM_ARCH_V6},
32935 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6Z},
32936 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6KZ},
32937 {TAG_CPU_ARCH_V6K, ARM_ARCH_V6K},
32938 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6T2},
32939 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KT2},
32940 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6ZT2},
32941 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KZT2},
2c6b98ea
TP
32942
32943 /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
32944 always selected build attributes to match those of ARMv6-M
32945 (resp. ARMv6S-M). However, due to these architectures being a strict
32946 subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
32947 would be selected when fully respecting chronology of architectures.
32948 It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
32949 move them before ARMv7 architectures. */
031254f2
AV
32950 {TAG_CPU_ARCH_V6_M, ARM_ARCH_V6M},
32951 {TAG_CPU_ARCH_V6S_M, ARM_ARCH_V6SM},
32952
32953 {TAG_CPU_ARCH_V7, ARM_ARCH_V7},
32954 {TAG_CPU_ARCH_V7, ARM_ARCH_V7A},
32955 {TAG_CPU_ARCH_V7, ARM_ARCH_V7R},
32956 {TAG_CPU_ARCH_V7, ARM_ARCH_V7M},
32957 {TAG_CPU_ARCH_V7, ARM_ARCH_V7VE},
32958 {TAG_CPU_ARCH_V7E_M, ARM_ARCH_V7EM},
32959 {TAG_CPU_ARCH_V8, ARM_ARCH_V8A},
32960 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_1A},
32961 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_2A},
32962 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_3A},
32963 {TAG_CPU_ARCH_V8M_BASE, ARM_ARCH_V8M_BASE},
32964 {TAG_CPU_ARCH_V8M_MAIN, ARM_ARCH_V8M_MAIN},
32965 {TAG_CPU_ARCH_V8R, ARM_ARCH_V8R},
32966 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_4A},
32967 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_5A},
32968 {TAG_CPU_ARCH_V8_1M_MAIN, ARM_ARCH_V8_1M_MAIN},
aab2c27d 32969 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_6A},
b3e4d932
RS
32970 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_7A},
32971 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_8A},
3197e593 32972 {TAG_CPU_ARCH_V9, ARM_ARCH_V9A},
a2b1ea81
RS
32973 {TAG_CPU_ARCH_V9, ARM_ARCH_V9_1A},
32974 {TAG_CPU_ARCH_V9, ARM_ARCH_V9_2A},
32975 {TAG_CPU_ARCH_V9, ARM_ARCH_V9_3A},
aab2c27d 32976 {-1, ARM_ARCH_NONE}
62b3e311
PB
32977};
32978
ee3c0378 32979/* Set an attribute if it has not already been set by the user. */
0198d5e6 32980
ee3c0378
AS
32981static void
32982aeabi_set_attribute_int (int tag, int value)
32983{
32984 if (tag < 1
32985 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
32986 || !attributes_set_explicitly[tag])
a1d1634d
AM
32987 if (!bfd_elf_add_proc_attr_int (stdoutput, tag, value))
32988 as_fatal (_("error adding attribute: %s"),
32989 bfd_errmsg (bfd_get_error ()));
ee3c0378
AS
32990}
32991
32992static void
32993aeabi_set_attribute_string (int tag, const char *value)
32994{
32995 if (tag < 1
32996 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
32997 || !attributes_set_explicitly[tag])
a1d1634d
AM
32998 if (!bfd_elf_add_proc_attr_string (stdoutput, tag, value))
32999 as_fatal (_("error adding attribute: %s"),
33000 bfd_errmsg (bfd_get_error ()));
ee3c0378
AS
33001}
33002
2c6b98ea
TP
33003/* Return whether features in the *NEEDED feature set are available via
33004 extensions for the architecture whose feature set is *ARCH_FSET. */
0198d5e6 33005
5b7c81bd 33006static bool
2c6b98ea
TP
33007have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
33008 const arm_feature_set *needed)
33009{
33010 int i, nb_allowed_archs;
33011 arm_feature_set ext_fset;
33012 const struct arm_option_extension_value_table *opt;
33013
33014 ext_fset = arm_arch_none;
33015 for (opt = arm_extensions; opt->name != NULL; opt++)
33016 {
33017 /* Extension does not provide any feature we need. */
33018 if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
33019 continue;
33020
33021 nb_allowed_archs =
33022 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
33023 for (i = 0; i < nb_allowed_archs; i++)
33024 {
33025 /* Empty entry. */
33026 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
33027 break;
33028
33029 /* Extension is available, add it. */
33030 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
33031 ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
33032 }
33033 }
33034
33035 /* Can we enable all features in *needed? */
33036 return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
33037}
33038
33039/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
33040 a given architecture feature set *ARCH_EXT_FSET including extension feature
33041 set *EXT_FSET. Selection logic used depend on EXACT_MATCH:
33042 - if true, check for an exact match of the architecture modulo extensions;
33043 - otherwise, select build attribute value of the first superset
33044 architecture released so that results remains stable when new architectures
33045 are added.
33046 For -march/-mcpu=all the build attribute value of the most featureful
33047 architecture is returned. Tag_CPU_arch_profile result is returned in
33048 PROFILE. */
0198d5e6 33049
2c6b98ea
TP
33050static int
33051get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
33052 const arm_feature_set *ext_fset,
33053 char *profile, int exact_match)
33054{
33055 arm_feature_set arch_fset;
33056 const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
33057
33058 /* Select most featureful architecture with all its extensions if building
33059 for -march=all as the feature sets used to set build attributes. */
33060 if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
33061 {
33062 /* Force revisiting of decision for each new architecture. */
3197e593 33063 gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V9);
2c6b98ea 33064 *profile = 'A';
3197e593 33065 return TAG_CPU_ARCH_V9;
2c6b98ea
TP
33066 }
33067
33068 ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
33069
33070 for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
33071 {
33072 arm_feature_set known_arch_fset;
33073
33074 ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
33075 if (exact_match)
33076 {
33077 /* Base architecture match user-specified architecture and
33078 extensions, eg. ARMv6S-M matching -march=armv6-m+os. */
33079 if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
33080 {
33081 p_ver_ret = p_ver;
33082 goto found;
33083 }
33084 /* Base architecture match user-specified architecture only
33085 (eg. ARMv6-M in the same case as above). Record it in case we
33086 find a match with above condition. */
33087 else if (p_ver_ret == NULL
33088 && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
33089 p_ver_ret = p_ver;
33090 }
33091 else
33092 {
33093
33094 /* Architecture has all features wanted. */
33095 if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
33096 {
33097 arm_feature_set added_fset;
33098
33099 /* Compute features added by this architecture over the one
33100 recorded in p_ver_ret. */
33101 if (p_ver_ret != NULL)
33102 ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
33103 p_ver_ret->flags);
33104 /* First architecture that match incl. with extensions, or the
33105 only difference in features over the recorded match is
33106 features that were optional and are now mandatory. */
33107 if (p_ver_ret == NULL
33108 || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
33109 {
33110 p_ver_ret = p_ver;
33111 goto found;
33112 }
33113 }
33114 else if (p_ver_ret == NULL)
33115 {
33116 arm_feature_set needed_ext_fset;
33117
33118 ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
33119
33120 /* Architecture has all features needed when using some
33121 extensions. Record it and continue searching in case there
33122 exist an architecture providing all needed features without
33123 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
33124 OS extension). */
33125 if (have_ext_for_needed_feat_p (&known_arch_fset,
33126 &needed_ext_fset))
33127 p_ver_ret = p_ver;
33128 }
33129 }
33130 }
33131
33132 if (p_ver_ret == NULL)
33133 return -1;
33134
dc1e8a47 33135 found:
2c6b98ea 33136 /* Tag_CPU_arch_profile. */
164446e0
AF
33137 if (!ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8r)
33138 && (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
33139 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
33140 || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
33141 && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only))))
2c6b98ea 33142 *profile = 'A';
164446e0
AF
33143 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r)
33144 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8r))
2c6b98ea
TP
33145 *profile = 'R';
33146 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
33147 *profile = 'M';
33148 else
33149 *profile = '\0';
33150 return p_ver_ret->val;
33151}
33152
ee065d83 33153/* Set the public EABI object attributes. */
0198d5e6 33154
c168ce07 33155static void
ee065d83
PB
33156aeabi_set_public_attributes (void)
33157{
b90d5ba0 33158 char profile = '\0';
2c6b98ea 33159 int arch = -1;
90ec0d68 33160 int virt_sec = 0;
bca38921 33161 int fp16_optional = 0;
2c6b98ea
TP
33162 int skip_exact_match = 0;
33163 arm_feature_set flags, flags_arch, flags_ext;
ee065d83 33164
54bab281
TP
33165 /* Autodetection mode, choose the architecture based the instructions
33166 actually used. */
33167 if (no_cpu_selected ())
33168 {
33169 ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
ddd7f988 33170
54bab281
TP
33171 if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
33172 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
ddd7f988 33173
54bab281
TP
33174 if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
33175 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
ddd7f988 33176
54bab281 33177 /* Code run during relaxation relies on selected_cpu being set. */
4d354d8b
TP
33178 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
33179 flags_ext = arm_arch_none;
33180 ARM_CLEAR_FEATURE (selected_arch, flags_arch, flags_ext);
33181 selected_ext = flags_ext;
54bab281
TP
33182 selected_cpu = flags;
33183 }
33184 /* Otherwise, choose the architecture based on the capabilities of the
33185 requested cpu. */
33186 else
4d354d8b
TP
33187 {
33188 ARM_MERGE_FEATURE_SETS (flags_arch, selected_arch, selected_ext);
33189 ARM_CLEAR_FEATURE (flags_arch, flags_arch, fpu_any);
33190 flags_ext = selected_ext;
33191 flags = selected_cpu;
33192 }
33193 ARM_MERGE_FEATURE_SETS (flags, flags, selected_fpu);
7f78eb34 33194
ddd7f988 33195 /* Allow the user to override the reported architecture. */
4d354d8b 33196 if (!ARM_FEATURE_ZERO (selected_object_arch))
7a1d4c38 33197 {
4d354d8b 33198 ARM_CLEAR_FEATURE (flags_arch, selected_object_arch, fpu_any);
2c6b98ea 33199 flags_ext = arm_arch_none;
7a1d4c38 33200 }
2c6b98ea 33201 else
4d354d8b 33202 skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
2c6b98ea
TP
33203
33204 /* When this function is run again after relaxation has happened there is no
33205 way to determine whether an architecture or CPU was specified by the user:
33206 - selected_cpu is set above for relaxation to work;
33207 - march_cpu_opt is not set if only -mcpu or .cpu is used;
33208 - mcpu_cpu_opt is set to arm_arch_any for autodetection.
33209 Therefore, if not in -march=all case we first try an exact match and fall
33210 back to autodetection. */
33211 if (!skip_exact_match)
33212 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
33213 if (arch == -1)
33214 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
33215 if (arch == -1)
33216 as_bad (_("no architecture contains all the instructions used\n"));
9e3c6df6 33217
ee065d83
PB
33218 /* Tag_CPU_name. */
33219 if (selected_cpu_name[0])
33220 {
91d6fa6a 33221 char *q;
ee065d83 33222
91d6fa6a 33223 q = selected_cpu_name;
d34049e8 33224 if (startswith (q, "armv"))
ee065d83
PB
33225 {
33226 int i;
5f4273c7 33227
91d6fa6a
NC
33228 q += 4;
33229 for (i = 0; q[i]; i++)
33230 q[i] = TOUPPER (q[i]);
ee065d83 33231 }
91d6fa6a 33232 aeabi_set_attribute_string (Tag_CPU_name, q);
ee065d83 33233 }
62f3b8c8 33234
ee065d83 33235 /* Tag_CPU_arch. */
ee3c0378 33236 aeabi_set_attribute_int (Tag_CPU_arch, arch);
62f3b8c8 33237
62b3e311 33238 /* Tag_CPU_arch_profile. */
69239280
MGD
33239 if (profile != '\0')
33240 aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
62f3b8c8 33241
15afaa63 33242 /* Tag_DSP_extension. */
4d354d8b 33243 if (ARM_CPU_HAS_FEATURE (selected_ext, arm_ext_dsp))
6c290d53 33244 aeabi_set_attribute_int (Tag_DSP_extension, 1);
15afaa63 33245
2c6b98ea 33246 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
ee065d83 33247 /* Tag_ARM_ISA_use. */
ee3c0378 33248 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
2c6b98ea 33249 || ARM_FEATURE_ZERO (flags_arch))
ee3c0378 33250 aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
62f3b8c8 33251
ee065d83 33252 /* Tag_THUMB_ISA_use. */
ee3c0378 33253 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
2c6b98ea 33254 || ARM_FEATURE_ZERO (flags_arch))
4ed7ed8d
TP
33255 {
33256 int thumb_isa_use;
33257
33258 if (!ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
16a1fa25 33259 && ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only))
4ed7ed8d
TP
33260 thumb_isa_use = 3;
33261 else if (ARM_CPU_HAS_FEATURE (flags, arm_arch_t2))
33262 thumb_isa_use = 2;
33263 else
33264 thumb_isa_use = 1;
33265 aeabi_set_attribute_int (Tag_THUMB_ISA_use, thumb_isa_use);
33266 }
62f3b8c8 33267
ee065d83 33268 /* Tag_VFP_arch. */
a715796b
TG
33269 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_armv8xd))
33270 aeabi_set_attribute_int (Tag_VFP_arch,
33271 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
33272 ? 7 : 8);
bca38921 33273 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_fma))
62f3b8c8
PB
33274 aeabi_set_attribute_int (Tag_VFP_arch,
33275 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
33276 ? 5 : 6);
33277 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32))
bca38921
MGD
33278 {
33279 fp16_optional = 1;
33280 aeabi_set_attribute_int (Tag_VFP_arch, 3);
33281 }
ada65aa3 33282 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v3xd))
bca38921
MGD
33283 {
33284 aeabi_set_attribute_int (Tag_VFP_arch, 4);
33285 fp16_optional = 1;
33286 }
ee3c0378
AS
33287 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v2))
33288 aeabi_set_attribute_int (Tag_VFP_arch, 2);
33289 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1)
477330fc 33290 || ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd))
ee3c0378 33291 aeabi_set_attribute_int (Tag_VFP_arch, 1);
62f3b8c8 33292
4547cb56
NC
33293 /* Tag_ABI_HardFP_use. */
33294 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd)
33295 && !ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1))
33296 aeabi_set_attribute_int (Tag_ABI_HardFP_use, 1);
33297
ee065d83 33298 /* Tag_WMMX_arch. */
ee3c0378
AS
33299 if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt2))
33300 aeabi_set_attribute_int (Tag_WMMX_arch, 2);
33301 else if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt))
33302 aeabi_set_attribute_int (Tag_WMMX_arch, 1);
62f3b8c8 33303
ee3c0378 33304 /* Tag_Advanced_SIMD_arch (formerly Tag_NEON_arch). */
9411fd44
MW
33305 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v8_1))
33306 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 4);
33307 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_armv8))
bca38921
MGD
33308 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 3);
33309 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v1))
33310 {
33311 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_fma))
33312 {
33313 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 2);
33314 }
33315 else
33316 {
33317 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 1);
33318 fp16_optional = 1;
33319 }
33320 }
fa94de6b 33321
a7ad558c
AV
33322 if (ARM_CPU_HAS_FEATURE (flags, mve_fp_ext))
33323 aeabi_set_attribute_int (Tag_MVE_arch, 2);
33324 else if (ARM_CPU_HAS_FEATURE (flags, mve_ext))
33325 aeabi_set_attribute_int (Tag_MVE_arch, 1);
33326
ee3c0378 33327 /* Tag_VFP_HP_extension (formerly Tag_NEON_FP16_arch). */
bca38921 33328 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_fp16) && fp16_optional)
ee3c0378 33329 aeabi_set_attribute_int (Tag_VFP_HP_extension, 1);
4547cb56 33330
69239280
MGD
33331 /* Tag_DIV_use.
33332
33333 We set Tag_DIV_use to two when integer divide instructions have been used
33334 in ARM state, or when Thumb integer divide instructions have been used,
33335 but we have no architecture profile set, nor have we any ARM instructions.
33336
4ed7ed8d
TP
33337 For ARMv8-A and ARMv8-M we set the tag to 0 as integer divide is implied
33338 by the base architecture.
bca38921 33339
69239280 33340 For new architectures we will have to check these tests. */
3197e593 33341 gas_assert (arch <= TAG_CPU_ARCH_V9);
4ed7ed8d
TP
33342 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
33343 || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
bca38921
MGD
33344 aeabi_set_attribute_int (Tag_DIV_use, 0);
33345 else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_adiv)
33346 || (profile == '\0'
33347 && ARM_CPU_HAS_FEATURE (flags, arm_ext_div)
33348 && !ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any)))
eea54501 33349 aeabi_set_attribute_int (Tag_DIV_use, 2);
60e5ef9f
MGD
33350
33351 /* Tag_MP_extension_use. */
33352 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_mp))
33353 aeabi_set_attribute_int (Tag_MPextension_use, 1);
f4c65163
MGD
33354
33355 /* Tag Virtualization_use. */
33356 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_sec))
90ec0d68
MGD
33357 virt_sec |= 1;
33358 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_virt))
33359 virt_sec |= 2;
33360 if (virt_sec != 0)
33361 aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
5312fe52
BW
33362
33363 if (fp16_format != ARM_FP16_FORMAT_DEFAULT)
33364 aeabi_set_attribute_int (Tag_ABI_FP_16bit_format, fp16_format);
ee065d83
PB
33365}
33366
c168ce07
TP
33367/* Post relaxation hook. Recompute ARM attributes now that relaxation is
33368 finished and free extension feature bits which will not be used anymore. */
0198d5e6 33369
c168ce07
TP
33370void
33371arm_md_post_relax (void)
33372{
33373 aeabi_set_public_attributes ();
4d354d8b
TP
33374 XDELETE (mcpu_ext_opt);
33375 mcpu_ext_opt = NULL;
33376 XDELETE (march_ext_opt);
33377 march_ext_opt = NULL;
c168ce07
TP
33378}
33379
104d59d1 33380/* Add the default contents for the .ARM.attributes section. */
0198d5e6 33381
ee065d83 33382void
ed2917de 33383arm_md_finish (void)
ee065d83 33384{
ee065d83
PB
33385 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
33386 return;
33387
33388 aeabi_set_public_attributes ();
ee065d83 33389}
8463be01 33390#endif /* OBJ_ELF */
ee065d83 33391
ee065d83
PB
33392/* Parse a .cpu directive. */
33393
33394static void
33395s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
33396{
e74cfd16 33397 const struct arm_cpu_option_table *opt;
ee065d83
PB
33398 char *name;
33399 char saved_char;
33400
33401 name = input_line_pointer;
a37854f9 33402 input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
ee065d83
PB
33403 saved_char = *input_line_pointer;
33404 *input_line_pointer = 0;
33405
a37854f9
RE
33406 if (!*name)
33407 {
33408 as_bad (_(".cpu: missing cpu name"));
33409 *input_line_pointer = saved_char;
33410 return;
33411 }
33412
ee065d83
PB
33413 /* Skip the first "all" entry. */
33414 for (opt = arm_cpus + 1; opt->name != NULL; opt++)
33415 if (streq (opt->name, name))
33416 {
4d354d8b
TP
33417 selected_arch = opt->value;
33418 selected_ext = opt->ext;
33419 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
ee065d83 33420 if (opt->canonical_name)
5f4273c7 33421 strcpy (selected_cpu_name, opt->canonical_name);
ee065d83
PB
33422 else
33423 {
33424 int i;
33425 for (i = 0; opt->name[i]; i++)
33426 selected_cpu_name[i] = TOUPPER (opt->name[i]);
f3bad469 33427
ee065d83
PB
33428 selected_cpu_name[i] = 0;
33429 }
4d354d8b
TP
33430 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
33431
ee065d83
PB
33432 *input_line_pointer = saved_char;
33433 demand_empty_rest_of_line ();
33434 return;
33435 }
33436 as_bad (_("unknown cpu `%s'"), name);
33437 *input_line_pointer = saved_char;
ee065d83
PB
33438}
33439
ee065d83
PB
33440/* Parse a .arch directive. */
33441
33442static void
33443s_arm_arch (int ignored ATTRIBUTE_UNUSED)
33444{
e74cfd16 33445 const struct arm_arch_option_table *opt;
ee065d83
PB
33446 char saved_char;
33447 char *name;
33448
33449 name = input_line_pointer;
a37854f9 33450 input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
ee065d83
PB
33451 saved_char = *input_line_pointer;
33452 *input_line_pointer = 0;
33453
a37854f9
RE
33454 if (!*name)
33455 {
33456 as_bad (_(".arch: missing architecture name"));
33457 *input_line_pointer = saved_char;
33458 return;
33459 }
33460
ee065d83
PB
33461 /* Skip the first "all" entry. */
33462 for (opt = arm_archs + 1; opt->name != NULL; opt++)
33463 if (streq (opt->name, name))
33464 {
4d354d8b 33465 selected_arch = opt->value;
0e7aaa72 33466 selected_ctx_ext_table = opt->ext_table;
4d354d8b
TP
33467 selected_ext = arm_arch_none;
33468 selected_cpu = selected_arch;
5f4273c7 33469 strcpy (selected_cpu_name, opt->name);
4d354d8b 33470 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
33471 *input_line_pointer = saved_char;
33472 demand_empty_rest_of_line ();
33473 return;
33474 }
33475
33476 as_bad (_("unknown architecture `%s'\n"), name);
33477 *input_line_pointer = saved_char;
33478 ignore_rest_of_line ();
33479}
33480
7a1d4c38
PB
33481/* Parse a .object_arch directive. */
33482
33483static void
33484s_arm_object_arch (int ignored ATTRIBUTE_UNUSED)
33485{
33486 const struct arm_arch_option_table *opt;
33487 char saved_char;
33488 char *name;
33489
33490 name = input_line_pointer;
a37854f9 33491 input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
7a1d4c38
PB
33492 saved_char = *input_line_pointer;
33493 *input_line_pointer = 0;
33494
a37854f9
RE
33495 if (!*name)
33496 {
33497 as_bad (_(".object_arch: missing architecture name"));
33498 *input_line_pointer = saved_char;
33499 return;
33500 }
33501
7a1d4c38
PB
33502 /* Skip the first "all" entry. */
33503 for (opt = arm_archs + 1; opt->name != NULL; opt++)
33504 if (streq (opt->name, name))
33505 {
4d354d8b 33506 selected_object_arch = opt->value;
7a1d4c38
PB
33507 *input_line_pointer = saved_char;
33508 demand_empty_rest_of_line ();
33509 return;
33510 }
33511
33512 as_bad (_("unknown architecture `%s'\n"), name);
33513 *input_line_pointer = saved_char;
33514 ignore_rest_of_line ();
33515}
33516
69133863
MGD
33517/* Parse a .arch_extension directive. */
33518
33519static void
33520s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
33521{
33522 const struct arm_option_extension_value_table *opt;
33523 char saved_char;
33524 char *name;
33525 int adding_value = 1;
33526
33527 name = input_line_pointer;
a37854f9 33528 input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
69133863
MGD
33529 saved_char = *input_line_pointer;
33530 *input_line_pointer = 0;
33531
a37854f9
RE
33532 if (!*name)
33533 {
33534 as_bad (_(".arch_extension: missing architecture extension"));
33535 *input_line_pointer = saved_char;
33536 return;
33537 }
33538
69133863 33539 if (strlen (name) >= 2
d34049e8 33540 && startswith (name, "no"))
69133863
MGD
33541 {
33542 adding_value = 0;
33543 name += 2;
33544 }
33545
e20f9590
MI
33546 /* Check the context specific extension table */
33547 if (selected_ctx_ext_table)
33548 {
33549 const struct arm_ext_table * ext_opt;
33550 for (ext_opt = selected_ctx_ext_table; ext_opt->name != NULL; ext_opt++)
33551 {
33552 if (streq (ext_opt->name, name))
33553 {
33554 if (adding_value)
33555 {
33556 if (ARM_FEATURE_ZERO (ext_opt->merge))
33557 /* TODO: Option not supported. When we remove the
33558 legacy table this case should error out. */
33559 continue;
33560 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
33561 ext_opt->merge);
33562 }
33563 else
33564 ARM_CLEAR_FEATURE (selected_ext, selected_ext, ext_opt->clear);
33565
33566 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
33567 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
33568 *input_line_pointer = saved_char;
33569 demand_empty_rest_of_line ();
33570 return;
33571 }
33572 }
33573 }
33574
69133863
MGD
33575 for (opt = arm_extensions; opt->name != NULL; opt++)
33576 if (streq (opt->name, name))
33577 {
d942732e
TP
33578 int i, nb_allowed_archs =
33579 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[i]);
33580 for (i = 0; i < nb_allowed_archs; i++)
33581 {
33582 /* Empty entry. */
4d354d8b 33583 if (ARM_CPU_IS_ANY (opt->allowed_archs[i]))
d942732e 33584 continue;
4d354d8b 33585 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], selected_arch))
d942732e
TP
33586 break;
33587 }
33588
33589 if (i == nb_allowed_archs)
69133863
MGD
33590 {
33591 as_bad (_("architectural extension `%s' is not allowed for the "
33592 "current base architecture"), name);
33593 break;
33594 }
33595
33596 if (adding_value)
4d354d8b 33597 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
5a70a223 33598 opt->merge_value);
69133863 33599 else
4d354d8b 33600 ARM_CLEAR_FEATURE (selected_ext, selected_ext, opt->clear_value);
69133863 33601
4d354d8b
TP
33602 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
33603 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
69133863
MGD
33604 *input_line_pointer = saved_char;
33605 demand_empty_rest_of_line ();
3d030cdb
TP
33606 /* Allowing Thumb division instructions for ARMv7 in autodetection rely
33607 on this return so that duplicate extensions (extensions with the
33608 same name as a previous extension in the list) are not considered
33609 for command-line parsing. */
69133863
MGD
33610 return;
33611 }
33612
33613 if (opt->name == NULL)
e673710a 33614 as_bad (_("unknown architecture extension `%s'\n"), name);
69133863
MGD
33615
33616 *input_line_pointer = saved_char;
69133863
MGD
33617}
33618
ee065d83
PB
33619/* Parse a .fpu directive. */
33620
33621static void
33622s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
33623{
69133863 33624 const struct arm_option_fpu_value_table *opt;
ee065d83
PB
33625 char saved_char;
33626 char *name;
33627
33628 name = input_line_pointer;
a37854f9 33629 input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
ee065d83
PB
33630 saved_char = *input_line_pointer;
33631 *input_line_pointer = 0;
5f4273c7 33632
a37854f9
RE
33633 if (!*name)
33634 {
33635 as_bad (_(".fpu: missing fpu name"));
33636 *input_line_pointer = saved_char;
33637 return;
33638 }
33639
ee065d83
PB
33640 for (opt = arm_fpus; opt->name != NULL; opt++)
33641 if (streq (opt->name, name))
33642 {
4d354d8b 33643 selected_fpu = opt->value;
f4399880 33644 ARM_CLEAR_FEATURE (selected_cpu, selected_cpu, fpu_any);
4d354d8b
TP
33645#ifndef CPU_DEFAULT
33646 if (no_cpu_selected ())
33647 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
33648 else
33649#endif
33650 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 33651 *input_line_pointer = saved_char;
ee065d83
PB
33652 return;
33653 }
33654
33655 as_bad (_("unknown floating point format `%s'\n"), name);
33656 *input_line_pointer = saved_char;
33657 ignore_rest_of_line ();
33658}
ee065d83 33659
794ba86a 33660/* Copy symbol information. */
f31fef98 33661
794ba86a
DJ
33662void
33663arm_copy_symbol_attributes (symbolS *dest, symbolS *src)
33664{
33665 ARM_GET_FLAG (dest) = ARM_GET_FLAG (src);
33666}
e04befd0 33667
f31fef98 33668#ifdef OBJ_ELF
e04befd0
AS
33669/* Given a symbolic attribute NAME, return the proper integer value.
33670 Returns -1 if the attribute is not known. */
f31fef98 33671
e04befd0
AS
33672int
33673arm_convert_symbolic_attribute (const char *name)
33674{
f31fef98
NC
33675 static const struct
33676 {
33677 const char * name;
33678 const int tag;
33679 }
33680 attribute_table[] =
33681 {
33682 /* When you modify this table you should
33683 also modify the list in doc/c-arm.texi. */
e04befd0 33684#define T(tag) {#tag, tag}
f31fef98
NC
33685 T (Tag_CPU_raw_name),
33686 T (Tag_CPU_name),
33687 T (Tag_CPU_arch),
33688 T (Tag_CPU_arch_profile),
33689 T (Tag_ARM_ISA_use),
33690 T (Tag_THUMB_ISA_use),
75375b3e 33691 T (Tag_FP_arch),
f31fef98
NC
33692 T (Tag_VFP_arch),
33693 T (Tag_WMMX_arch),
33694 T (Tag_Advanced_SIMD_arch),
33695 T (Tag_PCS_config),
33696 T (Tag_ABI_PCS_R9_use),
33697 T (Tag_ABI_PCS_RW_data),
33698 T (Tag_ABI_PCS_RO_data),
33699 T (Tag_ABI_PCS_GOT_use),
33700 T (Tag_ABI_PCS_wchar_t),
33701 T (Tag_ABI_FP_rounding),
33702 T (Tag_ABI_FP_denormal),
33703 T (Tag_ABI_FP_exceptions),
33704 T (Tag_ABI_FP_user_exceptions),
33705 T (Tag_ABI_FP_number_model),
75375b3e 33706 T (Tag_ABI_align_needed),
f31fef98 33707 T (Tag_ABI_align8_needed),
75375b3e 33708 T (Tag_ABI_align_preserved),
f31fef98
NC
33709 T (Tag_ABI_align8_preserved),
33710 T (Tag_ABI_enum_size),
33711 T (Tag_ABI_HardFP_use),
33712 T (Tag_ABI_VFP_args),
33713 T (Tag_ABI_WMMX_args),
33714 T (Tag_ABI_optimization_goals),
33715 T (Tag_ABI_FP_optimization_goals),
33716 T (Tag_compatibility),
33717 T (Tag_CPU_unaligned_access),
75375b3e 33718 T (Tag_FP_HP_extension),
f31fef98
NC
33719 T (Tag_VFP_HP_extension),
33720 T (Tag_ABI_FP_16bit_format),
cd21e546
MGD
33721 T (Tag_MPextension_use),
33722 T (Tag_DIV_use),
f31fef98
NC
33723 T (Tag_nodefaults),
33724 T (Tag_also_compatible_with),
33725 T (Tag_conformance),
33726 T (Tag_T2EE_use),
33727 T (Tag_Virtualization_use),
15afaa63 33728 T (Tag_DSP_extension),
a7ad558c 33729 T (Tag_MVE_arch),
99db83d0 33730 T (Tag_PAC_extension),
4b535030 33731 T (Tag_BTI_extension),
b81ee92f 33732 T (Tag_BTI_use),
c9fed665 33733 T (Tag_PACRET_use),
cd21e546 33734 /* We deliberately do not include Tag_MPextension_use_legacy. */
e04befd0 33735#undef T
f31fef98 33736 };
e04befd0
AS
33737 unsigned int i;
33738
33739 if (name == NULL)
33740 return -1;
33741
f31fef98 33742 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
c921be7d 33743 if (streq (name, attribute_table[i].name))
e04befd0
AS
33744 return attribute_table[i].tag;
33745
33746 return -1;
33747}
267bf995 33748
93ef582d
NC
33749/* Apply sym value for relocations only in the case that they are for
33750 local symbols in the same segment as the fixup and you have the
33751 respective architectural feature for blx and simple switches. */
0198d5e6 33752
267bf995 33753int
93ef582d 33754arm_apply_sym_value (struct fix * fixP, segT this_seg)
267bf995
RR
33755{
33756 if (fixP->fx_addsy
33757 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
93ef582d
NC
33758 /* PR 17444: If the local symbol is in a different section then a reloc
33759 will always be generated for it, so applying the symbol value now
33760 will result in a double offset being stored in the relocation. */
33761 && (S_GET_SEGMENT (fixP->fx_addsy) == this_seg)
5b7c81bd 33762 && !S_FORCE_RELOC (fixP->fx_addsy, true))
267bf995
RR
33763 {
33764 switch (fixP->fx_r_type)
33765 {
33766 case BFD_RELOC_ARM_PCREL_BLX:
33767 case BFD_RELOC_THUMB_PCREL_BRANCH23:
33768 if (ARM_IS_FUNC (fixP->fx_addsy))
33769 return 1;
33770 break;
33771
33772 case BFD_RELOC_ARM_PCREL_CALL:
33773 case BFD_RELOC_THUMB_PCREL_BLX:
33774 if (THUMB_IS_FUNC (fixP->fx_addsy))
93ef582d 33775 return 1;
267bf995
RR
33776 break;
33777
33778 default:
33779 break;
33780 }
33781
33782 }
33783 return 0;
33784}
f31fef98 33785#endif /* OBJ_ELF */