]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-arm.c
Fix build issues with mingw toolchain
[thirdparty/binutils-gdb.git] / gas / config / tc-arm.c
CommitLineData
b99bd4ef 1/* tc-arm.c -- Assemble for the ARM
fd67aa11 2 Copyright (C) 1994-2024 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
c621dd90 3350/* Directives: alignment. */
b99bd4ef 3351
c19d1205
ZW
3352static void
3353s_even (int ignore ATTRIBUTE_UNUSED)
3354{
3355 /* Never make frag if expect extra pass. */
3356 if (!need_pass_2)
3357 frag_align (1, 0, 0);
b99bd4ef 3358
c19d1205 3359 record_alignment (now_seg, 1);
b99bd4ef 3360
c19d1205 3361 demand_empty_rest_of_line ();
b99bd4ef
NC
3362}
3363
2e6976a8
DG
3364/* Directives: CodeComposer Studio. */
3365
3366/* .ref (for CodeComposer Studio syntax only). */
3367static void
3368s_ccs_ref (int unused ATTRIBUTE_UNUSED)
3369{
3370 if (codecomposer_syntax)
3371 ignore_rest_of_line ();
3372 else
3373 as_bad (_(".ref pseudo-op only available with -mccs flag."));
3374}
3375
3376/* If name is not NULL, then it is used for marking the beginning of a
2b0f3761 3377 function, whereas if it is NULL then it means the function end. */
2e6976a8
DG
3378static void
3379asmfunc_debug (const char * name)
3380{
3381 static const char * last_name = NULL;
3382
3383 if (name != NULL)
3384 {
3385 gas_assert (last_name == NULL);
3386 last_name = name;
3387
3388 if (debug_type == DEBUG_STABS)
3389 stabs_generate_asm_func (name, name);
3390 }
3391 else
3392 {
3393 gas_assert (last_name != NULL);
3394
3395 if (debug_type == DEBUG_STABS)
3396 stabs_generate_asm_endfunc (last_name, last_name);
3397
3398 last_name = NULL;
3399 }
3400}
3401
3402static void
3403s_ccs_asmfunc (int unused ATTRIBUTE_UNUSED)
3404{
3405 if (codecomposer_syntax)
3406 {
3407 switch (asmfunc_state)
3408 {
3409 case OUTSIDE_ASMFUNC:
3410 asmfunc_state = WAITING_ASMFUNC_NAME;
3411 break;
3412
3413 case WAITING_ASMFUNC_NAME:
3414 as_bad (_(".asmfunc repeated."));
3415 break;
3416
3417 case WAITING_ENDASMFUNC:
3418 as_bad (_(".asmfunc without function."));
3419 break;
3420 }
3421 demand_empty_rest_of_line ();
3422 }
3423 else
3424 as_bad (_(".asmfunc pseudo-op only available with -mccs flag."));
3425}
3426
3427static void
3428s_ccs_endasmfunc (int unused ATTRIBUTE_UNUSED)
3429{
3430 if (codecomposer_syntax)
3431 {
3432 switch (asmfunc_state)
3433 {
3434 case OUTSIDE_ASMFUNC:
3435 as_bad (_(".endasmfunc without a .asmfunc."));
3436 break;
3437
3438 case WAITING_ASMFUNC_NAME:
3439 as_bad (_(".endasmfunc without function."));
3440 break;
3441
3442 case WAITING_ENDASMFUNC:
3443 asmfunc_state = OUTSIDE_ASMFUNC;
3444 asmfunc_debug (NULL);
3445 break;
3446 }
3447 demand_empty_rest_of_line ();
3448 }
3449 else
3450 as_bad (_(".endasmfunc pseudo-op only available with -mccs flag."));
3451}
3452
3453static void
3454s_ccs_def (int name)
3455{
3456 if (codecomposer_syntax)
3457 s_globl (name);
3458 else
3459 as_bad (_(".def pseudo-op only available with -mccs flag."));
3460}
3461
c19d1205 3462/* Directives: Literal pools. */
a737bd4d 3463
c19d1205
ZW
3464static literal_pool *
3465find_literal_pool (void)
a737bd4d 3466{
c19d1205 3467 literal_pool * pool;
a737bd4d 3468
c19d1205 3469 for (pool = list_of_pools; pool != NULL; pool = pool->next)
a737bd4d 3470 {
c19d1205
ZW
3471 if (pool->section == now_seg
3472 && pool->sub_section == now_subseg)
3473 break;
a737bd4d
NC
3474 }
3475
c19d1205 3476 return pool;
a737bd4d
NC
3477}
3478
c19d1205
ZW
3479static literal_pool *
3480find_or_make_literal_pool (void)
a737bd4d 3481{
c19d1205
ZW
3482 /* Next literal pool ID number. */
3483 static unsigned int latest_pool_num = 1;
3484 literal_pool * pool;
a737bd4d 3485
c19d1205 3486 pool = find_literal_pool ();
a737bd4d 3487
c19d1205 3488 if (pool == NULL)
a737bd4d 3489 {
c19d1205 3490 /* Create a new pool. */
325801bd 3491 pool = XNEW (literal_pool);
c19d1205
ZW
3492 if (! pool)
3493 return NULL;
a737bd4d 3494
c19d1205
ZW
3495 pool->next_free_entry = 0;
3496 pool->section = now_seg;
3497 pool->sub_section = now_subseg;
3498 pool->next = list_of_pools;
3499 pool->symbol = NULL;
8335d6aa 3500 pool->alignment = 2;
c19d1205
ZW
3501
3502 /* Add it to the list. */
3503 list_of_pools = pool;
a737bd4d 3504 }
a737bd4d 3505
c19d1205
ZW
3506 /* New pools, and emptied pools, will have a NULL symbol. */
3507 if (pool->symbol == NULL)
a737bd4d 3508 {
c19d1205 3509 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
e01e1cee 3510 &zero_address_frag, 0);
c19d1205 3511 pool->id = latest_pool_num ++;
a737bd4d
NC
3512 }
3513
c19d1205
ZW
3514 /* Done. */
3515 return pool;
a737bd4d
NC
3516}
3517
c19d1205 3518/* Add the literal in the global 'inst'
5f4273c7 3519 structure to the relevant literal pool. */
b99bd4ef
NC
3520
3521static int
8335d6aa 3522add_to_lit_pool (unsigned int nbytes)
b99bd4ef 3523{
8335d6aa
JW
3524#define PADDING_SLOT 0x1
3525#define LIT_ENTRY_SIZE_MASK 0xFF
c19d1205 3526 literal_pool * pool;
8335d6aa 3527 unsigned int entry, pool_size = 0;
5b7c81bd 3528 bool padding_slot_p = false;
e56c722b 3529 unsigned imm1 = 0;
8335d6aa
JW
3530 unsigned imm2 = 0;
3531
3532 if (nbytes == 8)
3533 {
3534 imm1 = inst.operands[1].imm;
3535 imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
e2b0ab59 3536 : inst.relocs[0].exp.X_unsigned ? 0
0e3c1eeb 3537 : (int64_t) inst.operands[1].imm >> 32);
8335d6aa
JW
3538 if (target_big_endian)
3539 {
3540 imm1 = imm2;
3541 imm2 = inst.operands[1].imm;
3542 }
3543 }
b99bd4ef 3544
c19d1205
ZW
3545 pool = find_or_make_literal_pool ();
3546
3547 /* Check if this literal value is already in the pool. */
3548 for (entry = 0; entry < pool->next_free_entry; entry ++)
b99bd4ef 3549 {
8335d6aa
JW
3550 if (nbytes == 4)
3551 {
e2b0ab59
AV
3552 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3553 && (inst.relocs[0].exp.X_op == O_constant)
8335d6aa 3554 && (pool->literals[entry].X_add_number
e2b0ab59 3555 == inst.relocs[0].exp.X_add_number)
8335d6aa
JW
3556 && (pool->literals[entry].X_md == nbytes)
3557 && (pool->literals[entry].X_unsigned
e2b0ab59 3558 == inst.relocs[0].exp.X_unsigned))
8335d6aa
JW
3559 break;
3560
e2b0ab59
AV
3561 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3562 && (inst.relocs[0].exp.X_op == O_symbol)
8335d6aa 3563 && (pool->literals[entry].X_add_number
e2b0ab59 3564 == inst.relocs[0].exp.X_add_number)
8335d6aa 3565 && (pool->literals[entry].X_add_symbol
e2b0ab59 3566 == inst.relocs[0].exp.X_add_symbol)
8335d6aa 3567 && (pool->literals[entry].X_op_symbol
e2b0ab59 3568 == inst.relocs[0].exp.X_op_symbol)
8335d6aa
JW
3569 && (pool->literals[entry].X_md == nbytes))
3570 break;
3571 }
3572 else if ((nbytes == 8)
3573 && !(pool_size & 0x7)
3574 && ((entry + 1) != pool->next_free_entry)
3575 && (pool->literals[entry].X_op == O_constant)
19f2f6a9 3576 && (pool->literals[entry].X_add_number == (offsetT) imm1)
8335d6aa 3577 && (pool->literals[entry].X_unsigned
e2b0ab59 3578 == inst.relocs[0].exp.X_unsigned)
8335d6aa 3579 && (pool->literals[entry + 1].X_op == O_constant)
19f2f6a9 3580 && (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
8335d6aa 3581 && (pool->literals[entry + 1].X_unsigned
e2b0ab59 3582 == inst.relocs[0].exp.X_unsigned))
c19d1205
ZW
3583 break;
3584
8335d6aa
JW
3585 padding_slot_p = ((pool->literals[entry].X_md >> 8) == PADDING_SLOT);
3586 if (padding_slot_p && (nbytes == 4))
c19d1205 3587 break;
8335d6aa
JW
3588
3589 pool_size += 4;
b99bd4ef
NC
3590 }
3591
c19d1205
ZW
3592 /* Do we need to create a new entry? */
3593 if (entry == pool->next_free_entry)
3594 {
3595 if (entry >= MAX_LITERAL_POOL_SIZE)
3596 {
3597 inst.error = _("literal pool overflow");
3598 return FAIL;
3599 }
3600
8335d6aa
JW
3601 if (nbytes == 8)
3602 {
3603 /* For 8-byte entries, we align to an 8-byte boundary,
3604 and split it into two 4-byte entries, because on 32-bit
3605 host, 8-byte constants are treated as big num, thus
3606 saved in "generic_bignum" which will be overwritten
3607 by later assignments.
3608
3609 We also need to make sure there is enough space for
3610 the split.
3611
3612 We also check to make sure the literal operand is a
3613 constant number. */
e2b0ab59
AV
3614 if (!(inst.relocs[0].exp.X_op == O_constant
3615 || inst.relocs[0].exp.X_op == O_big))
8335d6aa
JW
3616 {
3617 inst.error = _("invalid type for literal pool");
3618 return FAIL;
3619 }
3620 else if (pool_size & 0x7)
3621 {
3622 if ((entry + 2) >= MAX_LITERAL_POOL_SIZE)
3623 {
3624 inst.error = _("literal pool overflow");
3625 return FAIL;
3626 }
3627
e2b0ab59 3628 pool->literals[entry] = inst.relocs[0].exp;
a6684f0d 3629 pool->literals[entry].X_op = O_constant;
8335d6aa
JW
3630 pool->literals[entry].X_add_number = 0;
3631 pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
3632 pool->next_free_entry += 1;
3633 pool_size += 4;
3634 }
3635 else if ((entry + 1) >= 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;
8335d6aa
JW
3642 pool->literals[entry].X_op = O_constant;
3643 pool->literals[entry].X_add_number = imm1;
e2b0ab59 3644 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa 3645 pool->literals[entry++].X_md = 4;
e2b0ab59 3646 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3647 pool->literals[entry].X_op = O_constant;
3648 pool->literals[entry].X_add_number = imm2;
e2b0ab59 3649 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa
JW
3650 pool->literals[entry].X_md = 4;
3651 pool->alignment = 3;
3652 pool->next_free_entry += 1;
3653 }
3654 else
3655 {
e2b0ab59 3656 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3657 pool->literals[entry].X_md = 4;
3658 }
3659
a8040cf2
NC
3660#ifdef OBJ_ELF
3661 /* PR ld/12974: Record the location of the first source line to reference
3662 this entry in the literal pool. If it turns out during linking that the
3663 symbol does not exist we will be able to give an accurate line number for
3664 the (first use of the) missing reference. */
3665 if (debug_type == DEBUG_DWARF2)
3666 dwarf2_where (pool->locs + entry);
3667#endif
c19d1205
ZW
3668 pool->next_free_entry += 1;
3669 }
8335d6aa
JW
3670 else if (padding_slot_p)
3671 {
e2b0ab59 3672 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3673 pool->literals[entry].X_md = nbytes;
3674 }
b99bd4ef 3675
e2b0ab59
AV
3676 inst.relocs[0].exp.X_op = O_symbol;
3677 inst.relocs[0].exp.X_add_number = pool_size;
3678 inst.relocs[0].exp.X_add_symbol = pool->symbol;
b99bd4ef 3679
c19d1205 3680 return SUCCESS;
b99bd4ef
NC
3681}
3682
5b7c81bd 3683bool
2e57ce7b 3684tc_start_label_without_colon (void)
2e6976a8 3685{
5b7c81bd 3686 bool ret = true;
2e6976a8
DG
3687
3688 if (codecomposer_syntax && asmfunc_state == WAITING_ASMFUNC_NAME)
3689 {
2e57ce7b 3690 const char *label = input_line_pointer;
2e6976a8
DG
3691
3692 while (!is_end_of_line[(int) label[-1]])
3693 --label;
3694
3695 if (*label == '.')
3696 {
3697 as_bad (_("Invalid label '%s'"), label);
5b7c81bd 3698 ret = false;
2e6976a8
DG
3699 }
3700
3701 asmfunc_debug (label);
3702
3703 asmfunc_state = WAITING_ENDASMFUNC;
3704 }
3705
3706 return ret;
3707}
3708
c19d1205 3709/* Can't use symbol_new here, so have to create a symbol and then at
33eaf5de 3710 a later date assign it a value. That's what these functions do. */
e16bb312 3711
c19d1205
ZW
3712static void
3713symbol_locate (symbolS * symbolP,
3714 const char * name, /* It is copied, the caller can modify. */
3715 segT segment, /* Segment identifier (SEG_<something>). */
3716 valueT valu, /* Symbol value. */
3717 fragS * frag) /* Associated fragment. */
3718{
e57e6ddc 3719 size_t name_length;
c19d1205 3720 char * preserved_copy_of_name;
e16bb312 3721
c19d1205
ZW
3722 name_length = strlen (name) + 1; /* +1 for \0. */
3723 obstack_grow (&notes, name, name_length);
21d799b5 3724 preserved_copy_of_name = (char *) obstack_finish (&notes);
e16bb312 3725
c19d1205
ZW
3726#ifdef tc_canonicalize_symbol_name
3727 preserved_copy_of_name =
3728 tc_canonicalize_symbol_name (preserved_copy_of_name);
3729#endif
b99bd4ef 3730
c19d1205 3731 S_SET_NAME (symbolP, preserved_copy_of_name);
b99bd4ef 3732
c19d1205
ZW
3733 S_SET_SEGMENT (symbolP, segment);
3734 S_SET_VALUE (symbolP, valu);
3735 symbol_clear_list_pointers (symbolP);
b99bd4ef 3736
c19d1205 3737 symbol_set_frag (symbolP, frag);
b99bd4ef 3738
c19d1205
ZW
3739 /* Link to end of symbol chain. */
3740 {
3741 extern int symbol_table_frozen;
b99bd4ef 3742
c19d1205
ZW
3743 if (symbol_table_frozen)
3744 abort ();
3745 }
b99bd4ef 3746
c19d1205 3747 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
b99bd4ef 3748
c19d1205 3749 obj_symbol_new_hook (symbolP);
b99bd4ef 3750
c19d1205
ZW
3751#ifdef tc_symbol_new_hook
3752 tc_symbol_new_hook (symbolP);
3753#endif
3754
3755#ifdef DEBUG_SYMS
3756 verify_symbol_chain (symbol_rootP, symbol_lastP);
3757#endif /* DEBUG_SYMS */
b99bd4ef
NC
3758}
3759
c19d1205
ZW
3760static void
3761s_ltorg (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 3762{
c19d1205
ZW
3763 unsigned int entry;
3764 literal_pool * pool;
3765 char sym_name[20];
b99bd4ef 3766
a37854f9 3767 demand_empty_rest_of_line ();
c19d1205
ZW
3768 pool = find_literal_pool ();
3769 if (pool == NULL
3770 || pool->symbol == NULL
3771 || pool->next_free_entry == 0)
3772 return;
b99bd4ef 3773
c19d1205
ZW
3774 /* Align pool as you have word accesses.
3775 Only make a frag if we have to. */
3776 if (!need_pass_2)
8335d6aa 3777 frag_align (pool->alignment, 0, 0);
b99bd4ef 3778
c19d1205 3779 record_alignment (now_seg, 2);
b99bd4ef 3780
aaca88ef 3781#ifdef OBJ_ELF
47fc6e36
WN
3782 seg_info (now_seg)->tc_segment_info_data.mapstate = MAP_DATA;
3783 make_mapping_symbol (MAP_DATA, (valueT) frag_now_fix (), frag_now);
aaca88ef 3784#endif
c19d1205 3785 sprintf (sym_name, "$$lit_\002%x", pool->id);
b99bd4ef 3786
c19d1205
ZW
3787 symbol_locate (pool->symbol, sym_name, now_seg,
3788 (valueT) frag_now_fix (), frag_now);
3789 symbol_table_insert (pool->symbol);
b99bd4ef 3790
c19d1205 3791 ARM_SET_THUMB (pool->symbol, thumb_mode);
b99bd4ef 3792
c19d1205
ZW
3793#if defined OBJ_COFF || defined OBJ_ELF
3794 ARM_SET_INTERWORK (pool->symbol, support_interwork);
3795#endif
6c43fab6 3796
c19d1205 3797 for (entry = 0; entry < pool->next_free_entry; entry ++)
a8040cf2
NC
3798 {
3799#ifdef OBJ_ELF
3800 if (debug_type == DEBUG_DWARF2)
3801 dwarf2_gen_line_info (frag_now_fix (), pool->locs + entry);
3802#endif
3803 /* First output the expression in the instruction to the pool. */
8335d6aa
JW
3804 emit_expr (&(pool->literals[entry]),
3805 pool->literals[entry].X_md & LIT_ENTRY_SIZE_MASK);
a8040cf2 3806 }
b99bd4ef 3807
c19d1205
ZW
3808 /* Mark the pool as empty. */
3809 pool->next_free_entry = 0;
3810 pool->symbol = NULL;
b99bd4ef
NC
3811}
3812
c19d1205
ZW
3813#ifdef OBJ_ELF
3814/* Forward declarations for functions below, in the MD interface
3815 section. */
3816static void fix_new_arm (fragS *, int, short, expressionS *, int, int);
3817static valueT create_unwind_entry (int);
3818static void start_unwind_section (const segT, int);
3819static void add_unwind_opcode (valueT, int);
3820static void flush_pending_unwind (void);
b99bd4ef 3821
c19d1205 3822/* Directives: Data. */
b99bd4ef 3823
c19d1205
ZW
3824static void
3825s_arm_elf_cons (int nbytes)
3826{
3827 expressionS exp;
b99bd4ef 3828
c19d1205
ZW
3829#ifdef md_flush_pending_output
3830 md_flush_pending_output ();
3831#endif
b99bd4ef 3832
c19d1205 3833 if (is_it_end_of_statement ())
b99bd4ef 3834 {
c19d1205
ZW
3835 demand_empty_rest_of_line ();
3836 return;
b99bd4ef
NC
3837 }
3838
c19d1205
ZW
3839#ifdef md_cons_align
3840 md_cons_align (nbytes);
3841#endif
b99bd4ef 3842
c19d1205
ZW
3843 mapping_state (MAP_DATA);
3844 do
b99bd4ef 3845 {
c19d1205
ZW
3846 int reloc;
3847 char *base = input_line_pointer;
b99bd4ef 3848
c19d1205 3849 expression (& exp);
b99bd4ef 3850
c19d1205
ZW
3851 if (exp.X_op != O_symbol)
3852 emit_expr (&exp, (unsigned int) nbytes);
3853 else
3854 {
3855 char *before_reloc = input_line_pointer;
3856 reloc = parse_reloc (&input_line_pointer);
3857 if (reloc == -1)
3858 {
3859 as_bad (_("unrecognized relocation suffix"));
3860 ignore_rest_of_line ();
3861 return;
3862 }
3863 else if (reloc == BFD_RELOC_UNUSED)
3864 emit_expr (&exp, (unsigned int) nbytes);
3865 else
3866 {
21d799b5 3867 reloc_howto_type *howto = (reloc_howto_type *)
477330fc
RM
3868 bfd_reloc_type_lookup (stdoutput,
3869 (bfd_reloc_code_real_type) reloc);
c19d1205 3870 int size = bfd_get_reloc_size (howto);
b99bd4ef 3871
2fc8bdac
ZW
3872 if (reloc == BFD_RELOC_ARM_PLT32)
3873 {
3874 as_bad (_("(plt) is only valid on branch targets"));
3875 reloc = BFD_RELOC_UNUSED;
3876 size = 0;
3877 }
3878
c19d1205 3879 if (size > nbytes)
992a06ee
AM
3880 as_bad (ngettext ("%s relocations do not fit in %d byte",
3881 "%s relocations do not fit in %d bytes",
3882 nbytes),
c19d1205
ZW
3883 howto->name, nbytes);
3884 else
3885 {
3886 /* We've parsed an expression stopping at O_symbol.
3887 But there may be more expression left now that we
3888 have parsed the relocation marker. Parse it again.
3889 XXX Surely there is a cleaner way to do this. */
3890 char *p = input_line_pointer;
3891 int offset;
325801bd 3892 char *save_buf = XNEWVEC (char, input_line_pointer - base);
e1fa0163 3893
c19d1205
ZW
3894 memcpy (save_buf, base, input_line_pointer - base);
3895 memmove (base + (input_line_pointer - before_reloc),
3896 base, before_reloc - base);
3897
3898 input_line_pointer = base + (input_line_pointer-before_reloc);
3899 expression (&exp);
3900 memcpy (base, save_buf, p - base);
3901
3902 offset = nbytes - size;
4b1a927e
AM
3903 p = frag_more (nbytes);
3904 memset (p, 0, nbytes);
c19d1205 3905 fix_new_exp (frag_now, p - frag_now->fr_literal + offset,
21d799b5 3906 size, &exp, 0, (enum bfd_reloc_code_real) reloc);
e1fa0163 3907 free (save_buf);
c19d1205
ZW
3908 }
3909 }
3910 }
b99bd4ef 3911 }
c19d1205 3912 while (*input_line_pointer++ == ',');
b99bd4ef 3913
c19d1205
ZW
3914 /* Put terminator back into stream. */
3915 input_line_pointer --;
3916 demand_empty_rest_of_line ();
b99bd4ef
NC
3917}
3918
c921be7d
NC
3919/* Emit an expression containing a 32-bit thumb instruction.
3920 Implementation based on put_thumb32_insn. */
3921
3922static void
3923emit_thumb32_expr (expressionS * exp)
3924{
3925 expressionS exp_high = *exp;
3926
3927 exp_high.X_add_number = (unsigned long)exp_high.X_add_number >> 16;
3928 emit_expr (& exp_high, (unsigned int) THUMB_SIZE);
3929 exp->X_add_number &= 0xffff;
3930 emit_expr (exp, (unsigned int) THUMB_SIZE);
3931}
3932
3933/* Guess the instruction size based on the opcode. */
3934
3935static int
3936thumb_insn_size (int opcode)
3937{
3938 if ((unsigned int) opcode < 0xe800u)
3939 return 2;
3940 else if ((unsigned int) opcode >= 0xe8000000u)
3941 return 4;
3942 else
3943 return 0;
3944}
3945
5b7c81bd 3946static bool
c921be7d
NC
3947emit_insn (expressionS *exp, int nbytes)
3948{
3949 int size = 0;
3950
3951 if (exp->X_op == O_constant)
3952 {
3953 size = nbytes;
3954
3955 if (size == 0)
3956 size = thumb_insn_size (exp->X_add_number);
3957
3958 if (size != 0)
3959 {
3960 if (size == 2 && (unsigned int)exp->X_add_number > 0xffffu)
3961 {
3962 as_bad (_(".inst.n operand too big. "\
3963 "Use .inst.w instead"));
3964 size = 0;
3965 }
3966 else
3967 {
5ee91343
AV
3968 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
3969 set_pred_insn_type_nonvoid (OUTSIDE_PRED_INSN, 0);
c921be7d 3970 else
5ee91343 3971 set_pred_insn_type_nonvoid (NEUTRAL_IT_INSN, 0);
c921be7d
NC
3972
3973 if (thumb_mode && (size > THUMB_SIZE) && !target_big_endian)
3974 emit_thumb32_expr (exp);
3975 else
3976 emit_expr (exp, (unsigned int) size);
3977
3978 it_fsm_post_encode ();
3979 }
3980 }
3981 else
3982 as_bad (_("cannot determine Thumb instruction size. " \
3983 "Use .inst.n/.inst.w instead"));
3984 }
3985 else
3986 as_bad (_("constant expression required"));
3987
3988 return (size != 0);
3989}
3990
3991/* Like s_arm_elf_cons but do not use md_cons_align and
3992 set the mapping state to MAP_ARM/MAP_THUMB. */
3993
3994static void
3995s_arm_elf_inst (int nbytes)
3996{
3997 if (is_it_end_of_statement ())
3998 {
3999 demand_empty_rest_of_line ();
4000 return;
4001 }
4002
4003 /* Calling mapping_state () here will not change ARM/THUMB,
4004 but will ensure not to be in DATA state. */
4005
4006 if (thumb_mode)
4007 mapping_state (MAP_THUMB);
4008 else
4009 {
4010 if (nbytes != 0)
4011 {
4012 as_bad (_("width suffixes are invalid in ARM mode"));
4013 ignore_rest_of_line ();
4014 return;
4015 }
4016
4017 nbytes = 4;
4018
4019 mapping_state (MAP_ARM);
4020 }
4021
13d414af
JB
4022 dwarf2_emit_insn (0);
4023
c921be7d
NC
4024 do
4025 {
4026 expressionS exp;
4027
4028 expression (& exp);
4029
4030 if (! emit_insn (& exp, nbytes))
4031 {
4032 ignore_rest_of_line ();
4033 return;
4034 }
4035 }
4036 while (*input_line_pointer++ == ',');
4037
4038 /* Put terminator back into stream. */
4039 input_line_pointer --;
4040 demand_empty_rest_of_line ();
4041}
b99bd4ef 4042
c19d1205 4043/* Parse a .rel31 directive. */
b99bd4ef 4044
c19d1205
ZW
4045static void
4046s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
4047{
4048 expressionS exp;
4049 char *p;
4050 valueT highbit;
b99bd4ef 4051
c19d1205
ZW
4052 highbit = 0;
4053 if (*input_line_pointer == '1')
4054 highbit = 0x80000000;
4055 else if (*input_line_pointer != '0')
4056 as_bad (_("expected 0 or 1"));
b99bd4ef 4057
c19d1205
ZW
4058 input_line_pointer++;
4059 if (*input_line_pointer != ',')
4060 as_bad (_("missing comma"));
4061 input_line_pointer++;
b99bd4ef 4062
c19d1205
ZW
4063#ifdef md_flush_pending_output
4064 md_flush_pending_output ();
4065#endif
b99bd4ef 4066
c19d1205
ZW
4067#ifdef md_cons_align
4068 md_cons_align (4);
4069#endif
b99bd4ef 4070
c19d1205 4071 mapping_state (MAP_DATA);
b99bd4ef 4072
c19d1205 4073 expression (&exp);
b99bd4ef 4074
c19d1205
ZW
4075 p = frag_more (4);
4076 md_number_to_chars (p, highbit, 4);
4077 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
4078 BFD_RELOC_ARM_PREL31);
b99bd4ef 4079
c19d1205 4080 demand_empty_rest_of_line ();
b99bd4ef
NC
4081}
4082
c19d1205 4083/* Directives: AEABI stack-unwind tables. */
b99bd4ef 4084
c19d1205 4085/* Parse an unwind_fnstart directive. Simply records the current location. */
b99bd4ef 4086
c19d1205
ZW
4087static void
4088s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
4089{
4090 demand_empty_rest_of_line ();
921e5f0a
PB
4091 if (unwind.proc_start)
4092 {
c921be7d 4093 as_bad (_("duplicate .fnstart directive"));
921e5f0a
PB
4094 return;
4095 }
4096
c19d1205
ZW
4097 /* Mark the start of the function. */
4098 unwind.proc_start = expr_build_dot ();
b99bd4ef 4099
c19d1205
ZW
4100 /* Reset the rest of the unwind info. */
4101 unwind.opcode_count = 0;
4102 unwind.table_entry = NULL;
4103 unwind.personality_routine = NULL;
4104 unwind.personality_index = -1;
4105 unwind.frame_size = 0;
4106 unwind.fp_offset = 0;
fdfde340 4107 unwind.fp_reg = REG_SP;
c19d1205
ZW
4108 unwind.fp_used = 0;
4109 unwind.sp_restored = 0;
4110}
b99bd4ef 4111
c19d1205
ZW
4112/* Parse a handlerdata directive. Creates the exception handling table entry
4113 for the function. */
b99bd4ef 4114
c19d1205
ZW
4115static void
4116s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
4117{
4118 demand_empty_rest_of_line ();
921e5f0a 4119 if (!unwind.proc_start)
c921be7d 4120 as_bad (MISSING_FNSTART);
921e5f0a 4121
c19d1205 4122 if (unwind.table_entry)
6decc662 4123 as_bad (_("duplicate .handlerdata directive"));
f02232aa 4124
c19d1205
ZW
4125 create_unwind_entry (1);
4126}
a737bd4d 4127
c19d1205 4128/* Parse an unwind_fnend directive. Generates the index table entry. */
b99bd4ef 4129
c19d1205
ZW
4130static void
4131s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
4132{
4133 long where;
4134 char *ptr;
4135 valueT val;
940b5ce0 4136 unsigned int marked_pr_dependency;
f02232aa 4137
c19d1205 4138 demand_empty_rest_of_line ();
f02232aa 4139
921e5f0a
PB
4140 if (!unwind.proc_start)
4141 {
c921be7d 4142 as_bad (_(".fnend directive without .fnstart"));
921e5f0a
PB
4143 return;
4144 }
4145
c19d1205
ZW
4146 /* Add eh table entry. */
4147 if (unwind.table_entry == NULL)
4148 val = create_unwind_entry (0);
4149 else
4150 val = 0;
f02232aa 4151
c19d1205
ZW
4152 /* Add index table entry. This is two words. */
4153 start_unwind_section (unwind.saved_seg, 1);
4154 frag_align (2, 0, 0);
4155 record_alignment (now_seg, 2);
b99bd4ef 4156
c19d1205 4157 ptr = frag_more (8);
5011093d 4158 memset (ptr, 0, 8);
c19d1205 4159 where = frag_now_fix () - 8;
f02232aa 4160
c19d1205
ZW
4161 /* Self relative offset of the function start. */
4162 fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
4163 BFD_RELOC_ARM_PREL31);
f02232aa 4164
c19d1205
ZW
4165 /* Indicate dependency on EHABI-defined personality routines to the
4166 linker, if it hasn't been done already. */
940b5ce0
DJ
4167 marked_pr_dependency
4168 = seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency;
c19d1205
ZW
4169 if (unwind.personality_index >= 0 && unwind.personality_index < 3
4170 && !(marked_pr_dependency & (1 << unwind.personality_index)))
4171 {
5f4273c7
NC
4172 static const char *const name[] =
4173 {
4174 "__aeabi_unwind_cpp_pr0",
4175 "__aeabi_unwind_cpp_pr1",
4176 "__aeabi_unwind_cpp_pr2"
4177 };
c19d1205
ZW
4178 symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
4179 fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
c19d1205 4180 seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
940b5ce0 4181 |= 1 << unwind.personality_index;
c19d1205 4182 }
f02232aa 4183
c19d1205
ZW
4184 if (val)
4185 /* Inline exception table entry. */
4186 md_number_to_chars (ptr + 4, val, 4);
4187 else
4188 /* Self relative offset of the table entry. */
4189 fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
4190 BFD_RELOC_ARM_PREL31);
f02232aa 4191
c19d1205
ZW
4192 /* Restore the original section. */
4193 subseg_set (unwind.saved_seg, unwind.saved_subseg);
921e5f0a
PB
4194
4195 unwind.proc_start = NULL;
c19d1205 4196}
f02232aa 4197
f02232aa 4198
c19d1205 4199/* Parse an unwind_cantunwind directive. */
b99bd4ef 4200
c19d1205
ZW
4201static void
4202s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
4203{
4204 demand_empty_rest_of_line ();
921e5f0a 4205 if (!unwind.proc_start)
c921be7d 4206 as_bad (MISSING_FNSTART);
921e5f0a 4207
c19d1205
ZW
4208 if (unwind.personality_routine || unwind.personality_index != -1)
4209 as_bad (_("personality routine specified for cantunwind frame"));
b99bd4ef 4210
c19d1205
ZW
4211 unwind.personality_index = -2;
4212}
b99bd4ef 4213
b99bd4ef 4214
c19d1205 4215/* Parse a personalityindex directive. */
b99bd4ef 4216
c19d1205
ZW
4217static void
4218s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
4219{
4220 expressionS exp;
b99bd4ef 4221
921e5f0a 4222 if (!unwind.proc_start)
c921be7d 4223 as_bad (MISSING_FNSTART);
921e5f0a 4224
c19d1205
ZW
4225 if (unwind.personality_routine || unwind.personality_index != -1)
4226 as_bad (_("duplicate .personalityindex directive"));
b99bd4ef 4227
c19d1205 4228 expression (&exp);
b99bd4ef 4229
c19d1205
ZW
4230 if (exp.X_op != O_constant
4231 || exp.X_add_number < 0 || exp.X_add_number > 15)
b99bd4ef 4232 {
c19d1205
ZW
4233 as_bad (_("bad personality routine number"));
4234 ignore_rest_of_line ();
4235 return;
b99bd4ef
NC
4236 }
4237
c19d1205 4238 unwind.personality_index = exp.X_add_number;
b99bd4ef 4239
c19d1205
ZW
4240 demand_empty_rest_of_line ();
4241}
e16bb312 4242
e16bb312 4243
c19d1205 4244/* Parse a personality directive. */
e16bb312 4245
c19d1205
ZW
4246static void
4247s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
4248{
4249 char *name, *p, c;
a737bd4d 4250
921e5f0a 4251 if (!unwind.proc_start)
c921be7d 4252 as_bad (MISSING_FNSTART);
921e5f0a 4253
c19d1205
ZW
4254 if (unwind.personality_routine || unwind.personality_index != -1)
4255 as_bad (_("duplicate .personality directive"));
a737bd4d 4256
d02603dc 4257 c = get_symbol_name (& name);
c19d1205 4258 p = input_line_pointer;
d02603dc
NC
4259 if (c == '"')
4260 ++ input_line_pointer;
c19d1205
ZW
4261 unwind.personality_routine = symbol_find_or_make (name);
4262 *p = c;
4263 demand_empty_rest_of_line ();
4264}
e16bb312 4265
8c299995
TB
4266/* Parse a directive saving pseudo registers. */
4267
4268static void
3a368c4c 4269s_arm_unwind_save_pseudo (int regno)
8c299995
TB
4270{
4271 valueT op;
8c299995 4272
3a368c4c 4273 switch (regno)
8c299995 4274 {
3a368c4c 4275 case REG_RA_AUTH_CODE:
8c299995
TB
4276 /* Opcode for restoring RA_AUTH_CODE. */
4277 op = 0xb4;
4278 add_unwind_opcode (op, 1);
3a368c4c
VDN
4279 break;
4280 default:
4281 as_bad (_("Unknown register no. encountered: %d\n"), regno);
8c299995
TB
4282 }
4283}
4284
e16bb312 4285
c19d1205 4286/* Parse a directive saving core registers. */
e16bb312 4287
c19d1205 4288static void
3363d856 4289s_arm_unwind_save_core (long range)
e16bb312 4290{
c19d1205 4291 valueT op;
c19d1205 4292 int n;
e16bb312 4293
c19d1205
ZW
4294 /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
4295 into .unwind_save {..., sp...}. We aren't bothered about the value of
4296 ip because it is clobbered by calls. */
4297 if (unwind.sp_restored && unwind.fp_reg == 12
4298 && (range & 0x3000) == 0x1000)
4299 {
4300 unwind.opcode_count--;
4301 unwind.sp_restored = 0;
4302 range = (range | 0x2000) & ~0x1000;
4303 unwind.pending_offset = 0;
4304 }
e16bb312 4305
01ae4198
DJ
4306 /* Pop r4-r15. */
4307 if (range & 0xfff0)
c19d1205 4308 {
01ae4198
DJ
4309 /* See if we can use the short opcodes. These pop a block of up to 8
4310 registers starting with r4, plus maybe r14. */
4311 for (n = 0; n < 8; n++)
4312 {
4313 /* Break at the first non-saved register. */
4314 if ((range & (1 << (n + 4))) == 0)
4315 break;
4316 }
4317 /* See if there are any other bits set. */
4318 if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
4319 {
4320 /* Use the long form. */
4321 op = 0x8000 | ((range >> 4) & 0xfff);
4322 add_unwind_opcode (op, 2);
4323 }
0dd132b6 4324 else
01ae4198
DJ
4325 {
4326 /* Use the short form. */
4327 if (range & 0x4000)
4328 op = 0xa8; /* Pop r14. */
4329 else
4330 op = 0xa0; /* Do not pop r14. */
4331 op |= (n - 1);
4332 add_unwind_opcode (op, 1);
4333 }
c19d1205 4334 }
0dd132b6 4335
c19d1205
ZW
4336 /* Pop r0-r3. */
4337 if (range & 0xf)
4338 {
4339 op = 0xb100 | (range & 0xf);
4340 add_unwind_opcode (op, 2);
0dd132b6
NC
4341 }
4342
c19d1205
ZW
4343 /* Record the number of bytes pushed. */
4344 for (n = 0; n < 16; n++)
4345 {
4346 if (range & (1 << n))
4347 unwind.frame_size += 4;
4348 }
0dd132b6
NC
4349}
4350
3a368c4c
VDN
4351/* Implement correct handling of .save lists enabling the split into
4352sublists where necessary, while preserving correct sublist ordering. */
4353
4354static void
4355parse_dot_save (char **str_p, int prev_reg)
4356{
4357 long core_regs = 0;
4358 int reg;
4359 int in_range = 0;
4360
4361 if (**str_p == ',')
4362 *str_p += 1;
4363 if (**str_p == '}')
4364 {
4365 *str_p += 1;
4366 return;
4367 }
4368
4369 while ((reg = arm_reg_parse (str_p, REG_TYPE_RN)) != FAIL)
4370 {
4371 if (!in_range)
4372 {
4373 if (core_regs & (1 << reg))
4374 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
4375 reg);
4376 else if (reg <= prev_reg)
4377 as_tsktsk (_("Warning: register list not in ascending order"));
4378
4379 core_regs |= (1 << reg);
4380 prev_reg = reg;
4381 if (skip_past_char(str_p, '-') != FAIL)
4382 in_range = 1;
4383 else if (skip_past_comma(str_p) == FAIL)
4384 first_error (_("bad register list"));
4385 }
4386 else
4387 {
4388 int i;
4389 if (reg <= prev_reg)
4390 first_error (_("bad range in register list"));
4391 for (i = prev_reg + 1; i <= reg; i++)
4392 {
4393 if (core_regs & (1 << i))
4394 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
4395 i);
4396 else
4397 core_regs |= 1 << i;
4398 }
4399 in_range = 0;
4400 }
4401 }
4402 if (core_regs)
4403 {
4404 /* Higher register numbers go in higher memory addresses. When splitting a list,
4405 right-most sublist should therefore be .saved first. Use recursion for this. */
4406 parse_dot_save (str_p, reg);
4407 /* We're back from recursion, so emit .save insn for sublist. */
4408 s_arm_unwind_save_core (core_regs);
4409 return;
4410 }
4411 /* Handle pseudo-regs, under assumption these are emitted singly. */
4412 else if ((reg = arm_reg_parse (str_p, REG_TYPE_PSEUDO)) != FAIL)
4413 {
4414 /* recurse for remainder of input. Note: No assumption is made regarding which
4415 register in core register set holds pseudo-register. It's not considered in
4416 ordering check beyond ensuring it's not sandwiched between 2 consecutive
4417 registers. */
4418 parse_dot_save (str_p, prev_reg + 1);
4419 s_arm_unwind_save_pseudo (reg);
4420 return;
4421 }
4422 else
4423 as_bad (BAD_SYNTAX);
4424}
c19d1205
ZW
4425
4426/* Parse a directive saving FPA registers. */
b99bd4ef
NC
4427
4428static void
c19d1205 4429s_arm_unwind_save_fpa (int reg)
b99bd4ef 4430{
c19d1205
ZW
4431 expressionS exp;
4432 int num_regs;
4433 valueT op;
b99bd4ef 4434
c19d1205
ZW
4435 /* Get Number of registers to transfer. */
4436 if (skip_past_comma (&input_line_pointer) != FAIL)
4437 expression (&exp);
4438 else
4439 exp.X_op = O_illegal;
b99bd4ef 4440
c19d1205 4441 if (exp.X_op != O_constant)
b99bd4ef 4442 {
c19d1205
ZW
4443 as_bad (_("expected , <constant>"));
4444 ignore_rest_of_line ();
b99bd4ef
NC
4445 return;
4446 }
4447
c19d1205
ZW
4448 num_regs = exp.X_add_number;
4449
4450 if (num_regs < 1 || num_regs > 4)
b99bd4ef 4451 {
c19d1205
ZW
4452 as_bad (_("number of registers must be in the range [1:4]"));
4453 ignore_rest_of_line ();
b99bd4ef
NC
4454 return;
4455 }
4456
c19d1205 4457 demand_empty_rest_of_line ();
b99bd4ef 4458
c19d1205
ZW
4459 if (reg == 4)
4460 {
4461 /* Short form. */
4462 op = 0xb4 | (num_regs - 1);
4463 add_unwind_opcode (op, 1);
4464 }
b99bd4ef
NC
4465 else
4466 {
c19d1205
ZW
4467 /* Long form. */
4468 op = 0xc800 | (reg << 4) | (num_regs - 1);
4469 add_unwind_opcode (op, 2);
b99bd4ef 4470 }
c19d1205 4471 unwind.frame_size += num_regs * 12;
b99bd4ef
NC
4472}
4473
c19d1205 4474
fa073d69
MS
4475/* Parse a directive saving VFP registers for ARMv6 and above. */
4476
4477static void
4478s_arm_unwind_save_vfp_armv6 (void)
4479{
4480 int count;
4481 unsigned int start;
4482 valueT op;
4483 int num_vfpv3_regs = 0;
4484 int num_regs_below_16;
5b7c81bd 4485 bool partial_match;
fa073d69 4486
efd6b359
AV
4487 count = parse_vfp_reg_list (&input_line_pointer, &start, REGLIST_VFP_D,
4488 &partial_match);
fa073d69
MS
4489 if (count == FAIL)
4490 {
4491 as_bad (_("expected register list"));
4492 ignore_rest_of_line ();
4493 return;
4494 }
4495
4496 demand_empty_rest_of_line ();
4497
4498 /* We always generate FSTMD/FLDMD-style unwinding opcodes (rather
4499 than FSTMX/FLDMX-style ones). */
4500
4501 /* Generate opcode for (VFPv3) registers numbered in the range 16 .. 31. */
4502 if (start >= 16)
4503 num_vfpv3_regs = count;
4504 else if (start + count > 16)
4505 num_vfpv3_regs = start + count - 16;
4506
4507 if (num_vfpv3_regs > 0)
4508 {
4509 int start_offset = start > 16 ? start - 16 : 0;
4510 op = 0xc800 | (start_offset << 4) | (num_vfpv3_regs - 1);
4511 add_unwind_opcode (op, 2);
4512 }
4513
4514 /* Generate opcode for registers numbered in the range 0 .. 15. */
4515 num_regs_below_16 = num_vfpv3_regs > 0 ? 16 - (int) start : count;
9c2799c2 4516 gas_assert (num_regs_below_16 + num_vfpv3_regs == count);
fa073d69
MS
4517 if (num_regs_below_16 > 0)
4518 {
4519 op = 0xc900 | (start << 4) | (num_regs_below_16 - 1);
4520 add_unwind_opcode (op, 2);
4521 }
4522
4523 unwind.frame_size += count * 8;
4524}
4525
4526
4527/* Parse a directive saving VFP registers for pre-ARMv6. */
b99bd4ef
NC
4528
4529static void
c19d1205 4530s_arm_unwind_save_vfp (void)
b99bd4ef 4531{
c19d1205 4532 int count;
ca3f61f7 4533 unsigned int reg;
c19d1205 4534 valueT op;
5b7c81bd 4535 bool partial_match;
b99bd4ef 4536
efd6b359
AV
4537 count = parse_vfp_reg_list (&input_line_pointer, &reg, REGLIST_VFP_D,
4538 &partial_match);
c19d1205 4539 if (count == FAIL)
b99bd4ef 4540 {
c19d1205
ZW
4541 as_bad (_("expected register list"));
4542 ignore_rest_of_line ();
b99bd4ef
NC
4543 return;
4544 }
4545
c19d1205 4546 demand_empty_rest_of_line ();
b99bd4ef 4547
c19d1205 4548 if (reg == 8)
b99bd4ef 4549 {
c19d1205
ZW
4550 /* Short form. */
4551 op = 0xb8 | (count - 1);
4552 add_unwind_opcode (op, 1);
b99bd4ef 4553 }
c19d1205 4554 else
b99bd4ef 4555 {
c19d1205
ZW
4556 /* Long form. */
4557 op = 0xb300 | (reg << 4) | (count - 1);
4558 add_unwind_opcode (op, 2);
b99bd4ef 4559 }
c19d1205
ZW
4560 unwind.frame_size += count * 8 + 4;
4561}
b99bd4ef 4562
b99bd4ef 4563
c19d1205
ZW
4564/* Parse a directive saving iWMMXt data registers. */
4565
4566static void
4567s_arm_unwind_save_mmxwr (void)
4568{
4569 int reg;
4570 int hi_reg;
4571 int i;
4572 unsigned mask = 0;
4573 valueT op;
b99bd4ef 4574
c19d1205
ZW
4575 if (*input_line_pointer == '{')
4576 input_line_pointer++;
b99bd4ef 4577
c19d1205 4578 do
b99bd4ef 4579 {
dcbf9037 4580 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
b99bd4ef 4581
c19d1205 4582 if (reg == FAIL)
b99bd4ef 4583 {
9b7132d3 4584 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205 4585 goto error;
b99bd4ef
NC
4586 }
4587
c19d1205
ZW
4588 if (mask >> reg)
4589 as_tsktsk (_("register list not in ascending order"));
4590 mask |= 1 << reg;
b99bd4ef 4591
c19d1205
ZW
4592 if (*input_line_pointer == '-')
4593 {
4594 input_line_pointer++;
dcbf9037 4595 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
c19d1205
ZW
4596 if (hi_reg == FAIL)
4597 {
9b7132d3 4598 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205
ZW
4599 goto error;
4600 }
4601 else if (reg >= hi_reg)
4602 {
4603 as_bad (_("bad register range"));
4604 goto error;
4605 }
4606 for (; reg < hi_reg; reg++)
4607 mask |= 1 << reg;
4608 }
4609 }
4610 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4611
d996d970 4612 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4613
c19d1205 4614 demand_empty_rest_of_line ();
b99bd4ef 4615
708587a4 4616 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4617 the list. */
4618 flush_pending_unwind ();
b99bd4ef 4619
c19d1205 4620 for (i = 0; i < 16; i++)
b99bd4ef 4621 {
c19d1205
ZW
4622 if (mask & (1 << i))
4623 unwind.frame_size += 8;
b99bd4ef
NC
4624 }
4625
c19d1205
ZW
4626 /* Attempt to combine with a previous opcode. We do this because gcc
4627 likes to output separate unwind directives for a single block of
4628 registers. */
4629 if (unwind.opcode_count > 0)
b99bd4ef 4630 {
c19d1205
ZW
4631 i = unwind.opcodes[unwind.opcode_count - 1];
4632 if ((i & 0xf8) == 0xc0)
4633 {
4634 i &= 7;
4635 /* Only merge if the blocks are contiguous. */
4636 if (i < 6)
4637 {
4638 if ((mask & 0xfe00) == (1 << 9))
4639 {
4640 mask |= ((1 << (i + 11)) - 1) & 0xfc00;
4641 unwind.opcode_count--;
4642 }
4643 }
4644 else if (i == 6 && unwind.opcode_count >= 2)
4645 {
4646 i = unwind.opcodes[unwind.opcode_count - 2];
4647 reg = i >> 4;
4648 i &= 0xf;
b99bd4ef 4649
c19d1205
ZW
4650 op = 0xffff << (reg - 1);
4651 if (reg > 0
87a1fd79 4652 && ((mask & op) == (1u << (reg - 1))))
c19d1205
ZW
4653 {
4654 op = (1 << (reg + i + 1)) - 1;
4655 op &= ~((1 << reg) - 1);
4656 mask |= op;
4657 unwind.opcode_count -= 2;
4658 }
4659 }
4660 }
b99bd4ef
NC
4661 }
4662
c19d1205
ZW
4663 hi_reg = 15;
4664 /* We want to generate opcodes in the order the registers have been
4665 saved, ie. descending order. */
4666 for (reg = 15; reg >= -1; reg--)
b99bd4ef 4667 {
c19d1205
ZW
4668 /* Save registers in blocks. */
4669 if (reg < 0
4670 || !(mask & (1 << reg)))
4671 {
4672 /* We found an unsaved reg. Generate opcodes to save the
5f4273c7 4673 preceding block. */
c19d1205
ZW
4674 if (reg != hi_reg)
4675 {
4676 if (reg == 9)
4677 {
4678 /* Short form. */
4679 op = 0xc0 | (hi_reg - 10);
4680 add_unwind_opcode (op, 1);
4681 }
4682 else
4683 {
4684 /* Long form. */
4685 op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
4686 add_unwind_opcode (op, 2);
4687 }
4688 }
4689 hi_reg = reg - 1;
4690 }
b99bd4ef
NC
4691 }
4692
c19d1205 4693 return;
dc1e8a47 4694 error:
c19d1205 4695 ignore_rest_of_line ();
b99bd4ef
NC
4696}
4697
4698static void
c19d1205 4699s_arm_unwind_save_mmxwcg (void)
b99bd4ef 4700{
c19d1205
ZW
4701 int reg;
4702 int hi_reg;
4703 unsigned mask = 0;
4704 valueT op;
b99bd4ef 4705
c19d1205
ZW
4706 if (*input_line_pointer == '{')
4707 input_line_pointer++;
b99bd4ef 4708
477330fc
RM
4709 skip_whitespace (input_line_pointer);
4710
c19d1205 4711 do
b99bd4ef 4712 {
dcbf9037 4713 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
b99bd4ef 4714
c19d1205
ZW
4715 if (reg == FAIL)
4716 {
9b7132d3 4717 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4718 goto error;
4719 }
b99bd4ef 4720
c19d1205
ZW
4721 reg -= 8;
4722 if (mask >> reg)
4723 as_tsktsk (_("register list not in ascending order"));
4724 mask |= 1 << reg;
b99bd4ef 4725
c19d1205
ZW
4726 if (*input_line_pointer == '-')
4727 {
4728 input_line_pointer++;
dcbf9037 4729 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
c19d1205
ZW
4730 if (hi_reg == FAIL)
4731 {
9b7132d3 4732 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4733 goto error;
4734 }
4735 else if (reg >= hi_reg)
4736 {
4737 as_bad (_("bad register range"));
4738 goto error;
4739 }
4740 for (; reg < hi_reg; reg++)
4741 mask |= 1 << reg;
4742 }
b99bd4ef 4743 }
c19d1205 4744 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4745
d996d970 4746 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4747
c19d1205
ZW
4748 demand_empty_rest_of_line ();
4749
708587a4 4750 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4751 the list. */
4752 flush_pending_unwind ();
b99bd4ef 4753
c19d1205 4754 for (reg = 0; reg < 16; reg++)
b99bd4ef 4755 {
c19d1205
ZW
4756 if (mask & (1 << reg))
4757 unwind.frame_size += 4;
b99bd4ef 4758 }
c19d1205
ZW
4759 op = 0xc700 | mask;
4760 add_unwind_opcode (op, 2);
4761 return;
dc1e8a47 4762 error:
c19d1205 4763 ignore_rest_of_line ();
b99bd4ef
NC
4764}
4765
fa073d69
MS
4766/* Parse an unwind_save directive.
4767 If the argument is non-zero, this is a .vsave directive. */
c19d1205 4768
b99bd4ef 4769static void
fa073d69 4770s_arm_unwind_save (int arch_v6)
b99bd4ef 4771{
3a368c4c 4772 char *peek;
c19d1205 4773 struct reg_entry *reg;
5b7c81bd 4774 bool had_brace = false;
b99bd4ef 4775
921e5f0a 4776 if (!unwind.proc_start)
c921be7d 4777 as_bad (MISSING_FNSTART);
921e5f0a 4778
c19d1205 4779 /* Figure out what sort of save we have. */
3a368c4c 4780 peek = input_line_pointer;
b99bd4ef 4781
c19d1205 4782 if (*peek == '{')
b99bd4ef 4783 {
5b7c81bd 4784 had_brace = true;
c19d1205 4785 peek++;
b99bd4ef
NC
4786 }
4787
c19d1205 4788 reg = arm_reg_parse_multi (&peek);
b99bd4ef 4789
c19d1205 4790 if (!reg)
b99bd4ef 4791 {
c19d1205
ZW
4792 as_bad (_("register expected"));
4793 ignore_rest_of_line ();
b99bd4ef
NC
4794 return;
4795 }
4796
c19d1205 4797 switch (reg->type)
b99bd4ef 4798 {
c19d1205
ZW
4799 case REG_TYPE_FN:
4800 if (had_brace)
4801 {
4802 as_bad (_("FPA .unwind_save does not take a register list"));
4803 ignore_rest_of_line ();
4804 return;
4805 }
93ac2687 4806 input_line_pointer = peek;
c19d1205 4807 s_arm_unwind_save_fpa (reg->number);
b99bd4ef 4808 return;
c19d1205 4809
3363d856 4810 case REG_TYPE_PSEUDO:
1f5afe1c 4811 case REG_TYPE_RN:
3a368c4c
VDN
4812 {
4813 if (had_brace)
4814 input_line_pointer++;
4815 parse_dot_save (&input_line_pointer, -1);
4816 demand_empty_rest_of_line ();
4817 return;
4818 }
8c299995 4819
fa073d69
MS
4820 case REG_TYPE_VFD:
4821 if (arch_v6)
477330fc 4822 s_arm_unwind_save_vfp_armv6 ();
fa073d69 4823 else
477330fc 4824 s_arm_unwind_save_vfp ();
fa073d69 4825 return;
1f5afe1c
NC
4826
4827 case REG_TYPE_MMXWR:
4828 s_arm_unwind_save_mmxwr ();
4829 return;
4830
4831 case REG_TYPE_MMXWCG:
4832 s_arm_unwind_save_mmxwcg ();
4833 return;
c19d1205
ZW
4834
4835 default:
4836 as_bad (_(".unwind_save does not support this kind of register"));
4837 ignore_rest_of_line ();
b99bd4ef 4838 }
c19d1205 4839}
b99bd4ef 4840
b99bd4ef 4841
c19d1205
ZW
4842/* Parse an unwind_movsp directive. */
4843
4844static void
4845s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
4846{
4847 int reg;
4848 valueT op;
4fa3602b 4849 int offset;
c19d1205 4850
921e5f0a 4851 if (!unwind.proc_start)
c921be7d 4852 as_bad (MISSING_FNSTART);
921e5f0a 4853
dcbf9037 4854 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205 4855 if (reg == FAIL)
b99bd4ef 4856 {
9b7132d3 4857 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_RN]));
c19d1205 4858 ignore_rest_of_line ();
b99bd4ef
NC
4859 return;
4860 }
4fa3602b
PB
4861
4862 /* Optional constant. */
4863 if (skip_past_comma (&input_line_pointer) != FAIL)
4864 {
4865 if (immediate_for_directive (&offset) == FAIL)
4866 return;
4867 }
4868 else
4869 offset = 0;
4870
c19d1205 4871 demand_empty_rest_of_line ();
b99bd4ef 4872
c19d1205 4873 if (reg == REG_SP || reg == REG_PC)
b99bd4ef 4874 {
c19d1205 4875 as_bad (_("SP and PC not permitted in .unwind_movsp directive"));
b99bd4ef
NC
4876 return;
4877 }
4878
c19d1205
ZW
4879 if (unwind.fp_reg != REG_SP)
4880 as_bad (_("unexpected .unwind_movsp directive"));
b99bd4ef 4881
c19d1205
ZW
4882 /* Generate opcode to restore the value. */
4883 op = 0x90 | reg;
4884 add_unwind_opcode (op, 1);
4885
4886 /* Record the information for later. */
4887 unwind.fp_reg = reg;
4fa3602b 4888 unwind.fp_offset = unwind.frame_size - offset;
c19d1205 4889 unwind.sp_restored = 1;
b05fe5cf
ZW
4890}
4891
c19d1205
ZW
4892/* Parse an unwind_pad directive. */
4893
b05fe5cf 4894static void
c19d1205 4895s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
b05fe5cf 4896{
c19d1205 4897 int offset;
b05fe5cf 4898
921e5f0a 4899 if (!unwind.proc_start)
c921be7d 4900 as_bad (MISSING_FNSTART);
921e5f0a 4901
c19d1205
ZW
4902 if (immediate_for_directive (&offset) == FAIL)
4903 return;
b99bd4ef 4904
c19d1205
ZW
4905 if (offset & 3)
4906 {
4907 as_bad (_("stack increment must be multiple of 4"));
4908 ignore_rest_of_line ();
4909 return;
4910 }
b99bd4ef 4911
c19d1205
ZW
4912 /* Don't generate any opcodes, just record the details for later. */
4913 unwind.frame_size += offset;
4914 unwind.pending_offset += offset;
4915
4916 demand_empty_rest_of_line ();
4917}
4918
9b1c7dc3
SP
4919/* Parse an unwind_pacspval directive. */
4920
4921static void
4922s_arm_unwind_pacspval (int ignored ATTRIBUTE_UNUSED)
4923{
4924 valueT op;
4925
4926 if (!unwind.proc_start)
4927 as_bad (MISSING_FNSTART);
4928
4929 demand_empty_rest_of_line ();
4930
4931 op = 0xb5;
4932 add_unwind_opcode (op, 1);
4933}
4934
c19d1205
ZW
4935/* Parse an unwind_setfp directive. */
4936
4937static void
4938s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 4939{
c19d1205
ZW
4940 int sp_reg;
4941 int fp_reg;
4942 int offset;
4943
921e5f0a 4944 if (!unwind.proc_start)
c921be7d 4945 as_bad (MISSING_FNSTART);
921e5f0a 4946
dcbf9037 4947 fp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205
ZW
4948 if (skip_past_comma (&input_line_pointer) == FAIL)
4949 sp_reg = FAIL;
4950 else
dcbf9037 4951 sp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
b99bd4ef 4952
c19d1205
ZW
4953 if (fp_reg == FAIL || sp_reg == FAIL)
4954 {
4955 as_bad (_("expected <reg>, <reg>"));
4956 ignore_rest_of_line ();
4957 return;
4958 }
b99bd4ef 4959
c19d1205
ZW
4960 /* Optional constant. */
4961 if (skip_past_comma (&input_line_pointer) != FAIL)
4962 {
4963 if (immediate_for_directive (&offset) == FAIL)
4964 return;
4965 }
4966 else
4967 offset = 0;
a737bd4d 4968
c19d1205 4969 demand_empty_rest_of_line ();
a737bd4d 4970
fdfde340 4971 if (sp_reg != REG_SP && sp_reg != unwind.fp_reg)
a737bd4d 4972 {
c19d1205
ZW
4973 as_bad (_("register must be either sp or set by a previous"
4974 "unwind_movsp directive"));
4975 return;
a737bd4d
NC
4976 }
4977
c19d1205
ZW
4978 /* Don't generate any opcodes, just record the information for later. */
4979 unwind.fp_reg = fp_reg;
4980 unwind.fp_used = 1;
fdfde340 4981 if (sp_reg == REG_SP)
c19d1205
ZW
4982 unwind.fp_offset = unwind.frame_size - offset;
4983 else
4984 unwind.fp_offset -= offset;
a737bd4d
NC
4985}
4986
c19d1205
ZW
4987/* Parse an unwind_raw directive. */
4988
4989static void
4990s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
a737bd4d 4991{
c19d1205 4992 expressionS exp;
708587a4 4993 /* This is an arbitrary limit. */
c19d1205
ZW
4994 unsigned char op[16];
4995 int count;
a737bd4d 4996
921e5f0a 4997 if (!unwind.proc_start)
c921be7d 4998 as_bad (MISSING_FNSTART);
921e5f0a 4999
c19d1205
ZW
5000 expression (&exp);
5001 if (exp.X_op == O_constant
5002 && skip_past_comma (&input_line_pointer) != FAIL)
a737bd4d 5003 {
c19d1205
ZW
5004 unwind.frame_size += exp.X_add_number;
5005 expression (&exp);
5006 }
5007 else
5008 exp.X_op = O_illegal;
a737bd4d 5009
c19d1205
ZW
5010 if (exp.X_op != O_constant)
5011 {
5012 as_bad (_("expected <offset>, <opcode>"));
5013 ignore_rest_of_line ();
5014 return;
5015 }
a737bd4d 5016
c19d1205 5017 count = 0;
a737bd4d 5018
c19d1205
ZW
5019 /* Parse the opcode. */
5020 for (;;)
5021 {
5022 if (count >= 16)
5023 {
5024 as_bad (_("unwind opcode too long"));
5025 ignore_rest_of_line ();
a737bd4d 5026 }
c19d1205 5027 if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
a737bd4d 5028 {
c19d1205
ZW
5029 as_bad (_("invalid unwind opcode"));
5030 ignore_rest_of_line ();
5031 return;
a737bd4d 5032 }
c19d1205 5033 op[count++] = exp.X_add_number;
a737bd4d 5034
c19d1205
ZW
5035 /* Parse the next byte. */
5036 if (skip_past_comma (&input_line_pointer) == FAIL)
5037 break;
a737bd4d 5038
c19d1205
ZW
5039 expression (&exp);
5040 }
b99bd4ef 5041
c19d1205
ZW
5042 /* Add the opcode bytes in reverse order. */
5043 while (count--)
5044 add_unwind_opcode (op[count], 1);
b99bd4ef 5045
c19d1205 5046 demand_empty_rest_of_line ();
b99bd4ef 5047}
ee065d83
PB
5048
5049
5050/* Parse a .eabi_attribute directive. */
5051
5052static void
5053s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
5054{
0420f52b 5055 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
ee3c0378 5056
3076e594 5057 if (tag >= 0 && tag < NUM_KNOWN_OBJ_ATTRIBUTES)
ee3c0378 5058 attributes_set_explicitly[tag] = 1;
ee065d83
PB
5059}
5060
0855e32b
NS
5061/* Emit a tls fix for the symbol. */
5062
5063static void
5064s_arm_tls_descseq (int ignored ATTRIBUTE_UNUSED)
5065{
5066 char *p;
5067 expressionS exp;
5068#ifdef md_flush_pending_output
5069 md_flush_pending_output ();
5070#endif
5071
5072#ifdef md_cons_align
5073 md_cons_align (4);
5074#endif
5075
5076 /* Since we're just labelling the code, there's no need to define a
5077 mapping symbol. */
5078 expression (&exp);
5079 p = obstack_next_free (&frchain_now->frch_obstack);
5080 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
5081 thumb_mode ? BFD_RELOC_ARM_THM_TLS_DESCSEQ
5082 : BFD_RELOC_ARM_TLS_DESCSEQ);
5083}
cdf9ccec 5084#endif /* OBJ_ELF */
0855e32b 5085
ee065d83 5086static void s_arm_arch (int);
7a1d4c38 5087static void s_arm_object_arch (int);
ee065d83
PB
5088static void s_arm_cpu (int);
5089static void s_arm_fpu (int);
69133863 5090static void s_arm_arch_extension (int);
b99bd4ef 5091
f0927246
NC
5092#ifdef TE_PE
5093
5094static void
5f4273c7 5095pe_directive_secrel (int dummy ATTRIBUTE_UNUSED)
f0927246
NC
5096{
5097 expressionS exp;
5098
5099 do
5100 {
5101 expression (&exp);
5102 if (exp.X_op == O_symbol)
5103 exp.X_op = O_secrel;
5104
5105 emit_expr (&exp, 4);
5106 }
5107 while (*input_line_pointer++ == ',');
5108
5109 input_line_pointer--;
5110 demand_empty_rest_of_line ();
5111}
5112#endif /* TE_PE */
5113
5312fe52
BW
5114int
5115arm_is_largest_exponent_ok (int precision)
5116{
5117 /* precision == 1 ensures that this will only return
5118 true for 16 bit floats. */
5119 return (precision == 1) && (fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
5120}
5121
5122static void
5123set_fp16_format (int dummy ATTRIBUTE_UNUSED)
5124{
5125 char saved_char;
5126 char* name;
5127 enum fp_16bit_format new_format;
5128
5129 new_format = ARM_FP16_FORMAT_DEFAULT;
5130
5131 name = input_line_pointer;
5132 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
5133 input_line_pointer++;
5134
5135 saved_char = *input_line_pointer;
5136 *input_line_pointer = 0;
5137
5138 if (strcasecmp (name, "ieee") == 0)
5139 new_format = ARM_FP16_FORMAT_IEEE;
5140 else if (strcasecmp (name, "alternative") == 0)
5141 new_format = ARM_FP16_FORMAT_ALTERNATIVE;
5142 else
5143 {
5144 as_bad (_("unrecognised float16 format \"%s\""), name);
5145 goto cleanup;
5146 }
5147
5148 /* Only set fp16_format if it is still the default (aka not already
5149 been set yet). */
5150 if (fp16_format == ARM_FP16_FORMAT_DEFAULT)
5151 fp16_format = new_format;
5152 else
5153 {
5154 if (new_format != fp16_format)
5155 as_warn (_("float16 format cannot be set more than once, ignoring."));
5156 }
5157
dc1e8a47 5158 cleanup:
5312fe52
BW
5159 *input_line_pointer = saved_char;
5160 ignore_rest_of_line ();
5161}
5162
c19d1205
ZW
5163/* This table describes all the machine specific pseudo-ops the assembler
5164 has to support. The fields are:
5165 pseudo-op name without dot
5166 function to call to execute this pseudo-op
5167 Integer arg to pass to the function. */
b99bd4ef 5168
c19d1205 5169const pseudo_typeS md_pseudo_table[] =
b99bd4ef 5170{
c19d1205
ZW
5171 /* Never called because '.req' does not start a line. */
5172 { "req", s_req, 0 },
dcbf9037
JB
5173 /* Following two are likewise never called. */
5174 { "dn", s_dn, 0 },
5175 { "qn", s_qn, 0 },
c19d1205 5176 { "unreq", s_unreq, 0 },
db2ed2e0 5177 { "align", s_align_ptwo, 2 },
c19d1205
ZW
5178 { "arm", s_arm, 0 },
5179 { "thumb", s_thumb, 0 },
5180 { "code", s_code, 0 },
5181 { "force_thumb", s_force_thumb, 0 },
5182 { "thumb_func", s_thumb_func, 0 },
5183 { "thumb_set", s_thumb_set, 0 },
5184 { "even", s_even, 0 },
5185 { "ltorg", s_ltorg, 0 },
5186 { "pool", s_ltorg, 0 },
5187 { "syntax", s_syntax, 0 },
8463be01
PB
5188 { "cpu", s_arm_cpu, 0 },
5189 { "arch", s_arm_arch, 0 },
7a1d4c38 5190 { "object_arch", s_arm_object_arch, 0 },
8463be01 5191 { "fpu", s_arm_fpu, 0 },
69133863 5192 { "arch_extension", s_arm_arch_extension, 0 },
c19d1205 5193#ifdef OBJ_ELF
c921be7d
NC
5194 { "word", s_arm_elf_cons, 4 },
5195 { "long", s_arm_elf_cons, 4 },
5196 { "inst.n", s_arm_elf_inst, 2 },
5197 { "inst.w", s_arm_elf_inst, 4 },
5198 { "inst", s_arm_elf_inst, 0 },
5199 { "rel31", s_arm_rel31, 0 },
c19d1205
ZW
5200 { "fnstart", s_arm_unwind_fnstart, 0 },
5201 { "fnend", s_arm_unwind_fnend, 0 },
5202 { "cantunwind", s_arm_unwind_cantunwind, 0 },
5203 { "personality", s_arm_unwind_personality, 0 },
5204 { "personalityindex", s_arm_unwind_personalityindex, 0 },
5205 { "handlerdata", s_arm_unwind_handlerdata, 0 },
5206 { "save", s_arm_unwind_save, 0 },
fa073d69 5207 { "vsave", s_arm_unwind_save, 1 },
c19d1205
ZW
5208 { "movsp", s_arm_unwind_movsp, 0 },
5209 { "pad", s_arm_unwind_pad, 0 },
9b1c7dc3 5210 { "pacspval", s_arm_unwind_pacspval, 0 },
c19d1205
ZW
5211 { "setfp", s_arm_unwind_setfp, 0 },
5212 { "unwind_raw", s_arm_unwind_raw, 0 },
ee065d83 5213 { "eabi_attribute", s_arm_eabi_attribute, 0 },
0855e32b 5214 { "tlsdescseq", s_arm_tls_descseq, 0 },
c19d1205
ZW
5215#else
5216 { "word", cons, 4},
f0927246
NC
5217
5218 /* These are used for dwarf. */
5219 {"2byte", cons, 2},
5220 {"4byte", cons, 4},
5221 {"8byte", cons, 8},
5222 /* These are used for dwarf2. */
68d20676 5223 { "file", dwarf2_directive_file, 0 },
f0927246
NC
5224 { "loc", dwarf2_directive_loc, 0 },
5225 { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
c19d1205
ZW
5226#endif
5227 { "extend", float_cons, 'x' },
5228 { "ldouble", float_cons, 'x' },
5229 { "packed", float_cons, 'p' },
27cce866 5230 { "bfloat16", float_cons, 'b' },
f0927246
NC
5231#ifdef TE_PE
5232 {"secrel32", pe_directive_secrel, 0},
5233#endif
2e6976a8
DG
5234
5235 /* These are for compatibility with CodeComposer Studio. */
5236 {"ref", s_ccs_ref, 0},
5237 {"def", s_ccs_def, 0},
5238 {"asmfunc", s_ccs_asmfunc, 0},
5239 {"endasmfunc", s_ccs_endasmfunc, 0},
5240
5312fe52
BW
5241 {"float16", float_cons, 'h' },
5242 {"float16_format", set_fp16_format, 0 },
5243
c19d1205
ZW
5244 { 0, 0, 0 }
5245};
5312fe52 5246
c19d1205 5247/* Parser functions used exclusively in instruction operands. */
b99bd4ef 5248
c19d1205
ZW
5249/* Generic immediate-value read function for use in insn parsing.
5250 STR points to the beginning of the immediate (the leading #);
5251 VAL receives the value; if the value is outside [MIN, MAX]
5252 issue an error. PREFIX_OPT is true if the immediate prefix is
5253 optional. */
b99bd4ef 5254
c19d1205
ZW
5255static int
5256parse_immediate (char **str, int *val, int min, int max,
5b7c81bd 5257 bool prefix_opt)
c19d1205
ZW
5258{
5259 expressionS exp;
0198d5e6 5260
c19d1205
ZW
5261 my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
5262 if (exp.X_op != O_constant)
b99bd4ef 5263 {
c19d1205
ZW
5264 inst.error = _("constant expression required");
5265 return FAIL;
5266 }
b99bd4ef 5267
c19d1205
ZW
5268 if (exp.X_add_number < min || exp.X_add_number > max)
5269 {
5270 inst.error = _("immediate value out of range");
5271 return FAIL;
5272 }
b99bd4ef 5273
c19d1205
ZW
5274 *val = exp.X_add_number;
5275 return SUCCESS;
5276}
b99bd4ef 5277
5287ad62 5278/* Less-generic immediate-value read function with the possibility of loading a
036dc3f7 5279 big (64-bit) immediate, as required by Neon VMOV, VMVN and logic immediate
5287ad62
JB
5280 instructions. Puts the result directly in inst.operands[i]. */
5281
5282static int
8335d6aa 5283parse_big_immediate (char **str, int i, expressionS *in_exp,
5b7c81bd 5284 bool allow_symbol_p)
5287ad62
JB
5285{
5286 expressionS exp;
8335d6aa 5287 expressionS *exp_p = in_exp ? in_exp : &exp;
5287ad62
JB
5288 char *ptr = *str;
5289
8335d6aa 5290 my_get_expression (exp_p, &ptr, GE_OPT_PREFIX_BIG);
5287ad62 5291
8335d6aa 5292 if (exp_p->X_op == O_constant)
036dc3f7 5293 {
8335d6aa 5294 inst.operands[i].imm = exp_p->X_add_number & 0xffffffff;
036dc3f7
PB
5295 /* If we're on a 64-bit host, then a 64-bit number can be returned using
5296 O_constant. We have to be careful not to break compilation for
5297 32-bit X_add_number, though. */
8335d6aa 5298 if ((exp_p->X_add_number & ~(offsetT)(0xffffffffU)) != 0)
036dc3f7 5299 {
8335d6aa
JW
5300 /* X >> 32 is illegal if sizeof (exp_p->X_add_number) == 4. */
5301 inst.operands[i].reg = (((exp_p->X_add_number >> 16) >> 16)
5302 & 0xffffffff);
036dc3f7
PB
5303 inst.operands[i].regisimm = 1;
5304 }
5305 }
8335d6aa
JW
5306 else if (exp_p->X_op == O_big
5307 && LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 32)
5287ad62
JB
5308 {
5309 unsigned parts = 32 / LITTLENUM_NUMBER_OF_BITS, j, idx = 0;
95b75c01 5310
5287ad62 5311 /* Bignums have their least significant bits in
477330fc
RM
5312 generic_bignum[0]. Make sure we put 32 bits in imm and
5313 32 bits in reg, in a (hopefully) portable way. */
9c2799c2 5314 gas_assert (parts != 0);
95b75c01
NC
5315
5316 /* Make sure that the number is not too big.
5317 PR 11972: Bignums can now be sign-extended to the
5318 size of a .octa so check that the out of range bits
5319 are all zero or all one. */
8335d6aa 5320 if (LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 64)
95b75c01
NC
5321 {
5322 LITTLENUM_TYPE m = -1;
5323
5324 if (generic_bignum[parts * 2] != 0
5325 && generic_bignum[parts * 2] != m)
5326 return FAIL;
5327
8335d6aa 5328 for (j = parts * 2 + 1; j < (unsigned) exp_p->X_add_number; j++)
95b75c01
NC
5329 if (generic_bignum[j] != generic_bignum[j-1])
5330 return FAIL;
5331 }
5332
5287ad62
JB
5333 inst.operands[i].imm = 0;
5334 for (j = 0; j < parts; j++, idx++)
7af67752
AM
5335 inst.operands[i].imm |= ((unsigned) generic_bignum[idx]
5336 << (LITTLENUM_NUMBER_OF_BITS * j));
5287ad62
JB
5337 inst.operands[i].reg = 0;
5338 for (j = 0; j < parts; j++, idx++)
7af67752
AM
5339 inst.operands[i].reg |= ((unsigned) generic_bignum[idx]
5340 << (LITTLENUM_NUMBER_OF_BITS * j));
5287ad62
JB
5341 inst.operands[i].regisimm = 1;
5342 }
8335d6aa 5343 else if (!(exp_p->X_op == O_symbol && allow_symbol_p))
5287ad62 5344 return FAIL;
5f4273c7 5345
5287ad62
JB
5346 *str = ptr;
5347
5348 return SUCCESS;
5349}
5350
c19d1205
ZW
5351/* Returns the pseudo-register number of an FPA immediate constant,
5352 or FAIL if there isn't a valid constant here. */
b99bd4ef 5353
c19d1205
ZW
5354static int
5355parse_fpa_immediate (char ** str)
5356{
5357 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5358 char * save_in;
5359 expressionS exp;
5360 int i;
5361 int j;
b99bd4ef 5362
c19d1205
ZW
5363 /* First try and match exact strings, this is to guarantee
5364 that some formats will work even for cross assembly. */
b99bd4ef 5365
c19d1205
ZW
5366 for (i = 0; fp_const[i]; i++)
5367 {
5368 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
b99bd4ef 5369 {
c19d1205 5370 char *start = *str;
b99bd4ef 5371
c19d1205
ZW
5372 *str += strlen (fp_const[i]);
5373 if (is_end_of_line[(unsigned char) **str])
5374 return i + 8;
5375 *str = start;
5376 }
5377 }
b99bd4ef 5378
c19d1205
ZW
5379 /* Just because we didn't get a match doesn't mean that the constant
5380 isn't valid, just that it is in a format that we don't
5381 automatically recognize. Try parsing it with the standard
5382 expression routines. */
b99bd4ef 5383
c19d1205 5384 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
b99bd4ef 5385
c19d1205
ZW
5386 /* Look for a raw floating point number. */
5387 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5388 && is_end_of_line[(unsigned char) *save_in])
5389 {
5390 for (i = 0; i < NUM_FLOAT_VALS; i++)
5391 {
5392 for (j = 0; j < MAX_LITTLENUMS; j++)
b99bd4ef 5393 {
c19d1205
ZW
5394 if (words[j] != fp_values[i][j])
5395 break;
b99bd4ef
NC
5396 }
5397
c19d1205 5398 if (j == MAX_LITTLENUMS)
b99bd4ef 5399 {
c19d1205
ZW
5400 *str = save_in;
5401 return i + 8;
b99bd4ef
NC
5402 }
5403 }
5404 }
b99bd4ef 5405
c19d1205
ZW
5406 /* Try and parse a more complex expression, this will probably fail
5407 unless the code uses a floating point prefix (eg "0f"). */
5408 save_in = input_line_pointer;
5409 input_line_pointer = *str;
5410 if (expression (&exp) == absolute_section
5411 && exp.X_op == O_big
5412 && exp.X_add_number < 0)
5413 {
5414 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5415 Ditto for 15. */
ba592044
AM
5416#define X_PRECISION 5
5417#define E_PRECISION 15L
5418 if (gen_to_words (words, X_PRECISION, E_PRECISION) == 0)
c19d1205
ZW
5419 {
5420 for (i = 0; i < NUM_FLOAT_VALS; i++)
5421 {
5422 for (j = 0; j < MAX_LITTLENUMS; j++)
5423 {
5424 if (words[j] != fp_values[i][j])
5425 break;
5426 }
b99bd4ef 5427
c19d1205
ZW
5428 if (j == MAX_LITTLENUMS)
5429 {
5430 *str = input_line_pointer;
5431 input_line_pointer = save_in;
5432 return i + 8;
5433 }
5434 }
5435 }
b99bd4ef
NC
5436 }
5437
c19d1205
ZW
5438 *str = input_line_pointer;
5439 input_line_pointer = save_in;
5440 inst.error = _("invalid FPA immediate expression");
5441 return FAIL;
b99bd4ef
NC
5442}
5443
136da414
JB
5444/* Returns 1 if a number has "quarter-precision" float format
5445 0baBbbbbbc defgh000 00000000 00000000. */
5446
5447static int
5448is_quarter_float (unsigned imm)
5449{
5450 int bs = (imm & 0x20000000) ? 0x3e000000 : 0x40000000;
5451 return (imm & 0x7ffff) == 0 && ((imm & 0x7e000000) ^ bs) == 0;
5452}
5453
aacf0b33
KT
5454
5455/* Detect the presence of a floating point or integer zero constant,
5456 i.e. #0.0 or #0. */
5457
5b7c81bd 5458static bool
aacf0b33
KT
5459parse_ifimm_zero (char **in)
5460{
5461 int error_code;
5462
5463 if (!is_immediate_prefix (**in))
3c6452ae
TP
5464 {
5465 /* In unified syntax, all prefixes are optional. */
5466 if (!unified_syntax)
5b7c81bd 5467 return false;
3c6452ae
TP
5468 }
5469 else
5470 ++*in;
0900a05b
JW
5471
5472 /* Accept #0x0 as a synonym for #0. */
d34049e8 5473 if (startswith (*in, "0x"))
0900a05b
JW
5474 {
5475 int val;
5b7c81bd
AM
5476 if (parse_immediate (in, &val, 0, 0, true) == FAIL)
5477 return false;
5478 return true;
0900a05b
JW
5479 }
5480
aacf0b33
KT
5481 error_code = atof_generic (in, ".", EXP_CHARS,
5482 &generic_floating_point_number);
5483
5484 if (!error_code
5485 && generic_floating_point_number.sign == '+'
5486 && (generic_floating_point_number.low
5487 > generic_floating_point_number.leader))
5b7c81bd 5488 return true;
aacf0b33 5489
5b7c81bd 5490 return false;
aacf0b33
KT
5491}
5492
136da414
JB
5493/* Parse an 8-bit "quarter-precision" floating point number of the form:
5494 0baBbbbbbc defgh000 00000000 00000000.
c96612cc
JB
5495 The zero and minus-zero cases need special handling, since they can't be
5496 encoded in the "quarter-precision" float format, but can nonetheless be
5497 loaded as integer constants. */
136da414
JB
5498
5499static unsigned
5500parse_qfloat_immediate (char **ccp, int *immed)
5501{
5502 char *str = *ccp;
c96612cc 5503 char *fpnum;
136da414 5504 LITTLENUM_TYPE words[MAX_LITTLENUMS];
c96612cc 5505 int found_fpchar = 0;
5f4273c7 5506
136da414 5507 skip_past_char (&str, '#');
5f4273c7 5508
c96612cc
JB
5509 /* We must not accidentally parse an integer as a floating-point number. Make
5510 sure that the value we parse is not an integer by checking for special
5511 characters '.' or 'e'.
5512 FIXME: This is a horrible hack, but doing better is tricky because type
5513 information isn't in a very usable state at parse time. */
5514 fpnum = str;
5515 skip_whitespace (fpnum);
5516
d34049e8 5517 if (startswith (fpnum, "0x"))
c96612cc
JB
5518 return FAIL;
5519 else
5520 {
5521 for (; *fpnum != '\0' && *fpnum != ' ' && *fpnum != '\n'; fpnum++)
477330fc
RM
5522 if (*fpnum == '.' || *fpnum == 'e' || *fpnum == 'E')
5523 {
5524 found_fpchar = 1;
5525 break;
5526 }
c96612cc
JB
5527
5528 if (!found_fpchar)
477330fc 5529 return FAIL;
c96612cc 5530 }
5f4273c7 5531
136da414
JB
5532 if ((str = atof_ieee (str, 's', words)) != NULL)
5533 {
5534 unsigned fpword = 0;
5535 int i;
5f4273c7 5536
136da414
JB
5537 /* Our FP word must be 32 bits (single-precision FP). */
5538 for (i = 0; i < 32 / LITTLENUM_NUMBER_OF_BITS; i++)
477330fc
RM
5539 {
5540 fpword <<= LITTLENUM_NUMBER_OF_BITS;
5541 fpword |= words[i];
5542 }
5f4273c7 5543
c96612cc 5544 if (is_quarter_float (fpword) || (fpword & 0x7fffffff) == 0)
477330fc 5545 *immed = fpword;
136da414 5546 else
477330fc 5547 return FAIL;
136da414
JB
5548
5549 *ccp = str;
5f4273c7 5550
136da414
JB
5551 return SUCCESS;
5552 }
5f4273c7 5553
136da414
JB
5554 return FAIL;
5555}
5556
c19d1205
ZW
5557/* Shift operands. */
5558enum shift_kind
b99bd4ef 5559{
f5f10c66 5560 SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX, SHIFT_UXTW
c19d1205 5561};
b99bd4ef 5562
c19d1205
ZW
5563struct asm_shift_name
5564{
5565 const char *name;
5566 enum shift_kind kind;
5567};
b99bd4ef 5568
c19d1205
ZW
5569/* Third argument to parse_shift. */
5570enum parse_shift_mode
5571{
5572 NO_SHIFT_RESTRICT, /* Any kind of shift is accepted. */
5573 SHIFT_IMMEDIATE, /* Shift operand must be an immediate. */
5574 SHIFT_LSL_OR_ASR_IMMEDIATE, /* Shift must be LSL or ASR immediate. */
5575 SHIFT_ASR_IMMEDIATE, /* Shift must be ASR immediate. */
5576 SHIFT_LSL_IMMEDIATE, /* Shift must be LSL immediate. */
f5f10c66 5577 SHIFT_UXTW_IMMEDIATE /* Shift must be UXTW immediate. */
c19d1205 5578};
b99bd4ef 5579
c19d1205
ZW
5580/* Parse a <shift> specifier on an ARM data processing instruction.
5581 This has three forms:
b99bd4ef 5582
c19d1205
ZW
5583 (LSL|LSR|ASL|ASR|ROR) Rs
5584 (LSL|LSR|ASL|ASR|ROR) #imm
5585 RRX
b99bd4ef 5586
c19d1205
ZW
5587 Note that ASL is assimilated to LSL in the instruction encoding, and
5588 RRX to ROR #0 (which cannot be written as such). */
b99bd4ef 5589
c19d1205
ZW
5590static int
5591parse_shift (char **str, int i, enum parse_shift_mode mode)
b99bd4ef 5592{
c19d1205
ZW
5593 const struct asm_shift_name *shift_name;
5594 enum shift_kind shift;
5595 char *s = *str;
5596 char *p = s;
5597 int reg;
b99bd4ef 5598
c19d1205
ZW
5599 for (p = *str; ISALPHA (*p); p++)
5600 ;
b99bd4ef 5601
c19d1205 5602 if (p == *str)
b99bd4ef 5603 {
c19d1205
ZW
5604 inst.error = _("shift expression expected");
5605 return FAIL;
b99bd4ef
NC
5606 }
5607
fe0e921f
AM
5608 shift_name
5609 = (const struct asm_shift_name *) str_hash_find_n (arm_shift_hsh, *str,
5610 p - *str);
c19d1205
ZW
5611
5612 if (shift_name == NULL)
b99bd4ef 5613 {
c19d1205
ZW
5614 inst.error = _("shift expression expected");
5615 return FAIL;
b99bd4ef
NC
5616 }
5617
c19d1205 5618 shift = shift_name->kind;
b99bd4ef 5619
c19d1205
ZW
5620 switch (mode)
5621 {
5622 case NO_SHIFT_RESTRICT:
f5f10c66
AV
5623 case SHIFT_IMMEDIATE:
5624 if (shift == SHIFT_UXTW)
5625 {
5626 inst.error = _("'UXTW' not allowed here");
5627 return FAIL;
5628 }
5629 break;
b99bd4ef 5630
c19d1205
ZW
5631 case SHIFT_LSL_OR_ASR_IMMEDIATE:
5632 if (shift != SHIFT_LSL && shift != SHIFT_ASR)
5633 {
5634 inst.error = _("'LSL' or 'ASR' required");
5635 return FAIL;
5636 }
5637 break;
b99bd4ef 5638
c19d1205
ZW
5639 case SHIFT_LSL_IMMEDIATE:
5640 if (shift != SHIFT_LSL)
5641 {
5642 inst.error = _("'LSL' required");
5643 return FAIL;
5644 }
5645 break;
b99bd4ef 5646
c19d1205
ZW
5647 case SHIFT_ASR_IMMEDIATE:
5648 if (shift != SHIFT_ASR)
5649 {
5650 inst.error = _("'ASR' required");
5651 return FAIL;
5652 }
5653 break;
f5f10c66
AV
5654 case SHIFT_UXTW_IMMEDIATE:
5655 if (shift != SHIFT_UXTW)
5656 {
5657 inst.error = _("'UXTW' required");
5658 return FAIL;
5659 }
5660 break;
b99bd4ef 5661
c19d1205
ZW
5662 default: abort ();
5663 }
b99bd4ef 5664
c19d1205
ZW
5665 if (shift != SHIFT_RRX)
5666 {
5667 /* Whitespace can appear here if the next thing is a bare digit. */
5668 skip_whitespace (p);
b99bd4ef 5669
c19d1205 5670 if (mode == NO_SHIFT_RESTRICT
dcbf9037 5671 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5672 {
5673 inst.operands[i].imm = reg;
5674 inst.operands[i].immisreg = 1;
5675 }
e2b0ab59 5676 else if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
c19d1205
ZW
5677 return FAIL;
5678 }
5679 inst.operands[i].shift_kind = shift;
5680 inst.operands[i].shifted = 1;
5681 *str = p;
5682 return SUCCESS;
b99bd4ef
NC
5683}
5684
c19d1205 5685/* Parse a <shifter_operand> for an ARM data processing instruction:
b99bd4ef 5686
c19d1205
ZW
5687 #<immediate>
5688 #<immediate>, <rotate>
5689 <Rm>
5690 <Rm>, <shift>
b99bd4ef 5691
c19d1205
ZW
5692 where <shift> is defined by parse_shift above, and <rotate> is a
5693 multiple of 2 between 0 and 30. Validation of immediate operands
55cf6793 5694 is deferred to md_apply_fix. */
b99bd4ef 5695
c19d1205
ZW
5696static int
5697parse_shifter_operand (char **str, int i)
5698{
5699 int value;
91d6fa6a 5700 expressionS exp;
b99bd4ef 5701
dcbf9037 5702 if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5703 {
5704 inst.operands[i].reg = value;
5705 inst.operands[i].isreg = 1;
b99bd4ef 5706
c19d1205 5707 /* parse_shift will override this if appropriate */
e2b0ab59
AV
5708 inst.relocs[0].exp.X_op = O_constant;
5709 inst.relocs[0].exp.X_add_number = 0;
b99bd4ef 5710
c19d1205
ZW
5711 if (skip_past_comma (str) == FAIL)
5712 return SUCCESS;
b99bd4ef 5713
c19d1205
ZW
5714 /* Shift operation on register. */
5715 return parse_shift (str, i, NO_SHIFT_RESTRICT);
b99bd4ef
NC
5716 }
5717
e2b0ab59 5718 if (my_get_expression (&inst.relocs[0].exp, str, GE_IMM_PREFIX))
c19d1205 5719 return FAIL;
b99bd4ef 5720
c19d1205 5721 if (skip_past_comma (str) == SUCCESS)
b99bd4ef 5722 {
c19d1205 5723 /* #x, y -- ie explicit rotation by Y. */
91d6fa6a 5724 if (my_get_expression (&exp, str, GE_NO_PREFIX))
c19d1205 5725 return FAIL;
b99bd4ef 5726
e2b0ab59 5727 if (exp.X_op != O_constant || inst.relocs[0].exp.X_op != O_constant)
c19d1205
ZW
5728 {
5729 inst.error = _("constant expression expected");
5730 return FAIL;
5731 }
b99bd4ef 5732
91d6fa6a 5733 value = exp.X_add_number;
c19d1205
ZW
5734 if (value < 0 || value > 30 || value % 2 != 0)
5735 {
5736 inst.error = _("invalid rotation");
5737 return FAIL;
5738 }
e2b0ab59
AV
5739 if (inst.relocs[0].exp.X_add_number < 0
5740 || inst.relocs[0].exp.X_add_number > 255)
c19d1205
ZW
5741 {
5742 inst.error = _("invalid constant");
5743 return FAIL;
5744 }
09d92015 5745
a415b1cd 5746 /* Encode as specified. */
e2b0ab59 5747 inst.operands[i].imm = inst.relocs[0].exp.X_add_number | value << 7;
a415b1cd 5748 return SUCCESS;
09d92015
MM
5749 }
5750
e2b0ab59
AV
5751 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
5752 inst.relocs[0].pc_rel = 0;
c19d1205 5753 return SUCCESS;
09d92015
MM
5754}
5755
4962c51a
MS
5756/* Group relocation information. Each entry in the table contains the
5757 textual name of the relocation as may appear in assembler source
5758 and must end with a colon.
5759 Along with this textual name are the relocation codes to be used if
5760 the corresponding instruction is an ALU instruction (ADD or SUB only),
5761 an LDR, an LDRS, or an LDC. */
5762
5763struct group_reloc_table_entry
5764{
5765 const char *name;
5766 int alu_code;
5767 int ldr_code;
5768 int ldrs_code;
5769 int ldc_code;
5770};
5771
5772typedef enum
5773{
5774 /* Varieties of non-ALU group relocation. */
5775
5776 GROUP_LDR,
5777 GROUP_LDRS,
35c228db
AV
5778 GROUP_LDC,
5779 GROUP_MVE
4962c51a
MS
5780} group_reloc_type;
5781
5782static struct group_reloc_table_entry group_reloc_table[] =
5783 { /* Program counter relative: */
5784 { "pc_g0_nc",
5785 BFD_RELOC_ARM_ALU_PC_G0_NC, /* ALU */
5786 0, /* LDR */
5787 0, /* LDRS */
5788 0 }, /* LDC */
5789 { "pc_g0",
5790 BFD_RELOC_ARM_ALU_PC_G0, /* ALU */
5791 BFD_RELOC_ARM_LDR_PC_G0, /* LDR */
5792 BFD_RELOC_ARM_LDRS_PC_G0, /* LDRS */
5793 BFD_RELOC_ARM_LDC_PC_G0 }, /* LDC */
5794 { "pc_g1_nc",
5795 BFD_RELOC_ARM_ALU_PC_G1_NC, /* ALU */
5796 0, /* LDR */
5797 0, /* LDRS */
5798 0 }, /* LDC */
5799 { "pc_g1",
5800 BFD_RELOC_ARM_ALU_PC_G1, /* ALU */
5801 BFD_RELOC_ARM_LDR_PC_G1, /* LDR */
5802 BFD_RELOC_ARM_LDRS_PC_G1, /* LDRS */
5803 BFD_RELOC_ARM_LDC_PC_G1 }, /* LDC */
5804 { "pc_g2",
5805 BFD_RELOC_ARM_ALU_PC_G2, /* ALU */
5806 BFD_RELOC_ARM_LDR_PC_G2, /* LDR */
5807 BFD_RELOC_ARM_LDRS_PC_G2, /* LDRS */
5808 BFD_RELOC_ARM_LDC_PC_G2 }, /* LDC */
5809 /* Section base relative */
5810 { "sb_g0_nc",
5811 BFD_RELOC_ARM_ALU_SB_G0_NC, /* ALU */
5812 0, /* LDR */
5813 0, /* LDRS */
5814 0 }, /* LDC */
5815 { "sb_g0",
5816 BFD_RELOC_ARM_ALU_SB_G0, /* ALU */
5817 BFD_RELOC_ARM_LDR_SB_G0, /* LDR */
5818 BFD_RELOC_ARM_LDRS_SB_G0, /* LDRS */
5819 BFD_RELOC_ARM_LDC_SB_G0 }, /* LDC */
5820 { "sb_g1_nc",
5821 BFD_RELOC_ARM_ALU_SB_G1_NC, /* ALU */
5822 0, /* LDR */
5823 0, /* LDRS */
5824 0 }, /* LDC */
5825 { "sb_g1",
5826 BFD_RELOC_ARM_ALU_SB_G1, /* ALU */
5827 BFD_RELOC_ARM_LDR_SB_G1, /* LDR */
5828 BFD_RELOC_ARM_LDRS_SB_G1, /* LDRS */
5829 BFD_RELOC_ARM_LDC_SB_G1 }, /* LDC */
5830 { "sb_g2",
5831 BFD_RELOC_ARM_ALU_SB_G2, /* ALU */
5832 BFD_RELOC_ARM_LDR_SB_G2, /* LDR */
5833 BFD_RELOC_ARM_LDRS_SB_G2, /* LDRS */
72d98d16
MG
5834 BFD_RELOC_ARM_LDC_SB_G2 }, /* LDC */
5835 /* Absolute thumb alu relocations. */
5836 { "lower0_7",
5837 BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,/* ALU. */
5838 0, /* LDR. */
5839 0, /* LDRS. */
5840 0 }, /* LDC. */
5841 { "lower8_15",
5842 BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,/* ALU. */
5843 0, /* LDR. */
5844 0, /* LDRS. */
5845 0 }, /* LDC. */
5846 { "upper0_7",
5847 BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,/* ALU. */
5848 0, /* LDR. */
5849 0, /* LDRS. */
5850 0 }, /* LDC. */
5851 { "upper8_15",
5852 BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,/* ALU. */
5853 0, /* LDR. */
5854 0, /* LDRS. */
5855 0 } }; /* LDC. */
4962c51a
MS
5856
5857/* Given the address of a pointer pointing to the textual name of a group
5858 relocation as may appear in assembler source, attempt to find its details
5859 in group_reloc_table. The pointer will be updated to the character after
5860 the trailing colon. On failure, FAIL will be returned; SUCCESS
5861 otherwise. On success, *entry will be updated to point at the relevant
5862 group_reloc_table entry. */
5863
5864static int
5865find_group_reloc_table_entry (char **str, struct group_reloc_table_entry **out)
5866{
5867 unsigned int i;
5868 for (i = 0; i < ARRAY_SIZE (group_reloc_table); i++)
5869 {
5870 int length = strlen (group_reloc_table[i].name);
5871
5f4273c7
NC
5872 if (strncasecmp (group_reloc_table[i].name, *str, length) == 0
5873 && (*str)[length] == ':')
477330fc
RM
5874 {
5875 *out = &group_reloc_table[i];
5876 *str += (length + 1);
5877 return SUCCESS;
5878 }
4962c51a
MS
5879 }
5880
5881 return FAIL;
5882}
5883
5884/* Parse a <shifter_operand> for an ARM data processing instruction
5885 (as for parse_shifter_operand) where group relocations are allowed:
5886
5887 #<immediate>
5888 #<immediate>, <rotate>
5889 #:<group_reloc>:<expression>
5890 <Rm>
5891 <Rm>, <shift>
5892
5893 where <group_reloc> is one of the strings defined in group_reloc_table.
5894 The hashes are optional.
5895
5896 Everything else is as for parse_shifter_operand. */
5897
5898static parse_operand_result
5899parse_shifter_operand_group_reloc (char **str, int i)
5900{
5901 /* Determine if we have the sequence of characters #: or just :
5902 coming next. If we do, then we check for a group relocation.
5903 If we don't, punt the whole lot to parse_shifter_operand. */
5904
5905 if (((*str)[0] == '#' && (*str)[1] == ':')
5906 || (*str)[0] == ':')
5907 {
5908 struct group_reloc_table_entry *entry;
5909
5910 if ((*str)[0] == '#')
477330fc 5911 (*str) += 2;
4962c51a 5912 else
477330fc 5913 (*str)++;
4962c51a
MS
5914
5915 /* Try to parse a group relocation. Anything else is an error. */
5916 if (find_group_reloc_table_entry (str, &entry) == FAIL)
477330fc
RM
5917 {
5918 inst.error = _("unknown group relocation");
5919 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5920 }
4962c51a
MS
5921
5922 /* We now have the group relocation table entry corresponding to
477330fc 5923 the name in the assembler source. Next, we parse the expression. */
e2b0ab59 5924 if (my_get_expression (&inst.relocs[0].exp, str, GE_NO_PREFIX))
477330fc 5925 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
4962c51a
MS
5926
5927 /* Record the relocation type (always the ALU variant here). */
e2b0ab59
AV
5928 inst.relocs[0].type = (bfd_reloc_code_real_type) entry->alu_code;
5929 gas_assert (inst.relocs[0].type != 0);
4962c51a
MS
5930
5931 return PARSE_OPERAND_SUCCESS;
5932 }
5933 else
5934 return parse_shifter_operand (str, i) == SUCCESS
477330fc 5935 ? PARSE_OPERAND_SUCCESS : PARSE_OPERAND_FAIL;
4962c51a
MS
5936
5937 /* Never reached. */
5938}
5939
8e560766
MGD
5940/* Parse a Neon alignment expression. Information is written to
5941 inst.operands[i]. We assume the initial ':' has been skipped.
fa94de6b 5942
8e560766
MGD
5943 align .imm = align << 8, .immisalign=1, .preind=0 */
5944static parse_operand_result
5945parse_neon_alignment (char **str, int i)
5946{
5947 char *p = *str;
5948 expressionS exp;
5949
5950 my_get_expression (&exp, &p, GE_NO_PREFIX);
5951
5952 if (exp.X_op != O_constant)
5953 {
5954 inst.error = _("alignment must be constant");
5955 return PARSE_OPERAND_FAIL;
5956 }
5957
5958 inst.operands[i].imm = exp.X_add_number << 8;
5959 inst.operands[i].immisalign = 1;
5960 /* Alignments are not pre-indexes. */
5961 inst.operands[i].preind = 0;
5962
5963 *str = p;
5964 return PARSE_OPERAND_SUCCESS;
5965}
5966
c19d1205 5967/* Parse all forms of an ARM address expression. Information is written
e2b0ab59 5968 to inst.operands[i] and/or inst.relocs[0].
09d92015 5969
c19d1205 5970 Preindexed addressing (.preind=1):
09d92015 5971
e2b0ab59 5972 [Rn, #offset] .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5973 [Rn, +/-Rm] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5974 [Rn, +/-Rm, shift] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5975 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5976
c19d1205 5977 These three may have a trailing ! which causes .writeback to be set also.
09d92015 5978
c19d1205 5979 Postindexed addressing (.postind=1, .writeback=1):
09d92015 5980
e2b0ab59 5981 [Rn], #offset .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5982 [Rn], +/-Rm .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5983 [Rn], +/-Rm, shift .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5984 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5985
c19d1205 5986 Unindexed addressing (.preind=0, .postind=0):
09d92015 5987
c19d1205 5988 [Rn], {option} .reg=Rn .imm=option .immisreg=0
09d92015 5989
c19d1205 5990 Other:
09d92015 5991
c19d1205 5992 [Rn]{!} shorthand for [Rn,#0]{!}
e2b0ab59
AV
5993 =immediate .isreg=0 .relocs[0].exp=immediate
5994 label .reg=PC .relocs[0].pc_rel=1 .relocs[0].exp=label
09d92015 5995
c19d1205 5996 It is the caller's responsibility to check for addressing modes not
e2b0ab59 5997 supported by the instruction, and to set inst.relocs[0].type. */
c19d1205 5998
4962c51a
MS
5999static parse_operand_result
6000parse_address_main (char **str, int i, int group_relocations,
477330fc 6001 group_reloc_type group_type)
09d92015 6002{
c19d1205
ZW
6003 char *p = *str;
6004 int reg;
09d92015 6005
c19d1205 6006 if (skip_past_char (&p, '[') == FAIL)
09d92015 6007 {
79248c83
SP
6008 if (group_type == GROUP_MVE
6009 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
6010 {
6011 /* [r0-r15] expected as argument but receiving r0-r15 without
6012 [] brackets. */
6013 inst.error = BAD_SYNTAX;
6014 return PARSE_OPERAND_FAIL;
6015 }
6016 else if (skip_past_char (&p, '=') == FAIL)
c19d1205 6017 {
974da60d 6018 /* Bare address - translate to PC-relative offset. */
e2b0ab59 6019 inst.relocs[0].pc_rel = 1;
c19d1205
ZW
6020 inst.operands[i].reg = REG_PC;
6021 inst.operands[i].isreg = 1;
6022 inst.operands[i].preind = 1;
09d92015 6023
e2b0ab59 6024 if (my_get_expression (&inst.relocs[0].exp, &p, GE_OPT_PREFIX_BIG))
8335d6aa
JW
6025 return PARSE_OPERAND_FAIL;
6026 }
e2b0ab59 6027 else if (parse_big_immediate (&p, i, &inst.relocs[0].exp,
5b7c81bd 6028 /*allow_symbol_p=*/true))
4962c51a 6029 return PARSE_OPERAND_FAIL;
09d92015 6030
c19d1205 6031 *str = p;
4962c51a 6032 return PARSE_OPERAND_SUCCESS;
09d92015
MM
6033 }
6034
8ab8155f
NC
6035 /* PR gas/14887: Allow for whitespace after the opening bracket. */
6036 skip_whitespace (p);
6037
f5f10c66
AV
6038 if (group_type == GROUP_MVE)
6039 {
6040 enum arm_reg_type rtype = REG_TYPE_MQ;
6041 struct neon_type_el et;
6042 if ((reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
6043 {
6044 inst.operands[i].isquad = 1;
6045 }
6046 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
6047 {
6048 inst.error = BAD_ADDR_MODE;
6049 return PARSE_OPERAND_FAIL;
6050 }
6051 }
6052 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
09d92015 6053 {
35c228db
AV
6054 if (group_type == GROUP_MVE)
6055 inst.error = BAD_ADDR_MODE;
6056 else
6057 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
4962c51a 6058 return PARSE_OPERAND_FAIL;
09d92015 6059 }
c19d1205
ZW
6060 inst.operands[i].reg = reg;
6061 inst.operands[i].isreg = 1;
09d92015 6062
c19d1205 6063 if (skip_past_comma (&p) == SUCCESS)
09d92015 6064 {
c19d1205 6065 inst.operands[i].preind = 1;
09d92015 6066
c19d1205
ZW
6067 if (*p == '+') p++;
6068 else if (*p == '-') p++, inst.operands[i].negative = 1;
6069
f5f10c66
AV
6070 enum arm_reg_type rtype = REG_TYPE_MQ;
6071 struct neon_type_el et;
6072 if (group_type == GROUP_MVE
6073 && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
6074 {
6075 inst.operands[i].immisreg = 2;
6076 inst.operands[i].imm = reg;
6077
6078 if (skip_past_comma (&p) == SUCCESS)
6079 {
6080 if (parse_shift (&p, i, SHIFT_UXTW_IMMEDIATE) == SUCCESS)
6081 {
6082 inst.operands[i].imm |= inst.relocs[0].exp.X_add_number << 5;
6083 inst.relocs[0].exp.X_add_number = 0;
6084 }
6085 else
6086 return PARSE_OPERAND_FAIL;
6087 }
6088 }
6089 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
09d92015 6090 {
c19d1205
ZW
6091 inst.operands[i].imm = reg;
6092 inst.operands[i].immisreg = 1;
6093
6094 if (skip_past_comma (&p) == SUCCESS)
6095 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 6096 return PARSE_OPERAND_FAIL;
c19d1205 6097 }
5287ad62 6098 else if (skip_past_char (&p, ':') == SUCCESS)
8e560766
MGD
6099 {
6100 /* FIXME: '@' should be used here, but it's filtered out by generic
6101 code before we get to see it here. This may be subject to
6102 change. */
6103 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 6104
8e560766
MGD
6105 if (result != PARSE_OPERAND_SUCCESS)
6106 return result;
6107 }
c19d1205
ZW
6108 else
6109 {
6110 if (inst.operands[i].negative)
6111 {
6112 inst.operands[i].negative = 0;
6113 p--;
6114 }
4962c51a 6115
5f4273c7
NC
6116 if (group_relocations
6117 && ((*p == '#' && *(p + 1) == ':') || *p == ':'))
4962c51a
MS
6118 {
6119 struct group_reloc_table_entry *entry;
6120
477330fc
RM
6121 /* Skip over the #: or : sequence. */
6122 if (*p == '#')
6123 p += 2;
6124 else
6125 p++;
4962c51a
MS
6126
6127 /* Try to parse a group relocation. Anything else is an
477330fc 6128 error. */
4962c51a
MS
6129 if (find_group_reloc_table_entry (&p, &entry) == FAIL)
6130 {
6131 inst.error = _("unknown group relocation");
6132 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6133 }
6134
6135 /* We now have the group relocation table entry corresponding to
6136 the name in the assembler source. Next, we parse the
477330fc 6137 expression. */
e2b0ab59 6138 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
4962c51a
MS
6139 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6140
6141 /* Record the relocation type. */
477330fc
RM
6142 switch (group_type)
6143 {
6144 case GROUP_LDR:
e2b0ab59
AV
6145 inst.relocs[0].type
6146 = (bfd_reloc_code_real_type) entry->ldr_code;
477330fc 6147 break;
4962c51a 6148
477330fc 6149 case GROUP_LDRS:
e2b0ab59
AV
6150 inst.relocs[0].type
6151 = (bfd_reloc_code_real_type) entry->ldrs_code;
477330fc 6152 break;
4962c51a 6153
477330fc 6154 case GROUP_LDC:
e2b0ab59
AV
6155 inst.relocs[0].type
6156 = (bfd_reloc_code_real_type) entry->ldc_code;
477330fc 6157 break;
4962c51a 6158
477330fc
RM
6159 default:
6160 gas_assert (0);
6161 }
4962c51a 6162
e2b0ab59 6163 if (inst.relocs[0].type == 0)
4962c51a
MS
6164 {
6165 inst.error = _("this group relocation is not allowed on this instruction");
6166 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6167 }
477330fc
RM
6168 }
6169 else
26d97720
NS
6170 {
6171 char *q = p;
0198d5e6 6172
e2b0ab59 6173 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
26d97720
NS
6174 return PARSE_OPERAND_FAIL;
6175 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
6176 if (inst.relocs[0].exp.X_op == O_constant
6177 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
6178 {
6179 skip_whitespace (q);
6180 if (*q == '#')
6181 {
6182 q++;
6183 skip_whitespace (q);
6184 }
6185 if (*q == '-')
6186 inst.operands[i].negative = 1;
6187 }
6188 }
09d92015
MM
6189 }
6190 }
8e560766
MGD
6191 else if (skip_past_char (&p, ':') == SUCCESS)
6192 {
6193 /* FIXME: '@' should be used here, but it's filtered out by generic code
6194 before we get to see it here. This may be subject to change. */
6195 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 6196
8e560766
MGD
6197 if (result != PARSE_OPERAND_SUCCESS)
6198 return result;
6199 }
09d92015 6200
c19d1205 6201 if (skip_past_char (&p, ']') == FAIL)
09d92015 6202 {
c19d1205 6203 inst.error = _("']' expected");
4962c51a 6204 return PARSE_OPERAND_FAIL;
09d92015
MM
6205 }
6206
c19d1205
ZW
6207 if (skip_past_char (&p, '!') == SUCCESS)
6208 inst.operands[i].writeback = 1;
09d92015 6209
c19d1205 6210 else if (skip_past_comma (&p) == SUCCESS)
09d92015 6211 {
c19d1205
ZW
6212 if (skip_past_char (&p, '{') == SUCCESS)
6213 {
6214 /* [Rn], {expr} - unindexed, with option */
6215 if (parse_immediate (&p, &inst.operands[i].imm,
5b7c81bd 6216 0, 255, true) == FAIL)
4962c51a 6217 return PARSE_OPERAND_FAIL;
09d92015 6218
c19d1205
ZW
6219 if (skip_past_char (&p, '}') == FAIL)
6220 {
6221 inst.error = _("'}' expected at end of 'option' field");
4962c51a 6222 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6223 }
6224 if (inst.operands[i].preind)
6225 {
6226 inst.error = _("cannot combine index with option");
4962c51a 6227 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6228 }
6229 *str = p;
4962c51a 6230 return PARSE_OPERAND_SUCCESS;
09d92015 6231 }
c19d1205
ZW
6232 else
6233 {
6234 inst.operands[i].postind = 1;
6235 inst.operands[i].writeback = 1;
09d92015 6236
c19d1205
ZW
6237 if (inst.operands[i].preind)
6238 {
6239 inst.error = _("cannot combine pre- and post-indexing");
4962c51a 6240 return PARSE_OPERAND_FAIL;
c19d1205 6241 }
09d92015 6242
c19d1205
ZW
6243 if (*p == '+') p++;
6244 else if (*p == '-') p++, inst.operands[i].negative = 1;
a737bd4d 6245
f5f10c66
AV
6246 enum arm_reg_type rtype = REG_TYPE_MQ;
6247 struct neon_type_el et;
6248 if (group_type == GROUP_MVE
6249 && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
6250 {
6251 inst.operands[i].immisreg = 2;
6252 inst.operands[i].imm = reg;
6253 }
6254 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205 6255 {
477330fc
RM
6256 /* We might be using the immediate for alignment already. If we
6257 are, OR the register number into the low-order bits. */
6258 if (inst.operands[i].immisalign)
6259 inst.operands[i].imm |= reg;
6260 else
6261 inst.operands[i].imm = reg;
c19d1205 6262 inst.operands[i].immisreg = 1;
a737bd4d 6263
c19d1205
ZW
6264 if (skip_past_comma (&p) == SUCCESS)
6265 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 6266 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6267 }
6268 else
6269 {
26d97720 6270 char *q = p;
0198d5e6 6271
c19d1205
ZW
6272 if (inst.operands[i].negative)
6273 {
6274 inst.operands[i].negative = 0;
6275 p--;
6276 }
e2b0ab59 6277 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
4962c51a 6278 return PARSE_OPERAND_FAIL;
26d97720 6279 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
6280 if (inst.relocs[0].exp.X_op == O_constant
6281 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
6282 {
6283 skip_whitespace (q);
6284 if (*q == '#')
6285 {
6286 q++;
6287 skip_whitespace (q);
6288 }
6289 if (*q == '-')
6290 inst.operands[i].negative = 1;
6291 }
c19d1205
ZW
6292 }
6293 }
a737bd4d
NC
6294 }
6295
c19d1205
ZW
6296 /* If at this point neither .preind nor .postind is set, we have a
6297 bare [Rn]{!}, which is shorthand for [Rn,#0]{!}. */
6298 if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
6299 {
6300 inst.operands[i].preind = 1;
e2b0ab59
AV
6301 inst.relocs[0].exp.X_op = O_constant;
6302 inst.relocs[0].exp.X_add_number = 0;
c19d1205
ZW
6303 }
6304 *str = p;
4962c51a
MS
6305 return PARSE_OPERAND_SUCCESS;
6306}
6307
6308static int
6309parse_address (char **str, int i)
6310{
21d799b5 6311 return parse_address_main (str, i, 0, GROUP_LDR) == PARSE_OPERAND_SUCCESS
477330fc 6312 ? SUCCESS : FAIL;
4962c51a
MS
6313}
6314
6315static parse_operand_result
6316parse_address_group_reloc (char **str, int i, group_reloc_type type)
6317{
6318 return parse_address_main (str, i, 1, type);
a737bd4d
NC
6319}
6320
b6895b4f
PB
6321/* Parse an operand for a MOVW or MOVT instruction. */
6322static int
6323parse_half (char **str)
6324{
6325 char * p;
5f4273c7 6326
b6895b4f
PB
6327 p = *str;
6328 skip_past_char (&p, '#');
5f4273c7 6329 if (strncasecmp (p, ":lower16:", 9) == 0)
e2b0ab59 6330 inst.relocs[0].type = BFD_RELOC_ARM_MOVW;
b6895b4f 6331 else if (strncasecmp (p, ":upper16:", 9) == 0)
e2b0ab59 6332 inst.relocs[0].type = BFD_RELOC_ARM_MOVT;
b6895b4f 6333
e2b0ab59 6334 if (inst.relocs[0].type != BFD_RELOC_UNUSED)
b6895b4f
PB
6335 {
6336 p += 9;
5f4273c7 6337 skip_whitespace (p);
b6895b4f
PB
6338 }
6339
e2b0ab59 6340 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
b6895b4f
PB
6341 return FAIL;
6342
e2b0ab59 6343 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 6344 {
e2b0ab59 6345 if (inst.relocs[0].exp.X_op != O_constant)
b6895b4f
PB
6346 {
6347 inst.error = _("constant expression expected");
6348 return FAIL;
6349 }
e2b0ab59
AV
6350 if (inst.relocs[0].exp.X_add_number < 0
6351 || inst.relocs[0].exp.X_add_number > 0xffff)
b6895b4f
PB
6352 {
6353 inst.error = _("immediate value out of range");
6354 return FAIL;
6355 }
6356 }
6357 *str = p;
6358 return SUCCESS;
6359}
6360
c19d1205 6361/* Miscellaneous. */
a737bd4d 6362
c19d1205
ZW
6363/* Parse a PSR flag operand. The value returned is FAIL on syntax error,
6364 or a bitmask suitable to be or-ed into the ARM msr instruction. */
6365static int
5b7c81bd 6366parse_psr (char **str, bool lhs)
09d92015 6367{
c19d1205
ZW
6368 char *p;
6369 unsigned long psr_field;
62b3e311
PB
6370 const struct asm_psr *psr;
6371 char *start;
5b7c81bd
AM
6372 bool is_apsr = false;
6373 bool m_profile = ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m);
09d92015 6374
a4482bb6
NC
6375 /* PR gas/12698: If the user has specified -march=all then m_profile will
6376 be TRUE, but we want to ignore it in this case as we are building for any
6377 CPU type, including non-m variants. */
823d2571 6378 if (ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
5b7c81bd 6379 m_profile = false;
a4482bb6 6380
c19d1205
ZW
6381 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
6382 feature for ease of use and backwards compatibility. */
6383 p = *str;
62b3e311 6384 if (strncasecmp (p, "SPSR", 4) == 0)
d2cd1205
JB
6385 {
6386 if (m_profile)
6387 goto unsupported_psr;
fa94de6b 6388
d2cd1205
JB
6389 psr_field = SPSR_BIT;
6390 }
6391 else if (strncasecmp (p, "CPSR", 4) == 0)
6392 {
6393 if (m_profile)
6394 goto unsupported_psr;
6395
6396 psr_field = 0;
6397 }
6398 else if (strncasecmp (p, "APSR", 4) == 0)
6399 {
6400 /* APSR[_<bits>] can be used as a synonym for CPSR[_<flags>] on ARMv7-A
6401 and ARMv7-R architecture CPUs. */
5b7c81bd 6402 is_apsr = true;
d2cd1205
JB
6403 psr_field = 0;
6404 }
6405 else if (m_profile)
62b3e311
PB
6406 {
6407 start = p;
6408 do
6409 p++;
6410 while (ISALNUM (*p) || *p == '_');
6411
d2cd1205
JB
6412 if (strncasecmp (start, "iapsr", 5) == 0
6413 || strncasecmp (start, "eapsr", 5) == 0
6414 || strncasecmp (start, "xpsr", 4) == 0
6415 || strncasecmp (start, "psr", 3) == 0)
6416 p = start + strcspn (start, "rR") + 1;
6417
629310ab 6418 psr = (const struct asm_psr *) str_hash_find_n (arm_v7m_psr_hsh, start,
fe0e921f 6419 p - start);
d2cd1205 6420
62b3e311
PB
6421 if (!psr)
6422 return FAIL;
09d92015 6423
d2cd1205
JB
6424 /* If APSR is being written, a bitfield may be specified. Note that
6425 APSR itself is handled above. */
6426 if (psr->field <= 3)
6427 {
6428 psr_field = psr->field;
5b7c81bd 6429 is_apsr = true;
d2cd1205
JB
6430 goto check_suffix;
6431 }
6432
62b3e311 6433 *str = p;
d2cd1205
JB
6434 /* M-profile MSR instructions have the mask field set to "10", except
6435 *PSR variants which modify APSR, which may use a different mask (and
6436 have been handled already). Do that by setting the PSR_f field
6437 here. */
6438 return psr->field | (lhs ? PSR_f : 0);
62b3e311 6439 }
d2cd1205
JB
6440 else
6441 goto unsupported_psr;
09d92015 6442
62b3e311 6443 p += 4;
dc1e8a47 6444 check_suffix:
c19d1205
ZW
6445 if (*p == '_')
6446 {
6447 /* A suffix follows. */
c19d1205
ZW
6448 p++;
6449 start = p;
a737bd4d 6450
c19d1205
ZW
6451 do
6452 p++;
6453 while (ISALNUM (*p) || *p == '_');
a737bd4d 6454
d2cd1205
JB
6455 if (is_apsr)
6456 {
6457 /* APSR uses a notation for bits, rather than fields. */
6458 unsigned int nzcvq_bits = 0;
6459 unsigned int g_bit = 0;
6460 char *bit;
fa94de6b 6461
d2cd1205
JB
6462 for (bit = start; bit != p; bit++)
6463 {
6464 switch (TOLOWER (*bit))
477330fc 6465 {
d2cd1205
JB
6466 case 'n':
6467 nzcvq_bits |= (nzcvq_bits & 0x01) ? 0x20 : 0x01;
6468 break;
6469
6470 case 'z':
6471 nzcvq_bits |= (nzcvq_bits & 0x02) ? 0x20 : 0x02;
6472 break;
6473
6474 case 'c':
6475 nzcvq_bits |= (nzcvq_bits & 0x04) ? 0x20 : 0x04;
6476 break;
6477
6478 case 'v':
6479 nzcvq_bits |= (nzcvq_bits & 0x08) ? 0x20 : 0x08;
6480 break;
fa94de6b 6481
d2cd1205
JB
6482 case 'q':
6483 nzcvq_bits |= (nzcvq_bits & 0x10) ? 0x20 : 0x10;
6484 break;
fa94de6b 6485
d2cd1205
JB
6486 case 'g':
6487 g_bit |= (g_bit & 0x1) ? 0x2 : 0x1;
6488 break;
fa94de6b 6489
d2cd1205
JB
6490 default:
6491 inst.error = _("unexpected bit specified after APSR");
6492 return FAIL;
6493 }
6494 }
fa94de6b 6495
d2cd1205
JB
6496 if (nzcvq_bits == 0x1f)
6497 psr_field |= PSR_f;
fa94de6b 6498
d2cd1205
JB
6499 if (g_bit == 0x1)
6500 {
6501 if (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp))
477330fc 6502 {
d2cd1205
JB
6503 inst.error = _("selected processor does not "
6504 "support DSP extension");
6505 return FAIL;
6506 }
6507
6508 psr_field |= PSR_s;
6509 }
fa94de6b 6510
d2cd1205
JB
6511 if ((nzcvq_bits & 0x20) != 0
6512 || (nzcvq_bits != 0x1f && nzcvq_bits != 0)
6513 || (g_bit & 0x2) != 0)
6514 {
6515 inst.error = _("bad bitmask specified after APSR");
6516 return FAIL;
6517 }
6518 }
6519 else
477330fc 6520 {
629310ab 6521 psr = (const struct asm_psr *) str_hash_find_n (arm_psr_hsh, start,
fe0e921f 6522 p - start);
d2cd1205 6523 if (!psr)
477330fc 6524 goto error;
a737bd4d 6525
d2cd1205
JB
6526 psr_field |= psr->field;
6527 }
a737bd4d 6528 }
c19d1205 6529 else
a737bd4d 6530 {
c19d1205
ZW
6531 if (ISALNUM (*p))
6532 goto error; /* Garbage after "[CS]PSR". */
6533
d2cd1205 6534 /* Unadorned APSR is equivalent to APSR_nzcvq/CPSR_f (for writes). This
477330fc 6535 is deprecated, but allow it anyway. */
d2cd1205
JB
6536 if (is_apsr && lhs)
6537 {
6538 psr_field |= PSR_f;
6539 as_tsktsk (_("writing to APSR without specifying a bitmask is "
6540 "deprecated"));
6541 }
6542 else if (!m_profile)
6543 /* These bits are never right for M-profile devices: don't set them
6544 (only code paths which read/write APSR reach here). */
6545 psr_field |= (PSR_c | PSR_f);
a737bd4d 6546 }
c19d1205
ZW
6547 *str = p;
6548 return psr_field;
a737bd4d 6549
d2cd1205
JB
6550 unsupported_psr:
6551 inst.error = _("selected processor does not support requested special "
6552 "purpose register");
6553 return FAIL;
6554
c19d1205
ZW
6555 error:
6556 inst.error = _("flag for {c}psr instruction expected");
6557 return FAIL;
a737bd4d
NC
6558}
6559
32c36c3c
AV
6560static int
6561parse_sys_vldr_vstr (char **str)
6562{
6563 unsigned i;
6564 int val = FAIL;
6565 struct {
6566 const char *name;
6567 int regl;
6568 int regh;
6569 } sysregs[] = {
6570 {"FPSCR", 0x1, 0x0},
6571 {"FPSCR_nzcvqc", 0x2, 0x0},
6572 {"VPR", 0x4, 0x1},
6573 {"P0", 0x5, 0x1},
6574 {"FPCXTNS", 0x6, 0x1},
ee3272d4
SP
6575 {"FPCXT_NS", 0x6, 0x1},
6576 {"fpcxtns", 0x6, 0x1},
6577 {"fpcxt_ns", 0x6, 0x1},
6578 {"FPCXTS", 0x7, 0x1},
6579 {"FPCXT_S", 0x7, 0x1},
6580 {"fpcxts", 0x7, 0x1},
6581 {"fpcxt_s", 0x7, 0x1}
32c36c3c
AV
6582 };
6583 char *op_end = strchr (*str, ',');
6584 size_t op_strlen = op_end - *str;
6585
6586 for (i = 0; i < sizeof (sysregs) / sizeof (sysregs[0]); i++)
6587 {
6588 if (!strncmp (*str, sysregs[i].name, op_strlen))
6589 {
6590 val = sysregs[i].regl | (sysregs[i].regh << 3);
6591 *str = op_end;
6592 break;
6593 }
6594 }
6595
6596 return val;
6597}
6598
c19d1205
ZW
6599/* Parse the flags argument to CPSI[ED]. Returns FAIL on error, or a
6600 value suitable for splatting into the AIF field of the instruction. */
a737bd4d 6601
c19d1205
ZW
6602static int
6603parse_cps_flags (char **str)
a737bd4d 6604{
c19d1205
ZW
6605 int val = 0;
6606 int saw_a_flag = 0;
6607 char *s = *str;
a737bd4d 6608
c19d1205
ZW
6609 for (;;)
6610 switch (*s++)
6611 {
6612 case '\0': case ',':
6613 goto done;
a737bd4d 6614
c19d1205
ZW
6615 case 'a': case 'A': saw_a_flag = 1; val |= 0x4; break;
6616 case 'i': case 'I': saw_a_flag = 1; val |= 0x2; break;
6617 case 'f': case 'F': saw_a_flag = 1; val |= 0x1; break;
a737bd4d 6618
c19d1205
ZW
6619 default:
6620 inst.error = _("unrecognized CPS flag");
6621 return FAIL;
6622 }
a737bd4d 6623
c19d1205
ZW
6624 done:
6625 if (saw_a_flag == 0)
a737bd4d 6626 {
c19d1205
ZW
6627 inst.error = _("missing CPS flags");
6628 return FAIL;
a737bd4d 6629 }
a737bd4d 6630
c19d1205
ZW
6631 *str = s - 1;
6632 return val;
a737bd4d
NC
6633}
6634
c19d1205
ZW
6635/* Parse an endian specifier ("BE" or "LE", case insensitive);
6636 returns 0 for big-endian, 1 for little-endian, FAIL for an error. */
a737bd4d
NC
6637
6638static int
c19d1205 6639parse_endian_specifier (char **str)
a737bd4d 6640{
c19d1205
ZW
6641 int little_endian;
6642 char *s = *str;
a737bd4d 6643
c19d1205
ZW
6644 if (strncasecmp (s, "BE", 2))
6645 little_endian = 0;
6646 else if (strncasecmp (s, "LE", 2))
6647 little_endian = 1;
6648 else
a737bd4d 6649 {
c19d1205 6650 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6651 return FAIL;
6652 }
6653
c19d1205 6654 if (ISALNUM (s[2]) || s[2] == '_')
a737bd4d 6655 {
c19d1205 6656 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6657 return FAIL;
6658 }
6659
c19d1205
ZW
6660 *str = s + 2;
6661 return little_endian;
6662}
a737bd4d 6663
c19d1205
ZW
6664/* Parse a rotation specifier: ROR #0, #8, #16, #24. *val receives a
6665 value suitable for poking into the rotate field of an sxt or sxta
6666 instruction, or FAIL on error. */
6667
6668static int
6669parse_ror (char **str)
6670{
6671 int rot;
6672 char *s = *str;
6673
6674 if (strncasecmp (s, "ROR", 3) == 0)
6675 s += 3;
6676 else
a737bd4d 6677 {
c19d1205 6678 inst.error = _("missing rotation field after comma");
a737bd4d
NC
6679 return FAIL;
6680 }
c19d1205 6681
5b7c81bd 6682 if (parse_immediate (&s, &rot, 0, 24, false) == FAIL)
c19d1205
ZW
6683 return FAIL;
6684
6685 switch (rot)
a737bd4d 6686 {
c19d1205
ZW
6687 case 0: *str = s; return 0x0;
6688 case 8: *str = s; return 0x1;
6689 case 16: *str = s; return 0x2;
6690 case 24: *str = s; return 0x3;
6691
6692 default:
6693 inst.error = _("rotation can only be 0, 8, 16, or 24");
a737bd4d
NC
6694 return FAIL;
6695 }
c19d1205 6696}
a737bd4d 6697
c19d1205
ZW
6698/* Parse a conditional code (from conds[] below). The value returned is in the
6699 range 0 .. 14, or FAIL. */
6700static int
6701parse_cond (char **str)
6702{
c462b453 6703 char *q;
c19d1205 6704 const struct asm_cond *c;
c462b453
PB
6705 int n;
6706 /* Condition codes are always 2 characters, so matching up to
6707 3 characters is sufficient. */
6708 char cond[3];
a737bd4d 6709
c462b453
PB
6710 q = *str;
6711 n = 0;
6712 while (ISALPHA (*q) && n < 3)
6713 {
e07e6e58 6714 cond[n] = TOLOWER (*q);
c462b453
PB
6715 q++;
6716 n++;
6717 }
a737bd4d 6718
629310ab 6719 c = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, cond, n);
c19d1205 6720 if (!c)
a737bd4d 6721 {
c19d1205 6722 inst.error = _("condition required");
a737bd4d
NC
6723 return FAIL;
6724 }
6725
c19d1205
ZW
6726 *str = q;
6727 return c->value;
6728}
6729
62b3e311
PB
6730/* Parse an option for a barrier instruction. Returns the encoding for the
6731 option, or FAIL. */
6732static int
6733parse_barrier (char **str)
6734{
6735 char *p, *q;
6736 const struct asm_barrier_opt *o;
6737
6738 p = q = *str;
6739 while (ISALPHA (*q))
6740 q++;
6741
629310ab 6742 o = (const struct asm_barrier_opt *) str_hash_find_n (arm_barrier_opt_hsh, p,
fe0e921f 6743 q - p);
62b3e311
PB
6744 if (!o)
6745 return FAIL;
6746
e797f7e0
MGD
6747 if (!mark_feature_used (&o->arch))
6748 return FAIL;
6749
62b3e311
PB
6750 *str = q;
6751 return o->value;
6752}
6753
92e90b6e
PB
6754/* Parse the operands of a table branch instruction. Similar to a memory
6755 operand. */
6756static int
6757parse_tb (char **str)
6758{
6759 char * p = *str;
6760 int reg;
6761
6762 if (skip_past_char (&p, '[') == FAIL)
ab1eb5fe
PB
6763 {
6764 inst.error = _("'[' expected");
6765 return FAIL;
6766 }
92e90b6e 6767
dcbf9037 6768 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6769 {
6770 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6771 return FAIL;
6772 }
6773 inst.operands[0].reg = reg;
6774
6775 if (skip_past_comma (&p) == FAIL)
ab1eb5fe
PB
6776 {
6777 inst.error = _("',' expected");
6778 return FAIL;
6779 }
5f4273c7 6780
dcbf9037 6781 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6782 {
6783 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6784 return FAIL;
6785 }
6786 inst.operands[0].imm = reg;
6787
6788 if (skip_past_comma (&p) == SUCCESS)
6789 {
6790 if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
6791 return FAIL;
e2b0ab59 6792 if (inst.relocs[0].exp.X_add_number != 1)
92e90b6e
PB
6793 {
6794 inst.error = _("invalid shift");
6795 return FAIL;
6796 }
6797 inst.operands[0].shifted = 1;
6798 }
6799
6800 if (skip_past_char (&p, ']') == FAIL)
6801 {
6802 inst.error = _("']' expected");
6803 return FAIL;
6804 }
6805 *str = p;
6806 return SUCCESS;
6807}
6808
5287ad62
JB
6809/* Parse the operands of a Neon VMOV instruction. See do_neon_mov for more
6810 information on the types the operands can take and how they are encoded.
037e8744
JB
6811 Up to four operands may be read; this function handles setting the
6812 ".present" field for each read operand itself.
5287ad62
JB
6813 Updates STR and WHICH_OPERAND if parsing is successful and returns SUCCESS,
6814 else returns FAIL. */
6815
6816static int
6817parse_neon_mov (char **str, int *which_operand)
6818{
6819 int i = *which_operand, val;
6820 enum arm_reg_type rtype;
6821 char *ptr = *str;
dcbf9037 6822 struct neon_type_el optype;
5f4273c7 6823
57785aa2
AV
6824 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6825 {
6826 /* Cases 17 or 19. */
6827 inst.operands[i].reg = val;
6828 inst.operands[i].isvec = 1;
6829 inst.operands[i].isscalar = 2;
6830 inst.operands[i].vectype = optype;
6831 inst.operands[i++].present = 1;
6832
6833 if (skip_past_comma (&ptr) == FAIL)
6834 goto wanted_comma;
6835
6836 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
6837 {
6838 /* Case 17: VMOV<c>.<dt> <Qd[idx]>, <Rt> */
6839 inst.operands[i].reg = val;
6840 inst.operands[i].isreg = 1;
6841 inst.operands[i].present = 1;
6842 }
6843 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6844 {
6845 /* Case 19: VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2> */
6846 inst.operands[i].reg = val;
6847 inst.operands[i].isvec = 1;
6848 inst.operands[i].isscalar = 2;
6849 inst.operands[i].vectype = optype;
6850 inst.operands[i++].present = 1;
6851
6852 if (skip_past_comma (&ptr) == FAIL)
6853 goto wanted_comma;
6854
6855 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6856 goto wanted_arm;
6857
6858 inst.operands[i].reg = val;
6859 inst.operands[i].isreg = 1;
6860 inst.operands[i++].present = 1;
6861
6862 if (skip_past_comma (&ptr) == FAIL)
6863 goto wanted_comma;
6864
6865 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6866 goto wanted_arm;
6867
6868 inst.operands[i].reg = val;
6869 inst.operands[i].isreg = 1;
6870 inst.operands[i].present = 1;
6871 }
6872 else
6873 {
6874 first_error (_("expected ARM or MVE vector register"));
6875 return FAIL;
6876 }
6877 }
6878 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
5287ad62
JB
6879 {
6880 /* Case 4: VMOV<c><q>.<size> <Dn[x]>, <Rd>. */
6881 inst.operands[i].reg = val;
6882 inst.operands[i].isscalar = 1;
dcbf9037 6883 inst.operands[i].vectype = optype;
5287ad62
JB
6884 inst.operands[i++].present = 1;
6885
6886 if (skip_past_comma (&ptr) == FAIL)
477330fc 6887 goto wanted_comma;
5f4273c7 6888
dcbf9037 6889 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
477330fc 6890 goto wanted_arm;
5f4273c7 6891
5287ad62
JB
6892 inst.operands[i].reg = val;
6893 inst.operands[i].isreg = 1;
6894 inst.operands[i].present = 1;
6895 }
57785aa2
AV
6896 else if (((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype, &optype))
6897 != FAIL)
6898 || ((val = arm_typed_reg_parse (&ptr, REG_TYPE_MQ, &rtype, &optype))
6899 != FAIL))
5287ad62
JB
6900 {
6901 /* Cases 0, 1, 2, 3, 5 (D only). */
6902 if (skip_past_comma (&ptr) == FAIL)
477330fc 6903 goto wanted_comma;
5f4273c7 6904
5287ad62
JB
6905 inst.operands[i].reg = val;
6906 inst.operands[i].isreg = 1;
6907 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
037e8744
JB
6908 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6909 inst.operands[i].isvec = 1;
dcbf9037 6910 inst.operands[i].vectype = optype;
5287ad62
JB
6911 inst.operands[i++].present = 1;
6912
dcbf9037 6913 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc
RM
6914 {
6915 /* Case 5: VMOV<c><q> <Dm>, <Rd>, <Rn>.
6916 Case 13: VMOV <Sd>, <Rm> */
6917 inst.operands[i].reg = val;
6918 inst.operands[i].isreg = 1;
6919 inst.operands[i].present = 1;
6920
6921 if (rtype == REG_TYPE_NQ)
6922 {
6923 first_error (_("can't use Neon quad register here"));
6924 return FAIL;
6925 }
6926 else if (rtype != REG_TYPE_VFS)
6927 {
6928 i++;
6929 if (skip_past_comma (&ptr) == FAIL)
6930 goto wanted_comma;
6931 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6932 goto wanted_arm;
6933 inst.operands[i].reg = val;
6934 inst.operands[i].isreg = 1;
6935 inst.operands[i].present = 1;
6936 }
6937 }
c4a23bf8
SP
6938 else if (((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype,
6939 &optype)) != FAIL)
6940 || ((val = arm_typed_reg_parse (&ptr, REG_TYPE_MQ, &rtype,
6941 &optype)) != FAIL))
477330fc
RM
6942 {
6943 /* Case 0: VMOV<c><q> <Qd>, <Qm>
6944 Case 1: VMOV<c><q> <Dd>, <Dm>
6945 Case 8: VMOV.F32 <Sd>, <Sm>
6946 Case 15: VMOV <Sd>, <Se>, <Rn>, <Rm> */
6947
6948 inst.operands[i].reg = val;
6949 inst.operands[i].isreg = 1;
6950 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
6951 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6952 inst.operands[i].isvec = 1;
6953 inst.operands[i].vectype = optype;
6954 inst.operands[i].present = 1;
6955
6956 if (skip_past_comma (&ptr) == SUCCESS)
6957 {
6958 /* Case 15. */
6959 i++;
6960
6961 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6962 goto wanted_arm;
6963
6964 inst.operands[i].reg = val;
6965 inst.operands[i].isreg = 1;
6966 inst.operands[i++].present = 1;
6967
6968 if (skip_past_comma (&ptr) == FAIL)
6969 goto wanted_comma;
6970
6971 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6972 goto wanted_arm;
6973
6974 inst.operands[i].reg = val;
6975 inst.operands[i].isreg = 1;
6976 inst.operands[i].present = 1;
6977 }
6978 }
4641781c 6979 else if (parse_qfloat_immediate (&ptr, &inst.operands[i].imm) == SUCCESS)
477330fc
RM
6980 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<float-imm>
6981 Case 3: VMOV<c><q>.<dt> <Dd>, #<float-imm>
6982 Case 10: VMOV.F32 <Sd>, #<imm>
6983 Case 11: VMOV.F64 <Dd>, #<imm> */
6984 inst.operands[i].immisfloat = 1;
5b7c81bd 6985 else if (parse_big_immediate (&ptr, i, NULL, /*allow_symbol_p=*/false)
8335d6aa 6986 == SUCCESS)
477330fc
RM
6987 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<imm>
6988 Case 3: VMOV<c><q>.<dt> <Dd>, #<imm> */
6989 ;
5287ad62 6990 else
477330fc
RM
6991 {
6992 first_error (_("expected <Rm> or <Dm> or <Qm> operand"));
6993 return FAIL;
6994 }
5287ad62 6995 }
dcbf9037 6996 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
5287ad62 6997 {
57785aa2 6998 /* Cases 6, 7, 16, 18. */
5287ad62
JB
6999 inst.operands[i].reg = val;
7000 inst.operands[i].isreg = 1;
7001 inst.operands[i++].present = 1;
5f4273c7 7002
5287ad62 7003 if (skip_past_comma (&ptr) == FAIL)
477330fc 7004 goto wanted_comma;
5f4273c7 7005
57785aa2
AV
7006 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
7007 {
7008 /* Case 18: VMOV<c>.<dt> <Rt>, <Qn[idx]> */
7009 inst.operands[i].reg = val;
7010 inst.operands[i].isscalar = 2;
7011 inst.operands[i].present = 1;
7012 inst.operands[i].vectype = optype;
7013 }
7014 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
477330fc
RM
7015 {
7016 /* Case 6: VMOV<c><q>.<dt> <Rd>, <Dn[x]> */
7017 inst.operands[i].reg = val;
7018 inst.operands[i].isscalar = 1;
7019 inst.operands[i].present = 1;
7020 inst.operands[i].vectype = optype;
7021 }
dcbf9037 7022 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc 7023 {
477330fc
RM
7024 inst.operands[i].reg = val;
7025 inst.operands[i].isreg = 1;
7026 inst.operands[i++].present = 1;
7027
7028 if (skip_past_comma (&ptr) == FAIL)
7029 goto wanted_comma;
7030
7031 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFSD, &rtype, &optype))
57785aa2 7032 != FAIL)
477330fc 7033 {
57785aa2 7034 /* Case 7: VMOV<c><q> <Rd>, <Rn>, <Dm> */
477330fc 7035
477330fc
RM
7036 inst.operands[i].reg = val;
7037 inst.operands[i].isreg = 1;
7038 inst.operands[i].isvec = 1;
57785aa2 7039 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
477330fc
RM
7040 inst.operands[i].vectype = optype;
7041 inst.operands[i].present = 1;
57785aa2
AV
7042
7043 if (rtype == REG_TYPE_VFS)
7044 {
7045 /* Case 14. */
7046 i++;
7047 if (skip_past_comma (&ptr) == FAIL)
7048 goto wanted_comma;
7049 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL,
7050 &optype)) == FAIL)
7051 {
7052 first_error (_(reg_expected_msgs[REG_TYPE_VFS]));
7053 return FAIL;
7054 }
7055 inst.operands[i].reg = val;
7056 inst.operands[i].isreg = 1;
7057 inst.operands[i].isvec = 1;
7058 inst.operands[i].issingle = 1;
7059 inst.operands[i].vectype = optype;
7060 inst.operands[i].present = 1;
7061 }
7062 }
7063 else
7064 {
7065 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
7066 != FAIL)
7067 {
7068 /* Case 16: VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]> */
7069 inst.operands[i].reg = val;
7070 inst.operands[i].isvec = 1;
7071 inst.operands[i].isscalar = 2;
7072 inst.operands[i].vectype = optype;
7073 inst.operands[i++].present = 1;
7074
7075 if (skip_past_comma (&ptr) == FAIL)
7076 goto wanted_comma;
7077
7078 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
7079 == FAIL)
7080 {
7081 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
7082 return FAIL;
7083 }
7084 inst.operands[i].reg = val;
7085 inst.operands[i].isvec = 1;
7086 inst.operands[i].isscalar = 2;
7087 inst.operands[i].vectype = optype;
7088 inst.operands[i].present = 1;
7089 }
7090 else
7091 {
7092 first_error (_("VFP single, double or MVE vector register"
7093 " expected"));
7094 return FAIL;
7095 }
477330fc
RM
7096 }
7097 }
037e8744 7098 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL, &optype))
477330fc
RM
7099 != FAIL)
7100 {
7101 /* Case 13. */
7102 inst.operands[i].reg = val;
7103 inst.operands[i].isreg = 1;
7104 inst.operands[i].isvec = 1;
7105 inst.operands[i].issingle = 1;
7106 inst.operands[i].vectype = optype;
7107 inst.operands[i].present = 1;
7108 }
5287ad62
JB
7109 }
7110 else
7111 {
dcbf9037 7112 first_error (_("parse error"));
5287ad62
JB
7113 return FAIL;
7114 }
7115
7116 /* Successfully parsed the operands. Update args. */
7117 *which_operand = i;
7118 *str = ptr;
7119 return SUCCESS;
7120
5f4273c7 7121 wanted_comma:
dcbf9037 7122 first_error (_("expected comma"));
5287ad62 7123 return FAIL;
5f4273c7
NC
7124
7125 wanted_arm:
dcbf9037 7126 first_error (_(reg_expected_msgs[REG_TYPE_RN]));
5287ad62 7127 return FAIL;
5287ad62
JB
7128}
7129
5be8be5d
DG
7130/* Use this macro when the operand constraints are different
7131 for ARM and THUMB (e.g. ldrd). */
7132#define MIX_ARM_THUMB_OPERANDS(arm_operand, thumb_operand) \
7133 ((arm_operand) | ((thumb_operand) << 16))
7134
c19d1205
ZW
7135/* Matcher codes for parse_operands. */
7136enum operand_parse_code
7137{
7138 OP_stop, /* end of line */
7139
7140 OP_RR, /* ARM register */
7141 OP_RRnpc, /* ARM register, not r15 */
5be8be5d 7142 OP_RRnpcsp, /* ARM register, neither r15 nor r13 (a.k.a. 'BadReg') */
c19d1205 7143 OP_RRnpcb, /* ARM register, not r15, in square brackets */
fa94de6b 7144 OP_RRnpctw, /* ARM register, not r15 in Thumb-state or with writeback,
55881a11 7145 optional trailing ! */
c19d1205
ZW
7146 OP_RRw, /* ARM register, not r15, optional trailing ! */
7147 OP_RCP, /* Coprocessor number */
7148 OP_RCN, /* Coprocessor register */
7149 OP_RF, /* FPA register */
7150 OP_RVS, /* VFP single precision register */
5287ad62
JB
7151 OP_RVD, /* VFP double precision register (0..15) */
7152 OP_RND, /* Neon double precision register (0..31) */
5ee91343
AV
7153 OP_RNDMQ, /* Neon double precision (0..31) or MVE vector register. */
7154 OP_RNDMQR, /* Neon double precision (0..31), MVE vector or ARM register.
7155 */
66d1f7cc
AV
7156 OP_RNSDMQR, /* Neon single or double precision, MVE vector or ARM register.
7157 */
5287ad62 7158 OP_RNQ, /* Neon quad precision register */
5ee91343 7159 OP_RNQMQ, /* Neon quad or MVE vector register. */
037e8744 7160 OP_RVSD, /* VFP single or double precision register */
1b883319 7161 OP_RVSD_COND, /* VFP single, double precision register or condition code. */
dd9634d9 7162 OP_RVSDMQ, /* VFP single, double precision or MVE vector register. */
dec41383 7163 OP_RNSD, /* Neon single or double precision register */
5287ad62 7164 OP_RNDQ, /* Neon double or quad precision register */
5ee91343 7165 OP_RNDQMQ, /* Neon double, quad or MVE vector register. */
7df54120 7166 OP_RNDQMQR, /* Neon double, quad, MVE vector or ARM register. */
037e8744 7167 OP_RNSDQ, /* Neon single, double or quad precision register */
5287ad62 7168 OP_RNSC, /* Neon scalar D[X] */
c19d1205
ZW
7169 OP_RVC, /* VFP control register */
7170 OP_RMF, /* Maverick F register */
7171 OP_RMD, /* Maverick D register */
7172 OP_RMFX, /* Maverick FX register */
7173 OP_RMDX, /* Maverick DX register */
7174 OP_RMAX, /* Maverick AX register */
7175 OP_RMDS, /* Maverick DSPSC register */
7176 OP_RIWR, /* iWMMXt wR register */
7177 OP_RIWC, /* iWMMXt wC register */
7178 OP_RIWG, /* iWMMXt wCG register */
7179 OP_RXA, /* XScale accumulator register */
7180
5aae9ae9 7181 OP_RNSDMQ, /* Neon single, double or MVE vector register */
5ee91343
AV
7182 OP_RNSDQMQ, /* Neon single, double or quad register or MVE vector register
7183 */
7184 OP_RNSDQMQR, /* Neon single, double or quad register, MVE vector register or
7185 GPR (no SP/SP) */
a302e574 7186 OP_RMQ, /* MVE vector register. */
1b883319 7187 OP_RMQRZ, /* MVE vector or ARM register including ZR. */
35d1cfc2 7188 OP_RMQRR, /* MVE vector or ARM register. */
a302e574 7189
60f993ce
AV
7190 /* New operands for Armv8.1-M Mainline. */
7191 OP_LR, /* ARM LR register */
f1e1d7f3
AC
7192 OP_SP, /* ARM SP register */
7193 OP_R12,
a302e574
AV
7194 OP_RRe, /* ARM register, only even numbered. */
7195 OP_RRo, /* ARM register, only odd numbered, not r13 or r15. */
60f993ce 7196 OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
e39c1607 7197 OP_RR_ZR, /* ARM register or ZR but no PC */
60f993ce 7198
c19d1205 7199 OP_REGLST, /* ARM register list */
4b5a202f 7200 OP_CLRMLST, /* CLRM register list */
c19d1205
ZW
7201 OP_VRSLST, /* VFP single-precision register list */
7202 OP_VRDLST, /* VFP double-precision register list */
037e8744 7203 OP_VRSDLST, /* VFP single or double-precision register list (& quad) */
5287ad62
JB
7204 OP_NRDLST, /* Neon double-precision register list (d0-d31, qN aliases) */
7205 OP_NSTRLST, /* Neon element/structure list */
efd6b359 7206 OP_VRSDVLST, /* VFP single or double-precision register list and VPR */
35c228db
AV
7207 OP_MSTRLST2, /* MVE vector list with two elements. */
7208 OP_MSTRLST4, /* MVE vector list with four elements. */
5287ad62 7209
5287ad62 7210 OP_RNDQ_I0, /* Neon D or Q reg, or immediate zero. */
037e8744 7211 OP_RVSD_I0, /* VFP S or D reg, or immediate zero. */
aacf0b33 7212 OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero. */
1b883319
AV
7213 OP_RSVDMQ_FI0, /* VFP S, D, MVE vector register or floating point immediate
7214 zero. */
5287ad62 7215 OP_RR_RNSC, /* ARM reg or Neon scalar. */
dec41383 7216 OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar. */
037e8744 7217 OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar. */
886e1c73
AV
7218 OP_RNSDQ_RNSC_MQ, /* Vector S, D or Q reg, Neon scalar or MVE vector register.
7219 */
a8465a06
AV
7220 OP_RNSDQ_RNSC_MQ_RR, /* Vector S, D or Q reg, or MVE vector reg , or Neon
7221 scalar, or ARM register. */
5287ad62 7222 OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar. */
42b16635
AV
7223 OP_RNDQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, or ARM register. */
7224 OP_RNDQMQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, MVE vector or ARM
7225 register. */
5d281bf0 7226 OP_RNDQMQ_RNSC, /* Neon D, Q or MVE vector reg, or Neon scalar. */
5287ad62
JB
7227 OP_RND_RNSC, /* Neon D reg, or Neon scalar. */
7228 OP_VMOV, /* Neon VMOV operands. */
4316f0d2 7229 OP_RNDQ_Ibig, /* Neon D or Q reg, or big immediate for logic and VMVN. */
f601a00c
AV
7230 /* Neon D, Q or MVE vector register, or big immediate for logic and VMVN. */
7231 OP_RNDQMQ_Ibig,
5287ad62 7232 OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift. */
5150f0d8
AV
7233 OP_RNDQMQ_I63b_RR, /* Neon D or Q reg, immediate for shift, MVE vector or
7234 ARM register. */
2d447fca 7235 OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2. */
32c36c3c 7236 OP_VLDR, /* VLDR operand. */
5287ad62
JB
7237
7238 OP_I0, /* immediate zero */
c19d1205
ZW
7239 OP_I7, /* immediate value 0 .. 7 */
7240 OP_I15, /* 0 .. 15 */
7241 OP_I16, /* 1 .. 16 */
5287ad62 7242 OP_I16z, /* 0 .. 16 */
c19d1205
ZW
7243 OP_I31, /* 0 .. 31 */
7244 OP_I31w, /* 0 .. 31, optional trailing ! */
7245 OP_I32, /* 1 .. 32 */
5287ad62 7246 OP_I32z, /* 0 .. 32 */
08132bdd 7247 OP_I48_I64, /* 48 or 64 */
5287ad62 7248 OP_I63, /* 0 .. 63 */
c19d1205 7249 OP_I63s, /* -64 .. 63 */
5287ad62
JB
7250 OP_I64, /* 1 .. 64 */
7251 OP_I64z, /* 0 .. 64 */
5aae9ae9 7252 OP_I127, /* 0 .. 127 */
c19d1205 7253 OP_I255, /* 0 .. 255 */
4934a27c 7254 OP_I511, /* 0 .. 511 */
5aae9ae9 7255 OP_I4095, /* 0 .. 4095 */
4934a27c 7256 OP_I8191, /* 0 .. 8191 */
c19d1205
ZW
7257 OP_I4b, /* immediate, prefix optional, 1 .. 4 */
7258 OP_I7b, /* 0 .. 7 */
7259 OP_I15b, /* 0 .. 15 */
7260 OP_I31b, /* 0 .. 31 */
7261
7262 OP_SH, /* shifter operand */
4962c51a 7263 OP_SHG, /* shifter operand with possible group relocation */
c19d1205 7264 OP_ADDR, /* Memory address expression (any mode) */
35c228db 7265 OP_ADDRMVE, /* Memory address expression for MVE's VSTR/VLDR. */
4962c51a
MS
7266 OP_ADDRGLDR, /* Mem addr expr (any mode) with possible LDR group reloc */
7267 OP_ADDRGLDRS, /* Mem addr expr (any mode) with possible LDRS group reloc */
7268 OP_ADDRGLDC, /* Mem addr expr (any mode) with possible LDC group reloc */
c19d1205
ZW
7269 OP_EXP, /* arbitrary expression */
7270 OP_EXPi, /* same, with optional immediate prefix */
7271 OP_EXPr, /* same, with optional relocation suffix */
e2b0ab59 7272 OP_EXPs, /* same, with optional non-first operand relocation suffix */
b6895b4f 7273 OP_HALF, /* 0 .. 65535 or low/high reloc. */
c28eeff2
SN
7274 OP_IROT1, /* VCADD rotate immediate: 90, 270. */
7275 OP_IROT2, /* VCMLA rotate immediate: 0, 90, 180, 270. */
c19d1205
ZW
7276
7277 OP_CPSF, /* CPS flags */
7278 OP_ENDI, /* Endianness specifier */
d2cd1205
JB
7279 OP_wPSR, /* CPSR/SPSR/APSR mask for msr (writing). */
7280 OP_rPSR, /* CPSR/SPSR/APSR mask for msr (reading). */
c19d1205 7281 OP_COND, /* conditional code */
92e90b6e 7282 OP_TB, /* Table branch. */
c19d1205 7283
037e8744
JB
7284 OP_APSR_RR, /* ARM register or "APSR_nzcv". */
7285
c19d1205 7286 OP_RRnpc_I0, /* ARM register or literal 0 */
33eaf5de 7287 OP_RR_EXr, /* ARM register or expression with opt. reloc stuff. */
c19d1205
ZW
7288 OP_RR_EXi, /* ARM register or expression with imm prefix */
7289 OP_RF_IF, /* FPA register or immediate */
7290 OP_RIWR_RIWC, /* iWMMXt R or C reg */
41adaa5c 7291 OP_RIWC_RIWG, /* iWMMXt wC or wCG reg */
c19d1205
ZW
7292
7293 /* Optional operands. */
7294 OP_oI7b, /* immediate, prefix optional, 0 .. 7 */
7295 OP_oI31b, /* 0 .. 31 */
5287ad62 7296 OP_oI32b, /* 1 .. 32 */
5f1af56b 7297 OP_oI32z, /* 0 .. 32 */
c19d1205
ZW
7298 OP_oIffffb, /* 0 .. 65535 */
7299 OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
7300
7301 OP_oRR, /* ARM register */
60f993ce 7302 OP_oLR, /* ARM LR register */
c19d1205 7303 OP_oRRnpc, /* ARM register, not the PC */
5be8be5d 7304 OP_oRRnpcsp, /* ARM register, neither the PC nor the SP (a.k.a. BadReg) */
b6702015 7305 OP_oRRw, /* ARM register, not r15, optional trailing ! */
5287ad62
JB
7306 OP_oRND, /* Optional Neon double precision register */
7307 OP_oRNQ, /* Optional Neon quad precision register */
5ee91343 7308 OP_oRNDQMQ, /* Optional Neon double, quad or MVE vector register. */
5287ad62 7309 OP_oRNDQ, /* Optional Neon double or quad precision register */
037e8744 7310 OP_oRNSDQ, /* Optional single, double or quad precision vector register */
5ee91343
AV
7311 OP_oRNSDQMQ, /* Optional single, double or quad register or MVE vector
7312 register. */
66d1f7cc
AV
7313 OP_oRNSDMQ, /* Optional single, double register or MVE vector
7314 register. */
c19d1205
ZW
7315 OP_oSHll, /* LSL immediate */
7316 OP_oSHar, /* ASR immediate */
7317 OP_oSHllar, /* LSL or ASR immediate */
7318 OP_oROR, /* ROR 0/8/16/24 */
52e7f43d 7319 OP_oBARRIER_I15, /* Option argument for a barrier instruction. */
c19d1205 7320
1b883319
AV
7321 OP_oRMQRZ, /* optional MVE vector or ARM register including ZR. */
7322
5be8be5d
DG
7323 /* Some pre-defined mixed (ARM/THUMB) operands. */
7324 OP_RR_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
7325 OP_RRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
7326 OP_oRRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_oRRnpc, OP_oRRnpcsp),
7327
c19d1205
ZW
7328 OP_FIRST_OPTIONAL = OP_oI7b
7329};
a737bd4d 7330
c19d1205
ZW
7331/* Generic instruction operand parser. This does no encoding and no
7332 semantic validation; it merely squirrels values away in the inst
7333 structure. Returns SUCCESS or FAIL depending on whether the
7334 specified grammar matched. */
7335static int
5b7c81bd 7336parse_operands (char *str, const unsigned int *pattern, bool thumb)
c19d1205 7337{
5be8be5d 7338 unsigned const int *upat = pattern;
c19d1205
ZW
7339 char *backtrack_pos = 0;
7340 const char *backtrack_error = 0;
99aad254 7341 int i, val = 0, backtrack_index = 0;
5287ad62 7342 enum arm_reg_type rtype;
4962c51a 7343 parse_operand_result result;
5be8be5d 7344 unsigned int op_parse_code;
5b7c81bd 7345 bool partial_match;
c19d1205 7346
e07e6e58
NC
7347#define po_char_or_fail(chr) \
7348 do \
7349 { \
7350 if (skip_past_char (&str, chr) == FAIL) \
477330fc 7351 goto bad_args; \
e07e6e58
NC
7352 } \
7353 while (0)
c19d1205 7354
e07e6e58
NC
7355#define po_reg_or_fail(regtype) \
7356 do \
dcbf9037 7357 { \
e07e6e58 7358 val = arm_typed_reg_parse (& str, regtype, & rtype, \
477330fc 7359 & inst.operands[i].vectype); \
e07e6e58 7360 if (val == FAIL) \
477330fc
RM
7361 { \
7362 first_error (_(reg_expected_msgs[regtype])); \
7363 goto failure; \
7364 } \
e07e6e58
NC
7365 inst.operands[i].reg = val; \
7366 inst.operands[i].isreg = 1; \
7367 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7368 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7369 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc
RM
7370 || rtype == REG_TYPE_VFD \
7371 || rtype == REG_TYPE_NQ); \
1b883319 7372 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
dcbf9037 7373 } \
e07e6e58
NC
7374 while (0)
7375
7376#define po_reg_or_goto(regtype, label) \
7377 do \
7378 { \
7379 val = arm_typed_reg_parse (& str, regtype, & rtype, \
7380 & inst.operands[i].vectype); \
7381 if (val == FAIL) \
7382 goto label; \
dcbf9037 7383 \
e07e6e58
NC
7384 inst.operands[i].reg = val; \
7385 inst.operands[i].isreg = 1; \
7386 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7387 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7388 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc 7389 || rtype == REG_TYPE_VFD \
e07e6e58 7390 || rtype == REG_TYPE_NQ); \
1b883319 7391 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
e07e6e58
NC
7392 } \
7393 while (0)
7394
7395#define po_imm_or_fail(min, max, popt) \
7396 do \
7397 { \
7398 if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
7399 goto failure; \
7400 inst.operands[i].imm = val; \
7401 } \
7402 while (0)
7403
08132bdd
SP
7404#define po_imm1_or_imm2_or_fail(imm1, imm2, popt) \
7405 do \
7406 { \
7407 expressionS exp; \
7408 my_get_expression (&exp, &str, popt); \
7409 if (exp.X_op != O_constant) \
7410 { \
7411 inst.error = _("constant expression required"); \
7412 goto failure; \
7413 } \
7414 if (exp.X_add_number != imm1 && exp.X_add_number != imm2) \
7415 { \
7416 inst.error = _("immediate value 48 or 64 expected"); \
7417 goto failure; \
7418 } \
7419 inst.operands[i].imm = exp.X_add_number; \
7420 } \
7421 while (0)
7422
57785aa2 7423#define po_scalar_or_goto(elsz, label, reg_type) \
e07e6e58
NC
7424 do \
7425 { \
57785aa2
AV
7426 val = parse_scalar (& str, elsz, & inst.operands[i].vectype, \
7427 reg_type); \
e07e6e58
NC
7428 if (val == FAIL) \
7429 goto label; \
7430 inst.operands[i].reg = val; \
7431 inst.operands[i].isscalar = 1; \
7432 } \
7433 while (0)
7434
7435#define po_misc_or_fail(expr) \
7436 do \
7437 { \
7438 if (expr) \
7439 goto failure; \
7440 } \
7441 while (0)
7442
7443#define po_misc_or_fail_no_backtrack(expr) \
7444 do \
7445 { \
7446 result = expr; \
7447 if (result == PARSE_OPERAND_FAIL_NO_BACKTRACK) \
7448 backtrack_pos = 0; \
7449 if (result != PARSE_OPERAND_SUCCESS) \
7450 goto failure; \
7451 } \
7452 while (0)
4962c51a 7453
52e7f43d
RE
7454#define po_barrier_or_imm(str) \
7455 do \
7456 { \
7457 val = parse_barrier (&str); \
ccb84d65
JB
7458 if (val == FAIL && ! ISALPHA (*str)) \
7459 goto immediate; \
7460 if (val == FAIL \
7461 /* ISB can only take SY as an option. */ \
7462 || ((inst.instruction & 0xf0) == 0x60 \
7463 && val != 0xf)) \
52e7f43d 7464 { \
ccb84d65
JB
7465 inst.error = _("invalid barrier type"); \
7466 backtrack_pos = 0; \
7467 goto failure; \
52e7f43d
RE
7468 } \
7469 } \
7470 while (0)
7471
c19d1205
ZW
7472 skip_whitespace (str);
7473
7474 for (i = 0; upat[i] != OP_stop; i++)
7475 {
5be8be5d
DG
7476 op_parse_code = upat[i];
7477 if (op_parse_code >= 1<<16)
7478 op_parse_code = thumb ? (op_parse_code >> 16)
7479 : (op_parse_code & ((1<<16)-1));
7480
7481 if (op_parse_code >= OP_FIRST_OPTIONAL)
c19d1205
ZW
7482 {
7483 /* Remember where we are in case we need to backtrack. */
c19d1205
ZW
7484 backtrack_pos = str;
7485 backtrack_error = inst.error;
7486 backtrack_index = i;
7487 }
7488
b6702015 7489 if (i > 0 && (i > 1 || inst.operands[0].present))
c19d1205
ZW
7490 po_char_or_fail (',');
7491
5be8be5d 7492 switch (op_parse_code)
c19d1205
ZW
7493 {
7494 /* Registers */
7495 case OP_oRRnpc:
5be8be5d 7496 case OP_oRRnpcsp:
c19d1205 7497 case OP_RRnpc:
5be8be5d 7498 case OP_RRnpcsp:
c19d1205 7499 case OP_oRR:
a302e574
AV
7500 case OP_RRe:
7501 case OP_RRo:
60f993ce
AV
7502 case OP_LR:
7503 case OP_oLR:
f1e1d7f3
AC
7504 case OP_SP:
7505 case OP_R12:
c19d1205
ZW
7506 case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
7507 case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
7508 case OP_RCN: po_reg_or_fail (REG_TYPE_CN); break;
7509 case OP_RF: po_reg_or_fail (REG_TYPE_FN); break;
7510 case OP_RVS: po_reg_or_fail (REG_TYPE_VFS); break;
7511 case OP_RVD: po_reg_or_fail (REG_TYPE_VFD); break;
477330fc 7512 case OP_oRND:
66d1f7cc
AV
7513 case OP_RNSDMQR:
7514 po_reg_or_goto (REG_TYPE_VFS, try_rndmqr);
7515 break;
7516 try_rndmqr:
5ee91343
AV
7517 case OP_RNDMQR:
7518 po_reg_or_goto (REG_TYPE_RN, try_rndmq);
7519 break;
7520 try_rndmq:
7521 case OP_RNDMQ:
7522 po_reg_or_goto (REG_TYPE_MQ, try_rnd);
7523 break;
7524 try_rnd:
5287ad62 7525 case OP_RND: po_reg_or_fail (REG_TYPE_VFD); break;
cd2cf30b
PB
7526 case OP_RVC:
7527 po_reg_or_goto (REG_TYPE_VFC, coproc_reg);
7528 break;
7529 /* Also accept generic coprocessor regs for unknown registers. */
7530 coproc_reg:
ba6cd17f
SD
7531 po_reg_or_goto (REG_TYPE_CN, vpr_po);
7532 break;
7533 /* Also accept P0 or p0 for VPR.P0. Since P0 is already an
7534 existing register with a value of 0, this seems like the
7535 best way to parse P0. */
7536 vpr_po:
7537 if (strncasecmp (str, "P0", 2) == 0)
7538 {
7539 str += 2;
7540 inst.operands[i].isreg = 1;
7541 inst.operands[i].reg = 13;
7542 }
7543 else
7544 goto failure;
cd2cf30b 7545 break;
c19d1205
ZW
7546 case OP_RMF: po_reg_or_fail (REG_TYPE_MVF); break;
7547 case OP_RMD: po_reg_or_fail (REG_TYPE_MVD); break;
7548 case OP_RMFX: po_reg_or_fail (REG_TYPE_MVFX); break;
7549 case OP_RMDX: po_reg_or_fail (REG_TYPE_MVDX); break;
7550 case OP_RMAX: po_reg_or_fail (REG_TYPE_MVAX); break;
7551 case OP_RMDS: po_reg_or_fail (REG_TYPE_DSPSC); break;
7552 case OP_RIWR: po_reg_or_fail (REG_TYPE_MMXWR); break;
7553 case OP_RIWC: po_reg_or_fail (REG_TYPE_MMXWC); break;
7554 case OP_RIWG: po_reg_or_fail (REG_TYPE_MMXWCG); break;
7555 case OP_RXA: po_reg_or_fail (REG_TYPE_XSCALE); break;
477330fc 7556 case OP_oRNQ:
5ee91343
AV
7557 case OP_RNQMQ:
7558 po_reg_or_goto (REG_TYPE_MQ, try_nq);
7559 break;
7560 try_nq:
5287ad62 7561 case OP_RNQ: po_reg_or_fail (REG_TYPE_NQ); break;
dec41383 7562 case OP_RNSD: po_reg_or_fail (REG_TYPE_NSD); break;
7df54120
AV
7563 case OP_RNDQMQR:
7564 po_reg_or_goto (REG_TYPE_RN, try_rndqmq);
7565 break;
7566 try_rndqmq:
5ee91343
AV
7567 case OP_oRNDQMQ:
7568 case OP_RNDQMQ:
7569 po_reg_or_goto (REG_TYPE_MQ, try_rndq);
7570 break;
7571 try_rndq:
477330fc 7572 case OP_oRNDQ:
5287ad62 7573 case OP_RNDQ: po_reg_or_fail (REG_TYPE_NDQ); break;
dd9634d9
AV
7574 case OP_RVSDMQ:
7575 po_reg_or_goto (REG_TYPE_MQ, try_rvsd);
7576 break;
7577 try_rvsd:
477330fc 7578 case OP_RVSD: po_reg_or_fail (REG_TYPE_VFSD); break;
1b883319
AV
7579 case OP_RVSD_COND:
7580 po_reg_or_goto (REG_TYPE_VFSD, try_cond);
7581 break;
66d1f7cc 7582 case OP_oRNSDMQ:
5aae9ae9
MM
7583 case OP_RNSDMQ:
7584 po_reg_or_goto (REG_TYPE_NSD, try_mq2);
7585 break;
7586 try_mq2:
7587 po_reg_or_fail (REG_TYPE_MQ);
7588 break;
477330fc
RM
7589 case OP_oRNSDQ:
7590 case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ); break;
5ee91343
AV
7591 case OP_RNSDQMQR:
7592 po_reg_or_goto (REG_TYPE_RN, try_mq);
7593 break;
7594 try_mq:
7595 case OP_oRNSDQMQ:
7596 case OP_RNSDQMQ:
7597 po_reg_or_goto (REG_TYPE_MQ, try_nsdq2);
7598 break;
7599 try_nsdq2:
7600 po_reg_or_fail (REG_TYPE_NSDQ);
7601 inst.error = 0;
7602 break;
35d1cfc2
AV
7603 case OP_RMQRR:
7604 po_reg_or_goto (REG_TYPE_RN, try_rmq);
7605 break;
7606 try_rmq:
a302e574
AV
7607 case OP_RMQ:
7608 po_reg_or_fail (REG_TYPE_MQ);
7609 break;
477330fc
RM
7610 /* Neon scalar. Using an element size of 8 means that some invalid
7611 scalars are accepted here, so deal with those in later code. */
57785aa2 7612 case OP_RNSC: po_scalar_or_goto (8, failure, REG_TYPE_VFD); break;
477330fc
RM
7613
7614 case OP_RNDQ_I0:
7615 {
7616 po_reg_or_goto (REG_TYPE_NDQ, try_imm0);
7617 break;
7618 try_imm0:
5b7c81bd 7619 po_imm_or_fail (0, 0, true);
477330fc
RM
7620 }
7621 break;
7622
7623 case OP_RVSD_I0:
7624 po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
7625 break;
7626
1b883319
AV
7627 case OP_RSVDMQ_FI0:
7628 po_reg_or_goto (REG_TYPE_MQ, try_rsvd_fi0);
7629 break;
7630 try_rsvd_fi0:
aacf0b33
KT
7631 case OP_RSVD_FI0:
7632 {
7633 po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
7634 break;
7635 try_ifimm0:
7636 if (parse_ifimm_zero (&str))
7637 inst.operands[i].imm = 0;
7638 else
7639 {
7640 inst.error
7641 = _("only floating point zero is allowed as immediate value");
7642 goto failure;
7643 }
7644 }
7645 break;
7646
477330fc
RM
7647 case OP_RR_RNSC:
7648 {
57785aa2 7649 po_scalar_or_goto (8, try_rr, REG_TYPE_VFD);
477330fc
RM
7650 break;
7651 try_rr:
7652 po_reg_or_fail (REG_TYPE_RN);
7653 }
7654 break;
7655
a8465a06
AV
7656 case OP_RNSDQ_RNSC_MQ_RR:
7657 po_reg_or_goto (REG_TYPE_RN, try_rnsdq_rnsc_mq);
7658 break;
7659 try_rnsdq_rnsc_mq:
886e1c73
AV
7660 case OP_RNSDQ_RNSC_MQ:
7661 po_reg_or_goto (REG_TYPE_MQ, try_rnsdq_rnsc);
7662 break;
7663 try_rnsdq_rnsc:
477330fc
RM
7664 case OP_RNSDQ_RNSC:
7665 {
57785aa2
AV
7666 po_scalar_or_goto (8, try_nsdq, REG_TYPE_VFD);
7667 inst.error = 0;
477330fc
RM
7668 break;
7669 try_nsdq:
7670 po_reg_or_fail (REG_TYPE_NSDQ);
57785aa2 7671 inst.error = 0;
477330fc
RM
7672 }
7673 break;
7674
dec41383
JW
7675 case OP_RNSD_RNSC:
7676 {
57785aa2 7677 po_scalar_or_goto (8, try_s_scalar, REG_TYPE_VFD);
dec41383
JW
7678 break;
7679 try_s_scalar:
57785aa2 7680 po_scalar_or_goto (4, try_nsd, REG_TYPE_VFS);
dec41383
JW
7681 break;
7682 try_nsd:
7683 po_reg_or_fail (REG_TYPE_NSD);
7684 }
7685 break;
7686
42b16635
AV
7687 case OP_RNDQMQ_RNSC_RR:
7688 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc_rr);
7689 break;
7690 try_rndq_rnsc_rr:
7691 case OP_RNDQ_RNSC_RR:
7692 po_reg_or_goto (REG_TYPE_RN, try_rndq_rnsc);
7693 break;
5d281bf0
AV
7694 case OP_RNDQMQ_RNSC:
7695 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc);
7696 break;
7697 try_rndq_rnsc:
477330fc
RM
7698 case OP_RNDQ_RNSC:
7699 {
57785aa2 7700 po_scalar_or_goto (8, try_ndq, REG_TYPE_VFD);
477330fc
RM
7701 break;
7702 try_ndq:
7703 po_reg_or_fail (REG_TYPE_NDQ);
7704 }
7705 break;
7706
7707 case OP_RND_RNSC:
7708 {
57785aa2 7709 po_scalar_or_goto (8, try_vfd, REG_TYPE_VFD);
477330fc
RM
7710 break;
7711 try_vfd:
7712 po_reg_or_fail (REG_TYPE_VFD);
7713 }
7714 break;
7715
7716 case OP_VMOV:
7717 /* WARNING: parse_neon_mov can move the operand counter, i. If we're
7718 not careful then bad things might happen. */
7719 po_misc_or_fail (parse_neon_mov (&str, &i) == FAIL);
7720 break;
7721
f601a00c
AV
7722 case OP_RNDQMQ_Ibig:
7723 po_reg_or_goto (REG_TYPE_MQ, try_rndq_ibig);
7724 break;
7725 try_rndq_ibig:
477330fc
RM
7726 case OP_RNDQ_Ibig:
7727 {
7728 po_reg_or_goto (REG_TYPE_NDQ, try_immbig);
7729 break;
7730 try_immbig:
7731 /* There's a possibility of getting a 64-bit immediate here, so
7732 we need special handling. */
5b7c81bd 7733 if (parse_big_immediate (&str, i, NULL, /*allow_symbol_p=*/false)
8335d6aa 7734 == FAIL)
477330fc
RM
7735 {
7736 inst.error = _("immediate value is out of range");
7737 goto failure;
7738 }
7739 }
7740 break;
7741
5150f0d8
AV
7742 case OP_RNDQMQ_I63b_RR:
7743 po_reg_or_goto (REG_TYPE_MQ, try_rndq_i63b_rr);
7744 break;
7745 try_rndq_i63b_rr:
7746 po_reg_or_goto (REG_TYPE_RN, try_rndq_i63b);
7747 break;
7748 try_rndq_i63b:
477330fc
RM
7749 case OP_RNDQ_I63b:
7750 {
7751 po_reg_or_goto (REG_TYPE_NDQ, try_shimm);
7752 break;
7753 try_shimm:
5b7c81bd 7754 po_imm_or_fail (0, 63, true);
477330fc
RM
7755 }
7756 break;
c19d1205
ZW
7757
7758 case OP_RRnpcb:
7759 po_char_or_fail ('[');
7760 po_reg_or_fail (REG_TYPE_RN);
7761 po_char_or_fail (']');
7762 break;
a737bd4d 7763
55881a11 7764 case OP_RRnpctw:
c19d1205 7765 case OP_RRw:
b6702015 7766 case OP_oRRw:
c19d1205
ZW
7767 po_reg_or_fail (REG_TYPE_RN);
7768 if (skip_past_char (&str, '!') == SUCCESS)
7769 inst.operands[i].writeback = 1;
7770 break;
7771
7772 /* Immediates */
5b7c81bd
AM
7773 case OP_I7: po_imm_or_fail ( 0, 7, false); break;
7774 case OP_I15: po_imm_or_fail ( 0, 15, false); break;
7775 case OP_I16: po_imm_or_fail ( 1, 16, false); break;
7776 case OP_I16z: po_imm_or_fail ( 0, 16, false); break;
7777 case OP_I31: po_imm_or_fail ( 0, 31, false); break;
7778 case OP_I32: po_imm_or_fail ( 1, 32, false); break;
7779 case OP_I32z: po_imm_or_fail ( 0, 32, false); break;
7780 case OP_I48_I64: po_imm1_or_imm2_or_fail (48, 64, false); break;
7781 case OP_I63s: po_imm_or_fail (-64, 63, false); break;
7782 case OP_I63: po_imm_or_fail ( 0, 63, false); break;
7783 case OP_I64: po_imm_or_fail ( 1, 64, false); break;
7784 case OP_I64z: po_imm_or_fail ( 0, 64, false); break;
7785 case OP_I127: po_imm_or_fail ( 0, 127, false); break;
7786 case OP_I255: po_imm_or_fail ( 0, 255, false); break;
7787 case OP_I511: po_imm_or_fail ( 0, 511, false); break;
7788 case OP_I4095: po_imm_or_fail ( 0, 4095, false); break;
7789 case OP_I8191: po_imm_or_fail ( 0, 8191, false); break;
7790 case OP_I4b: po_imm_or_fail ( 1, 4, true); break;
c19d1205 7791 case OP_oI7b:
5b7c81bd
AM
7792 case OP_I7b: po_imm_or_fail ( 0, 7, true); break;
7793 case OP_I15b: po_imm_or_fail ( 0, 15, true); break;
c19d1205 7794 case OP_oI31b:
5b7c81bd
AM
7795 case OP_I31b: po_imm_or_fail ( 0, 31, true); break;
7796 case OP_oI32b: po_imm_or_fail ( 1, 32, true); break;
7797 case OP_oI32z: po_imm_or_fail ( 0, 32, true); break;
7798 case OP_oIffffb: po_imm_or_fail ( 0, 0xffff, true); break;
c19d1205
ZW
7799
7800 /* Immediate variants */
7801 case OP_oI255c:
7802 po_char_or_fail ('{');
5b7c81bd 7803 po_imm_or_fail (0, 255, true);
c19d1205
ZW
7804 po_char_or_fail ('}');
7805 break;
7806
7807 case OP_I31w:
7808 /* The expression parser chokes on a trailing !, so we have
7809 to find it first and zap it. */
7810 {
7811 char *s = str;
7812 while (*s && *s != ',')
7813 s++;
7814 if (s[-1] == '!')
7815 {
7816 s[-1] = '\0';
7817 inst.operands[i].writeback = 1;
7818 }
5b7c81bd 7819 po_imm_or_fail (0, 31, true);
c19d1205
ZW
7820 if (str == s - 1)
7821 str = s;
7822 }
7823 break;
7824
7825 /* Expressions */
7826 case OP_EXPi: EXPi:
e2b0ab59 7827 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7828 GE_OPT_PREFIX));
7829 break;
7830
7831 case OP_EXP:
e2b0ab59 7832 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7833 GE_NO_PREFIX));
7834 break;
7835
7836 case OP_EXPr: EXPr:
e2b0ab59 7837 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205 7838 GE_NO_PREFIX));
e2b0ab59 7839 if (inst.relocs[0].exp.X_op == O_symbol)
a737bd4d 7840 {
c19d1205
ZW
7841 val = parse_reloc (&str);
7842 if (val == -1)
7843 {
7844 inst.error = _("unrecognized relocation suffix");
7845 goto failure;
7846 }
7847 else if (val != BFD_RELOC_UNUSED)
7848 {
7849 inst.operands[i].imm = val;
7850 inst.operands[i].hasreloc = 1;
7851 }
a737bd4d 7852 }
c19d1205 7853 break;
a737bd4d 7854
e2b0ab59
AV
7855 case OP_EXPs:
7856 po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
7857 GE_NO_PREFIX));
7858 if (inst.relocs[i].exp.X_op == O_symbol)
7859 {
7860 inst.operands[i].hasreloc = 1;
7861 }
7862 else if (inst.relocs[i].exp.X_op == O_constant)
7863 {
7864 inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
7865 inst.operands[i].hasreloc = 0;
7866 }
7867 break;
7868
b6895b4f
PB
7869 /* Operand for MOVW or MOVT. */
7870 case OP_HALF:
7871 po_misc_or_fail (parse_half (&str));
7872 break;
7873
e07e6e58 7874 /* Register or expression. */
c19d1205
ZW
7875 case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
7876 case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
a737bd4d 7877
e07e6e58 7878 /* Register or immediate. */
c19d1205 7879 case OP_RRnpc_I0: po_reg_or_goto (REG_TYPE_RN, I0); break;
5b7c81bd 7880 I0: po_imm_or_fail (0, 0, false); break;
a737bd4d 7881
23d00a41 7882 case OP_RRnpcsp_I32: po_reg_or_goto (REG_TYPE_RN, I32); break;
5b7c81bd 7883 I32: po_imm_or_fail (1, 32, false); break;
23d00a41 7884
c19d1205
ZW
7885 case OP_RF_IF: po_reg_or_goto (REG_TYPE_FN, IF); break;
7886 IF:
7887 if (!is_immediate_prefix (*str))
7888 goto bad_args;
7889 str++;
7890 val = parse_fpa_immediate (&str);
7891 if (val == FAIL)
7892 goto failure;
7893 /* FPA immediates are encoded as registers 8-15.
7894 parse_fpa_immediate has already applied the offset. */
7895 inst.operands[i].reg = val;
7896 inst.operands[i].isreg = 1;
7897 break;
09d92015 7898
2d447fca 7899 case OP_RIWR_I32z: po_reg_or_goto (REG_TYPE_MMXWR, I32z); break;
5b7c81bd 7900 I32z: po_imm_or_fail (0, 32, false); break;
2d447fca 7901
e07e6e58 7902 /* Two kinds of register. */
c19d1205
ZW
7903 case OP_RIWR_RIWC:
7904 {
7905 struct reg_entry *rege = arm_reg_parse_multi (&str);
97f87066
JM
7906 if (!rege
7907 || (rege->type != REG_TYPE_MMXWR
7908 && rege->type != REG_TYPE_MMXWC
7909 && rege->type != REG_TYPE_MMXWCG))
c19d1205
ZW
7910 {
7911 inst.error = _("iWMMXt data or control register expected");
7912 goto failure;
7913 }
7914 inst.operands[i].reg = rege->number;
7915 inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
7916 }
7917 break;
09d92015 7918
41adaa5c
JM
7919 case OP_RIWC_RIWG:
7920 {
7921 struct reg_entry *rege = arm_reg_parse_multi (&str);
7922 if (!rege
7923 || (rege->type != REG_TYPE_MMXWC
7924 && rege->type != REG_TYPE_MMXWCG))
7925 {
7926 inst.error = _("iWMMXt control register expected");
7927 goto failure;
7928 }
7929 inst.operands[i].reg = rege->number;
7930 inst.operands[i].isreg = 1;
7931 }
7932 break;
7933
c19d1205
ZW
7934 /* Misc */
7935 case OP_CPSF: val = parse_cps_flags (&str); break;
7936 case OP_ENDI: val = parse_endian_specifier (&str); break;
7937 case OP_oROR: val = parse_ror (&str); break;
1b883319 7938 try_cond:
c19d1205 7939 case OP_COND: val = parse_cond (&str); break;
52e7f43d
RE
7940 case OP_oBARRIER_I15:
7941 po_barrier_or_imm (str); break;
7942 immediate:
5b7c81bd 7943 if (parse_immediate (&str, &val, 0, 15, true) == FAIL)
477330fc 7944 goto failure;
52e7f43d 7945 break;
c19d1205 7946
fa94de6b 7947 case OP_wPSR:
d2cd1205 7948 case OP_rPSR:
90ec0d68
MGD
7949 po_reg_or_goto (REG_TYPE_RNB, try_psr);
7950 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_virt))
7951 {
7952 inst.error = _("Banked registers are not available with this "
7953 "architecture.");
7954 goto failure;
7955 }
7956 break;
d2cd1205
JB
7957 try_psr:
7958 val = parse_psr (&str, op_parse_code == OP_wPSR);
7959 break;
037e8744 7960
32c36c3c
AV
7961 case OP_VLDR:
7962 po_reg_or_goto (REG_TYPE_VFSD, try_sysreg);
7963 break;
7964 try_sysreg:
7965 val = parse_sys_vldr_vstr (&str);
7966 break;
7967
477330fc
RM
7968 case OP_APSR_RR:
7969 po_reg_or_goto (REG_TYPE_RN, try_apsr);
7970 break;
7971 try_apsr:
7972 /* Parse "APSR_nvzc" operand (for FMSTAT-equivalent MRS
7973 instruction). */
7974 if (strncasecmp (str, "APSR_", 5) == 0)
7975 {
7976 unsigned found = 0;
7977 str += 5;
7978 while (found < 15)
7979 switch (*str++)
7980 {
7981 case 'c': found = (found & 1) ? 16 : found | 1; break;
7982 case 'n': found = (found & 2) ? 16 : found | 2; break;
7983 case 'z': found = (found & 4) ? 16 : found | 4; break;
7984 case 'v': found = (found & 8) ? 16 : found | 8; break;
7985 default: found = 16;
7986 }
7987 if (found != 15)
7988 goto failure;
7989 inst.operands[i].isvec = 1;
f7c21dc7
NC
7990 /* APSR_nzcv is encoded in instructions as if it were the REG_PC. */
7991 inst.operands[i].reg = REG_PC;
477330fc
RM
7992 }
7993 else
7994 goto failure;
7995 break;
037e8744 7996
92e90b6e
PB
7997 case OP_TB:
7998 po_misc_or_fail (parse_tb (&str));
7999 break;
8000
e07e6e58 8001 /* Register lists. */
c19d1205 8002 case OP_REGLST:
4b5a202f 8003 val = parse_reg_list (&str, REGLIST_RN);
c19d1205
ZW
8004 if (*str == '^')
8005 {
5e0d7f77 8006 inst.operands[i].writeback = 1;
c19d1205
ZW
8007 str++;
8008 }
8009 break;
09d92015 8010
4b5a202f
AV
8011 case OP_CLRMLST:
8012 val = parse_reg_list (&str, REGLIST_CLRM);
8013 break;
8014
c19d1205 8015 case OP_VRSLST:
efd6b359
AV
8016 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_S,
8017 &partial_match);
c19d1205 8018 break;
09d92015 8019
c19d1205 8020 case OP_VRDLST:
efd6b359
AV
8021 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_D,
8022 &partial_match);
c19d1205 8023 break;
a737bd4d 8024
477330fc
RM
8025 case OP_VRSDLST:
8026 /* Allow Q registers too. */
8027 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 8028 REGLIST_NEON_D, &partial_match);
477330fc
RM
8029 if (val == FAIL)
8030 {
8031 inst.error = NULL;
8032 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359
AV
8033 REGLIST_VFP_S, &partial_match);
8034 inst.operands[i].issingle = 1;
8035 }
8036 break;
8037
8038 case OP_VRSDVLST:
8039 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
8040 REGLIST_VFP_D_VPR, &partial_match);
8041 if (val == FAIL && !partial_match)
8042 {
8043 inst.error = NULL;
8044 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
8045 REGLIST_VFP_S_VPR, &partial_match);
477330fc
RM
8046 inst.operands[i].issingle = 1;
8047 }
8048 break;
8049
8050 case OP_NRDLST:
8051 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 8052 REGLIST_NEON_D, &partial_match);
477330fc 8053 break;
5287ad62 8054
35c228db
AV
8055 case OP_MSTRLST4:
8056 case OP_MSTRLST2:
8057 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
8058 1, &inst.operands[i].vectype);
8059 if (val != (((op_parse_code == OP_MSTRLST2) ? 3 : 7) << 5 | 0xe))
8060 goto failure;
8061 break;
5287ad62 8062 case OP_NSTRLST:
477330fc 8063 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
35c228db 8064 0, &inst.operands[i].vectype);
477330fc 8065 break;
5287ad62 8066
c19d1205 8067 /* Addressing modes */
35c228db
AV
8068 case OP_ADDRMVE:
8069 po_misc_or_fail (parse_address_group_reloc (&str, i, GROUP_MVE));
8070 break;
8071
c19d1205
ZW
8072 case OP_ADDR:
8073 po_misc_or_fail (parse_address (&str, i));
8074 break;
09d92015 8075
4962c51a
MS
8076 case OP_ADDRGLDR:
8077 po_misc_or_fail_no_backtrack (
477330fc 8078 parse_address_group_reloc (&str, i, GROUP_LDR));
4962c51a
MS
8079 break;
8080
8081 case OP_ADDRGLDRS:
8082 po_misc_or_fail_no_backtrack (
477330fc 8083 parse_address_group_reloc (&str, i, GROUP_LDRS));
4962c51a
MS
8084 break;
8085
8086 case OP_ADDRGLDC:
8087 po_misc_or_fail_no_backtrack (
477330fc 8088 parse_address_group_reloc (&str, i, GROUP_LDC));
4962c51a
MS
8089 break;
8090
c19d1205
ZW
8091 case OP_SH:
8092 po_misc_or_fail (parse_shifter_operand (&str, i));
8093 break;
09d92015 8094
4962c51a
MS
8095 case OP_SHG:
8096 po_misc_or_fail_no_backtrack (
477330fc 8097 parse_shifter_operand_group_reloc (&str, i));
4962c51a
MS
8098 break;
8099
c19d1205
ZW
8100 case OP_oSHll:
8101 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_IMMEDIATE));
8102 break;
09d92015 8103
c19d1205
ZW
8104 case OP_oSHar:
8105 po_misc_or_fail (parse_shift (&str, i, SHIFT_ASR_IMMEDIATE));
8106 break;
09d92015 8107
c19d1205
ZW
8108 case OP_oSHllar:
8109 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
8110 break;
09d92015 8111
1b883319
AV
8112 case OP_RMQRZ:
8113 case OP_oRMQRZ:
8114 po_reg_or_goto (REG_TYPE_MQ, try_rr_zr);
8115 break;
e39c1607
SD
8116
8117 case OP_RR_ZR:
1b883319
AV
8118 try_rr_zr:
8119 po_reg_or_goto (REG_TYPE_RN, ZR);
8120 break;
8121 ZR:
8122 po_reg_or_fail (REG_TYPE_ZR);
8123 break;
8124
c19d1205 8125 default:
5be8be5d 8126 as_fatal (_("unhandled operand code %d"), op_parse_code);
c19d1205 8127 }
09d92015 8128
c19d1205
ZW
8129 /* Various value-based sanity checks and shared operations. We
8130 do not signal immediate failures for the register constraints;
8131 this allows a syntax error to take precedence. */
5be8be5d 8132 switch (op_parse_code)
c19d1205
ZW
8133 {
8134 case OP_oRRnpc:
8135 case OP_RRnpc:
8136 case OP_RRnpcb:
8137 case OP_RRw:
b6702015 8138 case OP_oRRw:
c19d1205
ZW
8139 case OP_RRnpc_I0:
8140 if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
8141 inst.error = BAD_PC;
8142 break;
09d92015 8143
5be8be5d
DG
8144 case OP_oRRnpcsp:
8145 case OP_RRnpcsp:
23d00a41 8146 case OP_RRnpcsp_I32:
5be8be5d
DG
8147 if (inst.operands[i].isreg)
8148 {
8149 if (inst.operands[i].reg == REG_PC)
8150 inst.error = BAD_PC;
5c8ed6a4
JW
8151 else if (inst.operands[i].reg == REG_SP
8152 /* The restriction on Rd/Rt/Rt2 on Thumb mode has been
8153 relaxed since ARMv8-A. */
8154 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
8155 {
8156 gas_assert (thumb);
8157 inst.error = BAD_SP;
8158 }
5be8be5d
DG
8159 }
8160 break;
8161
55881a11 8162 case OP_RRnpctw:
fa94de6b
RM
8163 if (inst.operands[i].isreg
8164 && inst.operands[i].reg == REG_PC
55881a11
MGD
8165 && (inst.operands[i].writeback || thumb))
8166 inst.error = BAD_PC;
8167 break;
8168
1b883319 8169 case OP_RVSD_COND:
32c36c3c
AV
8170 case OP_VLDR:
8171 if (inst.operands[i].isreg)
8172 break;
8173 /* fall through. */
1b883319 8174
c19d1205
ZW
8175 case OP_CPSF:
8176 case OP_ENDI:
8177 case OP_oROR:
d2cd1205
JB
8178 case OP_wPSR:
8179 case OP_rPSR:
c19d1205 8180 case OP_COND:
52e7f43d 8181 case OP_oBARRIER_I15:
c19d1205 8182 case OP_REGLST:
4b5a202f 8183 case OP_CLRMLST:
c19d1205
ZW
8184 case OP_VRSLST:
8185 case OP_VRDLST:
477330fc 8186 case OP_VRSDLST:
efd6b359 8187 case OP_VRSDVLST:
477330fc
RM
8188 case OP_NRDLST:
8189 case OP_NSTRLST:
35c228db
AV
8190 case OP_MSTRLST2:
8191 case OP_MSTRLST4:
c19d1205
ZW
8192 if (val == FAIL)
8193 goto failure;
8194 inst.operands[i].imm = val;
8195 break;
a737bd4d 8196
60f993ce
AV
8197 case OP_LR:
8198 case OP_oLR:
8199 if (inst.operands[i].reg != REG_LR)
8200 inst.error = _("operand must be LR register");
8201 break;
8202
f1e1d7f3
AC
8203 case OP_SP:
8204 if (inst.operands[i].reg != REG_SP)
8205 inst.error = _("operand must be SP register");
8206 break;
8207
8208 case OP_R12:
8209 if (inst.operands[i].reg != REG_R12)
8210 inst.error = _("operand must be r12");
8211 break;
8212
1b883319
AV
8213 case OP_RMQRZ:
8214 case OP_oRMQRZ:
e39c1607 8215 case OP_RR_ZR:
1b883319
AV
8216 if (!inst.operands[i].iszr && inst.operands[i].reg == REG_PC)
8217 inst.error = BAD_PC;
8218 break;
8219
a302e574
AV
8220 case OP_RRe:
8221 if (inst.operands[i].isreg
8222 && (inst.operands[i].reg & 0x00000001) != 0)
8223 inst.error = BAD_ODD;
8224 break;
8225
8226 case OP_RRo:
8227 if (inst.operands[i].isreg)
8228 {
8229 if ((inst.operands[i].reg & 0x00000001) != 1)
8230 inst.error = BAD_EVEN;
8231 else if (inst.operands[i].reg == REG_SP)
8232 as_tsktsk (MVE_BAD_SP);
8233 else if (inst.operands[i].reg == REG_PC)
8234 inst.error = BAD_PC;
8235 }
8236 break;
8237
c19d1205
ZW
8238 default:
8239 break;
8240 }
09d92015 8241
c19d1205
ZW
8242 /* If we get here, this operand was successfully parsed. */
8243 inst.operands[i].present = 1;
8244 continue;
09d92015 8245
c19d1205 8246 bad_args:
09d92015 8247 inst.error = BAD_ARGS;
c19d1205
ZW
8248
8249 failure:
8250 if (!backtrack_pos)
d252fdde
PB
8251 {
8252 /* The parse routine should already have set inst.error, but set a
5f4273c7 8253 default here just in case. */
d252fdde 8254 if (!inst.error)
5ee91343 8255 inst.error = BAD_SYNTAX;
d252fdde
PB
8256 return FAIL;
8257 }
c19d1205
ZW
8258
8259 /* Do not backtrack over a trailing optional argument that
8260 absorbed some text. We will only fail again, with the
8261 'garbage following instruction' error message, which is
8262 probably less helpful than the current one. */
8263 if (backtrack_index == i && backtrack_pos != str
8264 && upat[i+1] == OP_stop)
d252fdde
PB
8265 {
8266 if (!inst.error)
5ee91343 8267 inst.error = BAD_SYNTAX;
d252fdde
PB
8268 return FAIL;
8269 }
c19d1205
ZW
8270
8271 /* Try again, skipping the optional argument at backtrack_pos. */
8272 str = backtrack_pos;
8273 inst.error = backtrack_error;
8274 inst.operands[backtrack_index].present = 0;
8275 i = backtrack_index;
8276 backtrack_pos = 0;
09d92015 8277 }
09d92015 8278
c19d1205
ZW
8279 /* Check that we have parsed all the arguments. */
8280 if (*str != '\0' && !inst.error)
8281 inst.error = _("garbage following instruction");
09d92015 8282
c19d1205 8283 return inst.error ? FAIL : SUCCESS;
09d92015
MM
8284}
8285
c19d1205
ZW
8286#undef po_char_or_fail
8287#undef po_reg_or_fail
8288#undef po_reg_or_goto
8289#undef po_imm_or_fail
5287ad62 8290#undef po_scalar_or_fail
52e7f43d 8291#undef po_barrier_or_imm
e07e6e58 8292
c19d1205 8293/* Shorthand macro for instruction encoding functions issuing errors. */
e07e6e58
NC
8294#define constraint(expr, err) \
8295 do \
c19d1205 8296 { \
e07e6e58
NC
8297 if (expr) \
8298 { \
8299 inst.error = err; \
8300 return; \
8301 } \
c19d1205 8302 } \
e07e6e58 8303 while (0)
c19d1205 8304
fdfde340
JM
8305/* Reject "bad registers" for Thumb-2 instructions. Many Thumb-2
8306 instructions are unpredictable if these registers are used. This
5c8ed6a4
JW
8307 is the BadReg predicate in ARM's Thumb-2 documentation.
8308
8309 Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few
8310 places, while the restriction on REG_SP was relaxed since ARMv8-A. */
8311#define reject_bad_reg(reg) \
8312 do \
8313 if (reg == REG_PC) \
8314 { \
8315 inst.error = BAD_PC; \
8316 return; \
8317 } \
8318 else if (reg == REG_SP \
8319 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) \
8320 { \
8321 inst.error = BAD_SP; \
8322 return; \
8323 } \
fdfde340
JM
8324 while (0)
8325
94206790
MM
8326/* If REG is R13 (the stack pointer), warn that its use is
8327 deprecated. */
8328#define warn_deprecated_sp(reg) \
8329 do \
8330 if (warn_on_deprecated && reg == REG_SP) \
5c3696f8 8331 as_tsktsk (_("use of r13 is deprecated")); \
94206790
MM
8332 while (0)
8333
c19d1205
ZW
8334/* Functions for operand encoding. ARM, then Thumb. */
8335
d840c081 8336#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31))
c19d1205 8337
9db2f6b4
RL
8338/* If the current inst is scalar ARMv8.2 fp16 instruction, do special encoding.
8339
8340 The only binary encoding difference is the Coprocessor number. Coprocessor
8341 9 is used for half-precision calculations or conversions. The format of the
2b0f3761 8342 instruction is the same as the equivalent Coprocessor 10 instruction that
9db2f6b4
RL
8343 exists for Single-Precision operation. */
8344
8345static void
8346do_scalar_fp16_v82_encode (void)
8347{
5ee91343 8348 if (inst.cond < COND_ALWAYS)
55e0daa3 8349 as_warn (_("scalar fp16 instruction cannot be conditional,"
9db2f6b4
RL
8350 " the behaviour is UNPREDICTABLE"));
8351 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
8352 _(BAD_FP16));
8353
8354 inst.instruction = (inst.instruction & 0xfffff0ff) | 0x900;
8355 mark_feature_used (&arm_ext_fp16);
8356}
8357
c19d1205
ZW
8358/* If VAL can be encoded in the immediate field of an ARM instruction,
8359 return the encoded form. Otherwise, return FAIL. */
8360
8361static unsigned int
8362encode_arm_immediate (unsigned int val)
09d92015 8363{
c19d1205
ZW
8364 unsigned int a, i;
8365
4f1d6205
L
8366 if (val <= 0xff)
8367 return val;
8368
8369 for (i = 2; i < 32; i += 2)
c19d1205
ZW
8370 if ((a = rotate_left (val, i)) <= 0xff)
8371 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
8372
8373 return FAIL;
09d92015
MM
8374}
8375
c19d1205
ZW
8376/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
8377 return the encoded form. Otherwise, return FAIL. */
8378static unsigned int
8379encode_thumb32_immediate (unsigned int val)
09d92015 8380{
c19d1205 8381 unsigned int a, i;
09d92015 8382
9c3c69f2 8383 if (val <= 0xff)
c19d1205 8384 return val;
a737bd4d 8385
9c3c69f2 8386 for (i = 1; i <= 24; i++)
09d92015 8387 {
9c3c69f2 8388 a = val >> i;
7af67752 8389 if ((val & ~(0xffU << i)) == 0)
9c3c69f2 8390 return ((val >> i) & 0x7f) | ((32 - i) << 7);
09d92015 8391 }
a737bd4d 8392
c19d1205
ZW
8393 a = val & 0xff;
8394 if (val == ((a << 16) | a))
8395 return 0x100 | a;
8396 if (val == ((a << 24) | (a << 16) | (a << 8) | a))
8397 return 0x300 | a;
09d92015 8398
c19d1205
ZW
8399 a = val & 0xff00;
8400 if (val == ((a << 16) | a))
8401 return 0x200 | (a >> 8);
a737bd4d 8402
c19d1205 8403 return FAIL;
09d92015 8404}
5287ad62 8405/* Encode a VFP SP or DP register number into inst.instruction. */
09d92015
MM
8406
8407static void
5287ad62
JB
8408encode_arm_vfp_reg (int reg, enum vfp_reg_pos pos)
8409{
8410 if ((pos == VFP_REG_Dd || pos == VFP_REG_Dn || pos == VFP_REG_Dm)
8411 && reg > 15)
8412 {
b1cc4aeb 8413 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
8414 {
8415 if (thumb_mode)
8416 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
8417 fpu_vfp_ext_d32);
8418 else
8419 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
8420 fpu_vfp_ext_d32);
8421 }
5287ad62 8422 else
477330fc
RM
8423 {
8424 first_error (_("D register out of range for selected VFP version"));
8425 return;
8426 }
5287ad62
JB
8427 }
8428
c19d1205 8429 switch (pos)
09d92015 8430 {
c19d1205
ZW
8431 case VFP_REG_Sd:
8432 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8433 break;
8434
8435 case VFP_REG_Sn:
8436 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8437 break;
8438
8439 case VFP_REG_Sm:
8440 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8441 break;
8442
5287ad62
JB
8443 case VFP_REG_Dd:
8444 inst.instruction |= ((reg & 15) << 12) | ((reg >> 4) << 22);
8445 break;
5f4273c7 8446
5287ad62
JB
8447 case VFP_REG_Dn:
8448 inst.instruction |= ((reg & 15) << 16) | ((reg >> 4) << 7);
8449 break;
5f4273c7 8450
5287ad62
JB
8451 case VFP_REG_Dm:
8452 inst.instruction |= (reg & 15) | ((reg >> 4) << 5);
8453 break;
8454
c19d1205
ZW
8455 default:
8456 abort ();
09d92015 8457 }
09d92015
MM
8458}
8459
c19d1205 8460/* Encode a <shift> in an ARM-format instruction. The immediate,
55cf6793 8461 if any, is handled by md_apply_fix. */
09d92015 8462static void
c19d1205 8463encode_arm_shift (int i)
09d92015 8464{
008a97ef
RL
8465 /* register-shifted register. */
8466 if (inst.operands[i].immisreg)
8467 {
bf355b69
MR
8468 int op_index;
8469 for (op_index = 0; op_index <= i; ++op_index)
008a97ef 8470 {
5689c942
RL
8471 /* Check the operand only when it's presented. In pre-UAL syntax,
8472 if the destination register is the same as the first operand, two
8473 register form of the instruction can be used. */
bf355b69
MR
8474 if (inst.operands[op_index].present && inst.operands[op_index].isreg
8475 && inst.operands[op_index].reg == REG_PC)
008a97ef
RL
8476 as_warn (UNPRED_REG ("r15"));
8477 }
8478
8479 if (inst.operands[i].imm == REG_PC)
8480 as_warn (UNPRED_REG ("r15"));
8481 }
8482
c19d1205
ZW
8483 if (inst.operands[i].shift_kind == SHIFT_RRX)
8484 inst.instruction |= SHIFT_ROR << 5;
8485 else
09d92015 8486 {
c19d1205
ZW
8487 inst.instruction |= inst.operands[i].shift_kind << 5;
8488 if (inst.operands[i].immisreg)
8489 {
8490 inst.instruction |= SHIFT_BY_REG;
8491 inst.instruction |= inst.operands[i].imm << 8;
8492 }
8493 else
e2b0ab59 8494 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
09d92015 8495 }
c19d1205 8496}
09d92015 8497
c19d1205
ZW
8498static void
8499encode_arm_shifter_operand (int i)
8500{
8501 if (inst.operands[i].isreg)
09d92015 8502 {
c19d1205
ZW
8503 inst.instruction |= inst.operands[i].reg;
8504 encode_arm_shift (i);
09d92015 8505 }
c19d1205 8506 else
a415b1cd
JB
8507 {
8508 inst.instruction |= INST_IMMEDIATE;
e2b0ab59 8509 if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
a415b1cd
JB
8510 inst.instruction |= inst.operands[i].imm;
8511 }
09d92015
MM
8512}
8513
c19d1205 8514/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
09d92015 8515static void
5b7c81bd 8516encode_arm_addr_mode_common (int i, bool is_t)
09d92015 8517{
2b2f5df9
NC
8518 /* PR 14260:
8519 Generate an error if the operand is not a register. */
8520 constraint (!inst.operands[i].isreg,
8521 _("Instruction does not support =N addresses"));
8522
c19d1205 8523 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 8524
c19d1205 8525 if (inst.operands[i].preind)
09d92015 8526 {
c19d1205
ZW
8527 if (is_t)
8528 {
8529 inst.error = _("instruction does not accept preindexed addressing");
8530 return;
8531 }
8532 inst.instruction |= PRE_INDEX;
8533 if (inst.operands[i].writeback)
8534 inst.instruction |= WRITE_BACK;
09d92015 8535
c19d1205
ZW
8536 }
8537 else if (inst.operands[i].postind)
8538 {
9c2799c2 8539 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
8540 if (is_t)
8541 inst.instruction |= WRITE_BACK;
8542 }
8543 else /* unindexed - only for coprocessor */
09d92015 8544 {
c19d1205 8545 inst.error = _("instruction does not accept unindexed addressing");
09d92015
MM
8546 return;
8547 }
8548
c19d1205
ZW
8549 if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
8550 && (((inst.instruction & 0x000f0000) >> 16)
8551 == ((inst.instruction & 0x0000f000) >> 12)))
8552 as_warn ((inst.instruction & LOAD_BIT)
8553 ? _("destination register same as write-back base")
8554 : _("source register same as write-back base"));
09d92015
MM
8555}
8556
c19d1205
ZW
8557/* inst.operands[i] was set up by parse_address. Encode it into an
8558 ARM-format mode 2 load or store instruction. If is_t is true,
8559 reject forms that cannot be used with a T instruction (i.e. not
8560 post-indexed). */
a737bd4d 8561static void
5b7c81bd 8562encode_arm_addr_mode_2 (int i, bool is_t)
09d92015 8563{
5b7c81bd 8564 const bool is_pc = (inst.operands[i].reg == REG_PC);
5be8be5d 8565
c19d1205 8566 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8567
c19d1205 8568 if (inst.operands[i].immisreg)
09d92015 8569 {
5be8be5d
DG
8570 constraint ((inst.operands[i].imm == REG_PC
8571 || (is_pc && inst.operands[i].writeback)),
8572 BAD_PC_ADDRESSING);
c19d1205
ZW
8573 inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
8574 inst.instruction |= inst.operands[i].imm;
8575 if (!inst.operands[i].negative)
8576 inst.instruction |= INDEX_UP;
8577 if (inst.operands[i].shifted)
8578 {
8579 if (inst.operands[i].shift_kind == SHIFT_RRX)
8580 inst.instruction |= SHIFT_ROR << 5;
8581 else
8582 {
8583 inst.instruction |= inst.operands[i].shift_kind << 5;
e2b0ab59 8584 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
c19d1205
ZW
8585 }
8586 }
09d92015 8587 }
e2b0ab59 8588 else /* immediate offset in inst.relocs[0] */
09d92015 8589 {
e2b0ab59 8590 if (is_pc && !inst.relocs[0].pc_rel)
5be8be5d 8591 {
5b7c81bd 8592 const bool is_load = ((inst.instruction & LOAD_BIT) != 0);
23a10334
JZ
8593
8594 /* If is_t is TRUE, it's called from do_ldstt. ldrt/strt
8595 cannot use PC in addressing.
8596 PC cannot be used in writeback addressing, either. */
8597 constraint ((is_t || inst.operands[i].writeback),
5be8be5d 8598 BAD_PC_ADDRESSING);
23a10334 8599
dc5ec521 8600 /* Use of PC in str is deprecated for ARMv7. */
23a10334
JZ
8601 if (warn_on_deprecated
8602 && !is_load
8603 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
5c3696f8 8604 as_tsktsk (_("use of PC in this instruction is deprecated"));
5be8be5d
DG
8605 }
8606
e2b0ab59 8607 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8608 {
8609 /* Prefer + for zero encoded value. */
8610 if (!inst.operands[i].negative)
8611 inst.instruction |= INDEX_UP;
e2b0ab59 8612 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
26d97720 8613 }
09d92015 8614 }
09d92015
MM
8615}
8616
c19d1205
ZW
8617/* inst.operands[i] was set up by parse_address. Encode it into an
8618 ARM-format mode 3 load or store instruction. Reject forms that
8619 cannot be used with such instructions. If is_t is true, reject
8620 forms that cannot be used with a T instruction (i.e. not
8621 post-indexed). */
8622static void
5b7c81bd 8623encode_arm_addr_mode_3 (int i, bool is_t)
09d92015 8624{
c19d1205 8625 if (inst.operands[i].immisreg && inst.operands[i].shifted)
09d92015 8626 {
c19d1205
ZW
8627 inst.error = _("instruction does not accept scaled register index");
8628 return;
09d92015 8629 }
a737bd4d 8630
c19d1205 8631 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8632
c19d1205
ZW
8633 if (inst.operands[i].immisreg)
8634 {
5be8be5d 8635 constraint ((inst.operands[i].imm == REG_PC
eb9f3f00 8636 || (is_t && inst.operands[i].reg == REG_PC)),
5be8be5d 8637 BAD_PC_ADDRESSING);
eb9f3f00
JB
8638 constraint (inst.operands[i].reg == REG_PC && inst.operands[i].writeback,
8639 BAD_PC_WRITEBACK);
c19d1205
ZW
8640 inst.instruction |= inst.operands[i].imm;
8641 if (!inst.operands[i].negative)
8642 inst.instruction |= INDEX_UP;
8643 }
e2b0ab59 8644 else /* immediate offset in inst.relocs[0] */
c19d1205 8645 {
e2b0ab59 8646 constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
5be8be5d
DG
8647 && inst.operands[i].writeback),
8648 BAD_PC_WRITEBACK);
c19d1205 8649 inst.instruction |= HWOFFSET_IMM;
e2b0ab59 8650 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8651 {
8652 /* Prefer + for zero encoded value. */
8653 if (!inst.operands[i].negative)
8654 inst.instruction |= INDEX_UP;
8655
e2b0ab59 8656 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
26d97720 8657 }
c19d1205 8658 }
a737bd4d
NC
8659}
8660
8335d6aa
JW
8661/* Write immediate bits [7:0] to the following locations:
8662
8663 |28/24|23 19|18 16|15 4|3 0|
8664 | 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|
8665
8666 This function is used by VMOV/VMVN/VORR/VBIC. */
8667
8668static void
8669neon_write_immbits (unsigned immbits)
8670{
8671 inst.instruction |= immbits & 0xf;
8672 inst.instruction |= ((immbits >> 4) & 0x7) << 16;
8673 inst.instruction |= ((immbits >> 7) & 0x1) << (thumb_mode ? 28 : 24);
8674}
8675
8676/* Invert low-order SIZE bits of XHI:XLO. */
8677
8678static void
8679neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
8680{
8681 unsigned immlo = xlo ? *xlo : 0;
8682 unsigned immhi = xhi ? *xhi : 0;
8683
8684 switch (size)
8685 {
8686 case 8:
8687 immlo = (~immlo) & 0xff;
8688 break;
8689
8690 case 16:
8691 immlo = (~immlo) & 0xffff;
8692 break;
8693
8694 case 64:
8695 immhi = (~immhi) & 0xffffffff;
8696 /* fall through. */
8697
8698 case 32:
8699 immlo = (~immlo) & 0xffffffff;
8700 break;
8701
8702 default:
8703 abort ();
8704 }
8705
8706 if (xlo)
8707 *xlo = immlo;
8708
8709 if (xhi)
8710 *xhi = immhi;
8711}
8712
8713/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
8714 A, B, C, D. */
09d92015 8715
c19d1205 8716static int
8335d6aa 8717neon_bits_same_in_bytes (unsigned imm)
09d92015 8718{
8335d6aa
JW
8719 return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
8720 && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
8721 && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
8722 && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
8723}
a737bd4d 8724
8335d6aa 8725/* For immediate of above form, return 0bABCD. */
09d92015 8726
8335d6aa
JW
8727static unsigned
8728neon_squash_bits (unsigned imm)
8729{
8730 return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
8731 | ((imm & 0x01000000) >> 21);
8732}
8733
8734/* Compress quarter-float representation to 0b...000 abcdefgh. */
8735
8736static unsigned
8737neon_qfloat_bits (unsigned imm)
8738{
8739 return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
8740}
8741
8742/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
8743 the instruction. *OP is passed as the initial value of the op field, and
8744 may be set to a different value depending on the constant (i.e.
8745 "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
8746 MVN). If the immediate looks like a repeated pattern then also
8747 try smaller element sizes. */
8748
8749static int
8750neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
8751 unsigned *immbits, int *op, int size,
8752 enum neon_el_type type)
8753{
8754 /* Only permit float immediates (including 0.0/-0.0) if the operand type is
8755 float. */
8756 if (type == NT_float && !float_p)
8757 return FAIL;
8758
8759 if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
09d92015 8760 {
8335d6aa
JW
8761 if (size != 32 || *op == 1)
8762 return FAIL;
8763 *immbits = neon_qfloat_bits (immlo);
8764 return 0xf;
8765 }
8766
8767 if (size == 64)
8768 {
8769 if (neon_bits_same_in_bytes (immhi)
8770 && neon_bits_same_in_bytes (immlo))
c19d1205 8771 {
8335d6aa
JW
8772 if (*op == 1)
8773 return FAIL;
8774 *immbits = (neon_squash_bits (immhi) << 4)
8775 | neon_squash_bits (immlo);
8776 *op = 1;
8777 return 0xe;
c19d1205 8778 }
a737bd4d 8779
8335d6aa
JW
8780 if (immhi != immlo)
8781 return FAIL;
8782 }
a737bd4d 8783
8335d6aa 8784 if (size >= 32)
09d92015 8785 {
8335d6aa 8786 if (immlo == (immlo & 0x000000ff))
c19d1205 8787 {
8335d6aa
JW
8788 *immbits = immlo;
8789 return 0x0;
c19d1205 8790 }
8335d6aa 8791 else if (immlo == (immlo & 0x0000ff00))
c19d1205 8792 {
8335d6aa
JW
8793 *immbits = immlo >> 8;
8794 return 0x2;
c19d1205 8795 }
8335d6aa
JW
8796 else if (immlo == (immlo & 0x00ff0000))
8797 {
8798 *immbits = immlo >> 16;
8799 return 0x4;
8800 }
8801 else if (immlo == (immlo & 0xff000000))
8802 {
8803 *immbits = immlo >> 24;
8804 return 0x6;
8805 }
8806 else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
8807 {
8808 *immbits = (immlo >> 8) & 0xff;
8809 return 0xc;
8810 }
8811 else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
8812 {
8813 *immbits = (immlo >> 16) & 0xff;
8814 return 0xd;
8815 }
8816
8817 if ((immlo & 0xffff) != (immlo >> 16))
8818 return FAIL;
8819 immlo &= 0xffff;
09d92015 8820 }
a737bd4d 8821
8335d6aa 8822 if (size >= 16)
4962c51a 8823 {
8335d6aa
JW
8824 if (immlo == (immlo & 0x000000ff))
8825 {
8826 *immbits = immlo;
8827 return 0x8;
8828 }
8829 else if (immlo == (immlo & 0x0000ff00))
8830 {
8831 *immbits = immlo >> 8;
8832 return 0xa;
8833 }
8834
8835 if ((immlo & 0xff) != (immlo >> 8))
8836 return FAIL;
8837 immlo &= 0xff;
4962c51a
MS
8838 }
8839
8335d6aa
JW
8840 if (immlo == (immlo & 0x000000ff))
8841 {
8842 /* Don't allow MVN with 8-bit immediate. */
8843 if (*op == 1)
8844 return FAIL;
8845 *immbits = immlo;
8846 return 0xe;
8847 }
26d97720 8848
8335d6aa 8849 return FAIL;
c19d1205 8850}
a737bd4d 8851
ba592044
AM
8852/* Returns TRUE if double precision value V may be cast
8853 to single precision without loss of accuracy. */
8854
5b7c81bd 8855static bool
0e3c1eeb 8856is_double_a_single (uint64_t v)
ba592044 8857{
7e30b1eb 8858 int exp = (v >> 52) & 0x7FF;
0e3c1eeb 8859 uint64_t mantissa = v & 0xFFFFFFFFFFFFFULL;
ba592044 8860
7e30b1eb
AM
8861 return ((exp == 0 || exp == 0x7FF
8862 || (exp >= 1023 - 126 && exp <= 1023 + 127))
8863 && (mantissa & 0x1FFFFFFFL) == 0);
ba592044
AM
8864}
8865
3739860c 8866/* Returns a double precision value casted to single precision
ba592044
AM
8867 (ignoring the least significant bits in exponent and mantissa). */
8868
8869static int
0e3c1eeb 8870double_to_single (uint64_t v)
ba592044 8871{
7af67752
AM
8872 unsigned int sign = (v >> 63) & 1;
8873 int exp = (v >> 52) & 0x7FF;
0e3c1eeb 8874 uint64_t mantissa = v & 0xFFFFFFFFFFFFFULL;
ba592044
AM
8875
8876 if (exp == 0x7FF)
8877 exp = 0xFF;
8878 else
8879 {
8880 exp = exp - 1023 + 127;
8881 if (exp >= 0xFF)
8882 {
8883 /* Infinity. */
8884 exp = 0x7F;
8885 mantissa = 0;
8886 }
8887 else if (exp < 0)
8888 {
8889 /* No denormalized numbers. */
8890 exp = 0;
8891 mantissa = 0;
8892 }
8893 }
8894 mantissa >>= 29;
8895 return (sign << 31) | (exp << 23) | mantissa;
8896}
8897
8335d6aa
JW
8898enum lit_type
8899{
8900 CONST_THUMB,
8901 CONST_ARM,
8902 CONST_VEC
8903};
8904
ba592044
AM
8905static void do_vfp_nsyn_opcode (const char *);
8906
e2b0ab59 8907/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
c19d1205
ZW
8908 Determine whether it can be performed with a move instruction; if
8909 it can, convert inst.instruction to that move instruction and
5b7c81bd 8910 return true; if it can't, convert inst.instruction to a literal-pool
c921be7d
NC
8911 load and return FALSE. If this is not a valid thing to do in the
8912 current context, set inst.error and return TRUE.
a737bd4d 8913
c19d1205
ZW
8914 inst.operands[i] describes the destination register. */
8915
5b7c81bd
AM
8916static bool
8917move_or_literal_pool (int i, enum lit_type t, bool mode_3)
c19d1205 8918{
53365c0d 8919 unsigned long tbit;
5b7c81bd
AM
8920 bool thumb_p = (t == CONST_THUMB);
8921 bool arm_p = (t == CONST_ARM);
53365c0d
PB
8922
8923 if (thumb_p)
8924 tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
8925 else
8926 tbit = LOAD_BIT;
8927
8928 if ((inst.instruction & tbit) == 0)
09d92015 8929 {
c19d1205 8930 inst.error = _("invalid pseudo operation");
5b7c81bd 8931 return true;
09d92015 8932 }
ba592044 8933
e2b0ab59
AV
8934 if (inst.relocs[0].exp.X_op != O_constant
8935 && inst.relocs[0].exp.X_op != O_symbol
8936 && inst.relocs[0].exp.X_op != O_big)
09d92015
MM
8937 {
8938 inst.error = _("constant expression expected");
5b7c81bd 8939 return true;
09d92015 8940 }
ba592044 8941
e2b0ab59
AV
8942 if (inst.relocs[0].exp.X_op == O_constant
8943 || inst.relocs[0].exp.X_op == O_big)
8335d6aa 8944 {
0e3c1eeb 8945 uint64_t v;
e2b0ab59 8946 if (inst.relocs[0].exp.X_op == O_big)
8335d6aa 8947 {
ba592044
AM
8948 LITTLENUM_TYPE w[X_PRECISION];
8949 LITTLENUM_TYPE * l;
8950
e2b0ab59 8951 if (inst.relocs[0].exp.X_add_number == -1)
8335d6aa 8952 {
ba592044
AM
8953 gen_to_words (w, X_PRECISION, E_PRECISION);
8954 l = w;
8955 /* FIXME: Should we check words w[2..5] ? */
8335d6aa 8956 }
ba592044
AM
8957 else
8958 l = generic_bignum;
3739860c 8959
7e30b1eb
AM
8960 v = l[3] & LITTLENUM_MASK;
8961 v <<= LITTLENUM_NUMBER_OF_BITS;
8962 v |= l[2] & LITTLENUM_MASK;
8963 v <<= LITTLENUM_NUMBER_OF_BITS;
8964 v |= l[1] & LITTLENUM_MASK;
8965 v <<= LITTLENUM_NUMBER_OF_BITS;
8966 v |= l[0] & LITTLENUM_MASK;
8335d6aa 8967 }
ba592044 8968 else
e2b0ab59 8969 v = inst.relocs[0].exp.X_add_number;
ba592044
AM
8970
8971 if (!inst.operands[i].issingle)
8335d6aa 8972 {
12569877 8973 if (thumb_p)
8335d6aa 8974 {
53445554
TP
8975 /* LDR should not use lead in a flag-setting instruction being
8976 chosen so we do not check whether movs can be used. */
12569877 8977
53445554 8978 if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
ff8646ee 8979 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
53445554
TP
8980 && inst.operands[i].reg != 13
8981 && inst.operands[i].reg != 15)
12569877 8982 {
fc289b0a
TP
8983 /* Check if on thumb2 it can be done with a mov.w, mvn or
8984 movw instruction. */
12569877 8985 unsigned int newimm;
5b7c81bd 8986 bool isNegated = false;
12569877
AM
8987
8988 newimm = encode_thumb32_immediate (v);
f3da8a96 8989 if (newimm == (unsigned int) FAIL)
12569877 8990 {
582cfe03 8991 newimm = encode_thumb32_immediate (~v);
5b7c81bd 8992 isNegated = true;
12569877
AM
8993 }
8994
fc289b0a
TP
8995 /* The number can be loaded with a mov.w or mvn
8996 instruction. */
ff8646ee
TP
8997 if (newimm != (unsigned int) FAIL
8998 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
12569877 8999 {
fc289b0a 9000 inst.instruction = (0xf04f0000 /* MOV.W. */
582cfe03 9001 | (inst.operands[i].reg << 8));
fc289b0a 9002 /* Change to MOVN. */
582cfe03 9003 inst.instruction |= (isNegated ? 0x200000 : 0);
12569877
AM
9004 inst.instruction |= (newimm & 0x800) << 15;
9005 inst.instruction |= (newimm & 0x700) << 4;
9006 inst.instruction |= (newimm & 0x0ff);
5b7c81bd 9007 return true;
12569877 9008 }
fc289b0a 9009 /* The number can be loaded with a movw instruction. */
ff8646ee
TP
9010 else if ((v & ~0xFFFF) == 0
9011 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
3739860c 9012 {
582cfe03 9013 int imm = v & 0xFFFF;
12569877 9014
582cfe03 9015 inst.instruction = 0xf2400000; /* MOVW. */
12569877
AM
9016 inst.instruction |= (inst.operands[i].reg << 8);
9017 inst.instruction |= (imm & 0xf000) << 4;
9018 inst.instruction |= (imm & 0x0800) << 15;
9019 inst.instruction |= (imm & 0x0700) << 4;
9020 inst.instruction |= (imm & 0x00ff);
8fe9a076
AV
9021 /* In case this replacement is being done on Armv8-M
9022 Baseline we need to make sure to disable the
9023 instruction size check, as otherwise GAS will reject
9024 the use of this T32 instruction. */
9025 inst.size_req = 0;
5b7c81bd 9026 return true;
12569877
AM
9027 }
9028 }
8335d6aa 9029 }
12569877 9030 else if (arm_p)
ba592044
AM
9031 {
9032 int value = encode_arm_immediate (v);
12569877 9033
ba592044
AM
9034 if (value != FAIL)
9035 {
9036 /* This can be done with a mov instruction. */
9037 inst.instruction &= LITERAL_MASK;
9038 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
9039 inst.instruction |= value & 0xfff;
5b7c81bd 9040 return true;
ba592044 9041 }
8335d6aa 9042
ba592044
AM
9043 value = encode_arm_immediate (~ v);
9044 if (value != FAIL)
9045 {
9046 /* This can be done with a mvn instruction. */
9047 inst.instruction &= LITERAL_MASK;
9048 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
9049 inst.instruction |= value & 0xfff;
5b7c81bd 9050 return true;
ba592044
AM
9051 }
9052 }
934c2632 9053 else if (t == CONST_VEC && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
8335d6aa 9054 {
ba592044
AM
9055 int op = 0;
9056 unsigned immbits = 0;
9057 unsigned immlo = inst.operands[1].imm;
9058 unsigned immhi = inst.operands[1].regisimm
9059 ? inst.operands[1].reg
e2b0ab59 9060 : inst.relocs[0].exp.X_unsigned
ba592044 9061 ? 0
0e3c1eeb 9062 : (int64_t) (int) immlo >> 32;
5b7c81bd 9063 int cmode = neon_cmode_for_move_imm (immlo, immhi, false, &immbits,
ba592044
AM
9064 &op, 64, NT_invtype);
9065
9066 if (cmode == FAIL)
9067 {
9068 neon_invert_size (&immlo, &immhi, 64);
9069 op = !op;
5b7c81bd 9070 cmode = neon_cmode_for_move_imm (immlo, immhi, false, &immbits,
ba592044
AM
9071 &op, 64, NT_invtype);
9072 }
9073
9074 if (cmode != FAIL)
9075 {
9076 inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
9077 | (1 << 23)
9078 | (cmode << 8)
9079 | (op << 5)
9080 | (1 << 4);
9081
9082 /* Fill other bits in vmov encoding for both thumb and arm. */
9083 if (thumb_mode)
eff0bc54 9084 inst.instruction |= (0x7U << 29) | (0xF << 24);
ba592044 9085 else
eff0bc54 9086 inst.instruction |= (0xFU << 28) | (0x1 << 25);
ba592044 9087 neon_write_immbits (immbits);
5b7c81bd 9088 return true;
ba592044 9089 }
8335d6aa
JW
9090 }
9091 }
8335d6aa 9092
ba592044
AM
9093 if (t == CONST_VEC)
9094 {
9095 /* Check if vldr Rx, =constant could be optimized to vmov Rx, #constant. */
9096 if (inst.operands[i].issingle
9097 && is_quarter_float (inst.operands[1].imm)
9098 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3xd))
8335d6aa 9099 {
ba592044
AM
9100 inst.operands[1].imm =
9101 neon_qfloat_bits (v);
9102 do_vfp_nsyn_opcode ("fconsts");
5b7c81bd 9103 return true;
8335d6aa 9104 }
5fc177c8
NC
9105
9106 /* If our host does not support a 64-bit type then we cannot perform
9107 the following optimization. This mean that there will be a
9108 discrepancy between the output produced by an assembler built for
9109 a 32-bit-only host and the output produced from a 64-bit host, but
9110 this cannot be helped. */
ba592044
AM
9111 else if (!inst.operands[1].issingle
9112 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
8335d6aa 9113 {
ba592044
AM
9114 if (is_double_a_single (v)
9115 && is_quarter_float (double_to_single (v)))
9116 {
9117 inst.operands[1].imm =
9118 neon_qfloat_bits (double_to_single (v));
9119 do_vfp_nsyn_opcode ("fconstd");
5b7c81bd 9120 return true;
ba592044 9121 }
8335d6aa
JW
9122 }
9123 }
9124 }
9125
9126 if (add_to_lit_pool ((!inst.operands[i].isvec
9127 || inst.operands[i].issingle) ? 4 : 8) == FAIL)
5b7c81bd 9128 return true;
8335d6aa
JW
9129
9130 inst.operands[1].reg = REG_PC;
9131 inst.operands[1].isreg = 1;
9132 inst.operands[1].preind = 1;
e2b0ab59
AV
9133 inst.relocs[0].pc_rel = 1;
9134 inst.relocs[0].type = (thumb_p
8335d6aa
JW
9135 ? BFD_RELOC_ARM_THUMB_OFFSET
9136 : (mode_3
9137 ? BFD_RELOC_ARM_HWLITERAL
9138 : BFD_RELOC_ARM_LITERAL));
5b7c81bd 9139 return false;
8335d6aa
JW
9140}
9141
9142/* inst.operands[i] was set up by parse_address. Encode it into an
9143 ARM-format instruction. Reject all forms which cannot be encoded
9144 into a coprocessor load/store instruction. If wb_ok is false,
9145 reject use of writeback; if unind_ok is false, reject use of
9146 unindexed addressing. If reloc_override is not 0, use it instead
9147 of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
9148 (in which case it is preserved). */
9149
9150static int
9151encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
9152{
9153 if (!inst.operands[i].isreg)
9154 {
99b2a2dd
NC
9155 /* PR 18256 */
9156 if (! inst.operands[0].isvec)
9157 {
9158 inst.error = _("invalid co-processor operand");
9159 return FAIL;
9160 }
5b7c81bd 9161 if (move_or_literal_pool (0, CONST_VEC, /*mode_3=*/false))
8335d6aa
JW
9162 return SUCCESS;
9163 }
9164
9165 inst.instruction |= inst.operands[i].reg << 16;
9166
9167 gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
9168
9169 if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
9170 {
9171 gas_assert (!inst.operands[i].writeback);
9172 if (!unind_ok)
9173 {
9174 inst.error = _("instruction does not support unindexed addressing");
9175 return FAIL;
9176 }
9177 inst.instruction |= inst.operands[i].imm;
9178 inst.instruction |= INDEX_UP;
9179 return SUCCESS;
9180 }
9181
9182 if (inst.operands[i].preind)
9183 inst.instruction |= PRE_INDEX;
9184
9185 if (inst.operands[i].writeback)
09d92015 9186 {
8335d6aa 9187 if (inst.operands[i].reg == REG_PC)
c19d1205 9188 {
8335d6aa
JW
9189 inst.error = _("pc may not be used with write-back");
9190 return FAIL;
c19d1205 9191 }
8335d6aa 9192 if (!wb_ok)
c19d1205 9193 {
8335d6aa
JW
9194 inst.error = _("instruction does not support writeback");
9195 return FAIL;
c19d1205 9196 }
8335d6aa 9197 inst.instruction |= WRITE_BACK;
09d92015
MM
9198 }
9199
8335d6aa 9200 if (reloc_override)
e2b0ab59
AV
9201 inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
9202 else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
9203 || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
9204 && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
c19d1205 9205 {
8335d6aa 9206 if (thumb_mode)
e2b0ab59 9207 inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
8335d6aa 9208 else
e2b0ab59 9209 inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
c19d1205 9210 }
8335d6aa
JW
9211
9212 /* Prefer + for zero encoded value. */
9213 if (!inst.operands[i].negative)
9214 inst.instruction |= INDEX_UP;
9215
9216 return SUCCESS;
09d92015
MM
9217}
9218
5f4273c7 9219/* Functions for instruction encoding, sorted by sub-architecture.
c19d1205
ZW
9220 First some generics; their names are taken from the conventional
9221 bit positions for register arguments in ARM format instructions. */
09d92015 9222
a737bd4d 9223static void
c19d1205 9224do_noargs (void)
09d92015 9225{
c19d1205 9226}
a737bd4d 9227
c19d1205
ZW
9228static void
9229do_rd (void)
9230{
9231 inst.instruction |= inst.operands[0].reg << 12;
9232}
a737bd4d 9233
16a1fa25
TP
9234static void
9235do_rn (void)
9236{
9237 inst.instruction |= inst.operands[0].reg << 16;
9238}
9239
c19d1205
ZW
9240static void
9241do_rd_rm (void)
9242{
9243 inst.instruction |= inst.operands[0].reg << 12;
9244 inst.instruction |= inst.operands[1].reg;
9245}
09d92015 9246
9eb6c0f1
MGD
9247static void
9248do_rm_rn (void)
9249{
9250 inst.instruction |= inst.operands[0].reg;
9251 inst.instruction |= inst.operands[1].reg << 16;
9252}
9253
c19d1205
ZW
9254static void
9255do_rd_rn (void)
9256{
9257 inst.instruction |= inst.operands[0].reg << 12;
9258 inst.instruction |= inst.operands[1].reg << 16;
9259}
a737bd4d 9260
c19d1205
ZW
9261static void
9262do_rn_rd (void)
9263{
9264 inst.instruction |= inst.operands[0].reg << 16;
9265 inst.instruction |= inst.operands[1].reg << 12;
9266}
09d92015 9267
4ed7ed8d
TP
9268static void
9269do_tt (void)
9270{
9271 inst.instruction |= inst.operands[0].reg << 8;
9272 inst.instruction |= inst.operands[1].reg << 16;
9273}
9274
5b7c81bd 9275static bool
59d09be6
MGD
9276check_obsolete (const arm_feature_set *feature, const char *msg)
9277{
9278 if (ARM_CPU_IS_ANY (cpu_variant))
9279 {
5c3696f8 9280 as_tsktsk ("%s", msg);
5b7c81bd 9281 return true;
59d09be6
MGD
9282 }
9283 else if (ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
9284 {
9285 as_bad ("%s", msg);
5b7c81bd 9286 return true;
59d09be6
MGD
9287 }
9288
5b7c81bd 9289 return false;
59d09be6
MGD
9290}
9291
c19d1205
ZW
9292static void
9293do_rd_rm_rn (void)
9294{
9a64e435 9295 unsigned Rn = inst.operands[2].reg;
708587a4 9296 /* Enforce restrictions on SWP instruction. */
9a64e435 9297 if ((inst.instruction & 0x0fbfffff) == 0x01000090)
56adecf4
DG
9298 {
9299 constraint (Rn == inst.operands[0].reg || Rn == inst.operands[1].reg,
9300 _("Rn must not overlap other operands"));
9301
59d09be6
MGD
9302 /* SWP{b} is obsolete for ARMv8-A, and deprecated for ARMv6* and ARMv7.
9303 */
9304 if (!check_obsolete (&arm_ext_v8,
9305 _("swp{b} use is obsoleted for ARMv8 and later"))
9306 && warn_on_deprecated
9307 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6))
5c3696f8 9308 as_tsktsk (_("swp{b} use is deprecated for ARMv6 and ARMv7"));
56adecf4 9309 }
59d09be6 9310
c19d1205
ZW
9311 inst.instruction |= inst.operands[0].reg << 12;
9312 inst.instruction |= inst.operands[1].reg;
9a64e435 9313 inst.instruction |= Rn << 16;
c19d1205 9314}
09d92015 9315
c19d1205
ZW
9316static void
9317do_rd_rn_rm (void)
9318{
9319 inst.instruction |= inst.operands[0].reg << 12;
9320 inst.instruction |= inst.operands[1].reg << 16;
9321 inst.instruction |= inst.operands[2].reg;
9322}
a737bd4d 9323
c19d1205
ZW
9324static void
9325do_rm_rd_rn (void)
9326{
5be8be5d 9327 constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
e2b0ab59
AV
9328 constraint (((inst.relocs[0].exp.X_op != O_constant
9329 && inst.relocs[0].exp.X_op != O_illegal)
9330 || inst.relocs[0].exp.X_add_number != 0),
5be8be5d 9331 BAD_ADDR_MODE);
c19d1205
ZW
9332 inst.instruction |= inst.operands[0].reg;
9333 inst.instruction |= inst.operands[1].reg << 12;
9334 inst.instruction |= inst.operands[2].reg << 16;
9335}
09d92015 9336
c19d1205
ZW
9337static void
9338do_imm0 (void)
9339{
9340 inst.instruction |= inst.operands[0].imm;
9341}
09d92015 9342
c19d1205
ZW
9343static void
9344do_rd_cpaddr (void)
9345{
9346 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 9347 encode_arm_cp_address (1, true, true, 0);
09d92015 9348}
a737bd4d 9349
c19d1205
ZW
9350/* ARM instructions, in alphabetical order by function name (except
9351 that wrapper functions appear immediately after the function they
9352 wrap). */
09d92015 9353
c19d1205
ZW
9354/* This is a pseudo-op of the form "adr rd, label" to be converted
9355 into a relative address of the form "add rd, pc, #label-.-8". */
09d92015
MM
9356
9357static void
c19d1205 9358do_adr (void)
09d92015 9359{
c19d1205 9360 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9361
c19d1205
ZW
9362 /* Frag hacking will turn this into a sub instruction if the offset turns
9363 out to be negative. */
e2b0ab59
AV
9364 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9365 inst.relocs[0].pc_rel = 1;
9366 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9367
fc6141f0 9368 if (support_interwork
e2b0ab59
AV
9369 && inst.relocs[0].exp.X_op == O_symbol
9370 && inst.relocs[0].exp.X_add_symbol != NULL
9371 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9372 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9373 inst.relocs[0].exp.X_add_number |= 1;
c19d1205 9374}
b99bd4ef 9375
c19d1205
ZW
9376/* This is a pseudo-op of the form "adrl rd, label" to be converted
9377 into a relative address of the form:
9378 add rd, pc, #low(label-.-8)"
9379 add rd, rd, #high(label-.-8)" */
b99bd4ef 9380
c19d1205
ZW
9381static void
9382do_adrl (void)
9383{
9384 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9385
c19d1205
ZW
9386 /* Frag hacking will turn this into a sub instruction if the offset turns
9387 out to be negative. */
e2b0ab59
AV
9388 inst.relocs[0].type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
9389 inst.relocs[0].pc_rel = 1;
c19d1205 9390 inst.size = INSN_SIZE * 2;
e2b0ab59 9391 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9392
fc6141f0 9393 if (support_interwork
e2b0ab59
AV
9394 && inst.relocs[0].exp.X_op == O_symbol
9395 && inst.relocs[0].exp.X_add_symbol != NULL
9396 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9397 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9398 inst.relocs[0].exp.X_add_number |= 1;
b99bd4ef
NC
9399}
9400
b99bd4ef 9401static void
c19d1205 9402do_arit (void)
b99bd4ef 9403{
e2b0ab59
AV
9404 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9405 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9406 THUMB1_RELOC_ONLY);
c19d1205
ZW
9407 if (!inst.operands[1].present)
9408 inst.operands[1].reg = inst.operands[0].reg;
9409 inst.instruction |= inst.operands[0].reg << 12;
9410 inst.instruction |= inst.operands[1].reg << 16;
9411 encode_arm_shifter_operand (2);
9412}
b99bd4ef 9413
62b3e311
PB
9414static void
9415do_barrier (void)
9416{
9417 if (inst.operands[0].present)
ccb84d65 9418 inst.instruction |= inst.operands[0].imm;
62b3e311
PB
9419 else
9420 inst.instruction |= 0xf;
9421}
9422
c19d1205
ZW
9423static void
9424do_bfc (void)
9425{
9426 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
9427 constraint (msb > 32, _("bit-field extends past end of register"));
9428 /* The instruction encoding stores the LSB and MSB,
9429 not the LSB and width. */
9430 inst.instruction |= inst.operands[0].reg << 12;
9431 inst.instruction |= inst.operands[1].imm << 7;
9432 inst.instruction |= (msb - 1) << 16;
9433}
b99bd4ef 9434
c19d1205
ZW
9435static void
9436do_bfi (void)
9437{
9438 unsigned int msb;
b99bd4ef 9439
c19d1205
ZW
9440 /* #0 in second position is alternative syntax for bfc, which is
9441 the same instruction but with REG_PC in the Rm field. */
9442 if (!inst.operands[1].isreg)
9443 inst.operands[1].reg = REG_PC;
b99bd4ef 9444
c19d1205
ZW
9445 msb = inst.operands[2].imm + inst.operands[3].imm;
9446 constraint (msb > 32, _("bit-field extends past end of register"));
9447 /* The instruction encoding stores the LSB and MSB,
9448 not the LSB and width. */
9449 inst.instruction |= inst.operands[0].reg << 12;
9450 inst.instruction |= inst.operands[1].reg;
9451 inst.instruction |= inst.operands[2].imm << 7;
9452 inst.instruction |= (msb - 1) << 16;
b99bd4ef
NC
9453}
9454
b99bd4ef 9455static void
c19d1205 9456do_bfx (void)
b99bd4ef 9457{
c19d1205
ZW
9458 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
9459 _("bit-field extends past end of register"));
9460 inst.instruction |= inst.operands[0].reg << 12;
9461 inst.instruction |= inst.operands[1].reg;
9462 inst.instruction |= inst.operands[2].imm << 7;
9463 inst.instruction |= (inst.operands[3].imm - 1) << 16;
9464}
09d92015 9465
c19d1205
ZW
9466/* ARM V5 breakpoint instruction (argument parse)
9467 BKPT <16 bit unsigned immediate>
9468 Instruction is not conditional.
9469 The bit pattern given in insns[] has the COND_ALWAYS condition,
9470 and it is an error if the caller tried to override that. */
b99bd4ef 9471
c19d1205
ZW
9472static void
9473do_bkpt (void)
9474{
9475 /* Top 12 of 16 bits to bits 19:8. */
9476 inst.instruction |= (inst.operands[0].imm & 0xfff0) << 4;
09d92015 9477
c19d1205
ZW
9478 /* Bottom 4 of 16 bits to bits 3:0. */
9479 inst.instruction |= inst.operands[0].imm & 0xf;
9480}
09d92015 9481
c19d1205
ZW
9482static void
9483encode_branch (int default_reloc)
9484{
9485 if (inst.operands[0].hasreloc)
9486 {
0855e32b
NS
9487 constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
9488 && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
9489 _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
e2b0ab59 9490 inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
0855e32b
NS
9491 ? BFD_RELOC_ARM_PLT32
9492 : thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
c19d1205 9493 }
b99bd4ef 9494 else
e2b0ab59
AV
9495 inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
9496 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
9497}
9498
b99bd4ef 9499static void
c19d1205 9500do_branch (void)
b99bd4ef 9501{
39b41c9c
PB
9502#ifdef OBJ_ELF
9503 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9504 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9505 else
9506#endif
9507 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
9508}
9509
9510static void
9511do_bl (void)
9512{
9513#ifdef OBJ_ELF
9514 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9515 {
9516 if (inst.cond == COND_ALWAYS)
9517 encode_branch (BFD_RELOC_ARM_PCREL_CALL);
9518 else
9519 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9520 }
9521 else
9522#endif
9523 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
c19d1205 9524}
b99bd4ef 9525
c19d1205
ZW
9526/* ARM V5 branch-link-exchange instruction (argument parse)
9527 BLX <target_addr> ie BLX(1)
9528 BLX{<condition>} <Rm> ie BLX(2)
9529 Unfortunately, there are two different opcodes for this mnemonic.
9530 So, the insns[].value is not used, and the code here zaps values
9531 into inst.instruction.
9532 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
b99bd4ef 9533
c19d1205
ZW
9534static void
9535do_blx (void)
9536{
9537 if (inst.operands[0].isreg)
b99bd4ef 9538 {
c19d1205
ZW
9539 /* Arg is a register; the opcode provided by insns[] is correct.
9540 It is not illegal to do "blx pc", just useless. */
9541 if (inst.operands[0].reg == REG_PC)
9542 as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
b99bd4ef 9543
c19d1205
ZW
9544 inst.instruction |= inst.operands[0].reg;
9545 }
9546 else
b99bd4ef 9547 {
c19d1205 9548 /* Arg is an address; this instruction cannot be executed
267bf995
RR
9549 conditionally, and the opcode must be adjusted.
9550 We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
9551 where we generate out a BFD_RELOC_ARM_PCREL_CALL instead. */
c19d1205 9552 constraint (inst.cond != COND_ALWAYS, BAD_COND);
2fc8bdac 9553 inst.instruction = 0xfa000000;
267bf995 9554 encode_branch (BFD_RELOC_ARM_PCREL_BLX);
b99bd4ef 9555 }
c19d1205
ZW
9556}
9557
9558static void
9559do_bx (void)
9560{
5b7c81bd 9561 bool want_reloc;
845b51d6 9562
c19d1205
ZW
9563 if (inst.operands[0].reg == REG_PC)
9564 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
b99bd4ef 9565
c19d1205 9566 inst.instruction |= inst.operands[0].reg;
845b51d6
PB
9567 /* Output R_ARM_V4BX relocations if is an EABI object that looks like
9568 it is for ARMv4t or earlier. */
9569 want_reloc = !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5);
4d354d8b
TP
9570 if (!ARM_FEATURE_ZERO (selected_object_arch)
9571 && !ARM_CPU_HAS_FEATURE (selected_object_arch, arm_ext_v5))
5b7c81bd 9572 want_reloc = true;
845b51d6 9573
5ad34203 9574#ifdef OBJ_ELF
845b51d6 9575 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
5ad34203 9576#endif
5b7c81bd 9577 want_reloc = false;
845b51d6
PB
9578
9579 if (want_reloc)
e2b0ab59 9580 inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
09d92015
MM
9581}
9582
c19d1205
ZW
9583
9584/* ARM v5TEJ. Jump to Jazelle code. */
a737bd4d
NC
9585
9586static void
c19d1205 9587do_bxj (void)
a737bd4d 9588{
c19d1205
ZW
9589 if (inst.operands[0].reg == REG_PC)
9590 as_tsktsk (_("use of r15 in bxj is not really useful"));
9591
9592 inst.instruction |= inst.operands[0].reg;
a737bd4d
NC
9593}
9594
c19d1205
ZW
9595/* Co-processor data operation:
9596 CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
9597 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>} */
9598static void
9599do_cdp (void)
9600{
9601 inst.instruction |= inst.operands[0].reg << 8;
9602 inst.instruction |= inst.operands[1].imm << 20;
9603 inst.instruction |= inst.operands[2].reg << 12;
9604 inst.instruction |= inst.operands[3].reg << 16;
9605 inst.instruction |= inst.operands[4].reg;
9606 inst.instruction |= inst.operands[5].imm << 5;
9607}
a737bd4d
NC
9608
9609static void
c19d1205 9610do_cmp (void)
a737bd4d 9611{
c19d1205
ZW
9612 inst.instruction |= inst.operands[0].reg << 16;
9613 encode_arm_shifter_operand (1);
a737bd4d
NC
9614}
9615
c19d1205
ZW
9616/* Transfer between coprocessor and ARM registers.
9617 MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
9618 MRC2
9619 MCR{cond}
9620 MCR2
9621
9622 No special properties. */
09d92015 9623
dcbd0d71
MGD
9624struct deprecated_coproc_regs_s
9625{
9626 unsigned cp;
9627 int opc1;
9628 unsigned crn;
9629 unsigned crm;
9630 int opc2;
9631 arm_feature_set deprecated;
9632 arm_feature_set obsoleted;
9633 const char *dep_msg;
9634 const char *obs_msg;
9635};
9636
9637#define DEPR_ACCESS_V8 \
9638 N_("This coprocessor register access is deprecated in ARMv8")
9639
9640/* Table of all deprecated coprocessor registers. */
9641static struct deprecated_coproc_regs_s deprecated_coproc_regs[] =
9642{
9643 {15, 0, 7, 10, 5, /* CP15DMB. */
823d2571 9644 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9645 DEPR_ACCESS_V8, NULL},
9646 {15, 0, 7, 10, 4, /* CP15DSB. */
823d2571 9647 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9648 DEPR_ACCESS_V8, NULL},
9649 {15, 0, 7, 5, 4, /* CP15ISB. */
823d2571 9650 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9651 DEPR_ACCESS_V8, NULL},
9652 {14, 6, 1, 0, 0, /* TEEHBR. */
823d2571 9653 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9654 DEPR_ACCESS_V8, NULL},
9655 {14, 6, 0, 0, 0, /* TEECR. */
823d2571 9656 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9657 DEPR_ACCESS_V8, NULL},
9658};
9659
9660#undef DEPR_ACCESS_V8
9661
9662static const size_t deprecated_coproc_reg_count =
9663 sizeof (deprecated_coproc_regs) / sizeof (deprecated_coproc_regs[0]);
9664
09d92015 9665static void
c19d1205 9666do_co_reg (void)
09d92015 9667{
fdfde340 9668 unsigned Rd;
dcbd0d71 9669 size_t i;
fdfde340
JM
9670
9671 Rd = inst.operands[2].reg;
9672 if (thumb_mode)
9673 {
9674 if (inst.instruction == 0xee000010
9675 || inst.instruction == 0xfe000010)
9676 /* MCR, MCR2 */
9677 reject_bad_reg (Rd);
5c8ed6a4 9678 else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
fdfde340
JM
9679 /* MRC, MRC2 */
9680 constraint (Rd == REG_SP, BAD_SP);
9681 }
9682 else
9683 {
9684 /* MCR */
9685 if (inst.instruction == 0xe000010)
9686 constraint (Rd == REG_PC, BAD_PC);
9687 }
9688
dcbd0d71
MGD
9689 for (i = 0; i < deprecated_coproc_reg_count; ++i)
9690 {
9691 const struct deprecated_coproc_regs_s *r =
9692 deprecated_coproc_regs + i;
9693
9694 if (inst.operands[0].reg == r->cp
9695 && inst.operands[1].imm == r->opc1
9696 && inst.operands[3].reg == r->crn
9697 && inst.operands[4].reg == r->crm
9698 && inst.operands[5].imm == r->opc2)
9699 {
b10bf8c5 9700 if (! ARM_CPU_IS_ANY (cpu_variant)
477330fc 9701 && warn_on_deprecated
dcbd0d71 9702 && ARM_CPU_HAS_FEATURE (cpu_variant, r->deprecated))
5c3696f8 9703 as_tsktsk ("%s", r->dep_msg);
dcbd0d71
MGD
9704 }
9705 }
fdfde340 9706
c19d1205
ZW
9707 inst.instruction |= inst.operands[0].reg << 8;
9708 inst.instruction |= inst.operands[1].imm << 21;
fdfde340 9709 inst.instruction |= Rd << 12;
c19d1205
ZW
9710 inst.instruction |= inst.operands[3].reg << 16;
9711 inst.instruction |= inst.operands[4].reg;
9712 inst.instruction |= inst.operands[5].imm << 5;
9713}
09d92015 9714
c19d1205
ZW
9715/* Transfer between coprocessor register and pair of ARM registers.
9716 MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
9717 MCRR2
9718 MRRC{cond}
9719 MRRC2
b99bd4ef 9720
c19d1205 9721 Two XScale instructions are special cases of these:
09d92015 9722
c19d1205
ZW
9723 MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
9724 MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
b99bd4ef 9725
5f4273c7 9726 Result unpredictable if Rd or Rn is R15. */
a737bd4d 9727
c19d1205
ZW
9728static void
9729do_co_reg2c (void)
9730{
fdfde340
JM
9731 unsigned Rd, Rn;
9732
9733 Rd = inst.operands[2].reg;
9734 Rn = inst.operands[3].reg;
9735
9736 if (thumb_mode)
9737 {
9738 reject_bad_reg (Rd);
9739 reject_bad_reg (Rn);
9740 }
9741 else
9742 {
9743 constraint (Rd == REG_PC, BAD_PC);
9744 constraint (Rn == REG_PC, BAD_PC);
9745 }
9746
873f10f0
TC
9747 /* Only check the MRRC{2} variants. */
9748 if ((inst.instruction & 0x0FF00000) == 0x0C500000)
9749 {
9750 /* If Rd == Rn, error that the operation is
9751 unpredictable (example MRRC p3,#1,r1,r1,c4). */
9752 constraint (Rd == Rn, BAD_OVERLAP);
9753 }
9754
c19d1205
ZW
9755 inst.instruction |= inst.operands[0].reg << 8;
9756 inst.instruction |= inst.operands[1].imm << 4;
fdfde340
JM
9757 inst.instruction |= Rd << 12;
9758 inst.instruction |= Rn << 16;
c19d1205 9759 inst.instruction |= inst.operands[4].reg;
b99bd4ef
NC
9760}
9761
c19d1205
ZW
9762static void
9763do_cpsi (void)
9764{
9765 inst.instruction |= inst.operands[0].imm << 6;
a028a6f5
PB
9766 if (inst.operands[1].present)
9767 {
9768 inst.instruction |= CPSI_MMOD;
9769 inst.instruction |= inst.operands[1].imm;
9770 }
c19d1205 9771}
b99bd4ef 9772
62b3e311
PB
9773static void
9774do_dbg (void)
9775{
9776 inst.instruction |= inst.operands[0].imm;
9777}
9778
eea54501
MGD
9779static void
9780do_div (void)
9781{
9782 unsigned Rd, Rn, Rm;
9783
9784 Rd = inst.operands[0].reg;
9785 Rn = (inst.operands[1].present
9786 ? inst.operands[1].reg : Rd);
9787 Rm = inst.operands[2].reg;
9788
9789 constraint ((Rd == REG_PC), BAD_PC);
9790 constraint ((Rn == REG_PC), BAD_PC);
9791 constraint ((Rm == REG_PC), BAD_PC);
9792
9793 inst.instruction |= Rd << 16;
9794 inst.instruction |= Rn << 0;
9795 inst.instruction |= Rm << 8;
9796}
9797
b99bd4ef 9798static void
c19d1205 9799do_it (void)
b99bd4ef 9800{
c19d1205 9801 /* There is no IT instruction in ARM mode. We
e07e6e58
NC
9802 process it to do the validation as if in
9803 thumb mode, just in case the code gets
9804 assembled for thumb using the unified syntax. */
9805
c19d1205 9806 inst.size = 0;
e07e6e58
NC
9807 if (unified_syntax)
9808 {
5ee91343
AV
9809 set_pred_insn_type (IT_INSN);
9810 now_pred.mask = (inst.instruction & 0xf) | 0x10;
9811 now_pred.cc = inst.operands[0].imm;
e07e6e58 9812 }
09d92015 9813}
b99bd4ef 9814
6530b175
NC
9815/* If there is only one register in the register list,
9816 then return its register number. Otherwise return -1. */
9817static int
9818only_one_reg_in_list (int range)
9819{
9820 int i = ffs (range) - 1;
9821 return (i > 15 || range != (1 << i)) ? -1 : i;
9822}
9823
09d92015 9824static void
6530b175 9825encode_ldmstm(int from_push_pop_mnem)
ea6ef066 9826{
c19d1205
ZW
9827 int base_reg = inst.operands[0].reg;
9828 int range = inst.operands[1].imm;
6530b175 9829 int one_reg;
ea6ef066 9830
c19d1205
ZW
9831 inst.instruction |= base_reg << 16;
9832 inst.instruction |= range;
ea6ef066 9833
c19d1205
ZW
9834 if (inst.operands[1].writeback)
9835 inst.instruction |= LDM_TYPE_2_OR_3;
09d92015 9836
c19d1205 9837 if (inst.operands[0].writeback)
ea6ef066 9838 {
c19d1205
ZW
9839 inst.instruction |= WRITE_BACK;
9840 /* Check for unpredictable uses of writeback. */
9841 if (inst.instruction & LOAD_BIT)
09d92015 9842 {
c19d1205
ZW
9843 /* Not allowed in LDM type 2. */
9844 if ((inst.instruction & LDM_TYPE_2_OR_3)
9845 && ((range & (1 << REG_PC)) == 0))
9846 as_warn (_("writeback of base register is UNPREDICTABLE"));
9847 /* Only allowed if base reg not in list for other types. */
9848 else if (range & (1 << base_reg))
9849 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
9850 }
9851 else /* STM. */
9852 {
9853 /* Not allowed for type 2. */
9854 if (inst.instruction & LDM_TYPE_2_OR_3)
9855 as_warn (_("writeback of base register is UNPREDICTABLE"));
9856 /* Only allowed if base reg not in list, or first in list. */
9857 else if ((range & (1 << base_reg))
9858 && (range & ((1 << base_reg) - 1)))
9859 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
09d92015 9860 }
ea6ef066 9861 }
6530b175
NC
9862
9863 /* If PUSH/POP has only one register, then use the A2 encoding. */
9864 one_reg = only_one_reg_in_list (range);
9865 if (from_push_pop_mnem && one_reg >= 0)
9866 {
9867 int is_push = (inst.instruction & A_PUSH_POP_OP_MASK) == A1_OPCODE_PUSH;
9868
4f588891
NC
9869 if (is_push && one_reg == 13 /* SP */)
9870 /* PR 22483: The A2 encoding cannot be used when
9871 pushing the stack pointer as this is UNPREDICTABLE. */
9872 return;
9873
6530b175
NC
9874 inst.instruction &= A_COND_MASK;
9875 inst.instruction |= is_push ? A2_OPCODE_PUSH : A2_OPCODE_POP;
9876 inst.instruction |= one_reg << 12;
9877 }
9878}
9879
9880static void
9881do_ldmstm (void)
9882{
5b7c81bd 9883 encode_ldmstm (/*from_push_pop_mnem=*/false);
a737bd4d
NC
9884}
9885
c19d1205
ZW
9886/* ARMv5TE load-consecutive (argument parse)
9887 Mode is like LDRH.
9888
9889 LDRccD R, mode
9890 STRccD R, mode. */
9891
a737bd4d 9892static void
c19d1205 9893do_ldrd (void)
a737bd4d 9894{
c19d1205 9895 constraint (inst.operands[0].reg % 2 != 0,
c56791bb 9896 _("first transfer register must be even"));
c19d1205
ZW
9897 constraint (inst.operands[1].present
9898 && inst.operands[1].reg != inst.operands[0].reg + 1,
c56791bb 9899 _("can only transfer two consecutive registers"));
c19d1205
ZW
9900 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
9901 constraint (!inst.operands[2].isreg, _("'[' expected"));
a737bd4d 9902
c19d1205
ZW
9903 if (!inst.operands[1].present)
9904 inst.operands[1].reg = inst.operands[0].reg + 1;
5f4273c7 9905
c56791bb
RE
9906 /* encode_arm_addr_mode_3 will diagnose overlap between the base
9907 register and the first register written; we have to diagnose
9908 overlap between the base and the second register written here. */
ea6ef066 9909
c56791bb
RE
9910 if (inst.operands[2].reg == inst.operands[1].reg
9911 && (inst.operands[2].writeback || inst.operands[2].postind))
9912 as_warn (_("base register written back, and overlaps "
9913 "second transfer register"));
b05fe5cf 9914
c56791bb
RE
9915 if (!(inst.instruction & V4_STR_BIT))
9916 {
c19d1205 9917 /* For an index-register load, the index register must not overlap the
c56791bb
RE
9918 destination (even if not write-back). */
9919 if (inst.operands[2].immisreg
9920 && ((unsigned) inst.operands[2].imm == inst.operands[0].reg
9921 || (unsigned) inst.operands[2].imm == inst.operands[1].reg))
9922 as_warn (_("index register overlaps transfer register"));
b05fe5cf 9923 }
c19d1205 9924 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 9925 encode_arm_addr_mode_3 (2, /*is_t=*/false);
b05fe5cf
ZW
9926}
9927
9928static void
c19d1205 9929do_ldrex (void)
b05fe5cf 9930{
c19d1205
ZW
9931 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
9932 || inst.operands[1].postind || inst.operands[1].writeback
9933 || inst.operands[1].immisreg || inst.operands[1].shifted
01cfc07f
NC
9934 || inst.operands[1].negative
9935 /* This can arise if the programmer has written
9936 strex rN, rM, foo
9937 or if they have mistakenly used a register name as the last
9938 operand, eg:
9939 strex rN, rM, rX
9940 It is very difficult to distinguish between these two cases
9941 because "rX" might actually be a label. ie the register
9942 name has been occluded by a symbol of the same name. So we
9943 just generate a general 'bad addressing mode' type error
9944 message and leave it up to the programmer to discover the
9945 true cause and fix their mistake. */
9946 || (inst.operands[1].reg == REG_PC),
9947 BAD_ADDR_MODE);
b05fe5cf 9948
e2b0ab59
AV
9949 constraint (inst.relocs[0].exp.X_op != O_constant
9950 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9951 _("offset must be zero in ARM encoding"));
b05fe5cf 9952
5be8be5d
DG
9953 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
9954
c19d1205
ZW
9955 inst.instruction |= inst.operands[0].reg << 12;
9956 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 9957 inst.relocs[0].type = BFD_RELOC_UNUSED;
b05fe5cf
ZW
9958}
9959
9960static void
c19d1205 9961do_ldrexd (void)
b05fe5cf 9962{
c19d1205
ZW
9963 constraint (inst.operands[0].reg % 2 != 0,
9964 _("even register required"));
9965 constraint (inst.operands[1].present
9966 && inst.operands[1].reg != inst.operands[0].reg + 1,
9967 _("can only load two consecutive registers"));
9968 /* If op 1 were present and equal to PC, this function wouldn't
9969 have been called in the first place. */
9970 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
b05fe5cf 9971
c19d1205
ZW
9972 inst.instruction |= inst.operands[0].reg << 12;
9973 inst.instruction |= inst.operands[2].reg << 16;
b05fe5cf
ZW
9974}
9975
1be5fd2e
NC
9976/* In both ARM and thumb state 'ldr pc, #imm' with an immediate
9977 which is not a multiple of four is UNPREDICTABLE. */
9978static void
9979check_ldr_r15_aligned (void)
9980{
9981 constraint (!(inst.operands[1].immisreg)
9982 && (inst.operands[0].reg == REG_PC
9983 && inst.operands[1].reg == REG_PC
e2b0ab59 9984 && (inst.relocs[0].exp.X_add_number & 0x3)),
de194d85 9985 _("ldr to register 15 must be 4-byte aligned"));
1be5fd2e
NC
9986}
9987
b05fe5cf 9988static void
c19d1205 9989do_ldst (void)
b05fe5cf 9990{
c19d1205
ZW
9991 inst.instruction |= inst.operands[0].reg << 12;
9992 if (!inst.operands[1].isreg)
5b7c81bd 9993 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/false))
b05fe5cf 9994 return;
5b7c81bd 9995 encode_arm_addr_mode_2 (1, /*is_t=*/false);
1be5fd2e 9996 check_ldr_r15_aligned ();
b05fe5cf
ZW
9997}
9998
9999static void
c19d1205 10000do_ldstt (void)
b05fe5cf 10001{
c19d1205
ZW
10002 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
10003 reject [Rn,...]. */
10004 if (inst.operands[1].preind)
b05fe5cf 10005 {
e2b0ab59
AV
10006 constraint (inst.relocs[0].exp.X_op != O_constant
10007 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10008 _("this instruction requires a post-indexed address"));
b05fe5cf 10009
c19d1205
ZW
10010 inst.operands[1].preind = 0;
10011 inst.operands[1].postind = 1;
10012 inst.operands[1].writeback = 1;
b05fe5cf 10013 }
c19d1205 10014 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 10015 encode_arm_addr_mode_2 (1, /*is_t=*/true);
c19d1205 10016}
b05fe5cf 10017
c19d1205 10018/* Halfword and signed-byte load/store operations. */
b05fe5cf 10019
c19d1205
ZW
10020static void
10021do_ldstv4 (void)
10022{
ff4a8d2b 10023 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205
ZW
10024 inst.instruction |= inst.operands[0].reg << 12;
10025 if (!inst.operands[1].isreg)
5b7c81bd 10026 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/true))
b05fe5cf 10027 return;
5b7c81bd 10028 encode_arm_addr_mode_3 (1, /*is_t=*/false);
b05fe5cf
ZW
10029}
10030
10031static void
c19d1205 10032do_ldsttv4 (void)
b05fe5cf 10033{
c19d1205
ZW
10034 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
10035 reject [Rn,...]. */
10036 if (inst.operands[1].preind)
b05fe5cf 10037 {
e2b0ab59
AV
10038 constraint (inst.relocs[0].exp.X_op != O_constant
10039 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10040 _("this instruction requires a post-indexed address"));
b05fe5cf 10041
c19d1205
ZW
10042 inst.operands[1].preind = 0;
10043 inst.operands[1].postind = 1;
10044 inst.operands[1].writeback = 1;
b05fe5cf 10045 }
c19d1205 10046 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 10047 encode_arm_addr_mode_3 (1, /*is_t=*/true);
c19d1205 10048}
b05fe5cf 10049
c19d1205
ZW
10050/* Co-processor register load/store.
10051 Format: <LDC|STC>{cond}[L] CP#,CRd,<address> */
10052static void
10053do_lstc (void)
10054{
10055 inst.instruction |= inst.operands[0].reg << 8;
10056 inst.instruction |= inst.operands[1].reg << 12;
5b7c81bd 10057 encode_arm_cp_address (2, true, true, 0);
b05fe5cf
ZW
10058}
10059
b05fe5cf 10060static void
c19d1205 10061do_mlas (void)
b05fe5cf 10062{
8fb9d7b9 10063 /* This restriction does not apply to mls (nor to mla in v6 or later). */
c19d1205 10064 if (inst.operands[0].reg == inst.operands[1].reg
8fb9d7b9 10065 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6)
c19d1205 10066 && !(inst.instruction & 0x00400000))
8fb9d7b9 10067 as_tsktsk (_("Rd and Rm should be different in mla"));
b05fe5cf 10068
c19d1205
ZW
10069 inst.instruction |= inst.operands[0].reg << 16;
10070 inst.instruction |= inst.operands[1].reg;
10071 inst.instruction |= inst.operands[2].reg << 8;
10072 inst.instruction |= inst.operands[3].reg << 12;
c19d1205 10073}
b05fe5cf 10074
c19d1205
ZW
10075static void
10076do_mov (void)
10077{
e2b0ab59
AV
10078 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
10079 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 10080 THUMB1_RELOC_ONLY);
c19d1205
ZW
10081 inst.instruction |= inst.operands[0].reg << 12;
10082 encode_arm_shifter_operand (1);
10083}
b05fe5cf 10084
c19d1205
ZW
10085/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
10086static void
10087do_mov16 (void)
10088{
b6895b4f 10089 bfd_vma imm;
5b7c81bd 10090 bool top;
b6895b4f
PB
10091
10092 top = (inst.instruction & 0x00400000) != 0;
e2b0ab59 10093 constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
33eaf5de 10094 _(":lower16: not allowed in this instruction"));
e2b0ab59 10095 constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
33eaf5de 10096 _(":upper16: not allowed in this instruction"));
c19d1205 10097 inst.instruction |= inst.operands[0].reg << 12;
e2b0ab59 10098 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 10099 {
e2b0ab59 10100 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
10101 /* The value is in two pieces: 0:11, 16:19. */
10102 inst.instruction |= (imm & 0x00000fff);
10103 inst.instruction |= (imm & 0x0000f000) << 4;
10104 }
b05fe5cf 10105}
b99bd4ef 10106
037e8744
JB
10107static int
10108do_vfp_nsyn_mrs (void)
10109{
10110 if (inst.operands[0].isvec)
10111 {
10112 if (inst.operands[1].reg != 1)
477330fc 10113 first_error (_("operand 1 must be FPSCR"));
037e8744
JB
10114 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
10115 memset (&inst.operands[1], '\0', sizeof (inst.operands[1]));
10116 do_vfp_nsyn_opcode ("fmstat");
10117 }
10118 else if (inst.operands[1].isvec)
10119 do_vfp_nsyn_opcode ("fmrx");
10120 else
10121 return FAIL;
5f4273c7 10122
037e8744
JB
10123 return SUCCESS;
10124}
10125
10126static int
10127do_vfp_nsyn_msr (void)
10128{
10129 if (inst.operands[0].isvec)
10130 do_vfp_nsyn_opcode ("fmxr");
10131 else
10132 return FAIL;
10133
10134 return SUCCESS;
10135}
10136
f7c21dc7
NC
10137static void
10138do_vmrs (void)
10139{
10140 unsigned Rt = inst.operands[0].reg;
fa94de6b 10141
16d02dc9 10142 if (thumb_mode && Rt == REG_SP)
f7c21dc7
NC
10143 {
10144 inst.error = BAD_SP;
10145 return;
10146 }
10147
ba6cd17f
SD
10148 switch (inst.operands[1].reg)
10149 {
10150 /* MVFR2 is only valid for Armv8-A. */
10151 case 5:
10152 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
10153 _(BAD_FPU));
10154 break;
10155
10156 /* Check for new Armv8.1-M Mainline changes to <spec_reg>. */
10157 case 1: /* fpscr. */
10158 constraint (!(ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10159 || ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10160 _(BAD_FPU));
10161 break;
10162
ee3272d4
SP
10163 case 14: /* fpcxt_ns, fpcxtns, FPCXT_NS, FPCXTNS. */
10164 case 15: /* fpcxt_s, fpcxts, FPCXT_S, FPCXTS. */
ba6cd17f
SD
10165 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main),
10166 _("selected processor does not support instruction"));
10167 break;
10168
10169 case 2: /* fpscr_nzcvqc. */
10170 case 12: /* vpr. */
10171 case 13: /* p0. */
10172 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main)
10173 || (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10174 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10175 _("selected processor does not support instruction"));
10176 if (inst.operands[0].reg != 2
10177 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
10178 as_warn (_("accessing MVE system register without MVE is UNPREDICTABLE"));
10179 break;
10180
10181 default:
10182 break;
10183 }
40c7d507 10184
f7c21dc7 10185 /* APSR_ sets isvec. All other refs to PC are illegal. */
16d02dc9 10186 if (!inst.operands[0].isvec && Rt == REG_PC)
f7c21dc7
NC
10187 {
10188 inst.error = BAD_PC;
10189 return;
10190 }
10191
16d02dc9
JB
10192 /* If we get through parsing the register name, we just insert the number
10193 generated into the instruction without further validation. */
10194 inst.instruction |= (inst.operands[1].reg << 16);
f7c21dc7
NC
10195 inst.instruction |= (Rt << 12);
10196}
10197
10198static void
10199do_vmsr (void)
10200{
10201 unsigned Rt = inst.operands[1].reg;
fa94de6b 10202
f7c21dc7
NC
10203 if (thumb_mode)
10204 reject_bad_reg (Rt);
10205 else if (Rt == REG_PC)
10206 {
10207 inst.error = BAD_PC;
10208 return;
10209 }
10210
ba6cd17f
SD
10211 switch (inst.operands[0].reg)
10212 {
10213 /* MVFR2 is only valid for Armv8-A. */
10214 case 5:
10215 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
10216 _(BAD_FPU));
10217 break;
10218
10219 /* Check for new Armv8.1-M Mainline changes to <spec_reg>. */
10220 case 1: /* fpcr. */
10221 constraint (!(ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10222 || ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10223 _(BAD_FPU));
10224 break;
10225
10226 case 14: /* fpcxt_ns. */
10227 case 15: /* fpcxt_s. */
10228 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main),
10229 _("selected processor does not support instruction"));
10230 break;
10231
10232 case 2: /* fpscr_nzcvqc. */
10233 case 12: /* vpr. */
10234 case 13: /* p0. */
10235 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main)
10236 || (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10237 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10238 _("selected processor does not support instruction"));
10239 if (inst.operands[0].reg != 2
10240 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
10241 as_warn (_("accessing MVE system register without MVE is UNPREDICTABLE"));
10242 break;
10243
10244 default:
10245 break;
10246 }
40c7d507 10247
16d02dc9
JB
10248 /* If we get through parsing the register name, we just insert the number
10249 generated into the instruction without further validation. */
10250 inst.instruction |= (inst.operands[0].reg << 16);
f7c21dc7
NC
10251 inst.instruction |= (Rt << 12);
10252}
10253
b99bd4ef 10254static void
c19d1205 10255do_mrs (void)
b99bd4ef 10256{
90ec0d68
MGD
10257 unsigned br;
10258
037e8744
JB
10259 if (do_vfp_nsyn_mrs () == SUCCESS)
10260 return;
10261
ff4a8d2b 10262 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205 10263 inst.instruction |= inst.operands[0].reg << 12;
90ec0d68
MGD
10264
10265 if (inst.operands[1].isreg)
10266 {
10267 br = inst.operands[1].reg;
806ab1c0 10268 if (((br & 0x200) == 0) && ((br & 0xf0000) != 0xf0000))
90ec0d68
MGD
10269 as_bad (_("bad register for mrs"));
10270 }
10271 else
10272 {
10273 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
10274 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
10275 != (PSR_c|PSR_f),
d2cd1205 10276 _("'APSR', 'CPSR' or 'SPSR' expected"));
90ec0d68
MGD
10277 br = (15<<16) | (inst.operands[1].imm & SPSR_BIT);
10278 }
10279
10280 inst.instruction |= br;
c19d1205 10281}
b99bd4ef 10282
c19d1205
ZW
10283/* Two possible forms:
10284 "{C|S}PSR_<field>, Rm",
10285 "{C|S}PSR_f, #expression". */
b99bd4ef 10286
c19d1205
ZW
10287static void
10288do_msr (void)
10289{
037e8744
JB
10290 if (do_vfp_nsyn_msr () == SUCCESS)
10291 return;
10292
c19d1205
ZW
10293 inst.instruction |= inst.operands[0].imm;
10294 if (inst.operands[1].isreg)
10295 inst.instruction |= inst.operands[1].reg;
10296 else
b99bd4ef 10297 {
c19d1205 10298 inst.instruction |= INST_IMMEDIATE;
e2b0ab59
AV
10299 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
10300 inst.relocs[0].pc_rel = 0;
b99bd4ef 10301 }
b99bd4ef
NC
10302}
10303
c19d1205
ZW
10304static void
10305do_mul (void)
a737bd4d 10306{
ff4a8d2b
NC
10307 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
10308
c19d1205
ZW
10309 if (!inst.operands[2].present)
10310 inst.operands[2].reg = inst.operands[0].reg;
10311 inst.instruction |= inst.operands[0].reg << 16;
10312 inst.instruction |= inst.operands[1].reg;
10313 inst.instruction |= inst.operands[2].reg << 8;
a737bd4d 10314
8fb9d7b9
MS
10315 if (inst.operands[0].reg == inst.operands[1].reg
10316 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
10317 as_tsktsk (_("Rd and Rm should be different in mul"));
a737bd4d
NC
10318}
10319
c19d1205
ZW
10320/* Long Multiply Parser
10321 UMULL RdLo, RdHi, Rm, Rs
10322 SMULL RdLo, RdHi, Rm, Rs
10323 UMLAL RdLo, RdHi, Rm, Rs
10324 SMLAL RdLo, RdHi, Rm, Rs. */
b99bd4ef
NC
10325
10326static void
c19d1205 10327do_mull (void)
b99bd4ef 10328{
c19d1205
ZW
10329 inst.instruction |= inst.operands[0].reg << 12;
10330 inst.instruction |= inst.operands[1].reg << 16;
10331 inst.instruction |= inst.operands[2].reg;
10332 inst.instruction |= inst.operands[3].reg << 8;
b99bd4ef 10333
682b27ad
PB
10334 /* rdhi and rdlo must be different. */
10335 if (inst.operands[0].reg == inst.operands[1].reg)
10336 as_tsktsk (_("rdhi and rdlo must be different"));
10337
10338 /* rdhi, rdlo and rm must all be different before armv6. */
10339 if ((inst.operands[0].reg == inst.operands[2].reg
c19d1205 10340 || inst.operands[1].reg == inst.operands[2].reg)
682b27ad 10341 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
c19d1205
ZW
10342 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
10343}
b99bd4ef 10344
c19d1205
ZW
10345static void
10346do_nop (void)
10347{
e7495e45
NS
10348 if (inst.operands[0].present
10349 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k))
c19d1205
ZW
10350 {
10351 /* Architectural NOP hints are CPSR sets with no bits selected. */
10352 inst.instruction &= 0xf0000000;
e7495e45
NS
10353 inst.instruction |= 0x0320f000;
10354 if (inst.operands[0].present)
10355 inst.instruction |= inst.operands[0].imm;
c19d1205 10356 }
b99bd4ef
NC
10357}
10358
c19d1205
ZW
10359/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
10360 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
10361 Condition defaults to COND_ALWAYS.
10362 Error if Rd, Rn or Rm are R15. */
b99bd4ef
NC
10363
10364static void
c19d1205 10365do_pkhbt (void)
b99bd4ef 10366{
c19d1205
ZW
10367 inst.instruction |= inst.operands[0].reg << 12;
10368 inst.instruction |= inst.operands[1].reg << 16;
10369 inst.instruction |= inst.operands[2].reg;
10370 if (inst.operands[3].present)
10371 encode_arm_shift (3);
10372}
b99bd4ef 10373
c19d1205 10374/* ARM V6 PKHTB (Argument Parse). */
b99bd4ef 10375
c19d1205
ZW
10376static void
10377do_pkhtb (void)
10378{
10379 if (!inst.operands[3].present)
b99bd4ef 10380 {
c19d1205
ZW
10381 /* If the shift specifier is omitted, turn the instruction
10382 into pkhbt rd, rm, rn. */
10383 inst.instruction &= 0xfff00010;
10384 inst.instruction |= inst.operands[0].reg << 12;
10385 inst.instruction |= inst.operands[1].reg;
10386 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
10387 }
10388 else
10389 {
c19d1205
ZW
10390 inst.instruction |= inst.operands[0].reg << 12;
10391 inst.instruction |= inst.operands[1].reg << 16;
10392 inst.instruction |= inst.operands[2].reg;
10393 encode_arm_shift (3);
b99bd4ef
NC
10394 }
10395}
10396
c19d1205 10397/* ARMv5TE: Preload-Cache
60e5ef9f 10398 MP Extensions: Preload for write
c19d1205 10399
60e5ef9f 10400 PLD(W) <addr_mode>
c19d1205
ZW
10401
10402 Syntactically, like LDR with B=1, W=0, L=1. */
b99bd4ef
NC
10403
10404static void
c19d1205 10405do_pld (void)
b99bd4ef 10406{
c19d1205
ZW
10407 constraint (!inst.operands[0].isreg,
10408 _("'[' expected after PLD mnemonic"));
10409 constraint (inst.operands[0].postind,
10410 _("post-indexed expression used in preload instruction"));
10411 constraint (inst.operands[0].writeback,
10412 _("writeback used in preload instruction"));
10413 constraint (!inst.operands[0].preind,
10414 _("unindexed addressing used in preload instruction"));
5b7c81bd 10415 encode_arm_addr_mode_2 (0, /*is_t=*/false);
c19d1205 10416}
b99bd4ef 10417
62b3e311
PB
10418/* ARMv7: PLI <addr_mode> */
10419static void
10420do_pli (void)
10421{
10422 constraint (!inst.operands[0].isreg,
10423 _("'[' expected after PLI mnemonic"));
10424 constraint (inst.operands[0].postind,
10425 _("post-indexed expression used in preload instruction"));
10426 constraint (inst.operands[0].writeback,
10427 _("writeback used in preload instruction"));
10428 constraint (!inst.operands[0].preind,
10429 _("unindexed addressing used in preload instruction"));
5b7c81bd 10430 encode_arm_addr_mode_2 (0, /*is_t=*/false);
62b3e311
PB
10431 inst.instruction &= ~PRE_INDEX;
10432}
10433
c19d1205
ZW
10434static void
10435do_push_pop (void)
10436{
5e0d7f77
MP
10437 constraint (inst.operands[0].writeback,
10438 _("push/pop do not support {reglist}^"));
c19d1205
ZW
10439 inst.operands[1] = inst.operands[0];
10440 memset (&inst.operands[0], 0, sizeof inst.operands[0]);
10441 inst.operands[0].isreg = 1;
10442 inst.operands[0].writeback = 1;
10443 inst.operands[0].reg = REG_SP;
5b7c81bd 10444 encode_ldmstm (/*from_push_pop_mnem=*/true);
c19d1205 10445}
b99bd4ef 10446
c19d1205
ZW
10447/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
10448 word at the specified address and the following word
10449 respectively.
10450 Unconditionally executed.
10451 Error if Rn is R15. */
b99bd4ef 10452
c19d1205
ZW
10453static void
10454do_rfe (void)
10455{
10456 inst.instruction |= inst.operands[0].reg << 16;
10457 if (inst.operands[0].writeback)
10458 inst.instruction |= WRITE_BACK;
10459}
b99bd4ef 10460
c19d1205 10461/* ARM V6 ssat (argument parse). */
b99bd4ef 10462
c19d1205
ZW
10463static void
10464do_ssat (void)
10465{
10466 inst.instruction |= inst.operands[0].reg << 12;
10467 inst.instruction |= (inst.operands[1].imm - 1) << 16;
10468 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10469
c19d1205
ZW
10470 if (inst.operands[3].present)
10471 encode_arm_shift (3);
b99bd4ef
NC
10472}
10473
c19d1205 10474/* ARM V6 usat (argument parse). */
b99bd4ef
NC
10475
10476static void
c19d1205 10477do_usat (void)
b99bd4ef 10478{
c19d1205
ZW
10479 inst.instruction |= inst.operands[0].reg << 12;
10480 inst.instruction |= inst.operands[1].imm << 16;
10481 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10482
c19d1205
ZW
10483 if (inst.operands[3].present)
10484 encode_arm_shift (3);
b99bd4ef
NC
10485}
10486
c19d1205 10487/* ARM V6 ssat16 (argument parse). */
09d92015
MM
10488
10489static void
c19d1205 10490do_ssat16 (void)
09d92015 10491{
c19d1205
ZW
10492 inst.instruction |= inst.operands[0].reg << 12;
10493 inst.instruction |= ((inst.operands[1].imm - 1) << 16);
10494 inst.instruction |= inst.operands[2].reg;
09d92015
MM
10495}
10496
c19d1205
ZW
10497static void
10498do_usat16 (void)
a737bd4d 10499{
c19d1205
ZW
10500 inst.instruction |= inst.operands[0].reg << 12;
10501 inst.instruction |= inst.operands[1].imm << 16;
10502 inst.instruction |= inst.operands[2].reg;
10503}
a737bd4d 10504
c19d1205
ZW
10505/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
10506 preserving the other bits.
a737bd4d 10507
c19d1205
ZW
10508 setend <endian_specifier>, where <endian_specifier> is either
10509 BE or LE. */
a737bd4d 10510
c19d1205
ZW
10511static void
10512do_setend (void)
10513{
12e37cbc
MGD
10514 if (warn_on_deprecated
10515 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 10516 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 10517
c19d1205
ZW
10518 if (inst.operands[0].imm)
10519 inst.instruction |= 0x200;
a737bd4d
NC
10520}
10521
10522static void
c19d1205 10523do_shift (void)
a737bd4d 10524{
c19d1205
ZW
10525 unsigned int Rm = (inst.operands[1].present
10526 ? inst.operands[1].reg
10527 : inst.operands[0].reg);
a737bd4d 10528
c19d1205
ZW
10529 inst.instruction |= inst.operands[0].reg << 12;
10530 inst.instruction |= Rm;
10531 if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
a737bd4d 10532 {
c19d1205
ZW
10533 inst.instruction |= inst.operands[2].reg << 8;
10534 inst.instruction |= SHIFT_BY_REG;
94342ec3
NC
10535 /* PR 12854: Error on extraneous shifts. */
10536 constraint (inst.operands[2].shifted,
10537 _("extraneous shift as part of operand to shift insn"));
a737bd4d
NC
10538 }
10539 else
e2b0ab59 10540 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
a737bd4d
NC
10541}
10542
09d92015 10543static void
3eb17e6b 10544do_smc (void)
09d92015 10545{
ba85f98c
BW
10546 unsigned int value = inst.relocs[0].exp.X_add_number;
10547 constraint (value > 0xf, _("immediate too large (bigger than 0xF)"));
10548
e2b0ab59
AV
10549 inst.relocs[0].type = BFD_RELOC_ARM_SMC;
10550 inst.relocs[0].pc_rel = 0;
09d92015
MM
10551}
10552
90ec0d68
MGD
10553static void
10554do_hvc (void)
10555{
e2b0ab59
AV
10556 inst.relocs[0].type = BFD_RELOC_ARM_HVC;
10557 inst.relocs[0].pc_rel = 0;
90ec0d68
MGD
10558}
10559
09d92015 10560static void
c19d1205 10561do_swi (void)
09d92015 10562{
e2b0ab59
AV
10563 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
10564 inst.relocs[0].pc_rel = 0;
09d92015
MM
10565}
10566
ddfded2f
MW
10567static void
10568do_setpan (void)
10569{
10570 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10571 _("selected processor does not support SETPAN instruction"));
10572
10573 inst.instruction |= ((inst.operands[0].imm & 1) << 9);
10574}
10575
10576static void
10577do_t_setpan (void)
10578{
10579 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10580 _("selected processor does not support SETPAN instruction"));
10581
10582 inst.instruction |= (inst.operands[0].imm << 3);
10583}
10584
c19d1205
ZW
10585/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
10586 SMLAxy{cond} Rd,Rm,Rs,Rn
10587 SMLAWy{cond} Rd,Rm,Rs,Rn
10588 Error if any register is R15. */
e16bb312 10589
c19d1205
ZW
10590static void
10591do_smla (void)
e16bb312 10592{
c19d1205
ZW
10593 inst.instruction |= inst.operands[0].reg << 16;
10594 inst.instruction |= inst.operands[1].reg;
10595 inst.instruction |= inst.operands[2].reg << 8;
10596 inst.instruction |= inst.operands[3].reg << 12;
10597}
a737bd4d 10598
c19d1205
ZW
10599/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
10600 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
10601 Error if any register is R15.
10602 Warning if Rdlo == Rdhi. */
a737bd4d 10603
c19d1205
ZW
10604static void
10605do_smlal (void)
10606{
10607 inst.instruction |= inst.operands[0].reg << 12;
10608 inst.instruction |= inst.operands[1].reg << 16;
10609 inst.instruction |= inst.operands[2].reg;
10610 inst.instruction |= inst.operands[3].reg << 8;
a737bd4d 10611
c19d1205
ZW
10612 if (inst.operands[0].reg == inst.operands[1].reg)
10613 as_tsktsk (_("rdhi and rdlo must be different"));
10614}
a737bd4d 10615
c19d1205
ZW
10616/* ARM V5E (El Segundo) signed-multiply (argument parse)
10617 SMULxy{cond} Rd,Rm,Rs
10618 Error if any register is R15. */
a737bd4d 10619
c19d1205
ZW
10620static void
10621do_smul (void)
10622{
10623 inst.instruction |= inst.operands[0].reg << 16;
10624 inst.instruction |= inst.operands[1].reg;
10625 inst.instruction |= inst.operands[2].reg << 8;
10626}
a737bd4d 10627
b6702015
PB
10628/* ARM V6 srs (argument parse). The variable fields in the encoding are
10629 the same for both ARM and Thumb-2. */
a737bd4d 10630
c19d1205
ZW
10631static void
10632do_srs (void)
10633{
b6702015
PB
10634 int reg;
10635
10636 if (inst.operands[0].present)
10637 {
10638 reg = inst.operands[0].reg;
fdfde340 10639 constraint (reg != REG_SP, _("SRS base register must be r13"));
b6702015
PB
10640 }
10641 else
fdfde340 10642 reg = REG_SP;
b6702015
PB
10643
10644 inst.instruction |= reg << 16;
10645 inst.instruction |= inst.operands[1].imm;
10646 if (inst.operands[0].writeback || inst.operands[1].writeback)
c19d1205
ZW
10647 inst.instruction |= WRITE_BACK;
10648}
a737bd4d 10649
c19d1205 10650/* ARM V6 strex (argument parse). */
a737bd4d 10651
c19d1205
ZW
10652static void
10653do_strex (void)
10654{
10655 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10656 || inst.operands[2].postind || inst.operands[2].writeback
10657 || inst.operands[2].immisreg || inst.operands[2].shifted
01cfc07f
NC
10658 || inst.operands[2].negative
10659 /* See comment in do_ldrex(). */
10660 || (inst.operands[2].reg == REG_PC),
10661 BAD_ADDR_MODE);
a737bd4d 10662
c19d1205
ZW
10663 constraint (inst.operands[0].reg == inst.operands[1].reg
10664 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
a737bd4d 10665
e2b0ab59
AV
10666 constraint (inst.relocs[0].exp.X_op != O_constant
10667 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10668 _("offset must be zero in ARM encoding"));
a737bd4d 10669
c19d1205
ZW
10670 inst.instruction |= inst.operands[0].reg << 12;
10671 inst.instruction |= inst.operands[1].reg;
10672 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 10673 inst.relocs[0].type = BFD_RELOC_UNUSED;
e16bb312
NC
10674}
10675
877807f8
NC
10676static void
10677do_t_strexbh (void)
10678{
10679 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10680 || inst.operands[2].postind || inst.operands[2].writeback
10681 || inst.operands[2].immisreg || inst.operands[2].shifted
10682 || inst.operands[2].negative,
10683 BAD_ADDR_MODE);
10684
10685 constraint (inst.operands[0].reg == inst.operands[1].reg
10686 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10687
10688 do_rm_rd_rn ();
10689}
10690
e16bb312 10691static void
c19d1205 10692do_strexd (void)
e16bb312 10693{
c19d1205
ZW
10694 constraint (inst.operands[1].reg % 2 != 0,
10695 _("even register required"));
10696 constraint (inst.operands[2].present
10697 && inst.operands[2].reg != inst.operands[1].reg + 1,
10698 _("can only store two consecutive registers"));
10699 /* If op 2 were present and equal to PC, this function wouldn't
10700 have been called in the first place. */
10701 constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
e16bb312 10702
c19d1205
ZW
10703 constraint (inst.operands[0].reg == inst.operands[1].reg
10704 || inst.operands[0].reg == inst.operands[1].reg + 1
10705 || inst.operands[0].reg == inst.operands[3].reg,
10706 BAD_OVERLAP);
e16bb312 10707
c19d1205
ZW
10708 inst.instruction |= inst.operands[0].reg << 12;
10709 inst.instruction |= inst.operands[1].reg;
10710 inst.instruction |= inst.operands[3].reg << 16;
e16bb312
NC
10711}
10712
9eb6c0f1
MGD
10713/* ARM V8 STRL. */
10714static void
4b8c8c02 10715do_stlex (void)
9eb6c0f1
MGD
10716{
10717 constraint (inst.operands[0].reg == inst.operands[1].reg
10718 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10719
10720 do_rd_rm_rn ();
10721}
10722
10723static void
4b8c8c02 10724do_t_stlex (void)
9eb6c0f1
MGD
10725{
10726 constraint (inst.operands[0].reg == inst.operands[1].reg
10727 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10728
10729 do_rm_rd_rn ();
10730}
10731
c19d1205
ZW
10732/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
10733 extends it to 32-bits, and adds the result to a value in another
10734 register. You can specify a rotation by 0, 8, 16, or 24 bits
10735 before extracting the 16-bit value.
10736 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
10737 Condition defaults to COND_ALWAYS.
10738 Error if any register uses R15. */
10739
e16bb312 10740static void
c19d1205 10741do_sxtah (void)
e16bb312 10742{
c19d1205
ZW
10743 inst.instruction |= inst.operands[0].reg << 12;
10744 inst.instruction |= inst.operands[1].reg << 16;
10745 inst.instruction |= inst.operands[2].reg;
10746 inst.instruction |= inst.operands[3].imm << 10;
10747}
e16bb312 10748
c19d1205 10749/* ARM V6 SXTH.
e16bb312 10750
c19d1205
ZW
10751 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
10752 Condition defaults to COND_ALWAYS.
10753 Error if any register uses R15. */
e16bb312
NC
10754
10755static void
c19d1205 10756do_sxth (void)
e16bb312 10757{
c19d1205
ZW
10758 inst.instruction |= inst.operands[0].reg << 12;
10759 inst.instruction |= inst.operands[1].reg;
10760 inst.instruction |= inst.operands[2].imm << 10;
e16bb312 10761}
c19d1205
ZW
10762\f
10763/* VFP instructions. In a logical order: SP variant first, monad
10764 before dyad, arithmetic then move then load/store. */
e16bb312
NC
10765
10766static void
c19d1205 10767do_vfp_sp_monadic (void)
e16bb312 10768{
57785aa2
AV
10769 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10770 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10771 _(BAD_FPU));
10772
5287ad62
JB
10773 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10774 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10775}
10776
10777static void
c19d1205 10778do_vfp_sp_dyadic (void)
e16bb312 10779{
5287ad62
JB
10780 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10781 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
10782 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10783}
10784
10785static void
c19d1205 10786do_vfp_sp_compare_z (void)
e16bb312 10787{
5287ad62 10788 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
e16bb312
NC
10789}
10790
10791static void
c19d1205 10792do_vfp_dp_sp_cvt (void)
e16bb312 10793{
5287ad62
JB
10794 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10795 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10796}
10797
10798static void
c19d1205 10799do_vfp_sp_dp_cvt (void)
e16bb312 10800{
5287ad62
JB
10801 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10802 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
e16bb312
NC
10803}
10804
10805static void
c19d1205 10806do_vfp_reg_from_sp (void)
e16bb312 10807{
57785aa2
AV
10808 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10809 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10810 _(BAD_FPU));
10811
c19d1205 10812 inst.instruction |= inst.operands[0].reg << 12;
5287ad62 10813 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
e16bb312
NC
10814}
10815
10816static void
c19d1205 10817do_vfp_reg2_from_sp2 (void)
e16bb312 10818{
c19d1205
ZW
10819 constraint (inst.operands[2].imm != 2,
10820 _("only two consecutive VFP SP registers allowed here"));
10821 inst.instruction |= inst.operands[0].reg << 12;
10822 inst.instruction |= inst.operands[1].reg << 16;
5287ad62 10823 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10824}
10825
10826static void
c19d1205 10827do_vfp_sp_from_reg (void)
e16bb312 10828{
57785aa2
AV
10829 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10830 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10831 _(BAD_FPU));
10832
5287ad62 10833 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sn);
c19d1205 10834 inst.instruction |= inst.operands[1].reg << 12;
e16bb312
NC
10835}
10836
10837static void
c19d1205 10838do_vfp_sp2_from_reg2 (void)
e16bb312 10839{
c19d1205
ZW
10840 constraint (inst.operands[0].imm != 2,
10841 _("only two consecutive VFP SP registers allowed here"));
5287ad62 10842 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sm);
c19d1205
ZW
10843 inst.instruction |= inst.operands[1].reg << 12;
10844 inst.instruction |= inst.operands[2].reg << 16;
e16bb312
NC
10845}
10846
10847static void
c19d1205 10848do_vfp_sp_ldst (void)
e16bb312 10849{
5287ad62 10850 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
5b7c81bd 10851 encode_arm_cp_address (1, false, true, 0);
e16bb312
NC
10852}
10853
10854static void
c19d1205 10855do_vfp_dp_ldst (void)
e16bb312 10856{
5287ad62 10857 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
5b7c81bd 10858 encode_arm_cp_address (1, false, true, 0);
e16bb312
NC
10859}
10860
c19d1205 10861
e16bb312 10862static void
c19d1205 10863vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10864{
c19d1205
ZW
10865 if (inst.operands[0].writeback)
10866 inst.instruction |= WRITE_BACK;
10867 else
10868 constraint (ldstm_type != VFP_LDSTMIA,
10869 _("this addressing mode requires base-register writeback"));
10870 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10871 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sd);
c19d1205 10872 inst.instruction |= inst.operands[1].imm;
e16bb312
NC
10873}
10874
10875static void
c19d1205 10876vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10877{
c19d1205 10878 int count;
e16bb312 10879
c19d1205
ZW
10880 if (inst.operands[0].writeback)
10881 inst.instruction |= WRITE_BACK;
10882 else
10883 constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
10884 _("this addressing mode requires base-register writeback"));
e16bb312 10885
c19d1205 10886 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10887 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
e16bb312 10888
c19d1205
ZW
10889 count = inst.operands[1].imm << 1;
10890 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
10891 count += 1;
e16bb312 10892
c19d1205 10893 inst.instruction |= count;
e16bb312
NC
10894}
10895
10896static void
c19d1205 10897do_vfp_sp_ldstmia (void)
e16bb312 10898{
c19d1205 10899 vfp_sp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10900}
10901
10902static void
c19d1205 10903do_vfp_sp_ldstmdb (void)
e16bb312 10904{
c19d1205 10905 vfp_sp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10906}
10907
10908static void
c19d1205 10909do_vfp_dp_ldstmia (void)
e16bb312 10910{
c19d1205 10911 vfp_dp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10912}
10913
10914static void
c19d1205 10915do_vfp_dp_ldstmdb (void)
e16bb312 10916{
c19d1205 10917 vfp_dp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10918}
10919
10920static void
c19d1205 10921do_vfp_xp_ldstmia (void)
e16bb312 10922{
c19d1205
ZW
10923 vfp_dp_ldstm (VFP_LDSTMIAX);
10924}
e16bb312 10925
c19d1205
ZW
10926static void
10927do_vfp_xp_ldstmdb (void)
10928{
10929 vfp_dp_ldstm (VFP_LDSTMDBX);
e16bb312 10930}
5287ad62
JB
10931
10932static void
10933do_vfp_dp_rd_rm (void)
10934{
57785aa2
AV
10935 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
10936 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10937 _(BAD_FPU));
10938
5287ad62
JB
10939 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10940 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
10941}
10942
10943static void
10944do_vfp_dp_rn_rd (void)
10945{
10946 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dn);
10947 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10948}
10949
10950static void
10951do_vfp_dp_rd_rn (void)
10952{
10953 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10954 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10955}
10956
10957static void
10958do_vfp_dp_rd_rn_rm (void)
10959{
57785aa2
AV
10960 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10961 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10962 _(BAD_FPU));
10963
5287ad62
JB
10964 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10965 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10966 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dm);
10967}
10968
10969static void
10970do_vfp_dp_rd (void)
10971{
10972 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10973}
10974
10975static void
10976do_vfp_dp_rm_rd_rn (void)
10977{
57785aa2
AV
10978 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10979 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10980 _(BAD_FPU));
10981
5287ad62
JB
10982 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dm);
10983 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10984 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dn);
10985}
10986
10987/* VFPv3 instructions. */
10988static void
10989do_vfp_sp_const (void)
10990{
10991 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
00249aaa
PB
10992 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10993 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10994}
10995
10996static void
10997do_vfp_dp_const (void)
10998{
10999 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
00249aaa
PB
11000 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
11001 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
11002}
11003
11004static void
11005vfp_conv (int srcsize)
11006{
5f1af56b
MGD
11007 int immbits = srcsize - inst.operands[1].imm;
11008
fa94de6b
RM
11009 if (srcsize == 16 && !(immbits >= 0 && immbits <= srcsize))
11010 {
5f1af56b 11011 /* If srcsize is 16, inst.operands[1].imm must be in the range 0-16.
477330fc 11012 i.e. immbits must be in range 0 - 16. */
5f1af56b
MGD
11013 inst.error = _("immediate value out of range, expected range [0, 16]");
11014 return;
11015 }
fa94de6b 11016 else if (srcsize == 32 && !(immbits >= 0 && immbits < srcsize))
5f1af56b
MGD
11017 {
11018 /* If srcsize is 32, inst.operands[1].imm must be in the range 1-32.
477330fc 11019 i.e. immbits must be in range 0 - 31. */
5f1af56b
MGD
11020 inst.error = _("immediate value out of range, expected range [1, 32]");
11021 return;
11022 }
11023
5287ad62
JB
11024 inst.instruction |= (immbits & 1) << 5;
11025 inst.instruction |= (immbits >> 1);
11026}
11027
11028static void
11029do_vfp_sp_conv_16 (void)
11030{
11031 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
11032 vfp_conv (16);
11033}
11034
11035static void
11036do_vfp_dp_conv_16 (void)
11037{
11038 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
11039 vfp_conv (16);
11040}
11041
11042static void
11043do_vfp_sp_conv_32 (void)
11044{
11045 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
11046 vfp_conv (32);
11047}
11048
11049static void
11050do_vfp_dp_conv_32 (void)
11051{
11052 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
11053 vfp_conv (32);
11054}
c19d1205
ZW
11055\f
11056/* FPA instructions. Also in a logical order. */
e16bb312 11057
c19d1205
ZW
11058static void
11059do_fpa_cmp (void)
11060{
11061 inst.instruction |= inst.operands[0].reg << 16;
11062 inst.instruction |= inst.operands[1].reg;
11063}
b99bd4ef
NC
11064
11065static void
c19d1205 11066do_fpa_ldmstm (void)
b99bd4ef 11067{
c19d1205
ZW
11068 inst.instruction |= inst.operands[0].reg << 12;
11069 switch (inst.operands[1].imm)
11070 {
11071 case 1: inst.instruction |= CP_T_X; break;
11072 case 2: inst.instruction |= CP_T_Y; break;
11073 case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
11074 case 4: break;
11075 default: abort ();
11076 }
b99bd4ef 11077
c19d1205
ZW
11078 if (inst.instruction & (PRE_INDEX | INDEX_UP))
11079 {
11080 /* The instruction specified "ea" or "fd", so we can only accept
11081 [Rn]{!}. The instruction does not really support stacking or
11082 unstacking, so we have to emulate these by setting appropriate
11083 bits and offsets. */
e2b0ab59
AV
11084 constraint (inst.relocs[0].exp.X_op != O_constant
11085 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 11086 _("this instruction does not support indexing"));
b99bd4ef 11087
c19d1205 11088 if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
e2b0ab59 11089 inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
b99bd4ef 11090
c19d1205 11091 if (!(inst.instruction & INDEX_UP))
e2b0ab59 11092 inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
b99bd4ef 11093
c19d1205
ZW
11094 if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
11095 {
11096 inst.operands[2].preind = 0;
11097 inst.operands[2].postind = 1;
11098 }
11099 }
b99bd4ef 11100
5b7c81bd 11101 encode_arm_cp_address (2, true, true, 0);
b99bd4ef 11102}
c19d1205
ZW
11103\f
11104/* iWMMXt instructions: strictly in alphabetical order. */
b99bd4ef 11105
c19d1205
ZW
11106static void
11107do_iwmmxt_tandorc (void)
11108{
11109 constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
11110}
b99bd4ef 11111
c19d1205
ZW
11112static void
11113do_iwmmxt_textrc (void)
11114{
11115 inst.instruction |= inst.operands[0].reg << 12;
11116 inst.instruction |= inst.operands[1].imm;
11117}
b99bd4ef
NC
11118
11119static void
c19d1205 11120do_iwmmxt_textrm (void)
b99bd4ef 11121{
c19d1205
ZW
11122 inst.instruction |= inst.operands[0].reg << 12;
11123 inst.instruction |= inst.operands[1].reg << 16;
11124 inst.instruction |= inst.operands[2].imm;
11125}
b99bd4ef 11126
c19d1205
ZW
11127static void
11128do_iwmmxt_tinsr (void)
11129{
11130 inst.instruction |= inst.operands[0].reg << 16;
11131 inst.instruction |= inst.operands[1].reg << 12;
11132 inst.instruction |= inst.operands[2].imm;
11133}
b99bd4ef 11134
c19d1205
ZW
11135static void
11136do_iwmmxt_tmia (void)
11137{
11138 inst.instruction |= inst.operands[0].reg << 5;
11139 inst.instruction |= inst.operands[1].reg;
11140 inst.instruction |= inst.operands[2].reg << 12;
11141}
b99bd4ef 11142
c19d1205
ZW
11143static void
11144do_iwmmxt_waligni (void)
11145{
11146 inst.instruction |= inst.operands[0].reg << 12;
11147 inst.instruction |= inst.operands[1].reg << 16;
11148 inst.instruction |= inst.operands[2].reg;
11149 inst.instruction |= inst.operands[3].imm << 20;
11150}
b99bd4ef 11151
2d447fca
JM
11152static void
11153do_iwmmxt_wmerge (void)
11154{
11155 inst.instruction |= inst.operands[0].reg << 12;
11156 inst.instruction |= inst.operands[1].reg << 16;
11157 inst.instruction |= inst.operands[2].reg;
11158 inst.instruction |= inst.operands[3].imm << 21;
11159}
11160
c19d1205
ZW
11161static void
11162do_iwmmxt_wmov (void)
11163{
11164 /* WMOV rD, rN is an alias for WOR rD, rN, rN. */
11165 inst.instruction |= inst.operands[0].reg << 12;
11166 inst.instruction |= inst.operands[1].reg << 16;
11167 inst.instruction |= inst.operands[1].reg;
11168}
b99bd4ef 11169
c19d1205
ZW
11170static void
11171do_iwmmxt_wldstbh (void)
11172{
8f06b2d8 11173 int reloc;
c19d1205 11174 inst.instruction |= inst.operands[0].reg << 12;
8f06b2d8
PB
11175 if (thumb_mode)
11176 reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
11177 else
11178 reloc = BFD_RELOC_ARM_CP_OFF_IMM_S2;
5b7c81bd 11179 encode_arm_cp_address (1, true, false, reloc);
b99bd4ef
NC
11180}
11181
c19d1205
ZW
11182static void
11183do_iwmmxt_wldstw (void)
11184{
11185 /* RIWR_RIWC clears .isreg for a control register. */
11186 if (!inst.operands[0].isreg)
11187 {
11188 constraint (inst.cond != COND_ALWAYS, BAD_COND);
11189 inst.instruction |= 0xf0000000;
11190 }
b99bd4ef 11191
c19d1205 11192 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 11193 encode_arm_cp_address (1, true, true, 0);
c19d1205 11194}
b99bd4ef
NC
11195
11196static void
c19d1205 11197do_iwmmxt_wldstd (void)
b99bd4ef 11198{
c19d1205 11199 inst.instruction |= inst.operands[0].reg << 12;
2d447fca
JM
11200 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)
11201 && inst.operands[1].immisreg)
11202 {
11203 inst.instruction &= ~0x1a000ff;
eff0bc54 11204 inst.instruction |= (0xfU << 28);
2d447fca
JM
11205 if (inst.operands[1].preind)
11206 inst.instruction |= PRE_INDEX;
11207 if (!inst.operands[1].negative)
11208 inst.instruction |= INDEX_UP;
11209 if (inst.operands[1].writeback)
11210 inst.instruction |= WRITE_BACK;
11211 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 11212 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
2d447fca
JM
11213 inst.instruction |= inst.operands[1].imm;
11214 }
11215 else
5b7c81bd 11216 encode_arm_cp_address (1, true, false, 0);
c19d1205 11217}
b99bd4ef 11218
c19d1205
ZW
11219static void
11220do_iwmmxt_wshufh (void)
11221{
11222 inst.instruction |= inst.operands[0].reg << 12;
11223 inst.instruction |= inst.operands[1].reg << 16;
11224 inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
11225 inst.instruction |= (inst.operands[2].imm & 0x0f);
11226}
b99bd4ef 11227
c19d1205
ZW
11228static void
11229do_iwmmxt_wzero (void)
11230{
11231 /* WZERO reg is an alias for WANDN reg, reg, reg. */
11232 inst.instruction |= inst.operands[0].reg;
11233 inst.instruction |= inst.operands[0].reg << 12;
11234 inst.instruction |= inst.operands[0].reg << 16;
11235}
2d447fca
JM
11236
11237static void
11238do_iwmmxt_wrwrwr_or_imm5 (void)
11239{
11240 if (inst.operands[2].isreg)
11241 do_rd_rn_rm ();
11242 else {
11243 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2),
11244 _("immediate operand requires iWMMXt2"));
11245 do_rd_rn ();
11246 if (inst.operands[2].imm == 0)
11247 {
11248 switch ((inst.instruction >> 20) & 0xf)
11249 {
11250 case 4:
11251 case 5:
11252 case 6:
5f4273c7 11253 case 7:
2d447fca
JM
11254 /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16. */
11255 inst.operands[2].imm = 16;
11256 inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
11257 break;
11258 case 8:
11259 case 9:
11260 case 10:
11261 case 11:
11262 /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32. */
11263 inst.operands[2].imm = 32;
11264 inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
11265 break;
11266 case 12:
11267 case 13:
11268 case 14:
11269 case 15:
11270 {
11271 /* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn. */
11272 unsigned long wrn;
11273 wrn = (inst.instruction >> 16) & 0xf;
11274 inst.instruction &= 0xff0fff0f;
11275 inst.instruction |= wrn;
11276 /* Bail out here; the instruction is now assembled. */
11277 return;
11278 }
11279 }
11280 }
11281 /* Map 32 -> 0, etc. */
11282 inst.operands[2].imm &= 0x1f;
eff0bc54 11283 inst.instruction |= (0xfU << 28) | ((inst.operands[2].imm & 0x10) << 4) | (inst.operands[2].imm & 0xf);
2d447fca
JM
11284 }
11285}
c19d1205
ZW
11286\f
11287/* Cirrus Maverick instructions. Simple 2-, 3-, and 4-register
11288 operations first, then control, shift, and load/store. */
b99bd4ef 11289
c19d1205 11290/* Insns like "foo X,Y,Z". */
b99bd4ef 11291
c19d1205
ZW
11292static void
11293do_mav_triple (void)
11294{
11295 inst.instruction |= inst.operands[0].reg << 16;
11296 inst.instruction |= inst.operands[1].reg;
11297 inst.instruction |= inst.operands[2].reg << 12;
11298}
b99bd4ef 11299
c19d1205
ZW
11300/* Insns like "foo W,X,Y,Z".
11301 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
a737bd4d 11302
c19d1205
ZW
11303static void
11304do_mav_quad (void)
11305{
11306 inst.instruction |= inst.operands[0].reg << 5;
11307 inst.instruction |= inst.operands[1].reg << 12;
11308 inst.instruction |= inst.operands[2].reg << 16;
11309 inst.instruction |= inst.operands[3].reg;
a737bd4d
NC
11310}
11311
c19d1205
ZW
11312/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
11313static void
11314do_mav_dspsc (void)
a737bd4d 11315{
c19d1205
ZW
11316 inst.instruction |= inst.operands[1].reg << 12;
11317}
a737bd4d 11318
c19d1205
ZW
11319/* Maverick shift immediate instructions.
11320 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
11321 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
a737bd4d 11322
c19d1205
ZW
11323static void
11324do_mav_shift (void)
11325{
11326 int imm = inst.operands[2].imm;
a737bd4d 11327
c19d1205
ZW
11328 inst.instruction |= inst.operands[0].reg << 12;
11329 inst.instruction |= inst.operands[1].reg << 16;
a737bd4d 11330
c19d1205
ZW
11331 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
11332 Bits 5-7 of the insn should have bits 4-6 of the immediate.
11333 Bit 4 should be 0. */
11334 imm = (imm & 0xf) | ((imm & 0x70) << 1);
a737bd4d 11335
c19d1205
ZW
11336 inst.instruction |= imm;
11337}
11338\f
11339/* XScale instructions. Also sorted arithmetic before move. */
a737bd4d 11340
c19d1205
ZW
11341/* Xscale multiply-accumulate (argument parse)
11342 MIAcc acc0,Rm,Rs
11343 MIAPHcc acc0,Rm,Rs
11344 MIAxycc acc0,Rm,Rs. */
a737bd4d 11345
c19d1205
ZW
11346static void
11347do_xsc_mia (void)
11348{
11349 inst.instruction |= inst.operands[1].reg;
11350 inst.instruction |= inst.operands[2].reg << 12;
11351}
a737bd4d 11352
c19d1205 11353/* Xscale move-accumulator-register (argument parse)
a737bd4d 11354
c19d1205 11355 MARcc acc0,RdLo,RdHi. */
b99bd4ef 11356
c19d1205
ZW
11357static void
11358do_xsc_mar (void)
11359{
11360 inst.instruction |= inst.operands[1].reg << 12;
11361 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
11362}
11363
c19d1205 11364/* Xscale move-register-accumulator (argument parse)
b99bd4ef 11365
c19d1205 11366 MRAcc RdLo,RdHi,acc0. */
b99bd4ef
NC
11367
11368static void
c19d1205 11369do_xsc_mra (void)
b99bd4ef 11370{
c19d1205
ZW
11371 constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
11372 inst.instruction |= inst.operands[0].reg << 12;
11373 inst.instruction |= inst.operands[1].reg << 16;
11374}
11375\f
11376/* Encoding functions relevant only to Thumb. */
b99bd4ef 11377
c19d1205
ZW
11378/* inst.operands[i] is a shifted-register operand; encode
11379 it into inst.instruction in the format used by Thumb32. */
11380
11381static void
11382encode_thumb32_shifted_operand (int i)
11383{
e2b0ab59 11384 unsigned int value = inst.relocs[0].exp.X_add_number;
c19d1205 11385 unsigned int shift = inst.operands[i].shift_kind;
b99bd4ef 11386
9c3c69f2
PB
11387 constraint (inst.operands[i].immisreg,
11388 _("shift by register not allowed in thumb mode"));
c19d1205
ZW
11389 inst.instruction |= inst.operands[i].reg;
11390 if (shift == SHIFT_RRX)
11391 inst.instruction |= SHIFT_ROR << 4;
11392 else
b99bd4ef 11393 {
e2b0ab59 11394 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
11395 _("expression too complex"));
11396
11397 constraint (value > 32
11398 || (value == 32 && (shift == SHIFT_LSL
11399 || shift == SHIFT_ROR)),
11400 _("shift expression is too large"));
11401
11402 if (value == 0)
11403 shift = SHIFT_LSL;
11404 else if (value == 32)
11405 value = 0;
11406
11407 inst.instruction |= shift << 4;
11408 inst.instruction |= (value & 0x1c) << 10;
11409 inst.instruction |= (value & 0x03) << 6;
b99bd4ef 11410 }
c19d1205 11411}
b99bd4ef 11412
b99bd4ef 11413
c19d1205
ZW
11414/* inst.operands[i] was set up by parse_address. Encode it into a
11415 Thumb32 format load or store instruction. Reject forms that cannot
11416 be used with such instructions. If is_t is true, reject forms that
11417 cannot be used with a T instruction; if is_d is true, reject forms
5be8be5d
DG
11418 that cannot be used with a D instruction. If it is a store insn,
11419 reject PC in Rn. */
b99bd4ef 11420
c19d1205 11421static void
5b7c81bd 11422encode_thumb32_addr_mode (int i, bool is_t, bool is_d)
c19d1205 11423{
5b7c81bd 11424 const bool is_pc = (inst.operands[i].reg == REG_PC);
c19d1205
ZW
11425
11426 constraint (!inst.operands[i].isreg,
53365c0d 11427 _("Instruction does not support =N addresses"));
b99bd4ef 11428
c19d1205
ZW
11429 inst.instruction |= inst.operands[i].reg << 16;
11430 if (inst.operands[i].immisreg)
b99bd4ef 11431 {
5be8be5d 11432 constraint (is_pc, BAD_PC_ADDRESSING);
c19d1205
ZW
11433 constraint (is_t || is_d, _("cannot use register index with this instruction"));
11434 constraint (inst.operands[i].negative,
11435 _("Thumb does not support negative register indexing"));
11436 constraint (inst.operands[i].postind,
11437 _("Thumb does not support register post-indexing"));
11438 constraint (inst.operands[i].writeback,
11439 _("Thumb does not support register indexing with writeback"));
11440 constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
11441 _("Thumb supports only LSL in shifted register indexing"));
b99bd4ef 11442
f40d1643 11443 inst.instruction |= inst.operands[i].imm;
c19d1205 11444 if (inst.operands[i].shifted)
b99bd4ef 11445 {
e2b0ab59 11446 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 11447 _("expression too complex"));
e2b0ab59
AV
11448 constraint (inst.relocs[0].exp.X_add_number < 0
11449 || inst.relocs[0].exp.X_add_number > 3,
c19d1205 11450 _("shift out of range"));
e2b0ab59 11451 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
c19d1205 11452 }
e2b0ab59 11453 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
11454 }
11455 else if (inst.operands[i].preind)
11456 {
5be8be5d 11457 constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
f40d1643 11458 constraint (is_t && inst.operands[i].writeback,
c19d1205 11459 _("cannot use writeback with this instruction"));
4755303e
WN
11460 constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0),
11461 BAD_PC_ADDRESSING);
c19d1205
ZW
11462
11463 if (is_d)
11464 {
11465 inst.instruction |= 0x01000000;
11466 if (inst.operands[i].writeback)
11467 inst.instruction |= 0x00200000;
b99bd4ef 11468 }
c19d1205 11469 else
b99bd4ef 11470 {
c19d1205
ZW
11471 inst.instruction |= 0x00000c00;
11472 if (inst.operands[i].writeback)
11473 inst.instruction |= 0x00000100;
b99bd4ef 11474 }
e2b0ab59 11475 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
b99bd4ef 11476 }
c19d1205 11477 else if (inst.operands[i].postind)
b99bd4ef 11478 {
9c2799c2 11479 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
11480 constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
11481 constraint (is_t, _("cannot use post-indexing with this instruction"));
11482
11483 if (is_d)
11484 inst.instruction |= 0x00200000;
11485 else
11486 inst.instruction |= 0x00000900;
e2b0ab59 11487 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
c19d1205
ZW
11488 }
11489 else /* unindexed - only for coprocessor */
11490 inst.error = _("instruction does not accept unindexed addressing");
11491}
11492
e39c1607 11493/* Table of Thumb instructions which exist in 16- and/or 32-bit
c19d1205
ZW
11494 encodings (the latter only in post-V6T2 cores). The index is the
11495 value used in the insns table below. When there is more than one
11496 possible 16-bit encoding for the instruction, this table always
0110f2b8
PB
11497 holds variant (1).
11498 Also contains several pseudo-instructions used during relaxation. */
c19d1205 11499#define T16_32_TAB \
21d799b5
NC
11500 X(_adc, 4140, eb400000), \
11501 X(_adcs, 4140, eb500000), \
11502 X(_add, 1c00, eb000000), \
11503 X(_adds, 1c00, eb100000), \
11504 X(_addi, 0000, f1000000), \
11505 X(_addis, 0000, f1100000), \
11506 X(_add_pc,000f, f20f0000), \
11507 X(_add_sp,000d, f10d0000), \
11508 X(_adr, 000f, f20f0000), \
11509 X(_and, 4000, ea000000), \
11510 X(_ands, 4000, ea100000), \
11511 X(_asr, 1000, fa40f000), \
11512 X(_asrs, 1000, fa50f000), \
e43ca2cb 11513 X(_aut, 0000, f3af802d), \
be05908c 11514 X(_autg, 0000, fb500f00), \
21d799b5
NC
11515 X(_b, e000, f000b000), \
11516 X(_bcond, d000, f0008000), \
4389b29a 11517 X(_bf, 0000, f040e001), \
f6b2b12d 11518 X(_bfcsel,0000, f000e001), \
f1c7f421 11519 X(_bfx, 0000, f060e001), \
65d1bc05 11520 X(_bfl, 0000, f000c001), \
f1c7f421 11521 X(_bflx, 0000, f070e001), \
21d799b5
NC
11522 X(_bic, 4380, ea200000), \
11523 X(_bics, 4380, ea300000), \
e07352fa 11524 X(_bxaut, 0000, fb500f10), \
e39c1607
SD
11525 X(_cinc, 0000, ea509000), \
11526 X(_cinv, 0000, ea50a000), \
21d799b5
NC
11527 X(_cmn, 42c0, eb100f00), \
11528 X(_cmp, 2800, ebb00f00), \
e39c1607 11529 X(_cneg, 0000, ea50b000), \
21d799b5
NC
11530 X(_cpsie, b660, f3af8400), \
11531 X(_cpsid, b670, f3af8600), \
11532 X(_cpy, 4600, ea4f0000), \
e39c1607
SD
11533 X(_csel, 0000, ea508000), \
11534 X(_cset, 0000, ea5f900f), \
11535 X(_csetm, 0000, ea5fa00f), \
11536 X(_csinc, 0000, ea509000), \
11537 X(_csinv, 0000, ea50a000), \
11538 X(_csneg, 0000, ea50b000), \
21d799b5 11539 X(_dec_sp,80dd, f1ad0d00), \
60f993ce 11540 X(_dls, 0000, f040e001), \
1f6234a3 11541 X(_dlstp, 0000, f000e001), \
21d799b5
NC
11542 X(_eor, 4040, ea800000), \
11543 X(_eors, 4040, ea900000), \
11544 X(_inc_sp,00dd, f10d0d00), \
1f6234a3 11545 X(_lctp, 0000, f00fe001), \
21d799b5
NC
11546 X(_ldmia, c800, e8900000), \
11547 X(_ldr, 6800, f8500000), \
11548 X(_ldrb, 7800, f8100000), \
11549 X(_ldrh, 8800, f8300000), \
11550 X(_ldrsb, 5600, f9100000), \
11551 X(_ldrsh, 5e00, f9300000), \
11552 X(_ldr_pc,4800, f85f0000), \
11553 X(_ldr_pc2,4800, f85f0000), \
11554 X(_ldr_sp,9800, f85d0000), \
60f993ce 11555 X(_le, 0000, f00fc001), \
1f6234a3 11556 X(_letp, 0000, f01fc001), \
21d799b5
NC
11557 X(_lsl, 0000, fa00f000), \
11558 X(_lsls, 0000, fa10f000), \
11559 X(_lsr, 0800, fa20f000), \
11560 X(_lsrs, 0800, fa30f000), \
11561 X(_mov, 2000, ea4f0000), \
11562 X(_movs, 2000, ea5f0000), \
11563 X(_mul, 4340, fb00f000), \
11564 X(_muls, 4340, ffffffff), /* no 32b muls */ \
11565 X(_mvn, 43c0, ea6f0000), \
11566 X(_mvns, 43c0, ea7f0000), \
11567 X(_neg, 4240, f1c00000), /* rsb #0 */ \
11568 X(_negs, 4240, f1d00000), /* rsbs #0 */ \
11569 X(_orr, 4300, ea400000), \
11570 X(_orrs, 4300, ea500000), \
ce537a7d 11571 X(_pac, 0000, f3af801d), \
f1e1d7f3 11572 X(_pacbti, 0000, f3af800d), \
5c43020d 11573 X(_pacg, 0000, fb60f000), \
21d799b5
NC
11574 X(_pop, bc00, e8bd0000), /* ldmia sp!,... */ \
11575 X(_push, b400, e92d0000), /* stmdb sp!,... */ \
11576 X(_rev, ba00, fa90f080), \
11577 X(_rev16, ba40, fa90f090), \
11578 X(_revsh, bac0, fa90f0b0), \
11579 X(_ror, 41c0, fa60f000), \
11580 X(_rors, 41c0, fa70f000), \
11581 X(_sbc, 4180, eb600000), \
11582 X(_sbcs, 4180, eb700000), \
11583 X(_stmia, c000, e8800000), \
11584 X(_str, 6000, f8400000), \
11585 X(_strb, 7000, f8000000), \
11586 X(_strh, 8000, f8200000), \
11587 X(_str_sp,9000, f84d0000), \
11588 X(_sub, 1e00, eba00000), \
11589 X(_subs, 1e00, ebb00000), \
11590 X(_subi, 8000, f1a00000), \
11591 X(_subis, 8000, f1b00000), \
11592 X(_sxtb, b240, fa4ff080), \
11593 X(_sxth, b200, fa0ff080), \
11594 X(_tst, 4200, ea100f00), \
11595 X(_uxtb, b2c0, fa5ff080), \
11596 X(_uxth, b280, fa1ff080), \
11597 X(_nop, bf00, f3af8000), \
11598 X(_yield, bf10, f3af8001), \
11599 X(_wfe, bf20, f3af8002), \
11600 X(_wfi, bf30, f3af8003), \
60f993ce 11601 X(_wls, 0000, f040c001), \
1f6234a3 11602 X(_wlstp, 0000, f000c001), \
53c4b28b 11603 X(_sev, bf40, f3af8004), \
74db7efb
NC
11604 X(_sevl, bf50, f3af8005), \
11605 X(_udf, de00, f7f0a000)
c19d1205
ZW
11606
11607/* To catch errors in encoding functions, the codes are all offset by
11608 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
11609 as 16-bit instructions. */
21d799b5 11610#define X(a,b,c) T_MNEM##a
c19d1205
ZW
11611enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
11612#undef X
11613
11614#define X(a,b,c) 0x##b
11615static const unsigned short thumb_op16[] = { T16_32_TAB };
11616#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
11617#undef X
11618
11619#define X(a,b,c) 0x##c
11620static const unsigned int thumb_op32[] = { T16_32_TAB };
c921be7d
NC
11621#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
11622#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
c19d1205
ZW
11623#undef X
11624#undef T16_32_TAB
11625
11626/* Thumb instruction encoders, in alphabetical order. */
11627
92e90b6e 11628/* ADDW or SUBW. */
c921be7d 11629
92e90b6e
PB
11630static void
11631do_t_add_sub_w (void)
11632{
11633 int Rd, Rn;
11634
11635 Rd = inst.operands[0].reg;
11636 Rn = inst.operands[1].reg;
11637
539d4391
NC
11638 /* If Rn is REG_PC, this is ADR; if Rn is REG_SP, then this
11639 is the SP-{plus,minus}-immediate form of the instruction. */
11640 if (Rn == REG_SP)
11641 constraint (Rd == REG_PC, BAD_PC);
11642 else
11643 reject_bad_reg (Rd);
fdfde340 11644
92e90b6e 11645 inst.instruction |= (Rn << 16) | (Rd << 8);
e2b0ab59 11646 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
92e90b6e
PB
11647}
11648
c19d1205 11649/* Parse an add or subtract instruction. We get here with inst.instruction
33eaf5de 11650 equaling any of THUMB_OPCODE_add, adds, sub, or subs. */
c19d1205
ZW
11651
11652static void
11653do_t_add_sub (void)
11654{
11655 int Rd, Rs, Rn;
11656
11657 Rd = inst.operands[0].reg;
11658 Rs = (inst.operands[1].present
11659 ? inst.operands[1].reg /* Rd, Rs, foo */
11660 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11661
e07e6e58 11662 if (Rd == REG_PC)
5ee91343 11663 set_pred_insn_type_last ();
e07e6e58 11664
c19d1205
ZW
11665 if (unified_syntax)
11666 {
5b7c81bd
AM
11667 bool flags;
11668 bool narrow;
0110f2b8
PB
11669 int opcode;
11670
11671 flags = (inst.instruction == T_MNEM_adds
11672 || inst.instruction == T_MNEM_subs);
11673 if (flags)
5ee91343 11674 narrow = !in_pred_block ();
0110f2b8 11675 else
5ee91343 11676 narrow = in_pred_block ();
c19d1205 11677 if (!inst.operands[2].isreg)
b99bd4ef 11678 {
16805f35
PB
11679 int add;
11680
5c8ed6a4
JW
11681 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11682 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340 11683
16805f35
PB
11684 add = (inst.instruction == T_MNEM_add
11685 || inst.instruction == T_MNEM_adds);
0110f2b8
PB
11686 opcode = 0;
11687 if (inst.size_req != 4)
11688 {
0110f2b8 11689 /* Attempt to use a narrow opcode, with relaxation if
477330fc 11690 appropriate. */
0110f2b8
PB
11691 if (Rd == REG_SP && Rs == REG_SP && !flags)
11692 opcode = add ? T_MNEM_inc_sp : T_MNEM_dec_sp;
11693 else if (Rd <= 7 && Rs == REG_SP && add && !flags)
11694 opcode = T_MNEM_add_sp;
11695 else if (Rd <= 7 && Rs == REG_PC && add && !flags)
11696 opcode = T_MNEM_add_pc;
11697 else if (Rd <= 7 && Rs <= 7 && narrow)
11698 {
11699 if (flags)
11700 opcode = add ? T_MNEM_addis : T_MNEM_subis;
11701 else
11702 opcode = add ? T_MNEM_addi : T_MNEM_subi;
11703 }
11704 if (opcode)
11705 {
11706 inst.instruction = THUMB_OP16(opcode);
11707 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59
AV
11708 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
11709 || (inst.relocs[0].type
11710 > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
a9f02af8
MG
11711 {
11712 if (inst.size_req == 2)
e2b0ab59 11713 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
a9f02af8
MG
11714 else
11715 inst.relax = opcode;
11716 }
0110f2b8
PB
11717 }
11718 else
fe0171d2 11719 constraint (inst.size_req == 2, _("cannot honor width suffix"));
0110f2b8
PB
11720 }
11721 if (inst.size_req == 4
11722 || (inst.size_req != 2 && !opcode))
11723 {
e2b0ab59
AV
11724 constraint ((inst.relocs[0].type
11725 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
11726 && (inst.relocs[0].type
11727 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8 11728 THUMB1_RELOC_ONLY);
efd81785
PB
11729 if (Rd == REG_PC)
11730 {
fdfde340 11731 constraint (add, BAD_PC);
efd81785
PB
11732 constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
11733 _("only SUBS PC, LR, #const allowed"));
e2b0ab59 11734 constraint (inst.relocs[0].exp.X_op != O_constant,
efd81785 11735 _("expression too complex"));
e2b0ab59
AV
11736 constraint (inst.relocs[0].exp.X_add_number < 0
11737 || inst.relocs[0].exp.X_add_number > 0xff,
efd81785
PB
11738 _("immediate value out of range"));
11739 inst.instruction = T2_SUBS_PC_LR
e2b0ab59
AV
11740 | inst.relocs[0].exp.X_add_number;
11741 inst.relocs[0].type = BFD_RELOC_UNUSED;
efd81785
PB
11742 return;
11743 }
11744 else if (Rs == REG_PC)
16805f35
PB
11745 {
11746 /* Always use addw/subw. */
11747 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
e2b0ab59 11748 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
16805f35
PB
11749 }
11750 else
11751 {
11752 inst.instruction = THUMB_OP32 (inst.instruction);
11753 inst.instruction = (inst.instruction & 0xe1ffffff)
11754 | 0x10000000;
11755 if (flags)
e2b0ab59 11756 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
16805f35 11757 else
e2b0ab59 11758 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
16805f35 11759 }
dc4503c6
PB
11760 inst.instruction |= Rd << 8;
11761 inst.instruction |= Rs << 16;
0110f2b8 11762 }
b99bd4ef 11763 }
c19d1205
ZW
11764 else
11765 {
e2b0ab59 11766 unsigned int value = inst.relocs[0].exp.X_add_number;
5f4cb198
NC
11767 unsigned int shift = inst.operands[2].shift_kind;
11768
c19d1205
ZW
11769 Rn = inst.operands[2].reg;
11770 /* See if we can do this with a 16-bit instruction. */
11771 if (!inst.operands[2].shifted && inst.size_req != 4)
11772 {
e27ec89e 11773 if (Rd > 7 || Rs > 7 || Rn > 7)
5b7c81bd 11774 narrow = false;
e27ec89e
PB
11775
11776 if (narrow)
c19d1205 11777 {
e27ec89e
PB
11778 inst.instruction = ((inst.instruction == T_MNEM_adds
11779 || inst.instruction == T_MNEM_add)
c19d1205
ZW
11780 ? T_OPCODE_ADD_R3
11781 : T_OPCODE_SUB_R3);
11782 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
11783 return;
11784 }
b99bd4ef 11785
7e806470 11786 if (inst.instruction == T_MNEM_add && (Rd == Rs || Rd == Rn))
c19d1205 11787 {
7e806470
PB
11788 /* Thumb-1 cores (except v6-M) require at least one high
11789 register in a narrow non flag setting add. */
11790 if (Rd > 7 || Rn > 7
11791 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2)
11792 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_msr))
c19d1205 11793 {
7e806470
PB
11794 if (Rd == Rn)
11795 {
11796 Rn = Rs;
11797 Rs = Rd;
11798 }
c19d1205
ZW
11799 inst.instruction = T_OPCODE_ADD_HI;
11800 inst.instruction |= (Rd & 8) << 4;
11801 inst.instruction |= (Rd & 7);
11802 inst.instruction |= Rn << 3;
11803 return;
11804 }
c19d1205
ZW
11805 }
11806 }
c921be7d 11807
fdfde340 11808 constraint (Rd == REG_PC, BAD_PC);
5c8ed6a4
JW
11809 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11810 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340
JM
11811 constraint (Rs == REG_PC, BAD_PC);
11812 reject_bad_reg (Rn);
11813
c19d1205
ZW
11814 /* If we get here, it can't be done in 16 bits. */
11815 constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
11816 _("shift must be constant"));
11817 inst.instruction = THUMB_OP32 (inst.instruction);
11818 inst.instruction |= Rd << 8;
11819 inst.instruction |= Rs << 16;
5f4cb198
NC
11820 constraint (Rd == REG_SP && Rs == REG_SP && value > 3,
11821 _("shift value over 3 not allowed in thumb mode"));
11822 constraint (Rd == REG_SP && Rs == REG_SP && shift != SHIFT_LSL,
11823 _("only LSL shift allowed in thumb mode"));
c19d1205
ZW
11824 encode_thumb32_shifted_operand (2);
11825 }
11826 }
11827 else
11828 {
11829 constraint (inst.instruction == T_MNEM_adds
11830 || inst.instruction == T_MNEM_subs,
11831 BAD_THUMB32);
b99bd4ef 11832
c19d1205 11833 if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
b99bd4ef 11834 {
c19d1205
ZW
11835 constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
11836 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
11837 BAD_HIREG);
11838
11839 inst.instruction = (inst.instruction == T_MNEM_add
11840 ? 0x0000 : 0x8000);
11841 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59 11842 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
b99bd4ef
NC
11843 return;
11844 }
11845
c19d1205
ZW
11846 Rn = inst.operands[2].reg;
11847 constraint (inst.operands[2].shifted, _("unshifted register required"));
b99bd4ef 11848
c19d1205
ZW
11849 /* We now have Rd, Rs, and Rn set to registers. */
11850 if (Rd > 7 || Rs > 7 || Rn > 7)
b99bd4ef 11851 {
c19d1205
ZW
11852 /* Can't do this for SUB. */
11853 constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
11854 inst.instruction = T_OPCODE_ADD_HI;
11855 inst.instruction |= (Rd & 8) << 4;
11856 inst.instruction |= (Rd & 7);
11857 if (Rs == Rd)
11858 inst.instruction |= Rn << 3;
11859 else if (Rn == Rd)
11860 inst.instruction |= Rs << 3;
11861 else
11862 constraint (1, _("dest must overlap one source register"));
11863 }
11864 else
11865 {
11866 inst.instruction = (inst.instruction == T_MNEM_add
11867 ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
11868 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
b99bd4ef 11869 }
b99bd4ef 11870 }
b99bd4ef
NC
11871}
11872
c19d1205
ZW
11873static void
11874do_t_adr (void)
11875{
fdfde340
JM
11876 unsigned Rd;
11877
11878 Rd = inst.operands[0].reg;
11879 reject_bad_reg (Rd);
11880
11881 if (unified_syntax && inst.size_req == 0 && Rd <= 7)
0110f2b8
PB
11882 {
11883 /* Defer to section relaxation. */
11884 inst.relax = inst.instruction;
11885 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 11886 inst.instruction |= Rd << 4;
0110f2b8
PB
11887 }
11888 else if (unified_syntax && inst.size_req != 2)
e9f89963 11889 {
0110f2b8 11890 /* Generate a 32-bit opcode. */
e9f89963 11891 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 11892 inst.instruction |= Rd << 8;
e2b0ab59
AV
11893 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
11894 inst.relocs[0].pc_rel = 1;
e9f89963
PB
11895 }
11896 else
11897 {
0110f2b8 11898 /* Generate a 16-bit opcode. */
e9f89963 11899 inst.instruction = THUMB_OP16 (inst.instruction);
e2b0ab59
AV
11900 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
11901 inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust. */
11902 inst.relocs[0].pc_rel = 1;
fdfde340 11903 inst.instruction |= Rd << 4;
e9f89963 11904 }
52a86f84 11905
e2b0ab59
AV
11906 if (inst.relocs[0].exp.X_op == O_symbol
11907 && inst.relocs[0].exp.X_add_symbol != NULL
11908 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11909 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11910 inst.relocs[0].exp.X_add_number += 1;
c19d1205 11911}
b99bd4ef 11912
c19d1205
ZW
11913/* Arithmetic instructions for which there is just one 16-bit
11914 instruction encoding, and it allows only two low registers.
11915 For maximal compatibility with ARM syntax, we allow three register
11916 operands even when Thumb-32 instructions are not available, as long
11917 as the first two are identical. For instance, both "sbc r0,r1" and
11918 "sbc r0,r0,r1" are allowed. */
b99bd4ef 11919static void
c19d1205 11920do_t_arit3 (void)
b99bd4ef 11921{
c19d1205 11922 int Rd, Rs, Rn;
b99bd4ef 11923
c19d1205
ZW
11924 Rd = inst.operands[0].reg;
11925 Rs = (inst.operands[1].present
11926 ? inst.operands[1].reg /* Rd, Rs, foo */
11927 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11928 Rn = inst.operands[2].reg;
b99bd4ef 11929
fdfde340
JM
11930 reject_bad_reg (Rd);
11931 reject_bad_reg (Rs);
11932 if (inst.operands[2].isreg)
11933 reject_bad_reg (Rn);
11934
c19d1205 11935 if (unified_syntax)
b99bd4ef 11936 {
c19d1205
ZW
11937 if (!inst.operands[2].isreg)
11938 {
11939 /* For an immediate, we always generate a 32-bit opcode;
11940 section relaxation will shrink it later if possible. */
11941 inst.instruction = THUMB_OP32 (inst.instruction);
11942 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11943 inst.instruction |= Rd << 8;
11944 inst.instruction |= Rs << 16;
e2b0ab59 11945 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
c19d1205
ZW
11946 }
11947 else
11948 {
5b7c81bd 11949 bool narrow;
e27ec89e 11950
c19d1205 11951 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11952 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 11953 narrow = !in_pred_block ();
e27ec89e 11954 else
5ee91343 11955 narrow = in_pred_block ();
e27ec89e
PB
11956
11957 if (Rd > 7 || Rn > 7 || Rs > 7)
5b7c81bd 11958 narrow = false;
e27ec89e 11959 if (inst.operands[2].shifted)
5b7c81bd 11960 narrow = false;
e27ec89e 11961 if (inst.size_req == 4)
5b7c81bd 11962 narrow = false;
e27ec89e
PB
11963
11964 if (narrow
c19d1205
ZW
11965 && Rd == Rs)
11966 {
11967 inst.instruction = THUMB_OP16 (inst.instruction);
11968 inst.instruction |= Rd;
11969 inst.instruction |= Rn << 3;
11970 return;
11971 }
b99bd4ef 11972
c19d1205
ZW
11973 /* If we get here, it can't be done in 16 bits. */
11974 constraint (inst.operands[2].shifted
11975 && inst.operands[2].immisreg,
11976 _("shift must be constant"));
11977 inst.instruction = THUMB_OP32 (inst.instruction);
11978 inst.instruction |= Rd << 8;
11979 inst.instruction |= Rs << 16;
11980 encode_thumb32_shifted_operand (2);
11981 }
a737bd4d 11982 }
c19d1205 11983 else
b99bd4ef 11984 {
c19d1205
ZW
11985 /* On its face this is a lie - the instruction does set the
11986 flags. However, the only supported mnemonic in this mode
11987 says it doesn't. */
11988 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11989
c19d1205
ZW
11990 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11991 _("unshifted register required"));
11992 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11993 constraint (Rd != Rs,
11994 _("dest and source1 must be the same register"));
a737bd4d 11995
c19d1205
ZW
11996 inst.instruction = THUMB_OP16 (inst.instruction);
11997 inst.instruction |= Rd;
11998 inst.instruction |= Rn << 3;
b99bd4ef 11999 }
a737bd4d 12000}
b99bd4ef 12001
c19d1205
ZW
12002/* Similarly, but for instructions where the arithmetic operation is
12003 commutative, so we can allow either of them to be different from
12004 the destination operand in a 16-bit instruction. For instance, all
12005 three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
12006 accepted. */
12007static void
12008do_t_arit3c (void)
a737bd4d 12009{
c19d1205 12010 int Rd, Rs, Rn;
b99bd4ef 12011
c19d1205
ZW
12012 Rd = inst.operands[0].reg;
12013 Rs = (inst.operands[1].present
12014 ? inst.operands[1].reg /* Rd, Rs, foo */
12015 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
12016 Rn = inst.operands[2].reg;
c921be7d 12017
fdfde340
JM
12018 reject_bad_reg (Rd);
12019 reject_bad_reg (Rs);
12020 if (inst.operands[2].isreg)
12021 reject_bad_reg (Rn);
a737bd4d 12022
c19d1205 12023 if (unified_syntax)
a737bd4d 12024 {
c19d1205 12025 if (!inst.operands[2].isreg)
b99bd4ef 12026 {
c19d1205
ZW
12027 /* For an immediate, we always generate a 32-bit opcode;
12028 section relaxation will shrink it later if possible. */
12029 inst.instruction = THUMB_OP32 (inst.instruction);
12030 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
12031 inst.instruction |= Rd << 8;
12032 inst.instruction |= Rs << 16;
e2b0ab59 12033 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 12034 }
c19d1205 12035 else
a737bd4d 12036 {
5b7c81bd 12037 bool narrow;
e27ec89e 12038
c19d1205 12039 /* See if we can do this with a 16-bit instruction. */
e27ec89e 12040 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 12041 narrow = !in_pred_block ();
e27ec89e 12042 else
5ee91343 12043 narrow = in_pred_block ();
e27ec89e
PB
12044
12045 if (Rd > 7 || Rn > 7 || Rs > 7)
5b7c81bd 12046 narrow = false;
e27ec89e 12047 if (inst.operands[2].shifted)
5b7c81bd 12048 narrow = false;
e27ec89e 12049 if (inst.size_req == 4)
5b7c81bd 12050 narrow = false;
e27ec89e
PB
12051
12052 if (narrow)
a737bd4d 12053 {
c19d1205 12054 if (Rd == Rs)
a737bd4d 12055 {
c19d1205
ZW
12056 inst.instruction = THUMB_OP16 (inst.instruction);
12057 inst.instruction |= Rd;
12058 inst.instruction |= Rn << 3;
12059 return;
a737bd4d 12060 }
c19d1205 12061 if (Rd == Rn)
a737bd4d 12062 {
c19d1205
ZW
12063 inst.instruction = THUMB_OP16 (inst.instruction);
12064 inst.instruction |= Rd;
12065 inst.instruction |= Rs << 3;
12066 return;
a737bd4d
NC
12067 }
12068 }
c19d1205
ZW
12069
12070 /* If we get here, it can't be done in 16 bits. */
12071 constraint (inst.operands[2].shifted
12072 && inst.operands[2].immisreg,
12073 _("shift must be constant"));
12074 inst.instruction = THUMB_OP32 (inst.instruction);
12075 inst.instruction |= Rd << 8;
12076 inst.instruction |= Rs << 16;
12077 encode_thumb32_shifted_operand (2);
a737bd4d 12078 }
b99bd4ef 12079 }
c19d1205
ZW
12080 else
12081 {
12082 /* On its face this is a lie - the instruction does set the
12083 flags. However, the only supported mnemonic in this mode
12084 says it doesn't. */
12085 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 12086
c19d1205
ZW
12087 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
12088 _("unshifted register required"));
12089 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
12090
12091 inst.instruction = THUMB_OP16 (inst.instruction);
12092 inst.instruction |= Rd;
12093
12094 if (Rd == Rs)
12095 inst.instruction |= Rn << 3;
12096 else if (Rd == Rn)
12097 inst.instruction |= Rs << 3;
12098 else
12099 constraint (1, _("dest must overlap one source register"));
12100 }
a737bd4d
NC
12101}
12102
c19d1205
ZW
12103static void
12104do_t_bfc (void)
a737bd4d 12105{
fdfde340 12106 unsigned Rd;
c19d1205
ZW
12107 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
12108 constraint (msb > 32, _("bit-field extends past end of register"));
12109 /* The instruction encoding stores the LSB and MSB,
12110 not the LSB and width. */
fdfde340
JM
12111 Rd = inst.operands[0].reg;
12112 reject_bad_reg (Rd);
12113 inst.instruction |= Rd << 8;
c19d1205
ZW
12114 inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
12115 inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
12116 inst.instruction |= msb - 1;
b99bd4ef
NC
12117}
12118
c19d1205
ZW
12119static void
12120do_t_bfi (void)
b99bd4ef 12121{
fdfde340 12122 int Rd, Rn;
c19d1205 12123 unsigned int msb;
b99bd4ef 12124
fdfde340
JM
12125 Rd = inst.operands[0].reg;
12126 reject_bad_reg (Rd);
12127
c19d1205
ZW
12128 /* #0 in second position is alternative syntax for bfc, which is
12129 the same instruction but with REG_PC in the Rm field. */
12130 if (!inst.operands[1].isreg)
fdfde340
JM
12131 Rn = REG_PC;
12132 else
12133 {
12134 Rn = inst.operands[1].reg;
12135 reject_bad_reg (Rn);
12136 }
b99bd4ef 12137
c19d1205
ZW
12138 msb = inst.operands[2].imm + inst.operands[3].imm;
12139 constraint (msb > 32, _("bit-field extends past end of register"));
12140 /* The instruction encoding stores the LSB and MSB,
12141 not the LSB and width. */
fdfde340
JM
12142 inst.instruction |= Rd << 8;
12143 inst.instruction |= Rn << 16;
c19d1205
ZW
12144 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
12145 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
12146 inst.instruction |= msb - 1;
b99bd4ef
NC
12147}
12148
c19d1205
ZW
12149static void
12150do_t_bfx (void)
b99bd4ef 12151{
fdfde340
JM
12152 unsigned Rd, Rn;
12153
12154 Rd = inst.operands[0].reg;
12155 Rn = inst.operands[1].reg;
12156
12157 reject_bad_reg (Rd);
12158 reject_bad_reg (Rn);
12159
c19d1205
ZW
12160 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
12161 _("bit-field extends past end of register"));
fdfde340
JM
12162 inst.instruction |= Rd << 8;
12163 inst.instruction |= Rn << 16;
c19d1205
ZW
12164 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
12165 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
12166 inst.instruction |= inst.operands[3].imm - 1;
12167}
b99bd4ef 12168
c19d1205
ZW
12169/* ARM V5 Thumb BLX (argument parse)
12170 BLX <target_addr> which is BLX(1)
12171 BLX <Rm> which is BLX(2)
12172 Unfortunately, there are two different opcodes for this mnemonic.
12173 So, the insns[].value is not used, and the code here zaps values
12174 into inst.instruction.
b99bd4ef 12175
c19d1205
ZW
12176 ??? How to take advantage of the additional two bits of displacement
12177 available in Thumb32 mode? Need new relocation? */
b99bd4ef 12178
c19d1205
ZW
12179static void
12180do_t_blx (void)
12181{
5ee91343 12182 set_pred_insn_type_last ();
e07e6e58 12183
c19d1205 12184 if (inst.operands[0].isreg)
fdfde340
JM
12185 {
12186 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
12187 /* We have a register, so this is BLX(2). */
12188 inst.instruction |= inst.operands[0].reg << 3;
12189 }
b99bd4ef
NC
12190 else
12191 {
c19d1205 12192 /* No register. This must be BLX(1). */
2fc8bdac 12193 inst.instruction = 0xf000e800;
0855e32b 12194 encode_branch (BFD_RELOC_THUMB_PCREL_BLX);
b99bd4ef
NC
12195 }
12196}
12197
c19d1205
ZW
12198static void
12199do_t_branch (void)
b99bd4ef 12200{
0110f2b8 12201 int opcode;
dfa9f0d5 12202 int cond;
2fe88214 12203 bfd_reloc_code_real_type reloc;
dfa9f0d5 12204
e07e6e58 12205 cond = inst.cond;
5ee91343 12206 set_pred_insn_type (IF_INSIDE_IT_LAST_INSN);
e07e6e58 12207
5ee91343 12208 if (in_pred_block ())
dfa9f0d5
PB
12209 {
12210 /* Conditional branches inside IT blocks are encoded as unconditional
477330fc 12211 branches. */
dfa9f0d5 12212 cond = COND_ALWAYS;
dfa9f0d5
PB
12213 }
12214 else
12215 cond = inst.cond;
12216
12217 if (cond != COND_ALWAYS)
0110f2b8
PB
12218 opcode = T_MNEM_bcond;
12219 else
12220 opcode = inst.instruction;
12221
12d6b0b7
RS
12222 if (unified_syntax
12223 && (inst.size_req == 4
10960bfb
PB
12224 || (inst.size_req != 2
12225 && (inst.operands[0].hasreloc
e2b0ab59 12226 || inst.relocs[0].exp.X_op == O_constant))))
c19d1205 12227 {
0110f2b8 12228 inst.instruction = THUMB_OP32(opcode);
dfa9f0d5 12229 if (cond == COND_ALWAYS)
9ae92b05 12230 reloc = BFD_RELOC_THUMB_PCREL_BRANCH25;
c19d1205
ZW
12231 else
12232 {
ff8646ee
TP
12233 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2),
12234 _("selected architecture does not support "
12235 "wide conditional branch instruction"));
12236
9c2799c2 12237 gas_assert (cond != 0xF);
dfa9f0d5 12238 inst.instruction |= cond << 22;
9ae92b05 12239 reloc = BFD_RELOC_THUMB_PCREL_BRANCH20;
c19d1205
ZW
12240 }
12241 }
b99bd4ef
NC
12242 else
12243 {
0110f2b8 12244 inst.instruction = THUMB_OP16(opcode);
dfa9f0d5 12245 if (cond == COND_ALWAYS)
9ae92b05 12246 reloc = BFD_RELOC_THUMB_PCREL_BRANCH12;
c19d1205 12247 else
b99bd4ef 12248 {
dfa9f0d5 12249 inst.instruction |= cond << 8;
9ae92b05 12250 reloc = BFD_RELOC_THUMB_PCREL_BRANCH9;
b99bd4ef 12251 }
0110f2b8
PB
12252 /* Allow section relaxation. */
12253 if (unified_syntax && inst.size_req != 2)
12254 inst.relax = opcode;
b99bd4ef 12255 }
e2b0ab59
AV
12256 inst.relocs[0].type = reloc;
12257 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
12258}
12259
8884b720 12260/* Actually do the work for Thumb state bkpt and hlt. The only difference
bacebabc 12261 between the two is the maximum immediate allowed - which is passed in
8884b720 12262 RANGE. */
b99bd4ef 12263static void
8884b720 12264do_t_bkpt_hlt1 (int range)
b99bd4ef 12265{
dfa9f0d5
PB
12266 constraint (inst.cond != COND_ALWAYS,
12267 _("instruction is always unconditional"));
c19d1205 12268 if (inst.operands[0].present)
b99bd4ef 12269 {
8884b720 12270 constraint (inst.operands[0].imm > range,
c19d1205
ZW
12271 _("immediate value out of range"));
12272 inst.instruction |= inst.operands[0].imm;
b99bd4ef 12273 }
8884b720 12274
5ee91343 12275 set_pred_insn_type (NEUTRAL_IT_INSN);
8884b720
MGD
12276}
12277
12278static void
12279do_t_hlt (void)
12280{
12281 do_t_bkpt_hlt1 (63);
12282}
12283
12284static void
12285do_t_bkpt (void)
12286{
12287 do_t_bkpt_hlt1 (255);
b99bd4ef
NC
12288}
12289
12290static void
c19d1205 12291do_t_branch23 (void)
b99bd4ef 12292{
5ee91343 12293 set_pred_insn_type_last ();
0855e32b 12294 encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
fa94de6b 12295
0855e32b
NS
12296 /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
12297 this file. We used to simply ignore the PLT reloc type here --
12298 the branch encoding is now needed to deal with TLSCALL relocs.
12299 So if we see a PLT reloc now, put it back to how it used to be to
12300 keep the preexisting behaviour. */
e2b0ab59
AV
12301 if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
12302 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
90e4755a 12303
4343666d 12304#if defined(OBJ_COFF)
c19d1205
ZW
12305 /* If the destination of the branch is a defined symbol which does not have
12306 the THUMB_FUNC attribute, then we must be calling a function which has
12307 the (interfacearm) attribute. We look for the Thumb entry point to that
12308 function and change the branch to refer to that function instead. */
e2b0ab59
AV
12309 if ( inst.relocs[0].exp.X_op == O_symbol
12310 && inst.relocs[0].exp.X_add_symbol != NULL
12311 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
12312 && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
12313 inst.relocs[0].exp.X_add_symbol
12314 = find_real_start (inst.relocs[0].exp.X_add_symbol);
4343666d 12315#endif
90e4755a
RE
12316}
12317
12318static void
c19d1205 12319do_t_bx (void)
90e4755a 12320{
5ee91343 12321 set_pred_insn_type_last ();
c19d1205
ZW
12322 inst.instruction |= inst.operands[0].reg << 3;
12323 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
12324 should cause the alignment to be checked once it is known. This is
12325 because BX PC only works if the instruction is word aligned. */
12326}
90e4755a 12327
c19d1205
ZW
12328static void
12329do_t_bxj (void)
12330{
fdfde340 12331 int Rm;
90e4755a 12332
5ee91343 12333 set_pred_insn_type_last ();
fdfde340
JM
12334 Rm = inst.operands[0].reg;
12335 reject_bad_reg (Rm);
12336 inst.instruction |= Rm << 16;
90e4755a
RE
12337}
12338
12339static void
c19d1205 12340do_t_clz (void)
90e4755a 12341{
fdfde340
JM
12342 unsigned Rd;
12343 unsigned Rm;
12344
12345 Rd = inst.operands[0].reg;
12346 Rm = inst.operands[1].reg;
12347
12348 reject_bad_reg (Rd);
12349 reject_bad_reg (Rm);
12350
12351 inst.instruction |= Rd << 8;
12352 inst.instruction |= Rm << 16;
12353 inst.instruction |= Rm;
c19d1205 12354}
90e4755a 12355
e39c1607
SD
12356/* For the Armv8.1-M conditional instructions. */
12357static void
12358do_t_cond (void)
12359{
12360 unsigned Rd, Rn, Rm;
12361 signed int cond;
12362
12363 constraint (inst.cond != COND_ALWAYS, BAD_COND);
12364
12365 Rd = inst.operands[0].reg;
12366 switch (inst.instruction)
12367 {
12368 case T_MNEM_csinc:
12369 case T_MNEM_csinv:
12370 case T_MNEM_csneg:
12371 case T_MNEM_csel:
12372 Rn = inst.operands[1].reg;
12373 Rm = inst.operands[2].reg;
12374 cond = inst.operands[3].imm;
12375 constraint (Rn == REG_SP, BAD_SP);
12376 constraint (Rm == REG_SP, BAD_SP);
12377 break;
12378
12379 case T_MNEM_cinc:
12380 case T_MNEM_cinv:
12381 case T_MNEM_cneg:
12382 Rn = inst.operands[1].reg;
12383 cond = inst.operands[2].imm;
12384 /* Invert the last bit to invert the cond. */
12385 cond = TOGGLE_BIT (cond, 0);
12386 constraint (Rn == REG_SP, BAD_SP);
12387 Rm = Rn;
12388 break;
12389
12390 case T_MNEM_csetm:
12391 case T_MNEM_cset:
12392 cond = inst.operands[1].imm;
12393 /* Invert the last bit to invert the cond. */
12394 cond = TOGGLE_BIT (cond, 0);
12395 Rn = REG_PC;
12396 Rm = REG_PC;
12397 break;
12398
12399 default: abort ();
12400 }
12401
12402 set_pred_insn_type (OUTSIDE_PRED_INSN);
12403 inst.instruction = THUMB_OP32 (inst.instruction);
12404 inst.instruction |= Rd << 8;
12405 inst.instruction |= Rn << 16;
12406 inst.instruction |= Rm;
12407 inst.instruction |= cond << 4;
12408}
12409
91d8b670
JG
12410static void
12411do_t_csdb (void)
12412{
5ee91343 12413 set_pred_insn_type (OUTSIDE_PRED_INSN);
91d8b670
JG
12414}
12415
dfa9f0d5
PB
12416static void
12417do_t_cps (void)
12418{
5ee91343 12419 set_pred_insn_type (OUTSIDE_PRED_INSN);
dfa9f0d5
PB
12420 inst.instruction |= inst.operands[0].imm;
12421}
12422
c19d1205
ZW
12423static void
12424do_t_cpsi (void)
12425{
5ee91343 12426 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205 12427 if (unified_syntax
62b3e311
PB
12428 && (inst.operands[1].present || inst.size_req == 4)
12429 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
90e4755a 12430 {
c19d1205
ZW
12431 unsigned int imod = (inst.instruction & 0x0030) >> 4;
12432 inst.instruction = 0xf3af8000;
12433 inst.instruction |= imod << 9;
12434 inst.instruction |= inst.operands[0].imm << 5;
12435 if (inst.operands[1].present)
12436 inst.instruction |= 0x100 | inst.operands[1].imm;
90e4755a 12437 }
c19d1205 12438 else
90e4755a 12439 {
62b3e311
PB
12440 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)
12441 && (inst.operands[0].imm & 4),
12442 _("selected processor does not support 'A' form "
12443 "of this instruction"));
12444 constraint (inst.operands[1].present || inst.size_req == 4,
c19d1205
ZW
12445 _("Thumb does not support the 2-argument "
12446 "form of this instruction"));
12447 inst.instruction |= inst.operands[0].imm;
90e4755a 12448 }
90e4755a
RE
12449}
12450
c19d1205
ZW
12451/* THUMB CPY instruction (argument parse). */
12452
90e4755a 12453static void
c19d1205 12454do_t_cpy (void)
90e4755a 12455{
c19d1205 12456 if (inst.size_req == 4)
90e4755a 12457 {
c19d1205
ZW
12458 inst.instruction = THUMB_OP32 (T_MNEM_mov);
12459 inst.instruction |= inst.operands[0].reg << 8;
12460 inst.instruction |= inst.operands[1].reg;
90e4755a 12461 }
c19d1205 12462 else
90e4755a 12463 {
c19d1205
ZW
12464 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
12465 inst.instruction |= (inst.operands[0].reg & 0x7);
12466 inst.instruction |= inst.operands[1].reg << 3;
90e4755a 12467 }
90e4755a
RE
12468}
12469
90e4755a 12470static void
25fe350b 12471do_t_cbz (void)
90e4755a 12472{
5ee91343 12473 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
12474 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12475 inst.instruction |= inst.operands[0].reg;
e2b0ab59
AV
12476 inst.relocs[0].pc_rel = 1;
12477 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
c19d1205 12478}
90e4755a 12479
62b3e311
PB
12480static void
12481do_t_dbg (void)
12482{
12483 inst.instruction |= inst.operands[0].imm;
12484}
12485
12486static void
12487do_t_div (void)
12488{
fdfde340
JM
12489 unsigned Rd, Rn, Rm;
12490
12491 Rd = inst.operands[0].reg;
12492 Rn = (inst.operands[1].present
12493 ? inst.operands[1].reg : Rd);
12494 Rm = inst.operands[2].reg;
12495
12496 reject_bad_reg (Rd);
12497 reject_bad_reg (Rn);
12498 reject_bad_reg (Rm);
12499
12500 inst.instruction |= Rd << 8;
12501 inst.instruction |= Rn << 16;
12502 inst.instruction |= Rm;
62b3e311
PB
12503}
12504
c19d1205
ZW
12505static void
12506do_t_hint (void)
12507{
12508 if (unified_syntax && inst.size_req == 4)
12509 inst.instruction = THUMB_OP32 (inst.instruction);
12510 else
12511 inst.instruction = THUMB_OP16 (inst.instruction);
12512}
90e4755a 12513
c19d1205
ZW
12514static void
12515do_t_it (void)
12516{
12517 unsigned int cond = inst.operands[0].imm;
e27ec89e 12518
5ee91343
AV
12519 set_pred_insn_type (IT_INSN);
12520 now_pred.mask = (inst.instruction & 0xf) | 0x10;
12521 now_pred.cc = cond;
5b7c81bd 12522 now_pred.warn_deprecated = false;
5ee91343 12523 now_pred.type = SCALAR_PRED;
e27ec89e
PB
12524
12525 /* If the condition is a negative condition, invert the mask. */
c19d1205 12526 if ((cond & 0x1) == 0x0)
90e4755a 12527 {
c19d1205 12528 unsigned int mask = inst.instruction & 0x000f;
90e4755a 12529
c19d1205 12530 if ((mask & 0x7) == 0)
5a01bb1d
MGD
12531 {
12532 /* No conversion needed. */
5ee91343 12533 now_pred.block_length = 1;
5a01bb1d 12534 }
c19d1205 12535 else if ((mask & 0x3) == 0)
5a01bb1d
MGD
12536 {
12537 mask ^= 0x8;
5ee91343 12538 now_pred.block_length = 2;
5a01bb1d 12539 }
e27ec89e 12540 else if ((mask & 0x1) == 0)
5a01bb1d
MGD
12541 {
12542 mask ^= 0xC;
5ee91343 12543 now_pred.block_length = 3;
5a01bb1d 12544 }
c19d1205 12545 else
5a01bb1d
MGD
12546 {
12547 mask ^= 0xE;
5ee91343 12548 now_pred.block_length = 4;
5a01bb1d 12549 }
90e4755a 12550
e27ec89e
PB
12551 inst.instruction &= 0xfff0;
12552 inst.instruction |= mask;
c19d1205 12553 }
90e4755a 12554
c19d1205
ZW
12555 inst.instruction |= cond << 4;
12556}
90e4755a 12557
3c707909
PB
12558/* Helper function used for both push/pop and ldm/stm. */
12559static void
5b7c81bd
AM
12560encode_thumb2_multi (bool do_io, int base, unsigned mask,
12561 bool writeback)
3c707909 12562{
5b7c81bd 12563 bool load, store;
3c707909 12564
4b5a202f
AV
12565 gas_assert (base != -1 || !do_io);
12566 load = do_io && ((inst.instruction & (1 << 20)) != 0);
12567 store = do_io && !load;
3c707909
PB
12568
12569 if (mask & (1 << 13))
12570 inst.error = _("SP not allowed in register list");
1e5b0379 12571
4b5a202f 12572 if (do_io && (mask & (1 << base)) != 0
1e5b0379
NC
12573 && writeback)
12574 inst.error = _("having the base register in the register list when "
12575 "using write back is UNPREDICTABLE");
12576
3c707909
PB
12577 if (load)
12578 {
e07e6e58 12579 if (mask & (1 << 15))
477330fc
RM
12580 {
12581 if (mask & (1 << 14))
12582 inst.error = _("LR and PC should not both be in register list");
12583 else
5ee91343 12584 set_pred_insn_type_last ();
477330fc 12585 }
3c707909 12586 }
4b5a202f 12587 else if (store)
3c707909
PB
12588 {
12589 if (mask & (1 << 15))
12590 inst.error = _("PC not allowed in register list");
3c707909
PB
12591 }
12592
4b5a202f 12593 if (do_io && ((mask & (mask - 1)) == 0))
3c707909
PB
12594 {
12595 /* Single register transfers implemented as str/ldr. */
12596 if (writeback)
12597 {
12598 if (inst.instruction & (1 << 23))
12599 inst.instruction = 0x00000b04; /* ia! -> [base], #4 */
12600 else
12601 inst.instruction = 0x00000d04; /* db! -> [base, #-4]! */
12602 }
12603 else
12604 {
12605 if (inst.instruction & (1 << 23))
12606 inst.instruction = 0x00800000; /* ia -> [base] */
12607 else
12608 inst.instruction = 0x00000c04; /* db -> [base, #-4] */
12609 }
12610
12611 inst.instruction |= 0xf8400000;
12612 if (load)
12613 inst.instruction |= 0x00100000;
12614
5f4273c7 12615 mask = ffs (mask) - 1;
3c707909
PB
12616 mask <<= 12;
12617 }
12618 else if (writeback)
12619 inst.instruction |= WRITE_BACK;
12620
12621 inst.instruction |= mask;
4b5a202f
AV
12622 if (do_io)
12623 inst.instruction |= base << 16;
3c707909
PB
12624}
12625
c19d1205
ZW
12626static void
12627do_t_ldmstm (void)
12628{
12629 /* This really doesn't seem worth it. */
e2b0ab59 12630 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205
ZW
12631 _("expression too complex"));
12632 constraint (inst.operands[1].writeback,
12633 _("Thumb load/store multiple does not support {reglist}^"));
90e4755a 12634
c19d1205
ZW
12635 if (unified_syntax)
12636 {
5b7c81bd 12637 bool narrow;
3c707909
PB
12638 unsigned mask;
12639
5b7c81bd 12640 narrow = false;
c19d1205
ZW
12641 /* See if we can use a 16-bit instruction. */
12642 if (inst.instruction < 0xffff /* not ldmdb/stmdb */
12643 && inst.size_req != 4
3c707909 12644 && !(inst.operands[1].imm & ~0xff))
90e4755a 12645 {
3c707909 12646 mask = 1 << inst.operands[0].reg;
90e4755a 12647
eab4f823 12648 if (inst.operands[0].reg <= 7)
90e4755a 12649 {
3c707909 12650 if (inst.instruction == T_MNEM_stmia
eab4f823
MGD
12651 ? inst.operands[0].writeback
12652 : (inst.operands[0].writeback
12653 == !(inst.operands[1].imm & mask)))
477330fc 12654 {
eab4f823
MGD
12655 if (inst.instruction == T_MNEM_stmia
12656 && (inst.operands[1].imm & mask)
12657 && (inst.operands[1].imm & (mask - 1)))
12658 as_warn (_("value stored for r%d is UNKNOWN"),
12659 inst.operands[0].reg);
3c707909 12660
eab4f823
MGD
12661 inst.instruction = THUMB_OP16 (inst.instruction);
12662 inst.instruction |= inst.operands[0].reg << 8;
12663 inst.instruction |= inst.operands[1].imm;
5b7c81bd 12664 narrow = true;
eab4f823
MGD
12665 }
12666 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12667 {
12668 /* This means 1 register in reg list one of 3 situations:
12669 1. Instruction is stmia, but without writeback.
12670 2. lmdia without writeback, but with Rn not in
477330fc 12671 reglist.
eab4f823
MGD
12672 3. ldmia with writeback, but with Rn in reglist.
12673 Case 3 is UNPREDICTABLE behaviour, so we handle
12674 case 1 and 2 which can be converted into a 16-bit
12675 str or ldr. The SP cases are handled below. */
12676 unsigned long opcode;
12677 /* First, record an error for Case 3. */
12678 if (inst.operands[1].imm & mask
12679 && inst.operands[0].writeback)
fa94de6b 12680 inst.error =
eab4f823
MGD
12681 _("having the base register in the register list when "
12682 "using write back is UNPREDICTABLE");
fa94de6b
RM
12683
12684 opcode = (inst.instruction == T_MNEM_stmia ? T_MNEM_str
eab4f823
MGD
12685 : T_MNEM_ldr);
12686 inst.instruction = THUMB_OP16 (opcode);
12687 inst.instruction |= inst.operands[0].reg << 3;
12688 inst.instruction |= (ffs (inst.operands[1].imm)-1);
5b7c81bd 12689 narrow = true;
eab4f823 12690 }
90e4755a 12691 }
eab4f823 12692 else if (inst.operands[0] .reg == REG_SP)
90e4755a 12693 {
eab4f823
MGD
12694 if (inst.operands[0].writeback)
12695 {
fa94de6b 12696 inst.instruction =
eab4f823 12697 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12698 ? T_MNEM_push : T_MNEM_pop);
eab4f823 12699 inst.instruction |= inst.operands[1].imm;
5b7c81bd 12700 narrow = true;
eab4f823
MGD
12701 }
12702 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12703 {
fa94de6b 12704 inst.instruction =
eab4f823 12705 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12706 ? T_MNEM_str_sp : T_MNEM_ldr_sp);
eab4f823 12707 inst.instruction |= ((ffs (inst.operands[1].imm)-1) << 8);
5b7c81bd 12708 narrow = true;
eab4f823 12709 }
90e4755a 12710 }
3c707909
PB
12711 }
12712
12713 if (!narrow)
12714 {
c19d1205
ZW
12715 if (inst.instruction < 0xffff)
12716 inst.instruction = THUMB_OP32 (inst.instruction);
3c707909 12717
5b7c81bd 12718 encode_thumb2_multi (true /* do_io */, inst.operands[0].reg,
4b5a202f
AV
12719 inst.operands[1].imm,
12720 inst.operands[0].writeback);
90e4755a
RE
12721 }
12722 }
c19d1205 12723 else
90e4755a 12724 {
c19d1205
ZW
12725 constraint (inst.operands[0].reg > 7
12726 || (inst.operands[1].imm & ~0xff), BAD_HIREG);
1198ca51
PB
12727 constraint (inst.instruction != T_MNEM_ldmia
12728 && inst.instruction != T_MNEM_stmia,
12729 _("Thumb-2 instruction only valid in unified syntax"));
c19d1205 12730 if (inst.instruction == T_MNEM_stmia)
f03698e6 12731 {
c19d1205
ZW
12732 if (!inst.operands[0].writeback)
12733 as_warn (_("this instruction will write back the base register"));
12734 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
12735 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
1e5b0379 12736 as_warn (_("value stored for r%d is UNKNOWN"),
c19d1205 12737 inst.operands[0].reg);
f03698e6 12738 }
c19d1205 12739 else
90e4755a 12740 {
c19d1205
ZW
12741 if (!inst.operands[0].writeback
12742 && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
12743 as_warn (_("this instruction will write back the base register"));
12744 else if (inst.operands[0].writeback
12745 && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
12746 as_warn (_("this instruction will not write back the base register"));
90e4755a
RE
12747 }
12748
c19d1205
ZW
12749 inst.instruction = THUMB_OP16 (inst.instruction);
12750 inst.instruction |= inst.operands[0].reg << 8;
12751 inst.instruction |= inst.operands[1].imm;
12752 }
12753}
e28cd48c 12754
c19d1205
ZW
12755static void
12756do_t_ldrex (void)
12757{
12758 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
12759 || inst.operands[1].postind || inst.operands[1].writeback
12760 || inst.operands[1].immisreg || inst.operands[1].shifted
12761 || inst.operands[1].negative,
01cfc07f 12762 BAD_ADDR_MODE);
e28cd48c 12763
5be8be5d
DG
12764 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
12765
c19d1205
ZW
12766 inst.instruction |= inst.operands[0].reg << 12;
12767 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 12768 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
c19d1205 12769}
e28cd48c 12770
c19d1205
ZW
12771static void
12772do_t_ldrexd (void)
12773{
12774 if (!inst.operands[1].present)
1cac9012 12775 {
c19d1205
ZW
12776 constraint (inst.operands[0].reg == REG_LR,
12777 _("r14 not allowed as first register "
12778 "when second register is omitted"));
12779 inst.operands[1].reg = inst.operands[0].reg + 1;
b99bd4ef 12780 }
c19d1205
ZW
12781 constraint (inst.operands[0].reg == inst.operands[1].reg,
12782 BAD_OVERLAP);
b99bd4ef 12783
c19d1205
ZW
12784 inst.instruction |= inst.operands[0].reg << 12;
12785 inst.instruction |= inst.operands[1].reg << 8;
12786 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
12787}
12788
12789static void
c19d1205 12790do_t_ldst (void)
b99bd4ef 12791{
0110f2b8
PB
12792 unsigned long opcode;
12793 int Rn;
12794
e07e6e58
NC
12795 if (inst.operands[0].isreg
12796 && !inst.operands[0].preind
12797 && inst.operands[0].reg == REG_PC)
5ee91343 12798 set_pred_insn_type_last ();
e07e6e58 12799
0110f2b8 12800 opcode = inst.instruction;
c19d1205 12801 if (unified_syntax)
b99bd4ef 12802 {
53365c0d
PB
12803 if (!inst.operands[1].isreg)
12804 {
12805 if (opcode <= 0xffff)
12806 inst.instruction = THUMB_OP32 (opcode);
5b7c81bd 12807 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/false))
53365c0d
PB
12808 return;
12809 }
0110f2b8
PB
12810 if (inst.operands[1].isreg
12811 && !inst.operands[1].writeback
c19d1205
ZW
12812 && !inst.operands[1].shifted && !inst.operands[1].postind
12813 && !inst.operands[1].negative && inst.operands[0].reg <= 7
0110f2b8
PB
12814 && opcode <= 0xffff
12815 && inst.size_req != 4)
c19d1205 12816 {
0110f2b8
PB
12817 /* Insn may have a 16-bit form. */
12818 Rn = inst.operands[1].reg;
12819 if (inst.operands[1].immisreg)
12820 {
12821 inst.instruction = THUMB_OP16 (opcode);
5f4273c7 12822 /* [Rn, Rik] */
0110f2b8
PB
12823 if (Rn <= 7 && inst.operands[1].imm <= 7)
12824 goto op16;
5be8be5d
DG
12825 else if (opcode != T_MNEM_ldr && opcode != T_MNEM_str)
12826 reject_bad_reg (inst.operands[1].imm);
0110f2b8
PB
12827 }
12828 else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
12829 && opcode != T_MNEM_ldrsb)
12830 || ((Rn == REG_PC || Rn == REG_SP) && opcode == T_MNEM_ldr)
12831 || (Rn == REG_SP && opcode == T_MNEM_str))
12832 {
12833 /* [Rn, #const] */
12834 if (Rn > 7)
12835 {
12836 if (Rn == REG_PC)
12837 {
e2b0ab59 12838 if (inst.relocs[0].pc_rel)
0110f2b8
PB
12839 opcode = T_MNEM_ldr_pc2;
12840 else
12841 opcode = T_MNEM_ldr_pc;
12842 }
12843 else
12844 {
12845 if (opcode == T_MNEM_ldr)
12846 opcode = T_MNEM_ldr_sp;
12847 else
12848 opcode = T_MNEM_str_sp;
12849 }
12850 inst.instruction = inst.operands[0].reg << 8;
12851 }
12852 else
12853 {
12854 inst.instruction = inst.operands[0].reg;
12855 inst.instruction |= inst.operands[1].reg << 3;
12856 }
12857 inst.instruction |= THUMB_OP16 (opcode);
12858 if (inst.size_req == 2)
e2b0ab59 12859 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
0110f2b8
PB
12860 else
12861 inst.relax = opcode;
12862 return;
12863 }
c19d1205 12864 }
0110f2b8 12865 /* Definitely a 32-bit variant. */
5be8be5d 12866
8d67f500
NC
12867 /* Warning for Erratum 752419. */
12868 if (opcode == T_MNEM_ldr
12869 && inst.operands[0].reg == REG_SP
12870 && inst.operands[1].writeback == 1
12871 && !inst.operands[1].immisreg)
12872 {
12873 if (no_cpu_selected ()
12874 || (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7)
477330fc
RM
12875 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a)
12876 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7r)))
8d67f500
NC
12877 as_warn (_("This instruction may be unpredictable "
12878 "if executed on M-profile cores "
12879 "with interrupts enabled."));
12880 }
12881
5be8be5d 12882 /* Do some validations regarding addressing modes. */
1be5fd2e 12883 if (inst.operands[1].immisreg)
5be8be5d
DG
12884 reject_bad_reg (inst.operands[1].imm);
12885
1be5fd2e
NC
12886 constraint (inst.operands[1].writeback == 1
12887 && inst.operands[0].reg == inst.operands[1].reg,
12888 BAD_OVERLAP);
12889
0110f2b8 12890 inst.instruction = THUMB_OP32 (opcode);
c19d1205 12891 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 12892 encode_thumb32_addr_mode (1, /*is_t=*/false, /*is_d=*/false);
1be5fd2e 12893 check_ldr_r15_aligned ();
b99bd4ef
NC
12894 return;
12895 }
12896
c19d1205
ZW
12897 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12898
12899 if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
b99bd4ef 12900 {
c19d1205
ZW
12901 /* Only [Rn,Rm] is acceptable. */
12902 constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
12903 constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
12904 || inst.operands[1].postind || inst.operands[1].shifted
12905 || inst.operands[1].negative,
12906 _("Thumb does not support this addressing mode"));
12907 inst.instruction = THUMB_OP16 (inst.instruction);
12908 goto op16;
b99bd4ef 12909 }
5f4273c7 12910
c19d1205
ZW
12911 inst.instruction = THUMB_OP16 (inst.instruction);
12912 if (!inst.operands[1].isreg)
5b7c81bd 12913 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/false))
c19d1205 12914 return;
b99bd4ef 12915
c19d1205
ZW
12916 constraint (!inst.operands[1].preind
12917 || inst.operands[1].shifted
12918 || inst.operands[1].writeback,
12919 _("Thumb does not support this addressing mode"));
12920 if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
90e4755a 12921 {
c19d1205
ZW
12922 constraint (inst.instruction & 0x0600,
12923 _("byte or halfword not valid for base register"));
12924 constraint (inst.operands[1].reg == REG_PC
12925 && !(inst.instruction & THUMB_LOAD_BIT),
12926 _("r15 based store not allowed"));
12927 constraint (inst.operands[1].immisreg,
12928 _("invalid base register for register offset"));
b99bd4ef 12929
c19d1205
ZW
12930 if (inst.operands[1].reg == REG_PC)
12931 inst.instruction = T_OPCODE_LDR_PC;
12932 else if (inst.instruction & THUMB_LOAD_BIT)
12933 inst.instruction = T_OPCODE_LDR_SP;
12934 else
12935 inst.instruction = T_OPCODE_STR_SP;
b99bd4ef 12936
c19d1205 12937 inst.instruction |= inst.operands[0].reg << 8;
e2b0ab59 12938 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12939 return;
12940 }
90e4755a 12941
c19d1205
ZW
12942 constraint (inst.operands[1].reg > 7, BAD_HIREG);
12943 if (!inst.operands[1].immisreg)
12944 {
12945 /* Immediate offset. */
12946 inst.instruction |= inst.operands[0].reg;
12947 inst.instruction |= inst.operands[1].reg << 3;
e2b0ab59 12948 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12949 return;
12950 }
90e4755a 12951
c19d1205
ZW
12952 /* Register offset. */
12953 constraint (inst.operands[1].imm > 7, BAD_HIREG);
12954 constraint (inst.operands[1].negative,
12955 _("Thumb does not support this addressing mode"));
90e4755a 12956
c19d1205
ZW
12957 op16:
12958 switch (inst.instruction)
12959 {
12960 case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
12961 case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
12962 case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
12963 case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
12964 case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
12965 case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
12966 case 0x5600 /* ldrsb */:
12967 case 0x5e00 /* ldrsh */: break;
12968 default: abort ();
12969 }
90e4755a 12970
c19d1205
ZW
12971 inst.instruction |= inst.operands[0].reg;
12972 inst.instruction |= inst.operands[1].reg << 3;
12973 inst.instruction |= inst.operands[1].imm << 6;
12974}
90e4755a 12975
c19d1205
ZW
12976static void
12977do_t_ldstd (void)
12978{
12979 if (!inst.operands[1].present)
b99bd4ef 12980 {
c19d1205
ZW
12981 inst.operands[1].reg = inst.operands[0].reg + 1;
12982 constraint (inst.operands[0].reg == REG_LR,
12983 _("r14 not allowed here"));
bd340a04 12984 constraint (inst.operands[0].reg == REG_R12,
477330fc 12985 _("r12 not allowed here"));
b99bd4ef 12986 }
bd340a04
MGD
12987
12988 if (inst.operands[2].writeback
12989 && (inst.operands[0].reg == inst.operands[2].reg
12990 || inst.operands[1].reg == inst.operands[2].reg))
12991 as_warn (_("base register written back, and overlaps "
477330fc 12992 "one of transfer registers"));
bd340a04 12993
c19d1205
ZW
12994 inst.instruction |= inst.operands[0].reg << 12;
12995 inst.instruction |= inst.operands[1].reg << 8;
5b7c81bd 12996 encode_thumb32_addr_mode (2, /*is_t=*/false, /*is_d=*/true);
b99bd4ef
NC
12997}
12998
c19d1205
ZW
12999static void
13000do_t_ldstt (void)
13001{
13002 inst.instruction |= inst.operands[0].reg << 12;
5b7c81bd 13003 encode_thumb32_addr_mode (1, /*is_t=*/true, /*is_d=*/false);
c19d1205 13004}
a737bd4d 13005
b99bd4ef 13006static void
c19d1205 13007do_t_mla (void)
b99bd4ef 13008{
fdfde340 13009 unsigned Rd, Rn, Rm, Ra;
c921be7d 13010
fdfde340
JM
13011 Rd = inst.operands[0].reg;
13012 Rn = inst.operands[1].reg;
13013 Rm = inst.operands[2].reg;
13014 Ra = inst.operands[3].reg;
13015
13016 reject_bad_reg (Rd);
13017 reject_bad_reg (Rn);
13018 reject_bad_reg (Rm);
13019 reject_bad_reg (Ra);
13020
13021 inst.instruction |= Rd << 8;
13022 inst.instruction |= Rn << 16;
13023 inst.instruction |= Rm;
13024 inst.instruction |= Ra << 12;
c19d1205 13025}
b99bd4ef 13026
c19d1205
ZW
13027static void
13028do_t_mlal (void)
13029{
fdfde340
JM
13030 unsigned RdLo, RdHi, Rn, Rm;
13031
13032 RdLo = inst.operands[0].reg;
13033 RdHi = inst.operands[1].reg;
13034 Rn = inst.operands[2].reg;
13035 Rm = inst.operands[3].reg;
13036
13037 reject_bad_reg (RdLo);
13038 reject_bad_reg (RdHi);
13039 reject_bad_reg (Rn);
13040 reject_bad_reg (Rm);
13041
13042 inst.instruction |= RdLo << 12;
13043 inst.instruction |= RdHi << 8;
13044 inst.instruction |= Rn << 16;
13045 inst.instruction |= Rm;
c19d1205 13046}
b99bd4ef 13047
c19d1205
ZW
13048static void
13049do_t_mov_cmp (void)
13050{
fdfde340
JM
13051 unsigned Rn, Rm;
13052
13053 Rn = inst.operands[0].reg;
13054 Rm = inst.operands[1].reg;
13055
e07e6e58 13056 if (Rn == REG_PC)
5ee91343 13057 set_pred_insn_type_last ();
e07e6e58 13058
c19d1205 13059 if (unified_syntax)
b99bd4ef 13060 {
c19d1205
ZW
13061 int r0off = (inst.instruction == T_MNEM_mov
13062 || inst.instruction == T_MNEM_movs) ? 8 : 16;
0110f2b8 13063 unsigned long opcode;
5b7c81bd
AM
13064 bool narrow;
13065 bool low_regs;
3d388997 13066
fdfde340 13067 low_regs = (Rn <= 7 && Rm <= 7);
0110f2b8 13068 opcode = inst.instruction;
5ee91343 13069 if (in_pred_block ())
0110f2b8 13070 narrow = opcode != T_MNEM_movs;
3d388997 13071 else
0110f2b8 13072 narrow = opcode != T_MNEM_movs || low_regs;
3d388997
PB
13073 if (inst.size_req == 4
13074 || inst.operands[1].shifted)
5b7c81bd 13075 narrow = false;
3d388997 13076
efd81785
PB
13077 /* MOVS PC, LR is encoded as SUBS PC, LR, #0. */
13078 if (opcode == T_MNEM_movs && inst.operands[1].isreg
13079 && !inst.operands[1].shifted
fdfde340
JM
13080 && Rn == REG_PC
13081 && Rm == REG_LR)
efd81785
PB
13082 {
13083 inst.instruction = T2_SUBS_PC_LR;
13084 return;
13085 }
13086
fdfde340
JM
13087 if (opcode == T_MNEM_cmp)
13088 {
13089 constraint (Rn == REG_PC, BAD_PC);
94206790
MM
13090 if (narrow)
13091 {
13092 /* In the Thumb-2 ISA, use of R13 as Rm is deprecated,
13093 but valid. */
13094 warn_deprecated_sp (Rm);
13095 /* R15 was documented as a valid choice for Rm in ARMv6,
13096 but as UNPREDICTABLE in ARMv7. ARM's proprietary
13097 tools reject R15, so we do too. */
13098 constraint (Rm == REG_PC, BAD_PC);
13099 }
13100 else
13101 reject_bad_reg (Rm);
fdfde340
JM
13102 }
13103 else if (opcode == T_MNEM_mov
13104 || opcode == T_MNEM_movs)
13105 {
13106 if (inst.operands[1].isreg)
13107 {
13108 if (opcode == T_MNEM_movs)
13109 {
13110 reject_bad_reg (Rn);
13111 reject_bad_reg (Rm);
13112 }
76fa04a4
MGD
13113 else if (narrow)
13114 {
13115 /* This is mov.n. */
13116 if ((Rn == REG_SP || Rn == REG_PC)
13117 && (Rm == REG_SP || Rm == REG_PC))
13118 {
5c3696f8 13119 as_tsktsk (_("Use of r%u as a source register is "
76fa04a4
MGD
13120 "deprecated when r%u is the destination "
13121 "register."), Rm, Rn);
13122 }
13123 }
13124 else
13125 {
13126 /* This is mov.w. */
13127 constraint (Rn == REG_PC, BAD_PC);
13128 constraint (Rm == REG_PC, BAD_PC);
5c8ed6a4
JW
13129 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
13130 constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
76fa04a4 13131 }
fdfde340
JM
13132 }
13133 else
13134 reject_bad_reg (Rn);
13135 }
13136
c19d1205
ZW
13137 if (!inst.operands[1].isreg)
13138 {
0110f2b8 13139 /* Immediate operand. */
5ee91343 13140 if (!in_pred_block () && opcode == T_MNEM_mov)
0110f2b8
PB
13141 narrow = 0;
13142 if (low_regs && narrow)
13143 {
13144 inst.instruction = THUMB_OP16 (opcode);
fdfde340 13145 inst.instruction |= Rn << 8;
e2b0ab59
AV
13146 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
13147 || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
72d98d16 13148 {
a9f02af8 13149 if (inst.size_req == 2)
e2b0ab59 13150 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
a9f02af8
MG
13151 else
13152 inst.relax = opcode;
72d98d16 13153 }
0110f2b8
PB
13154 }
13155 else
13156 {
e2b0ab59
AV
13157 constraint ((inst.relocs[0].type
13158 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
13159 && (inst.relocs[0].type
13160 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8
MG
13161 THUMB1_RELOC_ONLY);
13162
0110f2b8
PB
13163 inst.instruction = THUMB_OP32 (inst.instruction);
13164 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 13165 inst.instruction |= Rn << r0off;
e2b0ab59 13166 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8 13167 }
c19d1205 13168 }
728ca7c9
PB
13169 else if (inst.operands[1].shifted && inst.operands[1].immisreg
13170 && (inst.instruction == T_MNEM_mov
13171 || inst.instruction == T_MNEM_movs))
13172 {
13173 /* Register shifts are encoded as separate shift instructions. */
5b7c81bd 13174 bool flags = (inst.instruction == T_MNEM_movs);
728ca7c9 13175
5ee91343 13176 if (in_pred_block ())
728ca7c9
PB
13177 narrow = !flags;
13178 else
13179 narrow = flags;
13180
13181 if (inst.size_req == 4)
5b7c81bd 13182 narrow = false;
728ca7c9
PB
13183
13184 if (!low_regs || inst.operands[1].imm > 7)
5b7c81bd 13185 narrow = false;
728ca7c9 13186
fdfde340 13187 if (Rn != Rm)
5b7c81bd 13188 narrow = false;
728ca7c9
PB
13189
13190 switch (inst.operands[1].shift_kind)
13191 {
13192 case SHIFT_LSL:
13193 opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl);
13194 break;
13195 case SHIFT_ASR:
13196 opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr);
13197 break;
13198 case SHIFT_LSR:
13199 opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr);
13200 break;
13201 case SHIFT_ROR:
13202 opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror);
13203 break;
13204 default:
5f4273c7 13205 abort ();
728ca7c9
PB
13206 }
13207
13208 inst.instruction = opcode;
13209 if (narrow)
13210 {
fdfde340 13211 inst.instruction |= Rn;
728ca7c9
PB
13212 inst.instruction |= inst.operands[1].imm << 3;
13213 }
13214 else
13215 {
13216 if (flags)
13217 inst.instruction |= CONDS_BIT;
13218
fdfde340
JM
13219 inst.instruction |= Rn << 8;
13220 inst.instruction |= Rm << 16;
728ca7c9
PB
13221 inst.instruction |= inst.operands[1].imm;
13222 }
13223 }
3d388997 13224 else if (!narrow)
c19d1205 13225 {
728ca7c9
PB
13226 /* Some mov with immediate shift have narrow variants.
13227 Register shifts are handled above. */
13228 if (low_regs && inst.operands[1].shifted
13229 && (inst.instruction == T_MNEM_mov
13230 || inst.instruction == T_MNEM_movs))
13231 {
5ee91343 13232 if (in_pred_block ())
728ca7c9
PB
13233 narrow = (inst.instruction == T_MNEM_mov);
13234 else
13235 narrow = (inst.instruction == T_MNEM_movs);
13236 }
13237
13238 if (narrow)
13239 {
13240 switch (inst.operands[1].shift_kind)
13241 {
13242 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
13243 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
13244 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
5b7c81bd 13245 default: narrow = false; break;
728ca7c9
PB
13246 }
13247 }
13248
13249 if (narrow)
13250 {
fdfde340
JM
13251 inst.instruction |= Rn;
13252 inst.instruction |= Rm << 3;
e2b0ab59 13253 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
728ca7c9
PB
13254 }
13255 else
13256 {
13257 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 13258 inst.instruction |= Rn << r0off;
728ca7c9
PB
13259 encode_thumb32_shifted_operand (1);
13260 }
c19d1205
ZW
13261 }
13262 else
13263 switch (inst.instruction)
13264 {
13265 case T_MNEM_mov:
837b3435 13266 /* In v4t or v5t a move of two lowregs produces unpredictable
c6400f8a
MGD
13267 results. Don't allow this. */
13268 if (low_regs)
13269 {
13270 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
13271 "MOV Rd, Rs with two low registers is not "
13272 "permitted on this architecture");
fa94de6b 13273 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
c6400f8a
MGD
13274 arm_ext_v6);
13275 }
13276
c19d1205 13277 inst.instruction = T_OPCODE_MOV_HR;
fdfde340
JM
13278 inst.instruction |= (Rn & 0x8) << 4;
13279 inst.instruction |= (Rn & 0x7);
13280 inst.instruction |= Rm << 3;
c19d1205 13281 break;
b99bd4ef 13282
c19d1205
ZW
13283 case T_MNEM_movs:
13284 /* We know we have low registers at this point.
941a8a52
MGD
13285 Generate LSLS Rd, Rs, #0. */
13286 inst.instruction = T_OPCODE_LSL_I;
fdfde340
JM
13287 inst.instruction |= Rn;
13288 inst.instruction |= Rm << 3;
c19d1205
ZW
13289 break;
13290
13291 case T_MNEM_cmp:
3d388997 13292 if (low_regs)
c19d1205
ZW
13293 {
13294 inst.instruction = T_OPCODE_CMP_LR;
fdfde340
JM
13295 inst.instruction |= Rn;
13296 inst.instruction |= Rm << 3;
c19d1205
ZW
13297 }
13298 else
13299 {
13300 inst.instruction = T_OPCODE_CMP_HR;
fdfde340
JM
13301 inst.instruction |= (Rn & 0x8) << 4;
13302 inst.instruction |= (Rn & 0x7);
13303 inst.instruction |= Rm << 3;
c19d1205
ZW
13304 }
13305 break;
13306 }
b99bd4ef
NC
13307 return;
13308 }
13309
c19d1205 13310 inst.instruction = THUMB_OP16 (inst.instruction);
539d4391
NC
13311
13312 /* PR 10443: Do not silently ignore shifted operands. */
13313 constraint (inst.operands[1].shifted,
13314 _("shifts in CMP/MOV instructions are only supported in unified syntax"));
13315
c19d1205 13316 if (inst.operands[1].isreg)
b99bd4ef 13317 {
fdfde340 13318 if (Rn < 8 && Rm < 8)
b99bd4ef 13319 {
c19d1205
ZW
13320 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
13321 since a MOV instruction produces unpredictable results. */
13322 if (inst.instruction == T_OPCODE_MOV_I8)
13323 inst.instruction = T_OPCODE_ADD_I3;
b99bd4ef 13324 else
c19d1205 13325 inst.instruction = T_OPCODE_CMP_LR;
b99bd4ef 13326
fdfde340
JM
13327 inst.instruction |= Rn;
13328 inst.instruction |= Rm << 3;
b99bd4ef
NC
13329 }
13330 else
13331 {
c19d1205
ZW
13332 if (inst.instruction == T_OPCODE_MOV_I8)
13333 inst.instruction = T_OPCODE_MOV_HR;
13334 else
13335 inst.instruction = T_OPCODE_CMP_HR;
13336 do_t_cpy ();
b99bd4ef
NC
13337 }
13338 }
c19d1205 13339 else
b99bd4ef 13340 {
fdfde340 13341 constraint (Rn > 7,
c19d1205 13342 _("only lo regs allowed with immediate"));
fdfde340 13343 inst.instruction |= Rn << 8;
e2b0ab59 13344 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
c19d1205
ZW
13345 }
13346}
b99bd4ef 13347
c19d1205
ZW
13348static void
13349do_t_mov16 (void)
13350{
fdfde340 13351 unsigned Rd;
b6895b4f 13352 bfd_vma imm;
5b7c81bd 13353 bool top;
b6895b4f
PB
13354
13355 top = (inst.instruction & 0x00800000) != 0;
e2b0ab59 13356 if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
b6895b4f 13357 {
33eaf5de 13358 constraint (top, _(":lower16: not allowed in this instruction"));
e2b0ab59 13359 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
b6895b4f 13360 }
e2b0ab59 13361 else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
b6895b4f 13362 {
33eaf5de 13363 constraint (!top, _(":upper16: not allowed in this instruction"));
e2b0ab59 13364 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
b6895b4f
PB
13365 }
13366
fdfde340
JM
13367 Rd = inst.operands[0].reg;
13368 reject_bad_reg (Rd);
13369
13370 inst.instruction |= Rd << 8;
e2b0ab59 13371 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 13372 {
e2b0ab59 13373 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
13374 inst.instruction |= (imm & 0xf000) << 4;
13375 inst.instruction |= (imm & 0x0800) << 15;
13376 inst.instruction |= (imm & 0x0700) << 4;
13377 inst.instruction |= (imm & 0x00ff);
13378 }
c19d1205 13379}
b99bd4ef 13380
c19d1205
ZW
13381static void
13382do_t_mvn_tst (void)
13383{
fdfde340 13384 unsigned Rn, Rm;
c921be7d 13385
fdfde340
JM
13386 Rn = inst.operands[0].reg;
13387 Rm = inst.operands[1].reg;
13388
13389 if (inst.instruction == T_MNEM_cmp
13390 || inst.instruction == T_MNEM_cmn)
13391 constraint (Rn == REG_PC, BAD_PC);
13392 else
13393 reject_bad_reg (Rn);
13394 reject_bad_reg (Rm);
13395
c19d1205
ZW
13396 if (unified_syntax)
13397 {
13398 int r0off = (inst.instruction == T_MNEM_mvn
13399 || inst.instruction == T_MNEM_mvns) ? 8 : 16;
5b7c81bd 13400 bool narrow;
3d388997
PB
13401
13402 if (inst.size_req == 4
13403 || inst.instruction > 0xffff
13404 || inst.operands[1].shifted
fdfde340 13405 || Rn > 7 || Rm > 7)
5b7c81bd 13406 narrow = false;
fe8b4cc3
KT
13407 else if (inst.instruction == T_MNEM_cmn
13408 || inst.instruction == T_MNEM_tst)
5b7c81bd 13409 narrow = true;
3d388997 13410 else if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13411 narrow = !in_pred_block ();
3d388997 13412 else
5ee91343 13413 narrow = in_pred_block ();
3d388997 13414
c19d1205 13415 if (!inst.operands[1].isreg)
b99bd4ef 13416 {
c19d1205
ZW
13417 /* For an immediate, we always generate a 32-bit opcode;
13418 section relaxation will shrink it later if possible. */
13419 if (inst.instruction < 0xffff)
13420 inst.instruction = THUMB_OP32 (inst.instruction);
13421 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 13422 inst.instruction |= Rn << r0off;
e2b0ab59 13423 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 13424 }
c19d1205 13425 else
b99bd4ef 13426 {
c19d1205 13427 /* See if we can do this with a 16-bit instruction. */
3d388997 13428 if (narrow)
b99bd4ef 13429 {
c19d1205 13430 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13431 inst.instruction |= Rn;
13432 inst.instruction |= Rm << 3;
b99bd4ef 13433 }
c19d1205 13434 else
b99bd4ef 13435 {
c19d1205
ZW
13436 constraint (inst.operands[1].shifted
13437 && inst.operands[1].immisreg,
13438 _("shift must be constant"));
13439 if (inst.instruction < 0xffff)
13440 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 13441 inst.instruction |= Rn << r0off;
c19d1205 13442 encode_thumb32_shifted_operand (1);
b99bd4ef 13443 }
b99bd4ef
NC
13444 }
13445 }
13446 else
13447 {
c19d1205
ZW
13448 constraint (inst.instruction > 0xffff
13449 || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
13450 constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
13451 _("unshifted register required"));
fdfde340 13452 constraint (Rn > 7 || Rm > 7,
c19d1205 13453 BAD_HIREG);
b99bd4ef 13454
c19d1205 13455 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13456 inst.instruction |= Rn;
13457 inst.instruction |= Rm << 3;
b99bd4ef 13458 }
b99bd4ef
NC
13459}
13460
b05fe5cf 13461static void
c19d1205 13462do_t_mrs (void)
b05fe5cf 13463{
fdfde340 13464 unsigned Rd;
037e8744
JB
13465
13466 if (do_vfp_nsyn_mrs () == SUCCESS)
13467 return;
13468
90ec0d68
MGD
13469 Rd = inst.operands[0].reg;
13470 reject_bad_reg (Rd);
13471 inst.instruction |= Rd << 8;
13472
13473 if (inst.operands[1].isreg)
62b3e311 13474 {
90ec0d68
MGD
13475 unsigned br = inst.operands[1].reg;
13476 if (((br & 0x200) == 0) && ((br & 0xf000) != 0xf000))
13477 as_bad (_("bad register for mrs"));
13478
13479 inst.instruction |= br & (0xf << 16);
13480 inst.instruction |= (br & 0x300) >> 4;
13481 inst.instruction |= (br & SPSR_BIT) >> 2;
62b3e311
PB
13482 }
13483 else
13484 {
90ec0d68 13485 int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
5f4273c7 13486
d2cd1205 13487 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
1a43faaf
NC
13488 {
13489 /* PR gas/12698: The constraint is only applied for m_profile.
13490 If the user has specified -march=all, we want to ignore it as
13491 we are building for any CPU type, including non-m variants. */
5b7c81bd 13492 bool m_profile =
823d2571 13493 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf
NC
13494 constraint ((flags != 0) && m_profile, _("selected processor does "
13495 "not support requested special purpose register"));
13496 }
90ec0d68 13497 else
d2cd1205
JB
13498 /* mrs only accepts APSR/CPSR/SPSR/CPSR_all/SPSR_all (for non-M profile
13499 devices). */
13500 constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
13501 _("'APSR', 'CPSR' or 'SPSR' expected"));
fdfde340 13502
90ec0d68
MGD
13503 inst.instruction |= (flags & SPSR_BIT) >> 2;
13504 inst.instruction |= inst.operands[1].imm & 0xff;
13505 inst.instruction |= 0xf0000;
13506 }
c19d1205 13507}
b05fe5cf 13508
c19d1205
ZW
13509static void
13510do_t_msr (void)
13511{
62b3e311 13512 int flags;
fdfde340 13513 unsigned Rn;
62b3e311 13514
037e8744
JB
13515 if (do_vfp_nsyn_msr () == SUCCESS)
13516 return;
13517
c19d1205
ZW
13518 constraint (!inst.operands[1].isreg,
13519 _("Thumb encoding does not support an immediate here"));
90ec0d68
MGD
13520
13521 if (inst.operands[0].isreg)
13522 flags = (int)(inst.operands[0].reg);
13523 else
13524 flags = inst.operands[0].imm;
13525
d2cd1205 13526 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
62b3e311 13527 {
d2cd1205
JB
13528 int bits = inst.operands[0].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
13529
1a43faaf 13530 /* PR gas/12698: The constraint is only applied for m_profile.
477330fc
RM
13531 If the user has specified -march=all, we want to ignore it as
13532 we are building for any CPU type, including non-m variants. */
5b7c81bd 13533 bool m_profile =
823d2571 13534 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf 13535 constraint (((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
477330fc
RM
13536 && (bits & ~(PSR_s | PSR_f)) != 0)
13537 || (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
13538 && bits != PSR_f)) && m_profile,
13539 _("selected processor does not support requested special "
13540 "purpose register"));
62b3e311
PB
13541 }
13542 else
d2cd1205
JB
13543 constraint ((flags & 0xff) != 0, _("selected processor does not support "
13544 "requested special purpose register"));
c921be7d 13545
fdfde340
JM
13546 Rn = inst.operands[1].reg;
13547 reject_bad_reg (Rn);
13548
62b3e311 13549 inst.instruction |= (flags & SPSR_BIT) >> 2;
90ec0d68
MGD
13550 inst.instruction |= (flags & 0xf0000) >> 8;
13551 inst.instruction |= (flags & 0x300) >> 4;
62b3e311 13552 inst.instruction |= (flags & 0xff);
fdfde340 13553 inst.instruction |= Rn << 16;
c19d1205 13554}
b05fe5cf 13555
c19d1205
ZW
13556static void
13557do_t_mul (void)
13558{
5b7c81bd 13559 bool narrow;
fdfde340 13560 unsigned Rd, Rn, Rm;
17828f45 13561
c19d1205
ZW
13562 if (!inst.operands[2].present)
13563 inst.operands[2].reg = inst.operands[0].reg;
b05fe5cf 13564
fdfde340
JM
13565 Rd = inst.operands[0].reg;
13566 Rn = inst.operands[1].reg;
13567 Rm = inst.operands[2].reg;
13568
17828f45 13569 if (unified_syntax)
b05fe5cf 13570 {
17828f45 13571 if (inst.size_req == 4
fdfde340
JM
13572 || (Rd != Rn
13573 && Rd != Rm)
13574 || Rn > 7
13575 || Rm > 7)
5b7c81bd 13576 narrow = false;
17828f45 13577 else if (inst.instruction == T_MNEM_muls)
5ee91343 13578 narrow = !in_pred_block ();
17828f45 13579 else
5ee91343 13580 narrow = in_pred_block ();
b05fe5cf 13581 }
c19d1205 13582 else
b05fe5cf 13583 {
17828f45 13584 constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32);
fdfde340 13585 constraint (Rn > 7 || Rm > 7,
c19d1205 13586 BAD_HIREG);
5b7c81bd 13587 narrow = true;
17828f45 13588 }
b05fe5cf 13589
17828f45
JM
13590 if (narrow)
13591 {
13592 /* 16-bit MULS/Conditional MUL. */
c19d1205 13593 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 13594 inst.instruction |= Rd;
b05fe5cf 13595
fdfde340
JM
13596 if (Rd == Rn)
13597 inst.instruction |= Rm << 3;
13598 else if (Rd == Rm)
13599 inst.instruction |= Rn << 3;
c19d1205
ZW
13600 else
13601 constraint (1, _("dest must overlap one source register"));
13602 }
17828f45
JM
13603 else
13604 {
e07e6e58
NC
13605 constraint (inst.instruction != T_MNEM_mul,
13606 _("Thumb-2 MUL must not set flags"));
17828f45
JM
13607 /* 32-bit MUL. */
13608 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13609 inst.instruction |= Rd << 8;
13610 inst.instruction |= Rn << 16;
13611 inst.instruction |= Rm << 0;
13612
13613 reject_bad_reg (Rd);
13614 reject_bad_reg (Rn);
13615 reject_bad_reg (Rm);
17828f45 13616 }
c19d1205 13617}
b05fe5cf 13618
c19d1205
ZW
13619static void
13620do_t_mull (void)
13621{
fdfde340 13622 unsigned RdLo, RdHi, Rn, Rm;
b05fe5cf 13623
fdfde340
JM
13624 RdLo = inst.operands[0].reg;
13625 RdHi = inst.operands[1].reg;
13626 Rn = inst.operands[2].reg;
13627 Rm = inst.operands[3].reg;
13628
13629 reject_bad_reg (RdLo);
13630 reject_bad_reg (RdHi);
13631 reject_bad_reg (Rn);
13632 reject_bad_reg (Rm);
13633
13634 inst.instruction |= RdLo << 12;
13635 inst.instruction |= RdHi << 8;
13636 inst.instruction |= Rn << 16;
13637 inst.instruction |= Rm;
13638
13639 if (RdLo == RdHi)
c19d1205
ZW
13640 as_tsktsk (_("rdhi and rdlo must be different"));
13641}
b05fe5cf 13642
c19d1205
ZW
13643static void
13644do_t_nop (void)
13645{
5ee91343 13646 set_pred_insn_type (NEUTRAL_IT_INSN);
e07e6e58 13647
c19d1205
ZW
13648 if (unified_syntax)
13649 {
13650 if (inst.size_req == 4 || inst.operands[0].imm > 15)
b05fe5cf 13651 {
c19d1205
ZW
13652 inst.instruction = THUMB_OP32 (inst.instruction);
13653 inst.instruction |= inst.operands[0].imm;
13654 }
13655 else
13656 {
bc2d1808
NC
13657 /* PR9722: Check for Thumb2 availability before
13658 generating a thumb2 nop instruction. */
afa62d5e 13659 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
bc2d1808
NC
13660 {
13661 inst.instruction = THUMB_OP16 (inst.instruction);
13662 inst.instruction |= inst.operands[0].imm << 4;
13663 }
13664 else
13665 inst.instruction = 0x46c0;
c19d1205
ZW
13666 }
13667 }
13668 else
13669 {
13670 constraint (inst.operands[0].present,
13671 _("Thumb does not support NOP with hints"));
13672 inst.instruction = 0x46c0;
13673 }
13674}
b05fe5cf 13675
c19d1205
ZW
13676static void
13677do_t_neg (void)
13678{
13679 if (unified_syntax)
13680 {
5b7c81bd 13681 bool narrow;
3d388997
PB
13682
13683 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13684 narrow = !in_pred_block ();
3d388997 13685 else
5ee91343 13686 narrow = in_pred_block ();
3d388997 13687 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
5b7c81bd 13688 narrow = false;
3d388997 13689 if (inst.size_req == 4)
5b7c81bd 13690 narrow = false;
3d388997
PB
13691
13692 if (!narrow)
c19d1205
ZW
13693 {
13694 inst.instruction = THUMB_OP32 (inst.instruction);
13695 inst.instruction |= inst.operands[0].reg << 8;
13696 inst.instruction |= inst.operands[1].reg << 16;
b05fe5cf
ZW
13697 }
13698 else
13699 {
c19d1205
ZW
13700 inst.instruction = THUMB_OP16 (inst.instruction);
13701 inst.instruction |= inst.operands[0].reg;
13702 inst.instruction |= inst.operands[1].reg << 3;
b05fe5cf
ZW
13703 }
13704 }
13705 else
13706 {
c19d1205
ZW
13707 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
13708 BAD_HIREG);
13709 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
13710
13711 inst.instruction = THUMB_OP16 (inst.instruction);
13712 inst.instruction |= inst.operands[0].reg;
13713 inst.instruction |= inst.operands[1].reg << 3;
13714 }
13715}
13716
1c444d06
JM
13717static void
13718do_t_orn (void)
13719{
13720 unsigned Rd, Rn;
13721
13722 Rd = inst.operands[0].reg;
13723 Rn = inst.operands[1].present ? inst.operands[1].reg : Rd;
13724
fdfde340
JM
13725 reject_bad_reg (Rd);
13726 /* Rn == REG_SP is unpredictable; Rn == REG_PC is MVN. */
13727 reject_bad_reg (Rn);
13728
1c444d06
JM
13729 inst.instruction |= Rd << 8;
13730 inst.instruction |= Rn << 16;
13731
13732 if (!inst.operands[2].isreg)
13733 {
13734 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13735 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
1c444d06
JM
13736 }
13737 else
13738 {
13739 unsigned Rm;
13740
13741 Rm = inst.operands[2].reg;
fdfde340 13742 reject_bad_reg (Rm);
1c444d06
JM
13743
13744 constraint (inst.operands[2].shifted
13745 && inst.operands[2].immisreg,
13746 _("shift must be constant"));
13747 encode_thumb32_shifted_operand (2);
13748 }
13749}
13750
c19d1205
ZW
13751static void
13752do_t_pkhbt (void)
13753{
fdfde340
JM
13754 unsigned Rd, Rn, Rm;
13755
13756 Rd = inst.operands[0].reg;
13757 Rn = inst.operands[1].reg;
13758 Rm = inst.operands[2].reg;
13759
13760 reject_bad_reg (Rd);
13761 reject_bad_reg (Rn);
13762 reject_bad_reg (Rm);
13763
13764 inst.instruction |= Rd << 8;
13765 inst.instruction |= Rn << 16;
13766 inst.instruction |= Rm;
c19d1205
ZW
13767 if (inst.operands[3].present)
13768 {
e2b0ab59
AV
13769 unsigned int val = inst.relocs[0].exp.X_add_number;
13770 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
13771 _("expression too complex"));
13772 inst.instruction |= (val & 0x1c) << 10;
13773 inst.instruction |= (val & 0x03) << 6;
b05fe5cf 13774 }
c19d1205 13775}
b05fe5cf 13776
c19d1205
ZW
13777static void
13778do_t_pkhtb (void)
13779{
13780 if (!inst.operands[3].present)
1ef52f49
NC
13781 {
13782 unsigned Rtmp;
13783
13784 inst.instruction &= ~0x00000020;
13785
13786 /* PR 10168. Swap the Rm and Rn registers. */
13787 Rtmp = inst.operands[1].reg;
13788 inst.operands[1].reg = inst.operands[2].reg;
13789 inst.operands[2].reg = Rtmp;
13790 }
c19d1205 13791 do_t_pkhbt ();
b05fe5cf
ZW
13792}
13793
c19d1205
ZW
13794static void
13795do_t_pld (void)
13796{
fdfde340
JM
13797 if (inst.operands[0].immisreg)
13798 reject_bad_reg (inst.operands[0].imm);
13799
5b7c81bd 13800 encode_thumb32_addr_mode (0, /*is_t=*/false, /*is_d=*/false);
c19d1205 13801}
b05fe5cf 13802
c19d1205
ZW
13803static void
13804do_t_push_pop (void)
b99bd4ef 13805{
e9f89963 13806 unsigned mask;
5f4273c7 13807
c19d1205
ZW
13808 constraint (inst.operands[0].writeback,
13809 _("push/pop do not support {reglist}^"));
e2b0ab59 13810 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205 13811 _("expression too complex"));
b99bd4ef 13812
e9f89963 13813 mask = inst.operands[0].imm;
d3bfe16e 13814 if (inst.size_req != 4 && (mask & ~0xff) == 0)
3c707909 13815 inst.instruction = THUMB_OP16 (inst.instruction) | mask;
d3bfe16e 13816 else if (inst.size_req != 4
c6025a80 13817 && (mask & ~0xff) == (1U << (inst.instruction == T_MNEM_push
d3bfe16e 13818 ? REG_LR : REG_PC)))
b99bd4ef 13819 {
c19d1205
ZW
13820 inst.instruction = THUMB_OP16 (inst.instruction);
13821 inst.instruction |= THUMB_PP_PC_LR;
3c707909 13822 inst.instruction |= mask & 0xff;
c19d1205
ZW
13823 }
13824 else if (unified_syntax)
13825 {
3c707909 13826 inst.instruction = THUMB_OP32 (inst.instruction);
5b7c81bd 13827 encode_thumb2_multi (true /* do_io */, 13, mask, true);
4b5a202f
AV
13828 }
13829 else
13830 {
13831 inst.error = _("invalid register list to push/pop instruction");
13832 return;
c19d1205 13833 }
4b5a202f
AV
13834}
13835
13836static void
13837do_t_clrm (void)
13838{
13839 if (unified_syntax)
5b7c81bd 13840 encode_thumb2_multi (false /* do_io */, -1, inst.operands[0].imm, false);
c19d1205
ZW
13841 else
13842 {
13843 inst.error = _("invalid register list to push/pop instruction");
13844 return;
13845 }
c19d1205 13846}
b99bd4ef 13847
efd6b359
AV
13848static void
13849do_t_vscclrm (void)
13850{
13851 if (inst.operands[0].issingle)
13852 {
13853 inst.instruction |= (inst.operands[0].reg & 0x1) << 22;
13854 inst.instruction |= (inst.operands[0].reg & 0x1e) << 11;
13855 inst.instruction |= inst.operands[0].imm;
13856 }
13857 else
13858 {
13859 inst.instruction |= (inst.operands[0].reg & 0x10) << 18;
13860 inst.instruction |= (inst.operands[0].reg & 0xf) << 12;
13861 inst.instruction |= 1 << 8;
13862 inst.instruction |= inst.operands[0].imm << 1;
13863 }
13864}
13865
c19d1205
ZW
13866static void
13867do_t_rbit (void)
13868{
fdfde340
JM
13869 unsigned Rd, Rm;
13870
13871 Rd = inst.operands[0].reg;
13872 Rm = inst.operands[1].reg;
13873
13874 reject_bad_reg (Rd);
13875 reject_bad_reg (Rm);
13876
13877 inst.instruction |= Rd << 8;
13878 inst.instruction |= Rm << 16;
13879 inst.instruction |= Rm;
c19d1205 13880}
b99bd4ef 13881
c19d1205
ZW
13882static void
13883do_t_rev (void)
13884{
fdfde340
JM
13885 unsigned Rd, Rm;
13886
13887 Rd = inst.operands[0].reg;
13888 Rm = inst.operands[1].reg;
13889
13890 reject_bad_reg (Rd);
13891 reject_bad_reg (Rm);
13892
13893 if (Rd <= 7 && Rm <= 7
c19d1205
ZW
13894 && inst.size_req != 4)
13895 {
13896 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13897 inst.instruction |= Rd;
13898 inst.instruction |= Rm << 3;
c19d1205
ZW
13899 }
13900 else if (unified_syntax)
13901 {
13902 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13903 inst.instruction |= Rd << 8;
13904 inst.instruction |= Rm << 16;
13905 inst.instruction |= Rm;
c19d1205
ZW
13906 }
13907 else
13908 inst.error = BAD_HIREG;
13909}
b99bd4ef 13910
1c444d06
JM
13911static void
13912do_t_rrx (void)
13913{
13914 unsigned Rd, Rm;
13915
13916 Rd = inst.operands[0].reg;
13917 Rm = inst.operands[1].reg;
13918
fdfde340
JM
13919 reject_bad_reg (Rd);
13920 reject_bad_reg (Rm);
c921be7d 13921
1c444d06
JM
13922 inst.instruction |= Rd << 8;
13923 inst.instruction |= Rm;
13924}
13925
c19d1205
ZW
13926static void
13927do_t_rsb (void)
13928{
fdfde340 13929 unsigned Rd, Rs;
b99bd4ef 13930
c19d1205
ZW
13931 Rd = inst.operands[0].reg;
13932 Rs = (inst.operands[1].present
13933 ? inst.operands[1].reg /* Rd, Rs, foo */
13934 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
b99bd4ef 13935
fdfde340
JM
13936 reject_bad_reg (Rd);
13937 reject_bad_reg (Rs);
13938 if (inst.operands[2].isreg)
13939 reject_bad_reg (inst.operands[2].reg);
13940
c19d1205
ZW
13941 inst.instruction |= Rd << 8;
13942 inst.instruction |= Rs << 16;
13943 if (!inst.operands[2].isreg)
13944 {
5b7c81bd 13945 bool narrow;
026d3abb
PB
13946
13947 if ((inst.instruction & 0x00100000) != 0)
5ee91343 13948 narrow = !in_pred_block ();
026d3abb 13949 else
5ee91343 13950 narrow = in_pred_block ();
026d3abb
PB
13951
13952 if (Rd > 7 || Rs > 7)
5b7c81bd 13953 narrow = false;
026d3abb
PB
13954
13955 if (inst.size_req == 4 || !unified_syntax)
5b7c81bd 13956 narrow = false;
026d3abb 13957
e2b0ab59
AV
13958 if (inst.relocs[0].exp.X_op != O_constant
13959 || inst.relocs[0].exp.X_add_number != 0)
5b7c81bd 13960 narrow = false;
026d3abb
PB
13961
13962 /* Turn rsb #0 into 16-bit neg. We should probably do this via
477330fc 13963 relaxation, but it doesn't seem worth the hassle. */
026d3abb
PB
13964 if (narrow)
13965 {
e2b0ab59 13966 inst.relocs[0].type = BFD_RELOC_UNUSED;
026d3abb
PB
13967 inst.instruction = THUMB_OP16 (T_MNEM_negs);
13968 inst.instruction |= Rs << 3;
13969 inst.instruction |= Rd;
13970 }
13971 else
13972 {
13973 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13974 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
026d3abb 13975 }
c19d1205
ZW
13976 }
13977 else
13978 encode_thumb32_shifted_operand (2);
13979}
b99bd4ef 13980
c19d1205
ZW
13981static void
13982do_t_setend (void)
13983{
12e37cbc
MGD
13984 if (warn_on_deprecated
13985 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 13986 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 13987
5ee91343 13988 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
13989 if (inst.operands[0].imm)
13990 inst.instruction |= 0x8;
13991}
b99bd4ef 13992
c19d1205
ZW
13993static void
13994do_t_shift (void)
13995{
13996 if (!inst.operands[1].present)
13997 inst.operands[1].reg = inst.operands[0].reg;
13998
13999 if (unified_syntax)
14000 {
5b7c81bd 14001 bool narrow;
3d388997
PB
14002 int shift_kind;
14003
14004 switch (inst.instruction)
14005 {
14006 case T_MNEM_asr:
14007 case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
14008 case T_MNEM_lsl:
14009 case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
14010 case T_MNEM_lsr:
14011 case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
14012 case T_MNEM_ror:
14013 case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
14014 default: abort ();
14015 }
14016
14017 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 14018 narrow = !in_pred_block ();
3d388997 14019 else
5ee91343 14020 narrow = in_pred_block ();
3d388997 14021 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
5b7c81bd 14022 narrow = false;
3d388997 14023 if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
5b7c81bd 14024 narrow = false;
3d388997
PB
14025 if (inst.operands[2].isreg
14026 && (inst.operands[1].reg != inst.operands[0].reg
14027 || inst.operands[2].reg > 7))
5b7c81bd 14028 narrow = false;
3d388997 14029 if (inst.size_req == 4)
5b7c81bd 14030 narrow = false;
3d388997 14031
fdfde340
JM
14032 reject_bad_reg (inst.operands[0].reg);
14033 reject_bad_reg (inst.operands[1].reg);
c921be7d 14034
3d388997 14035 if (!narrow)
c19d1205
ZW
14036 {
14037 if (inst.operands[2].isreg)
b99bd4ef 14038 {
fdfde340 14039 reject_bad_reg (inst.operands[2].reg);
c19d1205
ZW
14040 inst.instruction = THUMB_OP32 (inst.instruction);
14041 inst.instruction |= inst.operands[0].reg << 8;
14042 inst.instruction |= inst.operands[1].reg << 16;
14043 inst.instruction |= inst.operands[2].reg;
94342ec3
NC
14044
14045 /* PR 12854: Error on extraneous shifts. */
14046 constraint (inst.operands[2].shifted,
14047 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
14048 }
14049 else
14050 {
14051 inst.operands[1].shifted = 1;
3d388997 14052 inst.operands[1].shift_kind = shift_kind;
c19d1205
ZW
14053 inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
14054 ? T_MNEM_movs : T_MNEM_mov);
14055 inst.instruction |= inst.operands[0].reg << 8;
14056 encode_thumb32_shifted_operand (1);
14057 /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
e2b0ab59 14058 inst.relocs[0].type = BFD_RELOC_UNUSED;
b99bd4ef
NC
14059 }
14060 }
14061 else
14062 {
c19d1205 14063 if (inst.operands[2].isreg)
b99bd4ef 14064 {
3d388997 14065 switch (shift_kind)
b99bd4ef 14066 {
3d388997
PB
14067 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
14068 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
14069 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
14070 case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
c19d1205 14071 default: abort ();
b99bd4ef 14072 }
5f4273c7 14073
c19d1205
ZW
14074 inst.instruction |= inst.operands[0].reg;
14075 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
14076
14077 /* PR 12854: Error on extraneous shifts. */
14078 constraint (inst.operands[2].shifted,
14079 _("extraneous shift as part of operand to shift insn"));
b99bd4ef
NC
14080 }
14081 else
14082 {
3d388997 14083 switch (shift_kind)
b99bd4ef 14084 {
3d388997
PB
14085 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
14086 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
14087 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
c19d1205 14088 default: abort ();
b99bd4ef 14089 }
e2b0ab59 14090 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
14091 inst.instruction |= inst.operands[0].reg;
14092 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
14093 }
14094 }
c19d1205
ZW
14095 }
14096 else
14097 {
14098 constraint (inst.operands[0].reg > 7
14099 || inst.operands[1].reg > 7, BAD_HIREG);
14100 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
b99bd4ef 14101
c19d1205
ZW
14102 if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
14103 {
14104 constraint (inst.operands[2].reg > 7, BAD_HIREG);
14105 constraint (inst.operands[0].reg != inst.operands[1].reg,
14106 _("source1 and dest must be same register"));
b99bd4ef 14107
c19d1205
ZW
14108 switch (inst.instruction)
14109 {
14110 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
14111 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
14112 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
14113 case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
14114 default: abort ();
14115 }
5f4273c7 14116
c19d1205
ZW
14117 inst.instruction |= inst.operands[0].reg;
14118 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
14119
14120 /* PR 12854: Error on extraneous shifts. */
14121 constraint (inst.operands[2].shifted,
14122 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
14123 }
14124 else
b99bd4ef 14125 {
c19d1205
ZW
14126 switch (inst.instruction)
14127 {
14128 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
14129 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
14130 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
14131 case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
14132 default: abort ();
14133 }
e2b0ab59 14134 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
14135 inst.instruction |= inst.operands[0].reg;
14136 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
14137 }
14138 }
b99bd4ef
NC
14139}
14140
14141static void
c19d1205 14142do_t_simd (void)
b99bd4ef 14143{
fdfde340
JM
14144 unsigned Rd, Rn, Rm;
14145
14146 Rd = inst.operands[0].reg;
14147 Rn = inst.operands[1].reg;
14148 Rm = inst.operands[2].reg;
14149
14150 reject_bad_reg (Rd);
14151 reject_bad_reg (Rn);
14152 reject_bad_reg (Rm);
14153
14154 inst.instruction |= Rd << 8;
14155 inst.instruction |= Rn << 16;
14156 inst.instruction |= Rm;
c19d1205 14157}
b99bd4ef 14158
03ee1b7f
NC
14159static void
14160do_t_simd2 (void)
14161{
14162 unsigned Rd, Rn, Rm;
14163
14164 Rd = inst.operands[0].reg;
14165 Rm = inst.operands[1].reg;
14166 Rn = inst.operands[2].reg;
14167
14168 reject_bad_reg (Rd);
14169 reject_bad_reg (Rn);
14170 reject_bad_reg (Rm);
14171
14172 inst.instruction |= Rd << 8;
14173 inst.instruction |= Rn << 16;
14174 inst.instruction |= Rm;
14175}
14176
c19d1205 14177static void
3eb17e6b 14178do_t_smc (void)
c19d1205 14179{
e2b0ab59 14180 unsigned int value = inst.relocs[0].exp.X_add_number;
f4c65163
MGD
14181 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
14182 _("SMC is not permitted on this architecture"));
e2b0ab59 14183 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 14184 _("expression too complex"));
ba85f98c
BW
14185 constraint (value > 0xf, _("immediate too large (bigger than 0xF)"));
14186
e2b0ab59 14187 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205 14188 inst.instruction |= (value & 0x000f) << 16;
ba85f98c 14189
24382199 14190 /* PR gas/15623: SMC instructions must be last in an IT block. */
5ee91343 14191 set_pred_insn_type_last ();
c19d1205 14192}
b99bd4ef 14193
90ec0d68
MGD
14194static void
14195do_t_hvc (void)
14196{
e2b0ab59 14197 unsigned int value = inst.relocs[0].exp.X_add_number;
90ec0d68 14198
e2b0ab59 14199 inst.relocs[0].type = BFD_RELOC_UNUSED;
90ec0d68
MGD
14200 inst.instruction |= (value & 0x0fff);
14201 inst.instruction |= (value & 0xf000) << 4;
14202}
14203
c19d1205 14204static void
3a21c15a 14205do_t_ssat_usat (int bias)
c19d1205 14206{
fdfde340
JM
14207 unsigned Rd, Rn;
14208
14209 Rd = inst.operands[0].reg;
14210 Rn = inst.operands[2].reg;
14211
14212 reject_bad_reg (Rd);
14213 reject_bad_reg (Rn);
14214
14215 inst.instruction |= Rd << 8;
3a21c15a 14216 inst.instruction |= inst.operands[1].imm - bias;
fdfde340 14217 inst.instruction |= Rn << 16;
b99bd4ef 14218
c19d1205 14219 if (inst.operands[3].present)
b99bd4ef 14220 {
e2b0ab59 14221 offsetT shift_amount = inst.relocs[0].exp.X_add_number;
3a21c15a 14222
e2b0ab59 14223 inst.relocs[0].type = BFD_RELOC_UNUSED;
3a21c15a 14224
e2b0ab59 14225 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 14226 _("expression too complex"));
b99bd4ef 14227
3a21c15a 14228 if (shift_amount != 0)
6189168b 14229 {
3a21c15a
NC
14230 constraint (shift_amount > 31,
14231 _("shift expression is too large"));
14232
c19d1205 14233 if (inst.operands[3].shift_kind == SHIFT_ASR)
3a21c15a
NC
14234 inst.instruction |= 0x00200000; /* sh bit. */
14235
14236 inst.instruction |= (shift_amount & 0x1c) << 10;
14237 inst.instruction |= (shift_amount & 0x03) << 6;
6189168b
NC
14238 }
14239 }
b99bd4ef 14240}
c921be7d 14241
3a21c15a
NC
14242static void
14243do_t_ssat (void)
14244{
14245 do_t_ssat_usat (1);
14246}
b99bd4ef 14247
0dd132b6 14248static void
c19d1205 14249do_t_ssat16 (void)
0dd132b6 14250{
fdfde340
JM
14251 unsigned Rd, Rn;
14252
14253 Rd = inst.operands[0].reg;
14254 Rn = inst.operands[2].reg;
14255
14256 reject_bad_reg (Rd);
14257 reject_bad_reg (Rn);
14258
14259 inst.instruction |= Rd << 8;
c19d1205 14260 inst.instruction |= inst.operands[1].imm - 1;
fdfde340 14261 inst.instruction |= Rn << 16;
c19d1205 14262}
0dd132b6 14263
c19d1205
ZW
14264static void
14265do_t_strex (void)
14266{
14267 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
14268 || inst.operands[2].postind || inst.operands[2].writeback
14269 || inst.operands[2].immisreg || inst.operands[2].shifted
14270 || inst.operands[2].negative,
01cfc07f 14271 BAD_ADDR_MODE);
0dd132b6 14272
5be8be5d
DG
14273 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
14274
c19d1205
ZW
14275 inst.instruction |= inst.operands[0].reg << 8;
14276 inst.instruction |= inst.operands[1].reg << 12;
14277 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 14278 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
0dd132b6
NC
14279}
14280
b99bd4ef 14281static void
c19d1205 14282do_t_strexd (void)
b99bd4ef 14283{
c19d1205
ZW
14284 if (!inst.operands[2].present)
14285 inst.operands[2].reg = inst.operands[1].reg + 1;
b99bd4ef 14286
c19d1205
ZW
14287 constraint (inst.operands[0].reg == inst.operands[1].reg
14288 || inst.operands[0].reg == inst.operands[2].reg
f8a8e9d6 14289 || inst.operands[0].reg == inst.operands[3].reg,
c19d1205 14290 BAD_OVERLAP);
b99bd4ef 14291
c19d1205
ZW
14292 inst.instruction |= inst.operands[0].reg;
14293 inst.instruction |= inst.operands[1].reg << 12;
14294 inst.instruction |= inst.operands[2].reg << 8;
14295 inst.instruction |= inst.operands[3].reg << 16;
b99bd4ef
NC
14296}
14297
14298static void
c19d1205 14299do_t_sxtah (void)
b99bd4ef 14300{
fdfde340
JM
14301 unsigned Rd, Rn, Rm;
14302
14303 Rd = inst.operands[0].reg;
14304 Rn = inst.operands[1].reg;
14305 Rm = inst.operands[2].reg;
14306
14307 reject_bad_reg (Rd);
14308 reject_bad_reg (Rn);
14309 reject_bad_reg (Rm);
14310
14311 inst.instruction |= Rd << 8;
14312 inst.instruction |= Rn << 16;
14313 inst.instruction |= Rm;
c19d1205
ZW
14314 inst.instruction |= inst.operands[3].imm << 4;
14315}
b99bd4ef 14316
c19d1205
ZW
14317static void
14318do_t_sxth (void)
14319{
fdfde340
JM
14320 unsigned Rd, Rm;
14321
14322 Rd = inst.operands[0].reg;
14323 Rm = inst.operands[1].reg;
14324
14325 reject_bad_reg (Rd);
14326 reject_bad_reg (Rm);
c921be7d
NC
14327
14328 if (inst.instruction <= 0xffff
14329 && inst.size_req != 4
fdfde340 14330 && Rd <= 7 && Rm <= 7
c19d1205 14331 && (!inst.operands[2].present || inst.operands[2].imm == 0))
b99bd4ef 14332 {
c19d1205 14333 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
14334 inst.instruction |= Rd;
14335 inst.instruction |= Rm << 3;
b99bd4ef 14336 }
c19d1205 14337 else if (unified_syntax)
b99bd4ef 14338 {
c19d1205
ZW
14339 if (inst.instruction <= 0xffff)
14340 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
14341 inst.instruction |= Rd << 8;
14342 inst.instruction |= Rm;
c19d1205 14343 inst.instruction |= inst.operands[2].imm << 4;
b99bd4ef 14344 }
c19d1205 14345 else
b99bd4ef 14346 {
c19d1205
ZW
14347 constraint (inst.operands[2].present && inst.operands[2].imm != 0,
14348 _("Thumb encoding does not support rotation"));
14349 constraint (1, BAD_HIREG);
b99bd4ef 14350 }
c19d1205 14351}
b99bd4ef 14352
c19d1205
ZW
14353static void
14354do_t_swi (void)
14355{
e2b0ab59 14356 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
c19d1205 14357}
b99bd4ef 14358
92e90b6e
PB
14359static void
14360do_t_tb (void)
14361{
fdfde340 14362 unsigned Rn, Rm;
92e90b6e
PB
14363 int half;
14364
14365 half = (inst.instruction & 0x10) != 0;
5ee91343 14366 set_pred_insn_type_last ();
dfa9f0d5
PB
14367 constraint (inst.operands[0].immisreg,
14368 _("instruction requires register index"));
fdfde340
JM
14369
14370 Rn = inst.operands[0].reg;
14371 Rm = inst.operands[0].imm;
c921be7d 14372
5c8ed6a4
JW
14373 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
14374 constraint (Rn == REG_SP, BAD_SP);
fdfde340
JM
14375 reject_bad_reg (Rm);
14376
92e90b6e
PB
14377 constraint (!half && inst.operands[0].shifted,
14378 _("instruction does not allow shifted index"));
fdfde340 14379 inst.instruction |= (Rn << 16) | Rm;
92e90b6e
PB
14380}
14381
74db7efb
NC
14382static void
14383do_t_udf (void)
14384{
14385 if (!inst.operands[0].present)
14386 inst.operands[0].imm = 0;
14387
14388 if ((unsigned int) inst.operands[0].imm > 255 || inst.size_req == 4)
14389 {
14390 constraint (inst.size_req == 2,
14391 _("immediate value out of range"));
14392 inst.instruction = THUMB_OP32 (inst.instruction);
14393 inst.instruction |= (inst.operands[0].imm & 0xf000u) << 4;
14394 inst.instruction |= (inst.operands[0].imm & 0x0fffu) << 0;
14395 }
14396 else
14397 {
14398 inst.instruction = THUMB_OP16 (inst.instruction);
14399 inst.instruction |= inst.operands[0].imm;
14400 }
14401
5ee91343 14402 set_pred_insn_type (NEUTRAL_IT_INSN);
74db7efb
NC
14403}
14404
14405
c19d1205
ZW
14406static void
14407do_t_usat (void)
14408{
3a21c15a 14409 do_t_ssat_usat (0);
b99bd4ef
NC
14410}
14411
14412static void
c19d1205 14413do_t_usat16 (void)
b99bd4ef 14414{
fdfde340
JM
14415 unsigned Rd, Rn;
14416
14417 Rd = inst.operands[0].reg;
14418 Rn = inst.operands[2].reg;
14419
14420 reject_bad_reg (Rd);
14421 reject_bad_reg (Rn);
14422
14423 inst.instruction |= Rd << 8;
c19d1205 14424 inst.instruction |= inst.operands[1].imm;
fdfde340 14425 inst.instruction |= Rn << 16;
b99bd4ef 14426}
c19d1205 14427
e12437dc
AV
14428/* Checking the range of the branch offset (VAL) with NBITS bits
14429 and IS_SIGNED signedness. Also checks the LSB to be 0. */
14430static int
14431v8_1_branch_value_check (int val, int nbits, int is_signed)
14432{
14433 gas_assert (nbits > 0 && nbits <= 32);
14434 if (is_signed)
14435 {
14436 int cmp = (1 << (nbits - 1));
14437 if ((val < -cmp) || (val >= cmp) || (val & 0x01))
14438 return FAIL;
14439 }
14440 else
14441 {
14442 if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
14443 return FAIL;
14444 }
14445 return SUCCESS;
14446}
14447
4389b29a
AV
14448/* For branches in Armv8.1-M Mainline. */
14449static void
14450do_t_branch_future (void)
14451{
14452 unsigned long insn = inst.instruction;
14453
14454 inst.instruction = THUMB_OP32 (inst.instruction);
14455 if (inst.operands[0].hasreloc == 0)
14456 {
5b7c81bd 14457 if (v8_1_branch_value_check (inst.operands[0].imm, 5, false) == FAIL)
4389b29a
AV
14458 as_bad (BAD_BRANCH_OFF);
14459
14460 inst.instruction |= ((inst.operands[0].imm & 0x1f) >> 1) << 23;
14461 }
14462 else
14463 {
14464 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH5;
14465 inst.relocs[0].pc_rel = 1;
14466 }
14467
14468 switch (insn)
14469 {
14470 case T_MNEM_bf:
14471 if (inst.operands[1].hasreloc == 0)
14472 {
14473 int val = inst.operands[1].imm;
5b7c81bd 14474 if (v8_1_branch_value_check (inst.operands[1].imm, 17, true) == FAIL)
4389b29a
AV
14475 as_bad (BAD_BRANCH_OFF);
14476
14477 int immA = (val & 0x0001f000) >> 12;
14478 int immB = (val & 0x00000ffc) >> 2;
14479 int immC = (val & 0x00000002) >> 1;
14480 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14481 }
14482 else
14483 {
14484 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF17;
14485 inst.relocs[1].pc_rel = 1;
14486 }
14487 break;
14488
65d1bc05
AV
14489 case T_MNEM_bfl:
14490 if (inst.operands[1].hasreloc == 0)
14491 {
14492 int val = inst.operands[1].imm;
5b7c81bd 14493 if (v8_1_branch_value_check (inst.operands[1].imm, 19, true) == FAIL)
65d1bc05
AV
14494 as_bad (BAD_BRANCH_OFF);
14495
14496 int immA = (val & 0x0007f000) >> 12;
14497 int immB = (val & 0x00000ffc) >> 2;
14498 int immC = (val & 0x00000002) >> 1;
14499 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14500 }
14501 else
14502 {
14503 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
14504 inst.relocs[1].pc_rel = 1;
14505 }
14506 break;
14507
f6b2b12d
AV
14508 case T_MNEM_bfcsel:
14509 /* Operand 1. */
14510 if (inst.operands[1].hasreloc == 0)
14511 {
14512 int val = inst.operands[1].imm;
14513 int immA = (val & 0x00001000) >> 12;
14514 int immB = (val & 0x00000ffc) >> 2;
14515 int immC = (val & 0x00000002) >> 1;
14516 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14517 }
14518 else
14519 {
14520 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF13;
14521 inst.relocs[1].pc_rel = 1;
14522 }
14523
14524 /* Operand 2. */
14525 if (inst.operands[2].hasreloc == 0)
14526 {
14527 constraint ((inst.operands[0].hasreloc != 0), BAD_ARGS);
14528 int val2 = inst.operands[2].imm;
14529 int val0 = inst.operands[0].imm & 0x1f;
14530 int diff = val2 - val0;
14531 if (diff == 4)
14532 inst.instruction |= 1 << 17; /* T bit. */
14533 else if (diff != 2)
14534 as_bad (_("out of range label-relative fixup value"));
14535 }
14536 else
14537 {
14538 constraint ((inst.operands[0].hasreloc == 0), BAD_ARGS);
14539 inst.relocs[2].type = BFD_RELOC_THUMB_PCREL_BFCSEL;
14540 inst.relocs[2].pc_rel = 1;
14541 }
14542
14543 /* Operand 3. */
14544 constraint (inst.cond != COND_ALWAYS, BAD_COND);
14545 inst.instruction |= (inst.operands[3].imm & 0xf) << 18;
14546 break;
14547
f1c7f421
AV
14548 case T_MNEM_bfx:
14549 case T_MNEM_bflx:
14550 inst.instruction |= inst.operands[1].reg << 16;
14551 break;
14552
4389b29a
AV
14553 default: abort ();
14554 }
14555}
14556
60f993ce
AV
14557/* Helper function for do_t_loloop to handle relocations. */
14558static void
14559v8_1_loop_reloc (int is_le)
14560{
14561 if (inst.relocs[0].exp.X_op == O_constant)
14562 {
14563 int value = inst.relocs[0].exp.X_add_number;
14564 value = (is_le) ? -value : value;
14565
5b7c81bd 14566 if (v8_1_branch_value_check (value, 12, false) == FAIL)
60f993ce
AV
14567 as_bad (BAD_BRANCH_OFF);
14568
14569 int imml, immh;
14570
14571 immh = (value & 0x00000ffc) >> 2;
14572 imml = (value & 0x00000002) >> 1;
14573
14574 inst.instruction |= (imml << 11) | (immh << 1);
14575 }
14576 else
14577 {
14578 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_LOOP12;
14579 inst.relocs[0].pc_rel = 1;
14580 }
14581}
14582
08132bdd
SP
14583/* For shifts with four operands in MVE. */
14584static void
14585do_mve_scalar_shift1 (void)
14586{
14587 unsigned int value = inst.operands[2].imm;
14588
14589 inst.instruction |= inst.operands[0].reg << 16;
14590 inst.instruction |= inst.operands[1].reg << 8;
14591
14592 /* Setting the bit for saturation. */
14593 inst.instruction |= ((value == 64) ? 0: 1) << 7;
14594
14595 /* Assuming Rm is already checked not to be 11x1. */
14596 constraint (inst.operands[3].reg == inst.operands[0].reg, BAD_OVERLAP);
14597 constraint (inst.operands[3].reg == inst.operands[1].reg, BAD_OVERLAP);
14598 inst.instruction |= inst.operands[3].reg << 12;
14599}
14600
23d00a41
SD
14601/* For shifts in MVE. */
14602static void
14603do_mve_scalar_shift (void)
14604{
14605 if (!inst.operands[2].present)
14606 {
14607 inst.operands[2] = inst.operands[1];
14608 inst.operands[1].reg = 0xf;
14609 }
14610
14611 inst.instruction |= inst.operands[0].reg << 16;
14612 inst.instruction |= inst.operands[1].reg << 8;
14613
14614 if (inst.operands[2].isreg)
14615 {
14616 /* Assuming Rm is already checked not to be 11x1. */
14617 constraint (inst.operands[2].reg == inst.operands[0].reg, BAD_OVERLAP);
14618 constraint (inst.operands[2].reg == inst.operands[1].reg, BAD_OVERLAP);
14619 inst.instruction |= inst.operands[2].reg << 12;
14620 }
14621 else
14622 {
14623 /* Assuming imm is already checked as [1,32]. */
14624 unsigned int value = inst.operands[2].imm;
14625 inst.instruction |= (value & 0x1c) << 10;
14626 inst.instruction |= (value & 0x03) << 6;
14627 /* Change last 4 bits from 0xd to 0xf. */
14628 inst.instruction |= 0x2;
14629 }
14630}
14631
a302e574
AV
14632/* MVE instruction encoder helpers. */
14633#define M_MNEM_vabav 0xee800f01
14634#define M_MNEM_vmladav 0xeef00e00
14635#define M_MNEM_vmladava 0xeef00e20
14636#define M_MNEM_vmladavx 0xeef01e00
14637#define M_MNEM_vmladavax 0xeef01e20
14638#define M_MNEM_vmlsdav 0xeef00e01
14639#define M_MNEM_vmlsdava 0xeef00e21
14640#define M_MNEM_vmlsdavx 0xeef01e01
14641#define M_MNEM_vmlsdavax 0xeef01e21
886e1c73
AV
14642#define M_MNEM_vmullt 0xee011e00
14643#define M_MNEM_vmullb 0xee010e00
efd0b310 14644#define M_MNEM_vctp 0xf000e801
35c228db
AV
14645#define M_MNEM_vst20 0xfc801e00
14646#define M_MNEM_vst21 0xfc801e20
14647#define M_MNEM_vst40 0xfc801e01
14648#define M_MNEM_vst41 0xfc801e21
14649#define M_MNEM_vst42 0xfc801e41
14650#define M_MNEM_vst43 0xfc801e61
14651#define M_MNEM_vld20 0xfc901e00
14652#define M_MNEM_vld21 0xfc901e20
14653#define M_MNEM_vld40 0xfc901e01
14654#define M_MNEM_vld41 0xfc901e21
14655#define M_MNEM_vld42 0xfc901e41
14656#define M_MNEM_vld43 0xfc901e61
f5f10c66
AV
14657#define M_MNEM_vstrb 0xec000e00
14658#define M_MNEM_vstrh 0xec000e10
14659#define M_MNEM_vstrw 0xec000e40
14660#define M_MNEM_vstrd 0xec000e50
14661#define M_MNEM_vldrb 0xec100e00
14662#define M_MNEM_vldrh 0xec100e10
14663#define M_MNEM_vldrw 0xec100e40
14664#define M_MNEM_vldrd 0xec100e50
57785aa2
AV
14665#define M_MNEM_vmovlt 0xeea01f40
14666#define M_MNEM_vmovlb 0xeea00f40
14667#define M_MNEM_vmovnt 0xfe311e81
14668#define M_MNEM_vmovnb 0xfe310e81
c2dafc2a
AV
14669#define M_MNEM_vadc 0xee300f00
14670#define M_MNEM_vadci 0xee301f00
14671#define M_MNEM_vbrsr 0xfe011e60
26c1e780
AV
14672#define M_MNEM_vaddlv 0xee890f00
14673#define M_MNEM_vaddlva 0xee890f20
14674#define M_MNEM_vaddv 0xeef10f00
14675#define M_MNEM_vaddva 0xeef10f20
b409bdb6
AV
14676#define M_MNEM_vddup 0xee011f6e
14677#define M_MNEM_vdwdup 0xee011f60
14678#define M_MNEM_vidup 0xee010f6e
14679#define M_MNEM_viwdup 0xee010f60
13ccd4c0
AV
14680#define M_MNEM_vmaxv 0xeee20f00
14681#define M_MNEM_vmaxav 0xeee00f00
14682#define M_MNEM_vminv 0xeee20f80
14683#define M_MNEM_vminav 0xeee00f80
93925576
AV
14684#define M_MNEM_vmlaldav 0xee800e00
14685#define M_MNEM_vmlaldava 0xee800e20
14686#define M_MNEM_vmlaldavx 0xee801e00
14687#define M_MNEM_vmlaldavax 0xee801e20
14688#define M_MNEM_vmlsldav 0xee800e01
14689#define M_MNEM_vmlsldava 0xee800e21
14690#define M_MNEM_vmlsldavx 0xee801e01
14691#define M_MNEM_vmlsldavax 0xee801e21
14692#define M_MNEM_vrmlaldavhx 0xee801f00
14693#define M_MNEM_vrmlaldavhax 0xee801f20
14694#define M_MNEM_vrmlsldavh 0xfe800e01
14695#define M_MNEM_vrmlsldavha 0xfe800e21
14696#define M_MNEM_vrmlsldavhx 0xfe801e01
14697#define M_MNEM_vrmlsldavhax 0xfe801e21
1be7aba3
AV
14698#define M_MNEM_vqmovnt 0xee331e01
14699#define M_MNEM_vqmovnb 0xee330e01
14700#define M_MNEM_vqmovunt 0xee311e81
14701#define M_MNEM_vqmovunb 0xee310e81
4aa88b50
AV
14702#define M_MNEM_vshrnt 0xee801fc1
14703#define M_MNEM_vshrnb 0xee800fc1
14704#define M_MNEM_vrshrnt 0xfe801fc1
14705#define M_MNEM_vqshrnt 0xee801f40
14706#define M_MNEM_vqshrnb 0xee800f40
14707#define M_MNEM_vqshrunt 0xee801fc0
14708#define M_MNEM_vqshrunb 0xee800fc0
14709#define M_MNEM_vrshrnb 0xfe800fc1
14710#define M_MNEM_vqrshrnt 0xee801f41
14711#define M_MNEM_vqrshrnb 0xee800f41
14712#define M_MNEM_vqrshrunt 0xfe801fc0
14713#define M_MNEM_vqrshrunb 0xfe800fc0
a302e574 14714
aab2c27d
MM
14715/* Bfloat16 instruction encoder helpers. */
14716#define B_MNEM_vfmat 0xfc300850
14717#define B_MNEM_vfmab 0xfc300810
14718
5287ad62 14719/* Neon instruction encoder helpers. */
5f4273c7 14720
5287ad62 14721/* Encodings for the different types for various Neon opcodes. */
b99bd4ef 14722
5287ad62
JB
14723/* An "invalid" code for the following tables. */
14724#define N_INV -1u
14725
14726struct neon_tab_entry
b99bd4ef 14727{
5287ad62
JB
14728 unsigned integer;
14729 unsigned float_or_poly;
14730 unsigned scalar_or_imm;
14731};
5f4273c7 14732
5287ad62
JB
14733/* Map overloaded Neon opcodes to their respective encodings. */
14734#define NEON_ENC_TAB \
14735 X(vabd, 0x0000700, 0x1200d00, N_INV), \
5ee91343 14736 X(vabdl, 0x0800700, N_INV, N_INV), \
5287ad62
JB
14737 X(vmax, 0x0000600, 0x0000f00, N_INV), \
14738 X(vmin, 0x0000610, 0x0200f00, N_INV), \
14739 X(vpadd, 0x0000b10, 0x1000d00, N_INV), \
14740 X(vpmax, 0x0000a00, 0x1000f00, N_INV), \
14741 X(vpmin, 0x0000a10, 0x1200f00, N_INV), \
14742 X(vadd, 0x0000800, 0x0000d00, N_INV), \
5ee91343 14743 X(vaddl, 0x0800000, N_INV, N_INV), \
5287ad62 14744 X(vsub, 0x1000800, 0x0200d00, N_INV), \
5ee91343 14745 X(vsubl, 0x0800200, N_INV, N_INV), \
5287ad62
JB
14746 X(vceq, 0x1000810, 0x0000e00, 0x1b10100), \
14747 X(vcge, 0x0000310, 0x1000e00, 0x1b10080), \
14748 X(vcgt, 0x0000300, 0x1200e00, 0x1b10000), \
14749 /* Register variants of the following two instructions are encoded as
e07e6e58 14750 vcge / vcgt with the operands reversed. */ \
92559b5b
PB
14751 X(vclt, 0x0000300, 0x1200e00, 0x1b10200), \
14752 X(vcle, 0x0000310, 0x1000e00, 0x1b10180), \
62f3b8c8
PB
14753 X(vfma, N_INV, 0x0000c10, N_INV), \
14754 X(vfms, N_INV, 0x0200c10, N_INV), \
5287ad62
JB
14755 X(vmla, 0x0000900, 0x0000d10, 0x0800040), \
14756 X(vmls, 0x1000900, 0x0200d10, 0x0800440), \
14757 X(vmul, 0x0000910, 0x1000d10, 0x0800840), \
14758 X(vmull, 0x0800c00, 0x0800e00, 0x0800a40), /* polynomial not float. */ \
14759 X(vmlal, 0x0800800, N_INV, 0x0800240), \
14760 X(vmlsl, 0x0800a00, N_INV, 0x0800640), \
14761 X(vqdmlal, 0x0800900, N_INV, 0x0800340), \
14762 X(vqdmlsl, 0x0800b00, N_INV, 0x0800740), \
14763 X(vqdmull, 0x0800d00, N_INV, 0x0800b40), \
14764 X(vqdmulh, 0x0000b00, N_INV, 0x0800c40), \
14765 X(vqrdmulh, 0x1000b00, N_INV, 0x0800d40), \
d6b4b13e
MW
14766 X(vqrdmlah, 0x3000b10, N_INV, 0x0800e40), \
14767 X(vqrdmlsh, 0x3000c10, N_INV, 0x0800f40), \
5287ad62
JB
14768 X(vshl, 0x0000400, N_INV, 0x0800510), \
14769 X(vqshl, 0x0000410, N_INV, 0x0800710), \
14770 X(vand, 0x0000110, N_INV, 0x0800030), \
14771 X(vbic, 0x0100110, N_INV, 0x0800030), \
14772 X(veor, 0x1000110, N_INV, N_INV), \
14773 X(vorn, 0x0300110, N_INV, 0x0800010), \
14774 X(vorr, 0x0200110, N_INV, 0x0800010), \
14775 X(vmvn, 0x1b00580, N_INV, 0x0800030), \
14776 X(vshll, 0x1b20300, N_INV, 0x0800a10), /* max shift, immediate. */ \
14777 X(vcvt, 0x1b30600, N_INV, 0x0800e10), /* integer, fixed-point. */ \
14778 X(vdup, 0xe800b10, N_INV, 0x1b00c00), /* arm, scalar. */ \
14779 X(vld1, 0x0200000, 0x0a00000, 0x0a00c00), /* interlv, lane, dup. */ \
14780 X(vst1, 0x0000000, 0x0800000, N_INV), \
14781 X(vld2, 0x0200100, 0x0a00100, 0x0a00d00), \
14782 X(vst2, 0x0000100, 0x0800100, N_INV), \
14783 X(vld3, 0x0200200, 0x0a00200, 0x0a00e00), \
14784 X(vst3, 0x0000200, 0x0800200, N_INV), \
14785 X(vld4, 0x0200300, 0x0a00300, 0x0a00f00), \
14786 X(vst4, 0x0000300, 0x0800300, N_INV), \
14787 X(vmovn, 0x1b20200, N_INV, N_INV), \
14788 X(vtrn, 0x1b20080, N_INV, N_INV), \
14789 X(vqmovn, 0x1b20200, N_INV, N_INV), \
037e8744
JB
14790 X(vqmovun, 0x1b20240, N_INV, N_INV), \
14791 X(vnmul, 0xe200a40, 0xe200b40, N_INV), \
e6655fda
PB
14792 X(vnmla, 0xe100a40, 0xe100b40, N_INV), \
14793 X(vnmls, 0xe100a00, 0xe100b00, N_INV), \
62f3b8c8
PB
14794 X(vfnma, 0xe900a40, 0xe900b40, N_INV), \
14795 X(vfnms, 0xe900a00, 0xe900b00, N_INV), \
037e8744
JB
14796 X(vcmp, 0xeb40a40, 0xeb40b40, N_INV), \
14797 X(vcmpz, 0xeb50a40, 0xeb50b40, N_INV), \
14798 X(vcmpe, 0xeb40ac0, 0xeb40bc0, N_INV), \
33399f07
MGD
14799 X(vcmpez, 0xeb50ac0, 0xeb50bc0, N_INV), \
14800 X(vseleq, 0xe000a00, N_INV, N_INV), \
14801 X(vselvs, 0xe100a00, N_INV, N_INV), \
14802 X(vselge, 0xe200a00, N_INV, N_INV), \
73924fbc
MGD
14803 X(vselgt, 0xe300a00, N_INV, N_INV), \
14804 X(vmaxnm, 0xe800a00, 0x3000f10, N_INV), \
7e8e6784 14805 X(vminnm, 0xe800a40, 0x3200f10, N_INV), \
30bdf752
MGD
14806 X(vcvta, 0xebc0a40, 0x3bb0000, N_INV), \
14807 X(vrintr, 0xeb60a40, 0x3ba0400, N_INV), \
91ff7894 14808 X(vrinta, 0xeb80a40, 0x3ba0400, N_INV), \
48adcd8e 14809 X(aes, 0x3b00300, N_INV, N_INV), \
3c9017d2
MGD
14810 X(sha3op, 0x2000c00, N_INV, N_INV), \
14811 X(sha1h, 0x3b902c0, N_INV, N_INV), \
14812 X(sha2op, 0x3ba0380, N_INV, N_INV)
5287ad62
JB
14813
14814enum neon_opc
14815{
14816#define X(OPC,I,F,S) N_MNEM_##OPC
14817NEON_ENC_TAB
14818#undef X
14819};
b99bd4ef 14820
5287ad62
JB
14821static const struct neon_tab_entry neon_enc_tab[] =
14822{
14823#define X(OPC,I,F,S) { (I), (F), (S) }
14824NEON_ENC_TAB
14825#undef X
14826};
b99bd4ef 14827
88714cb8
DG
14828/* Do not use these macros; instead, use NEON_ENCODE defined below. */
14829#define NEON_ENC_INTEGER_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14830#define NEON_ENC_ARMREG_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14831#define NEON_ENC_POLY_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14832#define NEON_ENC_FLOAT_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14833#define NEON_ENC_SCALAR_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14834#define NEON_ENC_IMMED_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14835#define NEON_ENC_INTERLV_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14836#define NEON_ENC_LANE_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14837#define NEON_ENC_DUP_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14838#define NEON_ENC_SINGLE_(X) \
037e8744 14839 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf0000000))
88714cb8 14840#define NEON_ENC_DOUBLE_(X) \
037e8744 14841 ((neon_enc_tab[(X) & 0x0fffffff].float_or_poly) | ((X) & 0xf0000000))
33399f07
MGD
14842#define NEON_ENC_FPV8_(X) \
14843 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf000000))
5287ad62 14844
88714cb8
DG
14845#define NEON_ENCODE(type, inst) \
14846 do \
14847 { \
14848 inst.instruction = NEON_ENC_##type##_ (inst.instruction); \
14849 inst.is_neon = 1; \
14850 } \
14851 while (0)
14852
14853#define check_neon_suffixes \
14854 do \
14855 { \
14856 if (!inst.error && inst.vectype.elems > 0 && !inst.is_neon) \
14857 { \
14858 as_bad (_("invalid neon suffix for non neon instruction")); \
14859 return; \
14860 } \
14861 } \
14862 while (0)
14863
037e8744
JB
14864/* Define shapes for instruction operands. The following mnemonic characters
14865 are used in this table:
5287ad62 14866
037e8744 14867 F - VFP S<n> register
5287ad62
JB
14868 D - Neon D<n> register
14869 Q - Neon Q<n> register
14870 I - Immediate
14871 S - Scalar
14872 R - ARM register
14873 L - D<n> register list
5f4273c7 14874
037e8744
JB
14875 This table is used to generate various data:
14876 - enumerations of the form NS_DDR to be used as arguments to
14877 neon_select_shape.
14878 - a table classifying shapes into single, double, quad, mixed.
5f4273c7 14879 - a table used to drive neon_select_shape. */
b99bd4ef 14880
037e8744 14881#define NEON_SHAPE_DEF \
93925576 14882 X(4, (R, R, Q, Q), QUAD), \
b409bdb6 14883 X(4, (Q, R, R, I), QUAD), \
57785aa2
AV
14884 X(4, (R, R, S, S), QUAD), \
14885 X(4, (S, S, R, R), QUAD), \
b409bdb6 14886 X(3, (Q, R, I), QUAD), \
1b883319
AV
14887 X(3, (I, Q, Q), QUAD), \
14888 X(3, (I, Q, R), QUAD), \
a302e574 14889 X(3, (R, Q, Q), QUAD), \
037e8744
JB
14890 X(3, (D, D, D), DOUBLE), \
14891 X(3, (Q, Q, Q), QUAD), \
14892 X(3, (D, D, I), DOUBLE), \
14893 X(3, (Q, Q, I), QUAD), \
14894 X(3, (D, D, S), DOUBLE), \
14895 X(3, (Q, Q, S), QUAD), \
5ee91343 14896 X(3, (Q, Q, R), QUAD), \
26c1e780
AV
14897 X(3, (R, R, Q), QUAD), \
14898 X(2, (R, Q), QUAD), \
037e8744
JB
14899 X(2, (D, D), DOUBLE), \
14900 X(2, (Q, Q), QUAD), \
14901 X(2, (D, S), DOUBLE), \
14902 X(2, (Q, S), QUAD), \
14903 X(2, (D, R), DOUBLE), \
14904 X(2, (Q, R), QUAD), \
14905 X(2, (D, I), DOUBLE), \
14906 X(2, (Q, I), QUAD), \
5aae9ae9
MM
14907 X(3, (P, F, I), SINGLE), \
14908 X(3, (P, D, I), DOUBLE), \
14909 X(3, (P, Q, I), QUAD), \
14910 X(4, (P, F, F, I), SINGLE), \
14911 X(4, (P, D, D, I), DOUBLE), \
14912 X(4, (P, Q, Q, I), QUAD), \
14913 X(5, (P, F, F, F, I), SINGLE), \
14914 X(5, (P, D, D, D, I), DOUBLE), \
14915 X(5, (P, Q, Q, Q, I), QUAD), \
037e8744
JB
14916 X(3, (D, L, D), DOUBLE), \
14917 X(2, (D, Q), MIXED), \
14918 X(2, (Q, D), MIXED), \
14919 X(3, (D, Q, I), MIXED), \
14920 X(3, (Q, D, I), MIXED), \
14921 X(3, (Q, D, D), MIXED), \
14922 X(3, (D, Q, Q), MIXED), \
14923 X(3, (Q, Q, D), MIXED), \
14924 X(3, (Q, D, S), MIXED), \
14925 X(3, (D, Q, S), MIXED), \
14926 X(4, (D, D, D, I), DOUBLE), \
14927 X(4, (Q, Q, Q, I), QUAD), \
c28eeff2
SN
14928 X(4, (D, D, S, I), DOUBLE), \
14929 X(4, (Q, Q, S, I), QUAD), \
037e8744
JB
14930 X(2, (F, F), SINGLE), \
14931 X(3, (F, F, F), SINGLE), \
14932 X(2, (F, I), SINGLE), \
14933 X(2, (F, D), MIXED), \
14934 X(2, (D, F), MIXED), \
14935 X(3, (F, F, I), MIXED), \
14936 X(4, (R, R, F, F), SINGLE), \
14937 X(4, (F, F, R, R), SINGLE), \
14938 X(3, (D, R, R), DOUBLE), \
14939 X(3, (R, R, D), DOUBLE), \
14940 X(2, (S, R), SINGLE), \
14941 X(2, (R, S), SINGLE), \
14942 X(2, (F, R), SINGLE), \
d54af2d0 14943 X(2, (R, F), SINGLE), \
1f6234a3
AV
14944/* Used for MVE tail predicated loop instructions. */\
14945 X(2, (R, R), QUAD), \
d54af2d0
RL
14946/* Half float shape supported so far. */\
14947 X (2, (H, D), MIXED), \
14948 X (2, (D, H), MIXED), \
14949 X (2, (H, F), MIXED), \
14950 X (2, (F, H), MIXED), \
14951 X (2, (H, H), HALF), \
14952 X (2, (H, R), HALF), \
14953 X (2, (R, H), HALF), \
14954 X (2, (H, I), HALF), \
14955 X (3, (H, H, H), HALF), \
14956 X (3, (H, F, I), MIXED), \
dec41383
JW
14957 X (3, (F, H, I), MIXED), \
14958 X (3, (D, H, H), MIXED), \
14959 X (3, (D, H, S), MIXED)
037e8744
JB
14960
14961#define S2(A,B) NS_##A##B
14962#define S3(A,B,C) NS_##A##B##C
14963#define S4(A,B,C,D) NS_##A##B##C##D
5aae9ae9 14964#define S5(A,B,C,D,E) NS_##A##B##C##D##E
037e8744
JB
14965
14966#define X(N, L, C) S##N L
14967
5287ad62
JB
14968enum neon_shape
14969{
037e8744
JB
14970 NEON_SHAPE_DEF,
14971 NS_NULL
5287ad62 14972};
b99bd4ef 14973
037e8744
JB
14974#undef X
14975#undef S2
14976#undef S3
14977#undef S4
5aae9ae9 14978#undef S5
037e8744
JB
14979
14980enum neon_shape_class
14981{
d54af2d0 14982 SC_HALF,
037e8744
JB
14983 SC_SINGLE,
14984 SC_DOUBLE,
14985 SC_QUAD,
14986 SC_MIXED
14987};
14988
14989#define X(N, L, C) SC_##C
14990
14991static enum neon_shape_class neon_shape_class[] =
14992{
14993 NEON_SHAPE_DEF
14994};
14995
14996#undef X
14997
14998enum neon_shape_el
14999{
d54af2d0 15000 SE_H,
037e8744
JB
15001 SE_F,
15002 SE_D,
15003 SE_Q,
15004 SE_I,
15005 SE_S,
15006 SE_R,
5aae9ae9
MM
15007 SE_L,
15008 SE_P
037e8744
JB
15009};
15010
15011/* Register widths of above. */
15012static unsigned neon_shape_el_size[] =
15013{
d54af2d0 15014 16,
037e8744
JB
15015 32,
15016 64,
15017 128,
15018 0,
15019 32,
15020 32,
5aae9ae9 15021 0,
037e8744
JB
15022 0
15023};
15024
15025struct neon_shape_info
15026{
15027 unsigned els;
15028 enum neon_shape_el el[NEON_MAX_TYPE_ELS];
15029};
15030
15031#define S2(A,B) { SE_##A, SE_##B }
15032#define S3(A,B,C) { SE_##A, SE_##B, SE_##C }
15033#define S4(A,B,C,D) { SE_##A, SE_##B, SE_##C, SE_##D }
5aae9ae9 15034#define S5(A,B,C,D,E) { SE_##A, SE_##B, SE_##C, SE_##D, SE_##E }
037e8744
JB
15035
15036#define X(N, L, C) { N, S##N L }
15037
15038static struct neon_shape_info neon_shape_tab[] =
15039{
15040 NEON_SHAPE_DEF
15041};
15042
15043#undef X
15044#undef S2
15045#undef S3
15046#undef S4
5aae9ae9 15047#undef S5
037e8744 15048
5287ad62
JB
15049/* Bit masks used in type checking given instructions.
15050 'N_EQK' means the type must be the same as (or based on in some way) the key
15051 type, which itself is marked with the 'N_KEY' bit. If the 'N_EQK' bit is
15052 set, various other bits can be set as well in order to modify the meaning of
15053 the type constraint. */
15054
15055enum neon_type_mask
15056{
8e79c3df
CM
15057 N_S8 = 0x0000001,
15058 N_S16 = 0x0000002,
15059 N_S32 = 0x0000004,
15060 N_S64 = 0x0000008,
15061 N_U8 = 0x0000010,
15062 N_U16 = 0x0000020,
15063 N_U32 = 0x0000040,
15064 N_U64 = 0x0000080,
15065 N_I8 = 0x0000100,
15066 N_I16 = 0x0000200,
15067 N_I32 = 0x0000400,
15068 N_I64 = 0x0000800,
15069 N_8 = 0x0001000,
15070 N_16 = 0x0002000,
15071 N_32 = 0x0004000,
15072 N_64 = 0x0008000,
15073 N_P8 = 0x0010000,
15074 N_P16 = 0x0020000,
15075 N_F16 = 0x0040000,
15076 N_F32 = 0x0080000,
15077 N_F64 = 0x0100000,
4f51b4bd 15078 N_P64 = 0x0200000,
aab2c27d 15079 N_BF16 = 0x0400000,
c921be7d
NC
15080 N_KEY = 0x1000000, /* Key element (main type specifier). */
15081 N_EQK = 0x2000000, /* Given operand has the same type & size as the key. */
8e79c3df 15082 N_VFP = 0x4000000, /* VFP mode: operand size must match register width. */
91ff7894 15083 N_UNT = 0x8000000, /* Must be explicitly untyped. */
c921be7d
NC
15084 N_DBL = 0x0000001, /* If N_EQK, this operand is twice the size. */
15085 N_HLF = 0x0000002, /* If N_EQK, this operand is half the size. */
15086 N_SGN = 0x0000004, /* If N_EQK, this operand is forced to be signed. */
15087 N_UNS = 0x0000008, /* If N_EQK, this operand is forced to be unsigned. */
15088 N_INT = 0x0000010, /* If N_EQK, this operand is forced to be integer. */
15089 N_FLT = 0x0000020, /* If N_EQK, this operand is forced to be float. */
15090 N_SIZ = 0x0000040, /* If N_EQK, this operand is forced to be size-only. */
5287ad62 15091 N_UTYP = 0,
4f51b4bd 15092 N_MAX_NONSPECIAL = N_P64
5287ad62
JB
15093};
15094
dcbf9037
JB
15095#define N_ALLMODS (N_DBL | N_HLF | N_SGN | N_UNS | N_INT | N_FLT | N_SIZ)
15096
5287ad62
JB
15097#define N_SU_ALL (N_S8 | N_S16 | N_S32 | N_S64 | N_U8 | N_U16 | N_U32 | N_U64)
15098#define N_SU_32 (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
15099#define N_SU_16_64 (N_S16 | N_S32 | N_S64 | N_U16 | N_U32 | N_U64)
cc933301
JW
15100#define N_S_32 (N_S8 | N_S16 | N_S32)
15101#define N_F_16_32 (N_F16 | N_F32)
15102#define N_SUF_32 (N_SU_32 | N_F_16_32)
5287ad62 15103#define N_I_ALL (N_I8 | N_I16 | N_I32 | N_I64)
cc933301 15104#define N_IF_32 (N_I8 | N_I16 | N_I32 | N_F16 | N_F32)
d54af2d0 15105#define N_F_ALL (N_F16 | N_F32 | N_F64)
5ee91343
AV
15106#define N_I_MVE (N_I8 | N_I16 | N_I32)
15107#define N_F_MVE (N_F16 | N_F32)
15108#define N_SU_MVE (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
5287ad62
JB
15109
15110/* Pass this as the first type argument to neon_check_type to ignore types
15111 altogether. */
15112#define N_IGNORE_TYPE (N_KEY | N_EQK)
15113
037e8744
JB
15114/* Select a "shape" for the current instruction (describing register types or
15115 sizes) from a list of alternatives. Return NS_NULL if the current instruction
15116 doesn't fit. For non-polymorphic shapes, checking is usually done as a
15117 function of operand parsing, so this function doesn't need to be called.
15118 Shapes should be listed in order of decreasing length. */
5287ad62
JB
15119
15120static enum neon_shape
037e8744 15121neon_select_shape (enum neon_shape shape, ...)
5287ad62 15122{
037e8744
JB
15123 va_list ap;
15124 enum neon_shape first_shape = shape;
5287ad62
JB
15125
15126 /* Fix missing optional operands. FIXME: we don't know at this point how
15127 many arguments we should have, so this makes the assumption that we have
15128 > 1. This is true of all current Neon opcodes, I think, but may not be
15129 true in the future. */
15130 if (!inst.operands[1].present)
15131 inst.operands[1] = inst.operands[0];
15132
037e8744 15133 va_start (ap, shape);
5f4273c7 15134
21d799b5 15135 for (; shape != NS_NULL; shape = (enum neon_shape) va_arg (ap, int))
037e8744
JB
15136 {
15137 unsigned j;
15138 int matches = 1;
15139
15140 for (j = 0; j < neon_shape_tab[shape].els; j++)
477330fc
RM
15141 {
15142 if (!inst.operands[j].present)
15143 {
15144 matches = 0;
15145 break;
15146 }
15147
15148 switch (neon_shape_tab[shape].el[j])
15149 {
d54af2d0
RL
15150 /* If a .f16, .16, .u16, .s16 type specifier is given over
15151 a VFP single precision register operand, it's essentially
15152 means only half of the register is used.
15153
15154 If the type specifier is given after the mnemonics, the
15155 information is stored in inst.vectype. If the type specifier
15156 is given after register operand, the information is stored
15157 in inst.operands[].vectype.
15158
15159 When there is only one type specifier, and all the register
15160 operands are the same type of hardware register, the type
15161 specifier applies to all register operands.
15162
15163 If no type specifier is given, the shape is inferred from
15164 operand information.
15165
15166 for example:
15167 vadd.f16 s0, s1, s2: NS_HHH
15168 vabs.f16 s0, s1: NS_HH
15169 vmov.f16 s0, r1: NS_HR
15170 vmov.f16 r0, s1: NS_RH
15171 vcvt.f16 r0, s1: NS_RH
15172 vcvt.f16.s32 s2, s2, #29: NS_HFI
15173 vcvt.f16.s32 s2, s2: NS_HF
15174 */
15175 case SE_H:
15176 if (!(inst.operands[j].isreg
15177 && inst.operands[j].isvec
15178 && inst.operands[j].issingle
15179 && !inst.operands[j].isquad
15180 && ((inst.vectype.elems == 1
15181 && inst.vectype.el[0].size == 16)
15182 || (inst.vectype.elems > 1
15183 && inst.vectype.el[j].size == 16)
15184 || (inst.vectype.elems == 0
15185 && inst.operands[j].vectype.type != NT_invtype
15186 && inst.operands[j].vectype.size == 16))))
15187 matches = 0;
15188 break;
15189
477330fc
RM
15190 case SE_F:
15191 if (!(inst.operands[j].isreg
15192 && inst.operands[j].isvec
15193 && inst.operands[j].issingle
d54af2d0
RL
15194 && !inst.operands[j].isquad
15195 && ((inst.vectype.elems == 1 && inst.vectype.el[0].size == 32)
15196 || (inst.vectype.elems > 1 && inst.vectype.el[j].size == 32)
15197 || (inst.vectype.elems == 0
15198 && (inst.operands[j].vectype.size == 32
15199 || inst.operands[j].vectype.type == NT_invtype)))))
477330fc
RM
15200 matches = 0;
15201 break;
15202
15203 case SE_D:
15204 if (!(inst.operands[j].isreg
15205 && inst.operands[j].isvec
15206 && !inst.operands[j].isquad
15207 && !inst.operands[j].issingle))
15208 matches = 0;
15209 break;
15210
15211 case SE_R:
15212 if (!(inst.operands[j].isreg
15213 && !inst.operands[j].isvec))
15214 matches = 0;
15215 break;
15216
15217 case SE_Q:
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_I:
15226 if (!(!inst.operands[j].isreg
15227 && !inst.operands[j].isscalar))
15228 matches = 0;
15229 break;
15230
15231 case SE_S:
15232 if (!(!inst.operands[j].isreg
15233 && inst.operands[j].isscalar))
15234 matches = 0;
15235 break;
15236
5aae9ae9 15237 case SE_P:
477330fc
RM
15238 case SE_L:
15239 break;
15240 }
3fde54a2
JZ
15241 if (!matches)
15242 break;
477330fc 15243 }
ad6cec43
MGD
15244 if (matches && (j >= ARM_IT_MAX_OPERANDS || !inst.operands[j].present))
15245 /* We've matched all the entries in the shape table, and we don't
15246 have any left over operands which have not been matched. */
477330fc 15247 break;
037e8744 15248 }
5f4273c7 15249
037e8744 15250 va_end (ap);
5287ad62 15251
037e8744
JB
15252 if (shape == NS_NULL && first_shape != NS_NULL)
15253 first_error (_("invalid instruction shape"));
5287ad62 15254
037e8744
JB
15255 return shape;
15256}
5287ad62 15257
037e8744
JB
15258/* True if SHAPE is predominantly a quadword operation (most of the time, this
15259 means the Q bit should be set). */
15260
15261static int
15262neon_quad (enum neon_shape shape)
15263{
15264 return neon_shape_class[shape] == SC_QUAD;
5287ad62 15265}
037e8744 15266
5287ad62
JB
15267static void
15268neon_modify_type_size (unsigned typebits, enum neon_el_type *g_type,
477330fc 15269 unsigned *g_size)
5287ad62
JB
15270{
15271 /* Allow modification to be made to types which are constrained to be
15272 based on the key element, based on bits set alongside N_EQK. */
15273 if ((typebits & N_EQK) != 0)
15274 {
15275 if ((typebits & N_HLF) != 0)
15276 *g_size /= 2;
15277 else if ((typebits & N_DBL) != 0)
15278 *g_size *= 2;
15279 if ((typebits & N_SGN) != 0)
15280 *g_type = NT_signed;
15281 else if ((typebits & N_UNS) != 0)
477330fc 15282 *g_type = NT_unsigned;
5287ad62 15283 else if ((typebits & N_INT) != 0)
477330fc 15284 *g_type = NT_integer;
5287ad62 15285 else if ((typebits & N_FLT) != 0)
477330fc 15286 *g_type = NT_float;
dcbf9037 15287 else if ((typebits & N_SIZ) != 0)
477330fc 15288 *g_type = NT_untyped;
5287ad62
JB
15289 }
15290}
5f4273c7 15291
5287ad62
JB
15292/* Return operand OPNO promoted by bits set in THISARG. KEY should be the "key"
15293 operand type, i.e. the single type specified in a Neon instruction when it
15294 is the only one given. */
15295
15296static struct neon_type_el
15297neon_type_promote (struct neon_type_el *key, unsigned thisarg)
15298{
15299 struct neon_type_el dest = *key;
5f4273c7 15300
9c2799c2 15301 gas_assert ((thisarg & N_EQK) != 0);
5f4273c7 15302
5287ad62
JB
15303 neon_modify_type_size (thisarg, &dest.type, &dest.size);
15304
15305 return dest;
15306}
15307
15308/* Convert Neon type and size into compact bitmask representation. */
15309
15310static enum neon_type_mask
15311type_chk_of_el_type (enum neon_el_type type, unsigned size)
15312{
15313 switch (type)
15314 {
15315 case NT_untyped:
15316 switch (size)
477330fc
RM
15317 {
15318 case 8: return N_8;
15319 case 16: return N_16;
15320 case 32: return N_32;
15321 case 64: return N_64;
15322 default: ;
15323 }
5287ad62
JB
15324 break;
15325
15326 case NT_integer:
15327 switch (size)
477330fc
RM
15328 {
15329 case 8: return N_I8;
15330 case 16: return N_I16;
15331 case 32: return N_I32;
15332 case 64: return N_I64;
15333 default: ;
15334 }
5287ad62
JB
15335 break;
15336
15337 case NT_float:
037e8744 15338 switch (size)
477330fc 15339 {
8e79c3df 15340 case 16: return N_F16;
477330fc
RM
15341 case 32: return N_F32;
15342 case 64: return N_F64;
15343 default: ;
15344 }
5287ad62
JB
15345 break;
15346
15347 case NT_poly:
15348 switch (size)
477330fc
RM
15349 {
15350 case 8: return N_P8;
15351 case 16: return N_P16;
4f51b4bd 15352 case 64: return N_P64;
477330fc
RM
15353 default: ;
15354 }
5287ad62
JB
15355 break;
15356
15357 case NT_signed:
15358 switch (size)
477330fc
RM
15359 {
15360 case 8: return N_S8;
15361 case 16: return N_S16;
15362 case 32: return N_S32;
15363 case 64: return N_S64;
15364 default: ;
15365 }
5287ad62
JB
15366 break;
15367
15368 case NT_unsigned:
15369 switch (size)
477330fc
RM
15370 {
15371 case 8: return N_U8;
15372 case 16: return N_U16;
15373 case 32: return N_U32;
15374 case 64: return N_U64;
15375 default: ;
15376 }
5287ad62
JB
15377 break;
15378
aab2c27d
MM
15379 case NT_bfloat:
15380 if (size == 16) return N_BF16;
15381 break;
15382
5287ad62
JB
15383 default: ;
15384 }
5f4273c7 15385
5287ad62
JB
15386 return N_UTYP;
15387}
15388
15389/* Convert compact Neon bitmask type representation to a type and size. Only
15390 handles the case where a single bit is set in the mask. */
15391
dcbf9037 15392static int
5287ad62 15393el_type_of_type_chk (enum neon_el_type *type, unsigned *size,
477330fc 15394 enum neon_type_mask mask)
5287ad62 15395{
dcbf9037
JB
15396 if ((mask & N_EQK) != 0)
15397 return FAIL;
15398
5287ad62
JB
15399 if ((mask & (N_S8 | N_U8 | N_I8 | N_8 | N_P8)) != 0)
15400 *size = 8;
aab2c27d
MM
15401 else if ((mask & (N_S16 | N_U16 | N_I16 | N_16 | N_F16 | N_P16 | N_BF16))
15402 != 0)
5287ad62 15403 *size = 16;
dcbf9037 15404 else if ((mask & (N_S32 | N_U32 | N_I32 | N_32 | N_F32)) != 0)
5287ad62 15405 *size = 32;
4f51b4bd 15406 else if ((mask & (N_S64 | N_U64 | N_I64 | N_64 | N_F64 | N_P64)) != 0)
5287ad62 15407 *size = 64;
dcbf9037
JB
15408 else
15409 return FAIL;
15410
5287ad62
JB
15411 if ((mask & (N_S8 | N_S16 | N_S32 | N_S64)) != 0)
15412 *type = NT_signed;
dcbf9037 15413 else if ((mask & (N_U8 | N_U16 | N_U32 | N_U64)) != 0)
5287ad62 15414 *type = NT_unsigned;
dcbf9037 15415 else if ((mask & (N_I8 | N_I16 | N_I32 | N_I64)) != 0)
5287ad62 15416 *type = NT_integer;
dcbf9037 15417 else if ((mask & (N_8 | N_16 | N_32 | N_64)) != 0)
5287ad62 15418 *type = NT_untyped;
4f51b4bd 15419 else if ((mask & (N_P8 | N_P16 | N_P64)) != 0)
5287ad62 15420 *type = NT_poly;
d54af2d0 15421 else if ((mask & (N_F_ALL)) != 0)
5287ad62 15422 *type = NT_float;
aab2c27d
MM
15423 else if ((mask & (N_BF16)) != 0)
15424 *type = NT_bfloat;
dcbf9037
JB
15425 else
15426 return FAIL;
5f4273c7 15427
dcbf9037 15428 return SUCCESS;
5287ad62
JB
15429}
15430
15431/* Modify a bitmask of allowed types. This is only needed for type
15432 relaxation. */
15433
15434static unsigned
15435modify_types_allowed (unsigned allowed, unsigned mods)
15436{
15437 unsigned size;
15438 enum neon_el_type type;
15439 unsigned destmask;
15440 int i;
5f4273c7 15441
5287ad62 15442 destmask = 0;
5f4273c7 15443
5287ad62
JB
15444 for (i = 1; i <= N_MAX_NONSPECIAL; i <<= 1)
15445 {
21d799b5 15446 if (el_type_of_type_chk (&type, &size,
477330fc
RM
15447 (enum neon_type_mask) (allowed & i)) == SUCCESS)
15448 {
15449 neon_modify_type_size (mods, &type, &size);
15450 destmask |= type_chk_of_el_type (type, size);
15451 }
5287ad62 15452 }
5f4273c7 15453
5287ad62
JB
15454 return destmask;
15455}
15456
15457/* Check type and return type classification.
15458 The manual states (paraphrase): If one datatype is given, it indicates the
15459 type given in:
15460 - the second operand, if there is one
15461 - the operand, if there is no second operand
15462 - the result, if there are no operands.
15463 This isn't quite good enough though, so we use a concept of a "key" datatype
15464 which is set on a per-instruction basis, which is the one which matters when
15465 only one data type is written.
15466 Note: this function has side-effects (e.g. filling in missing operands). All
037e8744 15467 Neon instructions should call it before performing bit encoding. */
5287ad62
JB
15468
15469static struct neon_type_el
15470neon_check_type (unsigned els, enum neon_shape ns, ...)
15471{
15472 va_list ap;
15473 unsigned i, pass, key_el = 0;
15474 unsigned types[NEON_MAX_TYPE_ELS];
15475 enum neon_el_type k_type = NT_invtype;
15476 unsigned k_size = -1u;
15477 struct neon_type_el badtype = {NT_invtype, -1};
15478 unsigned key_allowed = 0;
15479
15480 /* Optional registers in Neon instructions are always (not) in operand 1.
15481 Fill in the missing operand here, if it was omitted. */
15482 if (els > 1 && !inst.operands[1].present)
15483 inst.operands[1] = inst.operands[0];
15484
15485 /* Suck up all the varargs. */
15486 va_start (ap, ns);
15487 for (i = 0; i < els; i++)
15488 {
15489 unsigned thisarg = va_arg (ap, unsigned);
15490 if (thisarg == N_IGNORE_TYPE)
477330fc
RM
15491 {
15492 va_end (ap);
15493 return badtype;
15494 }
5287ad62
JB
15495 types[i] = thisarg;
15496 if ((thisarg & N_KEY) != 0)
477330fc 15497 key_el = i;
5287ad62
JB
15498 }
15499 va_end (ap);
15500
dcbf9037
JB
15501 if (inst.vectype.elems > 0)
15502 for (i = 0; i < els; i++)
15503 if (inst.operands[i].vectype.type != NT_invtype)
477330fc
RM
15504 {
15505 first_error (_("types specified in both the mnemonic and operands"));
15506 return badtype;
15507 }
dcbf9037 15508
5287ad62
JB
15509 /* Duplicate inst.vectype elements here as necessary.
15510 FIXME: No idea if this is exactly the same as the ARM assembler,
15511 particularly when an insn takes one register and one non-register
15512 operand. */
15513 if (inst.vectype.elems == 1 && els > 1)
15514 {
15515 unsigned j;
15516 inst.vectype.elems = els;
15517 inst.vectype.el[key_el] = inst.vectype.el[0];
15518 for (j = 0; j < els; j++)
477330fc
RM
15519 if (j != key_el)
15520 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
15521 types[j]);
dcbf9037
JB
15522 }
15523 else if (inst.vectype.elems == 0 && els > 0)
15524 {
15525 unsigned j;
15526 /* No types were given after the mnemonic, so look for types specified
477330fc
RM
15527 after each operand. We allow some flexibility here; as long as the
15528 "key" operand has a type, we can infer the others. */
dcbf9037 15529 for (j = 0; j < els; j++)
477330fc
RM
15530 if (inst.operands[j].vectype.type != NT_invtype)
15531 inst.vectype.el[j] = inst.operands[j].vectype;
dcbf9037
JB
15532
15533 if (inst.operands[key_el].vectype.type != NT_invtype)
477330fc
RM
15534 {
15535 for (j = 0; j < els; j++)
15536 if (inst.operands[j].vectype.type == NT_invtype)
15537 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
15538 types[j]);
15539 }
dcbf9037 15540 else
477330fc
RM
15541 {
15542 first_error (_("operand types can't be inferred"));
15543 return badtype;
15544 }
5287ad62
JB
15545 }
15546 else if (inst.vectype.elems != els)
15547 {
dcbf9037 15548 first_error (_("type specifier has the wrong number of parts"));
5287ad62
JB
15549 return badtype;
15550 }
15551
15552 for (pass = 0; pass < 2; pass++)
15553 {
15554 for (i = 0; i < els; i++)
477330fc
RM
15555 {
15556 unsigned thisarg = types[i];
15557 unsigned types_allowed = ((thisarg & N_EQK) != 0 && pass != 0)
15558 ? modify_types_allowed (key_allowed, thisarg) : thisarg;
15559 enum neon_el_type g_type = inst.vectype.el[i].type;
15560 unsigned g_size = inst.vectype.el[i].size;
15561
15562 /* Decay more-specific signed & unsigned types to sign-insensitive
5287ad62 15563 integer types if sign-specific variants are unavailable. */
477330fc 15564 if ((g_type == NT_signed || g_type == NT_unsigned)
5287ad62
JB
15565 && (types_allowed & N_SU_ALL) == 0)
15566 g_type = NT_integer;
15567
477330fc 15568 /* If only untyped args are allowed, decay any more specific types to
5287ad62
JB
15569 them. Some instructions only care about signs for some element
15570 sizes, so handle that properly. */
477330fc 15571 if (((types_allowed & N_UNT) == 0)
91ff7894
MGD
15572 && ((g_size == 8 && (types_allowed & N_8) != 0)
15573 || (g_size == 16 && (types_allowed & N_16) != 0)
15574 || (g_size == 32 && (types_allowed & N_32) != 0)
15575 || (g_size == 64 && (types_allowed & N_64) != 0)))
5287ad62
JB
15576 g_type = NT_untyped;
15577
477330fc
RM
15578 if (pass == 0)
15579 {
15580 if ((thisarg & N_KEY) != 0)
15581 {
15582 k_type = g_type;
15583 k_size = g_size;
15584 key_allowed = thisarg & ~N_KEY;
cc933301
JW
15585
15586 /* Check architecture constraint on FP16 extension. */
15587 if (k_size == 16
15588 && k_type == NT_float
15589 && ! ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15590 {
15591 inst.error = _(BAD_FP16);
15592 return badtype;
15593 }
477330fc
RM
15594 }
15595 }
15596 else
15597 {
15598 if ((thisarg & N_VFP) != 0)
15599 {
15600 enum neon_shape_el regshape;
15601 unsigned regwidth, match;
99b253c5
NC
15602
15603 /* PR 11136: Catch the case where we are passed a shape of NS_NULL. */
15604 if (ns == NS_NULL)
15605 {
15606 first_error (_("invalid instruction shape"));
15607 return badtype;
15608 }
477330fc
RM
15609 regshape = neon_shape_tab[ns].el[i];
15610 regwidth = neon_shape_el_size[regshape];
15611
15612 /* In VFP mode, operands must match register widths. If we
15613 have a key operand, use its width, else use the width of
15614 the current operand. */
15615 if (k_size != -1u)
15616 match = k_size;
15617 else
15618 match = g_size;
15619
9db2f6b4
RL
15620 /* FP16 will use a single precision register. */
15621 if (regwidth == 32 && match == 16)
15622 {
15623 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15624 match = regwidth;
15625 else
15626 {
15627 inst.error = _(BAD_FP16);
15628 return badtype;
15629 }
15630 }
15631
477330fc
RM
15632 if (regwidth != match)
15633 {
15634 first_error (_("operand size must match register width"));
15635 return badtype;
15636 }
15637 }
15638
15639 if ((thisarg & N_EQK) == 0)
15640 {
15641 unsigned given_type = type_chk_of_el_type (g_type, g_size);
15642
15643 if ((given_type & types_allowed) == 0)
15644 {
a302e574 15645 first_error (BAD_SIMD_TYPE);
477330fc
RM
15646 return badtype;
15647 }
15648 }
15649 else
15650 {
15651 enum neon_el_type mod_k_type = k_type;
15652 unsigned mod_k_size = k_size;
15653 neon_modify_type_size (thisarg, &mod_k_type, &mod_k_size);
15654 if (g_type != mod_k_type || g_size != mod_k_size)
15655 {
15656 first_error (_("inconsistent types in Neon instruction"));
15657 return badtype;
15658 }
15659 }
15660 }
15661 }
5287ad62
JB
15662 }
15663
15664 return inst.vectype.el[key_el];
15665}
15666
037e8744 15667/* Neon-style VFP instruction forwarding. */
5287ad62 15668
037e8744
JB
15669/* Thumb VFP instructions have 0xE in the condition field. */
15670
15671static void
15672do_vfp_cond_or_thumb (void)
5287ad62 15673{
88714cb8
DG
15674 inst.is_neon = 1;
15675
5287ad62 15676 if (thumb_mode)
037e8744 15677 inst.instruction |= 0xe0000000;
5287ad62 15678 else
037e8744 15679 inst.instruction |= inst.cond << 28;
5287ad62
JB
15680}
15681
037e8744
JB
15682/* Look up and encode a simple mnemonic, for use as a helper function for the
15683 Neon-style VFP syntax. This avoids duplication of bits of the insns table,
15684 etc. It is assumed that operand parsing has already been done, and that the
15685 operands are in the form expected by the given opcode (this isn't necessarily
15686 the same as the form in which they were parsed, hence some massaging must
15687 take place before this function is called).
15688 Checks current arch version against that in the looked-up opcode. */
5287ad62 15689
037e8744
JB
15690static void
15691do_vfp_nsyn_opcode (const char *opname)
5287ad62 15692{
037e8744 15693 const struct asm_opcode *opcode;
5f4273c7 15694
629310ab 15695 opcode = (const struct asm_opcode *) str_hash_find (arm_ops_hsh, opname);
5287ad62 15696
037e8744
JB
15697 if (!opcode)
15698 abort ();
5287ad62 15699
037e8744 15700 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant,
477330fc
RM
15701 thumb_mode ? *opcode->tvariant : *opcode->avariant),
15702 _(BAD_FPU));
5287ad62 15703
88714cb8
DG
15704 inst.is_neon = 1;
15705
037e8744
JB
15706 if (thumb_mode)
15707 {
15708 inst.instruction = opcode->tvalue;
15709 opcode->tencode ();
15710 }
15711 else
15712 {
15713 inst.instruction = (inst.cond << 28) | opcode->avalue;
15714 opcode->aencode ();
15715 }
15716}
5287ad62
JB
15717
15718static void
037e8744 15719do_vfp_nsyn_add_sub (enum neon_shape rs)
5287ad62 15720{
037e8744
JB
15721 int is_add = (inst.instruction & 0x0fffffff) == N_MNEM_vadd;
15722
9db2f6b4 15723 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15724 {
15725 if (is_add)
477330fc 15726 do_vfp_nsyn_opcode ("fadds");
037e8744 15727 else
477330fc 15728 do_vfp_nsyn_opcode ("fsubs");
9db2f6b4
RL
15729
15730 /* ARMv8.2 fp16 instruction. */
15731 if (rs == NS_HHH)
15732 do_scalar_fp16_v82_encode ();
037e8744
JB
15733 }
15734 else
15735 {
15736 if (is_add)
477330fc 15737 do_vfp_nsyn_opcode ("faddd");
037e8744 15738 else
477330fc 15739 do_vfp_nsyn_opcode ("fsubd");
037e8744
JB
15740 }
15741}
15742
15743/* Check operand types to see if this is a VFP instruction, and if so call
15744 PFN (). */
15745
15746static int
15747try_vfp_nsyn (int args, void (*pfn) (enum neon_shape))
15748{
15749 enum neon_shape rs;
15750 struct neon_type_el et;
15751
15752 switch (args)
15753 {
15754 case 2:
9db2f6b4
RL
15755 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15756 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
037e8744 15757 break;
5f4273c7 15758
037e8744 15759 case 3:
9db2f6b4
RL
15760 rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
15761 et = neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
15762 N_F_ALL | N_KEY | N_VFP);
037e8744
JB
15763 break;
15764
15765 default:
15766 abort ();
15767 }
15768
15769 if (et.type != NT_invtype)
15770 {
15771 pfn (rs);
15772 return SUCCESS;
15773 }
037e8744 15774
99b253c5 15775 inst.error = NULL;
037e8744
JB
15776 return FAIL;
15777}
15778
15779static void
15780do_vfp_nsyn_mla_mls (enum neon_shape rs)
15781{
15782 int is_mla = (inst.instruction & 0x0fffffff) == N_MNEM_vmla;
5f4273c7 15783
9db2f6b4 15784 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15785 {
15786 if (is_mla)
477330fc 15787 do_vfp_nsyn_opcode ("fmacs");
037e8744 15788 else
477330fc 15789 do_vfp_nsyn_opcode ("fnmacs");
9db2f6b4
RL
15790
15791 /* ARMv8.2 fp16 instruction. */
15792 if (rs == NS_HHH)
15793 do_scalar_fp16_v82_encode ();
037e8744
JB
15794 }
15795 else
15796 {
15797 if (is_mla)
477330fc 15798 do_vfp_nsyn_opcode ("fmacd");
037e8744 15799 else
477330fc 15800 do_vfp_nsyn_opcode ("fnmacd");
037e8744
JB
15801 }
15802}
15803
62f3b8c8
PB
15804static void
15805do_vfp_nsyn_fma_fms (enum neon_shape rs)
15806{
15807 int is_fma = (inst.instruction & 0x0fffffff) == N_MNEM_vfma;
15808
9db2f6b4 15809 if (rs == NS_FFF || rs == NS_HHH)
62f3b8c8
PB
15810 {
15811 if (is_fma)
477330fc 15812 do_vfp_nsyn_opcode ("ffmas");
62f3b8c8 15813 else
477330fc 15814 do_vfp_nsyn_opcode ("ffnmas");
9db2f6b4
RL
15815
15816 /* ARMv8.2 fp16 instruction. */
15817 if (rs == NS_HHH)
15818 do_scalar_fp16_v82_encode ();
62f3b8c8
PB
15819 }
15820 else
15821 {
15822 if (is_fma)
477330fc 15823 do_vfp_nsyn_opcode ("ffmad");
62f3b8c8 15824 else
477330fc 15825 do_vfp_nsyn_opcode ("ffnmad");
62f3b8c8
PB
15826 }
15827}
15828
037e8744
JB
15829static void
15830do_vfp_nsyn_mul (enum neon_shape rs)
15831{
9db2f6b4
RL
15832 if (rs == NS_FFF || rs == NS_HHH)
15833 {
15834 do_vfp_nsyn_opcode ("fmuls");
15835
15836 /* ARMv8.2 fp16 instruction. */
15837 if (rs == NS_HHH)
15838 do_scalar_fp16_v82_encode ();
15839 }
037e8744
JB
15840 else
15841 do_vfp_nsyn_opcode ("fmuld");
15842}
15843
15844static void
15845do_vfp_nsyn_abs_neg (enum neon_shape rs)
15846{
15847 int is_neg = (inst.instruction & 0x80) != 0;
9db2f6b4 15848 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_VFP | N_KEY);
037e8744 15849
9db2f6b4 15850 if (rs == NS_FF || rs == NS_HH)
037e8744
JB
15851 {
15852 if (is_neg)
477330fc 15853 do_vfp_nsyn_opcode ("fnegs");
037e8744 15854 else
477330fc 15855 do_vfp_nsyn_opcode ("fabss");
9db2f6b4
RL
15856
15857 /* ARMv8.2 fp16 instruction. */
15858 if (rs == NS_HH)
15859 do_scalar_fp16_v82_encode ();
037e8744
JB
15860 }
15861 else
15862 {
15863 if (is_neg)
477330fc 15864 do_vfp_nsyn_opcode ("fnegd");
037e8744 15865 else
477330fc 15866 do_vfp_nsyn_opcode ("fabsd");
037e8744
JB
15867 }
15868}
15869
15870/* Encode single-precision (only!) VFP fldm/fstm instructions. Double precision
15871 insns belong to Neon, and are handled elsewhere. */
15872
15873static void
15874do_vfp_nsyn_ldm_stm (int is_dbmode)
15875{
15876 int is_ldm = (inst.instruction & (1 << 20)) != 0;
15877 if (is_ldm)
15878 {
15879 if (is_dbmode)
477330fc 15880 do_vfp_nsyn_opcode ("fldmdbs");
037e8744 15881 else
477330fc 15882 do_vfp_nsyn_opcode ("fldmias");
037e8744
JB
15883 }
15884 else
15885 {
15886 if (is_dbmode)
477330fc 15887 do_vfp_nsyn_opcode ("fstmdbs");
037e8744 15888 else
477330fc 15889 do_vfp_nsyn_opcode ("fstmias");
037e8744
JB
15890 }
15891}
15892
037e8744
JB
15893static void
15894do_vfp_nsyn_sqrt (void)
15895{
9db2f6b4
RL
15896 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15897 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 15898
9db2f6b4
RL
15899 if (rs == NS_FF || rs == NS_HH)
15900 {
15901 do_vfp_nsyn_opcode ("fsqrts");
15902
15903 /* ARMv8.2 fp16 instruction. */
15904 if (rs == NS_HH)
15905 do_scalar_fp16_v82_encode ();
15906 }
037e8744
JB
15907 else
15908 do_vfp_nsyn_opcode ("fsqrtd");
15909}
15910
15911static void
15912do_vfp_nsyn_div (void)
15913{
9db2f6b4 15914 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15915 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15916 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15917
9db2f6b4
RL
15918 if (rs == NS_FFF || rs == NS_HHH)
15919 {
15920 do_vfp_nsyn_opcode ("fdivs");
15921
15922 /* ARMv8.2 fp16 instruction. */
15923 if (rs == NS_HHH)
15924 do_scalar_fp16_v82_encode ();
15925 }
037e8744
JB
15926 else
15927 do_vfp_nsyn_opcode ("fdivd");
15928}
15929
15930static void
15931do_vfp_nsyn_nmul (void)
15932{
9db2f6b4 15933 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15934 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15935 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15936
9db2f6b4 15937 if (rs == NS_FFF || rs == NS_HHH)
037e8744 15938 {
88714cb8 15939 NEON_ENCODE (SINGLE, inst);
037e8744 15940 do_vfp_sp_dyadic ();
9db2f6b4
RL
15941
15942 /* ARMv8.2 fp16 instruction. */
15943 if (rs == NS_HHH)
15944 do_scalar_fp16_v82_encode ();
037e8744
JB
15945 }
15946 else
15947 {
88714cb8 15948 NEON_ENCODE (DOUBLE, inst);
037e8744
JB
15949 do_vfp_dp_rd_rn_rm ();
15950 }
15951 do_vfp_cond_or_thumb ();
9db2f6b4 15952
037e8744
JB
15953}
15954
1b883319
AV
15955/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
15956 (0, 1, 2, 3). */
15957
15958static unsigned
15959neon_logbits (unsigned x)
15960{
15961 return ffs (x) - 4;
15962}
15963
15964#define LOW4(R) ((R) & 0xf)
15965#define HI1(R) (((R) >> 4) & 1)
5aae9ae9
MM
15966#define LOW1(R) ((R) & 0x1)
15967#define HI4(R) (((R) >> 1) & 0xf)
1b883319
AV
15968
15969static unsigned
15970mve_get_vcmp_vpt_cond (struct neon_type_el et)
15971{
15972 switch (et.type)
15973 {
15974 default:
15975 first_error (BAD_EL_TYPE);
15976 return 0;
15977 case NT_float:
15978 switch (inst.operands[0].imm)
15979 {
15980 default:
15981 first_error (_("invalid condition"));
15982 return 0;
15983 case 0x0:
15984 /* eq. */
15985 return 0;
15986 case 0x1:
15987 /* ne. */
15988 return 1;
15989 case 0xa:
15990 /* ge/ */
15991 return 4;
15992 case 0xb:
15993 /* lt. */
15994 return 5;
15995 case 0xc:
15996 /* gt. */
15997 return 6;
15998 case 0xd:
15999 /* le. */
16000 return 7;
16001 }
16002 case NT_integer:
16003 /* only accept eq and ne. */
16004 if (inst.operands[0].imm > 1)
16005 {
16006 first_error (_("invalid condition"));
16007 return 0;
16008 }
16009 return inst.operands[0].imm;
16010 case NT_unsigned:
16011 if (inst.operands[0].imm == 0x2)
16012 return 2;
16013 else if (inst.operands[0].imm == 0x8)
16014 return 3;
16015 else
16016 {
16017 first_error (_("invalid condition"));
16018 return 0;
16019 }
16020 case NT_signed:
16021 switch (inst.operands[0].imm)
16022 {
16023 default:
16024 first_error (_("invalid condition"));
16025 return 0;
16026 case 0xa:
16027 /* ge. */
16028 return 4;
16029 case 0xb:
16030 /* lt. */
16031 return 5;
16032 case 0xc:
16033 /* gt. */
16034 return 6;
16035 case 0xd:
16036 /* le. */
16037 return 7;
16038 }
16039 }
16040 /* Should be unreachable. */
16041 abort ();
16042}
16043
efd0b310
SP
16044/* For VCTP (create vector tail predicate) in MVE. */
16045static void
16046do_mve_vctp (void)
16047{
16048 int dt = 0;
16049 unsigned size = 0x0;
16050
16051 if (inst.cond > COND_ALWAYS)
16052 inst.pred_insn_type = INSIDE_VPT_INSN;
16053 else
16054 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16055
16056 /* This is a typical MVE instruction which has no type but have size 8, 16,
16057 32 and 64. For instructions with no type, inst.vectype.el[j].type is set
16058 to NT_untyped and size is updated in inst.vectype.el[j].size. */
16059 if ((inst.operands[0].present) && (inst.vectype.el[0].type == NT_untyped))
16060 dt = inst.vectype.el[0].size;
16061
16062 /* Setting this does not indicate an actual NEON instruction, but only
16063 indicates that the mnemonic accepts neon-style type suffixes. */
16064 inst.is_neon = 1;
16065
16066 switch (dt)
16067 {
16068 case 8:
16069 break;
16070 case 16:
16071 size = 0x1; break;
16072 case 32:
16073 size = 0x2; break;
16074 case 64:
16075 size = 0x3; break;
16076 default:
16077 first_error (_("Type is not allowed for this instruction"));
16078 }
16079 inst.instruction |= size << 20;
16080 inst.instruction |= inst.operands[0].reg << 16;
16081}
16082
1b883319
AV
16083static void
16084do_mve_vpt (void)
16085{
16086 /* We are dealing with a vector predicated block. */
16087 if (inst.operands[0].present)
16088 {
16089 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
16090 struct neon_type_el et
16091 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
16092 N_EQK);
16093
16094 unsigned fcond = mve_get_vcmp_vpt_cond (et);
16095
16096 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
16097
16098 if (et.type == NT_invtype)
16099 return;
16100
16101 if (et.type == NT_float)
16102 {
16103 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
16104 BAD_FPU);
16105 constraint (et.size != 16 && et.size != 32, BAD_EL_TYPE);
16106 inst.instruction |= (et.size == 16) << 28;
16107 inst.instruction |= 0x3 << 20;
16108 }
16109 else
16110 {
16111 constraint (et.size != 8 && et.size != 16 && et.size != 32,
16112 BAD_EL_TYPE);
16113 inst.instruction |= 1 << 28;
16114 inst.instruction |= neon_logbits (et.size) << 20;
16115 }
16116
16117 if (inst.operands[2].isquad)
16118 {
16119 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16120 inst.instruction |= LOW4 (inst.operands[2].reg);
16121 inst.instruction |= (fcond & 0x2) >> 1;
16122 }
16123 else
16124 {
16125 if (inst.operands[2].reg == REG_SP)
16126 as_tsktsk (MVE_BAD_SP);
16127 inst.instruction |= 1 << 6;
16128 inst.instruction |= (fcond & 0x2) << 4;
16129 inst.instruction |= inst.operands[2].reg;
16130 }
16131 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16132 inst.instruction |= (fcond & 0x4) << 10;
16133 inst.instruction |= (fcond & 0x1) << 7;
16134
16135 }
16136 set_pred_insn_type (VPT_INSN);
16137 now_pred.cc = 0;
16138 now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
16139 | ((inst.instruction & 0xe000) >> 13);
5b7c81bd 16140 now_pred.warn_deprecated = false;
1b883319
AV
16141 now_pred.type = VECTOR_PRED;
16142 inst.is_neon = 1;
16143}
16144
16145static void
16146do_mve_vcmp (void)
16147{
16148 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
16149 if (!inst.operands[1].isreg || !inst.operands[1].isquad)
16150 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
16151 if (!inst.operands[2].present)
16152 first_error (_("MVE vector or ARM register expected"));
16153 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
16154
16155 /* Deal with 'else' conditional MVE's vcmp, it will be parsed as vcmpe. */
16156 if ((inst.instruction & 0xffffffff) == N_MNEM_vcmpe
16157 && inst.operands[1].isquad)
16158 {
16159 inst.instruction = N_MNEM_vcmp;
16160 inst.cond = 0x10;
16161 }
16162
16163 if (inst.cond > COND_ALWAYS)
16164 inst.pred_insn_type = INSIDE_VPT_INSN;
16165 else
16166 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16167
16168 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
16169 struct neon_type_el et
16170 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
16171 N_EQK);
16172
16173 constraint (rs == NS_IQR && inst.operands[2].reg == REG_PC
16174 && !inst.operands[2].iszr, BAD_PC);
16175
16176 unsigned fcond = mve_get_vcmp_vpt_cond (et);
16177
16178 inst.instruction = 0xee010f00;
16179 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16180 inst.instruction |= (fcond & 0x4) << 10;
16181 inst.instruction |= (fcond & 0x1) << 7;
16182 if (et.type == NT_float)
16183 {
16184 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
16185 BAD_FPU);
16186 inst.instruction |= (et.size == 16) << 28;
16187 inst.instruction |= 0x3 << 20;
16188 }
16189 else
16190 {
16191 inst.instruction |= 1 << 28;
16192 inst.instruction |= neon_logbits (et.size) << 20;
16193 }
16194 if (inst.operands[2].isquad)
16195 {
16196 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16197 inst.instruction |= (fcond & 0x2) >> 1;
16198 inst.instruction |= LOW4 (inst.operands[2].reg);
16199 }
16200 else
16201 {
16202 if (inst.operands[2].reg == REG_SP)
16203 as_tsktsk (MVE_BAD_SP);
16204 inst.instruction |= 1 << 6;
16205 inst.instruction |= (fcond & 0x2) << 4;
16206 inst.instruction |= inst.operands[2].reg;
16207 }
16208
16209 inst.is_neon = 1;
16210 return;
16211}
16212
935295b5
AV
16213static void
16214do_mve_vmaxa_vmina (void)
16215{
16216 if (inst.cond > COND_ALWAYS)
16217 inst.pred_insn_type = INSIDE_VPT_INSN;
16218 else
16219 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16220
16221 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
16222 struct neon_type_el et
16223 = neon_check_type (2, rs, N_EQK, N_KEY | N_S8 | N_S16 | N_S32);
16224
16225 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16226 inst.instruction |= neon_logbits (et.size) << 18;
16227 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16228 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16229 inst.instruction |= LOW4 (inst.operands[1].reg);
16230 inst.is_neon = 1;
16231}
16232
f30ee27c
AV
16233static void
16234do_mve_vfmas (void)
16235{
16236 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
16237 struct neon_type_el et
16238 = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK, N_EQK);
16239
16240 if (inst.cond > COND_ALWAYS)
16241 inst.pred_insn_type = INSIDE_VPT_INSN;
16242 else
16243 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16244
16245 if (inst.operands[2].reg == REG_SP)
16246 as_tsktsk (MVE_BAD_SP);
16247 else if (inst.operands[2].reg == REG_PC)
16248 as_tsktsk (MVE_BAD_PC);
16249
16250 inst.instruction |= (et.size == 16) << 28;
16251 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16252 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16253 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16254 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16255 inst.instruction |= inst.operands[2].reg;
16256 inst.is_neon = 1;
16257}
16258
b409bdb6
AV
16259static void
16260do_mve_viddup (void)
16261{
16262 if (inst.cond > COND_ALWAYS)
16263 inst.pred_insn_type = INSIDE_VPT_INSN;
16264 else
16265 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16266
16267 unsigned imm = inst.relocs[0].exp.X_add_number;
16268 constraint (imm != 1 && imm != 2 && imm != 4 && imm != 8,
16269 _("immediate must be either 1, 2, 4 or 8"));
16270
16271 enum neon_shape rs;
16272 struct neon_type_el et;
16273 unsigned Rm;
16274 if (inst.instruction == M_MNEM_vddup || inst.instruction == M_MNEM_vidup)
16275 {
16276 rs = neon_select_shape (NS_QRI, NS_NULL);
16277 et = neon_check_type (2, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK);
16278 Rm = 7;
16279 }
16280 else
16281 {
16282 constraint ((inst.operands[2].reg % 2) != 1, BAD_EVEN);
16283 if (inst.operands[2].reg == REG_SP)
16284 as_tsktsk (MVE_BAD_SP);
16285 else if (inst.operands[2].reg == REG_PC)
16286 first_error (BAD_PC);
16287
16288 rs = neon_select_shape (NS_QRRI, NS_NULL);
16289 et = neon_check_type (3, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK, N_EQK);
16290 Rm = inst.operands[2].reg >> 1;
16291 }
16292 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16293 inst.instruction |= neon_logbits (et.size) << 20;
16294 inst.instruction |= inst.operands[1].reg << 16;
16295 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16296 inst.instruction |= (imm > 2) << 7;
16297 inst.instruction |= Rm << 1;
16298 inst.instruction |= (imm == 2 || imm == 8);
16299 inst.is_neon = 1;
16300}
16301
2d78f95b
AV
16302static void
16303do_mve_vmlas (void)
16304{
16305 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
16306 struct neon_type_el et
16307 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
16308
16309 if (inst.operands[2].reg == REG_PC)
16310 as_tsktsk (MVE_BAD_PC);
16311 else if (inst.operands[2].reg == REG_SP)
16312 as_tsktsk (MVE_BAD_SP);
16313
16314 if (inst.cond > COND_ALWAYS)
16315 inst.pred_insn_type = INSIDE_VPT_INSN;
16316 else
16317 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16318
16319 inst.instruction |= (et.type == NT_unsigned) << 28;
16320 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16321 inst.instruction |= neon_logbits (et.size) << 20;
16322 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16323 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16324 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16325 inst.instruction |= inst.operands[2].reg;
16326 inst.is_neon = 1;
16327}
16328
acca5630
AV
16329static void
16330do_mve_vshll (void)
16331{
16332 struct neon_type_el et
16333 = neon_check_type (2, NS_QQI, N_EQK, N_S8 | N_U8 | N_S16 | N_U16 | N_KEY);
16334
16335 if (inst.cond > COND_ALWAYS)
16336 inst.pred_insn_type = INSIDE_VPT_INSN;
16337 else
16338 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16339
16340 int imm = inst.operands[2].imm;
16341 constraint (imm < 1 || (unsigned)imm > et.size,
16342 _("immediate value out of range"));
16343
16344 if ((unsigned)imm == et.size)
16345 {
16346 inst.instruction |= neon_logbits (et.size) << 18;
16347 inst.instruction |= 0x110001;
16348 }
16349 else
16350 {
16351 inst.instruction |= (et.size + imm) << 16;
16352 inst.instruction |= 0x800140;
16353 }
16354
16355 inst.instruction |= (et.type == NT_unsigned) << 28;
16356 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16357 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16358 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16359 inst.instruction |= LOW4 (inst.operands[1].reg);
16360 inst.is_neon = 1;
16361}
16362
16363static void
16364do_mve_vshlc (void)
16365{
16366 if (inst.cond > COND_ALWAYS)
16367 inst.pred_insn_type = INSIDE_VPT_INSN;
16368 else
16369 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16370
16371 if (inst.operands[1].reg == REG_PC)
16372 as_tsktsk (MVE_BAD_PC);
16373 else if (inst.operands[1].reg == REG_SP)
16374 as_tsktsk (MVE_BAD_SP);
16375
16376 int imm = inst.operands[2].imm;
16377 constraint (imm < 1 || imm > 32, _("immediate value out of range"));
16378
16379 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16380 inst.instruction |= (imm & 0x1f) << 16;
16381 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16382 inst.instruction |= inst.operands[1].reg;
16383 inst.is_neon = 1;
16384}
16385
4aa88b50
AV
16386static void
16387do_mve_vshrn (void)
16388{
16389 unsigned types;
16390 switch (inst.instruction)
16391 {
16392 case M_MNEM_vshrnt:
16393 case M_MNEM_vshrnb:
16394 case M_MNEM_vrshrnt:
16395 case M_MNEM_vrshrnb:
16396 types = N_I16 | N_I32;
16397 break;
16398 case M_MNEM_vqshrnt:
16399 case M_MNEM_vqshrnb:
16400 case M_MNEM_vqrshrnt:
16401 case M_MNEM_vqrshrnb:
16402 types = N_U16 | N_U32 | N_S16 | N_S32;
16403 break;
16404 case M_MNEM_vqshrunt:
16405 case M_MNEM_vqshrunb:
16406 case M_MNEM_vqrshrunt:
16407 case M_MNEM_vqrshrunb:
16408 types = N_S16 | N_S32;
16409 break;
16410 default:
16411 abort ();
16412 }
16413
16414 struct neon_type_el et = neon_check_type (2, NS_QQI, N_EQK, types | N_KEY);
16415
16416 if (inst.cond > COND_ALWAYS)
16417 inst.pred_insn_type = INSIDE_VPT_INSN;
16418 else
16419 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16420
16421 unsigned Qd = inst.operands[0].reg;
16422 unsigned Qm = inst.operands[1].reg;
16423 unsigned imm = inst.operands[2].imm;
16424 constraint (imm < 1 || ((unsigned) imm) > (et.size / 2),
16425 et.size == 16
16426 ? _("immediate operand expected in the range [1,8]")
16427 : _("immediate operand expected in the range [1,16]"));
16428
16429 inst.instruction |= (et.type == NT_unsigned) << 28;
16430 inst.instruction |= HI1 (Qd) << 22;
16431 inst.instruction |= (et.size - imm) << 16;
16432 inst.instruction |= LOW4 (Qd) << 12;
16433 inst.instruction |= HI1 (Qm) << 5;
16434 inst.instruction |= LOW4 (Qm);
16435 inst.is_neon = 1;
16436}
16437
1be7aba3
AV
16438static void
16439do_mve_vqmovn (void)
16440{
16441 struct neon_type_el et;
16442 if (inst.instruction == M_MNEM_vqmovnt
16443 || inst.instruction == M_MNEM_vqmovnb)
16444 et = neon_check_type (2, NS_QQ, N_EQK,
16445 N_U16 | N_U32 | N_S16 | N_S32 | N_KEY);
16446 else
16447 et = neon_check_type (2, NS_QQ, N_EQK, N_S16 | N_S32 | N_KEY);
16448
16449 if (inst.cond > COND_ALWAYS)
16450 inst.pred_insn_type = INSIDE_VPT_INSN;
16451 else
16452 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16453
16454 inst.instruction |= (et.type == NT_unsigned) << 28;
16455 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16456 inst.instruction |= (et.size == 32) << 18;
16457 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16458 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16459 inst.instruction |= LOW4 (inst.operands[1].reg);
16460 inst.is_neon = 1;
16461}
16462
3063888e
AV
16463static void
16464do_mve_vpsel (void)
16465{
16466 neon_select_shape (NS_QQQ, NS_NULL);
16467
16468 if (inst.cond > COND_ALWAYS)
16469 inst.pred_insn_type = INSIDE_VPT_INSN;
16470 else
16471 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16472
16473 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16474 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16475 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16476 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16477 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16478 inst.instruction |= LOW4 (inst.operands[2].reg);
16479 inst.is_neon = 1;
16480}
16481
16482static void
16483do_mve_vpnot (void)
16484{
16485 if (inst.cond > COND_ALWAYS)
16486 inst.pred_insn_type = INSIDE_VPT_INSN;
16487 else
16488 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16489}
16490
935295b5
AV
16491static void
16492do_mve_vmaxnma_vminnma (void)
16493{
16494 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
16495 struct neon_type_el et
16496 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
16497
16498 if (inst.cond > COND_ALWAYS)
16499 inst.pred_insn_type = INSIDE_VPT_INSN;
16500 else
16501 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16502
16503 inst.instruction |= (et.size == 16) << 28;
16504 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16505 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16506 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16507 inst.instruction |= LOW4 (inst.operands[1].reg);
16508 inst.is_neon = 1;
16509}
16510
5d281bf0
AV
16511static void
16512do_mve_vcmul (void)
16513{
16514 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
16515 struct neon_type_el et
16516 = neon_check_type (3, rs, N_EQK, N_EQK, N_F_MVE | N_KEY);
16517
16518 if (inst.cond > COND_ALWAYS)
16519 inst.pred_insn_type = INSIDE_VPT_INSN;
16520 else
16521 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16522
16523 unsigned rot = inst.relocs[0].exp.X_add_number;
16524 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
16525 _("immediate out of range"));
16526
16527 if (et.size == 32 && (inst.operands[0].reg == inst.operands[1].reg
16528 || inst.operands[0].reg == inst.operands[2].reg))
16529 as_tsktsk (BAD_MVE_SRCDEST);
16530
16531 inst.instruction |= (et.size == 32) << 28;
16532 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16533 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16534 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16535 inst.instruction |= (rot > 90) << 12;
16536 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16537 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16538 inst.instruction |= LOW4 (inst.operands[2].reg);
16539 inst.instruction |= (rot == 90 || rot == 270);
16540 inst.is_neon = 1;
16541}
16542
1f6234a3
AV
16543/* To handle the Low Overhead Loop instructions
16544 in Armv8.1-M Mainline and MVE. */
16545static void
16546do_t_loloop (void)
16547{
16548 unsigned long insn = inst.instruction;
16549
16550 inst.instruction = THUMB_OP32 (inst.instruction);
16551
16552 if (insn == T_MNEM_lctp)
16553 return;
16554
16555 set_pred_insn_type (MVE_OUTSIDE_PRED_INSN);
16556
16557 if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
16558 {
16559 struct neon_type_el et
16560 = neon_check_type (2, NS_RR, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
16561 inst.instruction |= neon_logbits (et.size) << 20;
16562 inst.is_neon = 1;
16563 }
16564
16565 switch (insn)
16566 {
16567 case T_MNEM_letp:
16568 constraint (!inst.operands[0].present,
16569 _("expected LR"));
16570 /* fall through. */
16571 case T_MNEM_le:
16572 /* le <label>. */
16573 if (!inst.operands[0].present)
16574 inst.instruction |= 1 << 21;
16575
5b7c81bd 16576 v8_1_loop_reloc (true);
1f6234a3
AV
16577 break;
16578
16579 case T_MNEM_wls:
16580 case T_MNEM_wlstp:
5b7c81bd 16581 v8_1_loop_reloc (false);
1f6234a3
AV
16582 /* fall through. */
16583 case T_MNEM_dlstp:
16584 case T_MNEM_dls:
16585 constraint (inst.operands[1].isreg != 1, BAD_ARGS);
16586
16587 if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
16588 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
16589 else if (inst.operands[1].reg == REG_PC)
16590 as_tsktsk (MVE_BAD_PC);
16591 if (inst.operands[1].reg == REG_SP)
16592 as_tsktsk (MVE_BAD_SP);
16593
16594 inst.instruction |= (inst.operands[1].reg << 16);
16595 break;
16596
16597 default:
16598 abort ();
16599 }
16600}
16601
16602
037e8744
JB
16603static void
16604do_vfp_nsyn_cmp (void)
16605{
9db2f6b4 16606 enum neon_shape rs;
1b883319
AV
16607 if (!inst.operands[0].isreg)
16608 {
16609 do_mve_vcmp ();
16610 return;
16611 }
16612 else
16613 {
16614 constraint (inst.operands[2].present, BAD_SYNTAX);
16615 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd),
16616 BAD_FPU);
16617 }
16618
037e8744
JB
16619 if (inst.operands[1].isreg)
16620 {
9db2f6b4
RL
16621 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
16622 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 16623
9db2f6b4 16624 if (rs == NS_FF || rs == NS_HH)
477330fc
RM
16625 {
16626 NEON_ENCODE (SINGLE, inst);
16627 do_vfp_sp_monadic ();
16628 }
037e8744 16629 else
477330fc
RM
16630 {
16631 NEON_ENCODE (DOUBLE, inst);
16632 do_vfp_dp_rd_rm ();
16633 }
037e8744
JB
16634 }
16635 else
16636 {
9db2f6b4
RL
16637 rs = neon_select_shape (NS_HI, NS_FI, NS_DI, NS_NULL);
16638 neon_check_type (2, rs, N_F_ALL | N_KEY | N_VFP, N_EQK);
037e8744
JB
16639
16640 switch (inst.instruction & 0x0fffffff)
477330fc
RM
16641 {
16642 case N_MNEM_vcmp:
16643 inst.instruction += N_MNEM_vcmpz - N_MNEM_vcmp;
16644 break;
16645 case N_MNEM_vcmpe:
16646 inst.instruction += N_MNEM_vcmpez - N_MNEM_vcmpe;
16647 break;
16648 default:
16649 abort ();
16650 }
5f4273c7 16651
9db2f6b4 16652 if (rs == NS_FI || rs == NS_HI)
477330fc
RM
16653 {
16654 NEON_ENCODE (SINGLE, inst);
16655 do_vfp_sp_compare_z ();
16656 }
037e8744 16657 else
477330fc
RM
16658 {
16659 NEON_ENCODE (DOUBLE, inst);
16660 do_vfp_dp_rd ();
16661 }
037e8744
JB
16662 }
16663 do_vfp_cond_or_thumb ();
9db2f6b4
RL
16664
16665 /* ARMv8.2 fp16 instruction. */
16666 if (rs == NS_HI || rs == NS_HH)
16667 do_scalar_fp16_v82_encode ();
037e8744
JB
16668}
16669
16670static void
16671nsyn_insert_sp (void)
16672{
16673 inst.operands[1] = inst.operands[0];
16674 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
fdfde340 16675 inst.operands[0].reg = REG_SP;
037e8744
JB
16676 inst.operands[0].isreg = 1;
16677 inst.operands[0].writeback = 1;
16678 inst.operands[0].present = 1;
16679}
16680
037e8744
JB
16681/* Fix up Neon data-processing instructions, ORing in the correct bits for
16682 ARM mode or Thumb mode and moving the encoded bit 24 to bit 28. */
16683
88714cb8
DG
16684static void
16685neon_dp_fixup (struct arm_it* insn)
037e8744 16686{
88714cb8
DG
16687 unsigned int i = insn->instruction;
16688 insn->is_neon = 1;
16689
037e8744
JB
16690 if (thumb_mode)
16691 {
16692 /* The U bit is at bit 24 by default. Move to bit 28 in Thumb mode. */
16693 if (i & (1 << 24))
477330fc 16694 i |= 1 << 28;
5f4273c7 16695
037e8744 16696 i &= ~(1 << 24);
5f4273c7 16697
037e8744
JB
16698 i |= 0xef000000;
16699 }
16700 else
16701 i |= 0xf2000000;
5f4273c7 16702
88714cb8 16703 insn->instruction = i;
037e8744
JB
16704}
16705
5ee91343 16706static void
7df54120 16707mve_encode_qqr (int size, int U, int fp)
5ee91343
AV
16708{
16709 if (inst.operands[2].reg == REG_SP)
16710 as_tsktsk (MVE_BAD_SP);
16711 else if (inst.operands[2].reg == REG_PC)
16712 as_tsktsk (MVE_BAD_PC);
16713
16714 if (fp)
16715 {
16716 /* vadd. */
16717 if (((unsigned)inst.instruction) == 0xd00)
16718 inst.instruction = 0xee300f40;
16719 /* vsub. */
16720 else if (((unsigned)inst.instruction) == 0x200d00)
16721 inst.instruction = 0xee301f40;
a8465a06
AV
16722 /* vmul. */
16723 else if (((unsigned)inst.instruction) == 0x1000d10)
16724 inst.instruction = 0xee310e60;
5ee91343
AV
16725
16726 /* Setting size which is 1 for F16 and 0 for F32. */
16727 inst.instruction |= (size == 16) << 28;
16728 }
16729 else
16730 {
16731 /* vadd. */
16732 if (((unsigned)inst.instruction) == 0x800)
16733 inst.instruction = 0xee010f40;
16734 /* vsub. */
16735 else if (((unsigned)inst.instruction) == 0x1000800)
16736 inst.instruction = 0xee011f40;
7df54120
AV
16737 /* vhadd. */
16738 else if (((unsigned)inst.instruction) == 0)
16739 inst.instruction = 0xee000f40;
16740 /* vhsub. */
16741 else if (((unsigned)inst.instruction) == 0x200)
16742 inst.instruction = 0xee001f40;
a8465a06
AV
16743 /* vmla. */
16744 else if (((unsigned)inst.instruction) == 0x900)
16745 inst.instruction = 0xee010e40;
16746 /* vmul. */
16747 else if (((unsigned)inst.instruction) == 0x910)
16748 inst.instruction = 0xee011e60;
16749 /* vqadd. */
16750 else if (((unsigned)inst.instruction) == 0x10)
16751 inst.instruction = 0xee000f60;
16752 /* vqsub. */
16753 else if (((unsigned)inst.instruction) == 0x210)
16754 inst.instruction = 0xee001f60;
42b16635
AV
16755 /* vqrdmlah. */
16756 else if (((unsigned)inst.instruction) == 0x3000b10)
16757 inst.instruction = 0xee000e40;
16758 /* vqdmulh. */
16759 else if (((unsigned)inst.instruction) == 0x0000b00)
16760 inst.instruction = 0xee010e60;
16761 /* vqrdmulh. */
16762 else if (((unsigned)inst.instruction) == 0x1000b00)
16763 inst.instruction = 0xfe010e60;
7df54120
AV
16764
16765 /* Set U-bit. */
16766 inst.instruction |= U << 28;
16767
5ee91343
AV
16768 /* Setting bits for size. */
16769 inst.instruction |= neon_logbits (size) << 20;
16770 }
16771 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16772 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16773 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16774 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16775 inst.instruction |= inst.operands[2].reg;
16776 inst.is_neon = 1;
16777}
16778
a302e574
AV
16779static void
16780mve_encode_rqq (unsigned bit28, unsigned size)
16781{
16782 inst.instruction |= bit28 << 28;
16783 inst.instruction |= neon_logbits (size) << 20;
16784 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16785 inst.instruction |= inst.operands[0].reg << 12;
16786 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16787 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16788 inst.instruction |= LOW4 (inst.operands[2].reg);
16789 inst.is_neon = 1;
16790}
16791
886e1c73
AV
16792static void
16793mve_encode_qqq (int ubit, int size)
16794{
16795
16796 inst.instruction |= (ubit != 0) << 28;
16797 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16798 inst.instruction |= neon_logbits (size) << 20;
16799 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16800 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16801 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16802 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16803 inst.instruction |= LOW4 (inst.operands[2].reg);
16804
16805 inst.is_neon = 1;
16806}
16807
26c1e780
AV
16808static void
16809mve_encode_rq (unsigned bit28, unsigned size)
16810{
16811 inst.instruction |= bit28 << 28;
16812 inst.instruction |= neon_logbits (size) << 18;
16813 inst.instruction |= inst.operands[0].reg << 12;
16814 inst.instruction |= LOW4 (inst.operands[1].reg);
16815 inst.is_neon = 1;
16816}
886e1c73 16817
93925576
AV
16818static void
16819mve_encode_rrqq (unsigned U, unsigned size)
16820{
16821 constraint (inst.operands[3].reg > 14, MVE_BAD_QREG);
16822
16823 inst.instruction |= U << 28;
16824 inst.instruction |= (inst.operands[1].reg >> 1) << 20;
16825 inst.instruction |= LOW4 (inst.operands[2].reg) << 16;
16826 inst.instruction |= (size == 32) << 16;
16827 inst.instruction |= inst.operands[0].reg << 12;
16828 inst.instruction |= HI1 (inst.operands[2].reg) << 7;
16829 inst.instruction |= inst.operands[3].reg;
16830 inst.is_neon = 1;
16831}
16832
aab2c27d
MM
16833/* Helper function for neon_three_same handling the operands. */
16834static void
16835neon_three_args (int isquad)
16836{
16837 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16838 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16839 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16840 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16841 inst.instruction |= LOW4 (inst.operands[2].reg);
16842 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16843 inst.instruction |= (isquad != 0) << 6;
16844 inst.is_neon = 1;
16845}
16846
037e8744
JB
16847/* Encode insns with bit pattern:
16848
16849 |28/24|23|22 |21 20|19 16|15 12|11 8|7|6|5|4|3 0|
16850 | U |x |D |size | Rn | Rd |x x x x|N|Q|M|x| Rm |
5f4273c7 16851
037e8744
JB
16852 SIZE is passed in bits. -1 means size field isn't changed, in case it has a
16853 different meaning for some instruction. */
16854
16855static void
16856neon_three_same (int isquad, int ubit, int size)
16857{
aab2c27d 16858 neon_three_args (isquad);
037e8744
JB
16859 inst.instruction |= (ubit != 0) << 24;
16860 if (size != -1)
16861 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 16862
88714cb8 16863 neon_dp_fixup (&inst);
037e8744
JB
16864}
16865
16866/* Encode instructions of the form:
16867
16868 |28/24|23|22|21 20|19 18|17 16|15 12|11 7|6|5|4|3 0|
16869 | U |x |D |x x |size |x x | Rd |x x x x x|Q|M|x| Rm |
5287ad62
JB
16870
16871 Don't write size if SIZE == -1. */
16872
16873static void
16874neon_two_same (int qbit, int ubit, int size)
16875{
16876 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16877 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16878 inst.instruction |= LOW4 (inst.operands[1].reg);
16879 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16880 inst.instruction |= (qbit != 0) << 6;
16881 inst.instruction |= (ubit != 0) << 24;
16882
16883 if (size != -1)
16884 inst.instruction |= neon_logbits (size) << 18;
16885
88714cb8 16886 neon_dp_fixup (&inst);
5287ad62
JB
16887}
16888
7df54120
AV
16889enum vfp_or_neon_is_neon_bits
16890{
16891NEON_CHECK_CC = 1,
16892NEON_CHECK_ARCH = 2,
16893NEON_CHECK_ARCH8 = 4
16894};
16895
16896/* Call this function if an instruction which may have belonged to the VFP or
16897 Neon instruction sets, but turned out to be a Neon instruction (due to the
16898 operand types involved, etc.). We have to check and/or fix-up a couple of
16899 things:
16900
16901 - Make sure the user hasn't attempted to make a Neon instruction
16902 conditional.
16903 - Alter the value in the condition code field if necessary.
16904 - Make sure that the arch supports Neon instructions.
16905
16906 Which of these operations take place depends on bits from enum
16907 vfp_or_neon_is_neon_bits.
16908
16909 WARNING: This function has side effects! If NEON_CHECK_CC is used and the
16910 current instruction's condition is COND_ALWAYS, the condition field is
16911 changed to inst.uncond_value. This is necessary because instructions shared
16912 between VFP and Neon may be conditional for the VFP variants only, and the
16913 unconditional Neon version must have, e.g., 0xF in the condition field. */
16914
16915static int
16916vfp_or_neon_is_neon (unsigned check)
16917{
16918/* Conditions are always legal in Thumb mode (IT blocks). */
16919if (!thumb_mode && (check & NEON_CHECK_CC))
16920 {
16921 if (inst.cond != COND_ALWAYS)
16922 {
16923 first_error (_(BAD_COND));
16924 return FAIL;
16925 }
7af67752 16926 if (inst.uncond_value != -1u)
7df54120
AV
16927 inst.instruction |= inst.uncond_value << 28;
16928 }
16929
16930
16931 if (((check & NEON_CHECK_ARCH) && !mark_feature_used (&fpu_neon_ext_v1))
16932 || ((check & NEON_CHECK_ARCH8)
16933 && !mark_feature_used (&fpu_neon_ext_armv8)))
16934 {
16935 first_error (_(BAD_FPU));
16936 return FAIL;
16937 }
16938
16939return SUCCESS;
16940}
16941
64c350f2
AV
16942
16943/* Return TRUE if the SIMD instruction is available for the current
16944 cpu_variant. FP is set to TRUE if this is a SIMD floating-point
16945 instruction. CHECK contains th. CHECK contains the set of bits to pass to
16946 vfp_or_neon_is_neon for the NEON specific checks. */
16947
5b7c81bd 16948static bool
7df54120
AV
16949check_simd_pred_availability (int fp, unsigned check)
16950{
16951if (inst.cond > COND_ALWAYS)
16952 {
16953 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16954 {
16955 inst.error = BAD_FPU;
5b7c81bd 16956 return false;
7df54120
AV
16957 }
16958 inst.pred_insn_type = INSIDE_VPT_INSN;
16959 }
16960else if (inst.cond < COND_ALWAYS)
16961 {
16962 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16963 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16964 else if (vfp_or_neon_is_neon (check) == FAIL)
5b7c81bd 16965 return false;
7df54120
AV
16966 }
16967else
16968 {
16969 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fp ? mve_fp_ext : mve_ext)
16970 && vfp_or_neon_is_neon (check) == FAIL)
5b7c81bd 16971 return false;
7df54120
AV
16972
16973 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16974 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16975 }
5b7c81bd 16976return true;
7df54120
AV
16977}
16978
5287ad62
JB
16979/* Neon instruction encoders, in approximate order of appearance. */
16980
16981static void
16982do_neon_dyadic_i_su (void)
16983{
5b7c81bd 16984 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
7df54120
AV
16985 return;
16986
16987 enum neon_shape rs;
16988 struct neon_type_el et;
16989 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16990 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
16991 else
16992 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16993
16994 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_32 | N_KEY);
16995
16996
16997 if (rs != NS_QQR)
16998 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
16999 else
17000 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
5287ad62
JB
17001}
17002
17003static void
17004do_neon_dyadic_i64_su (void)
17005{
5b7c81bd 17006 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
a8465a06
AV
17007 return;
17008 enum neon_shape rs;
17009 struct neon_type_el et;
17010 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17011 {
17012 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
17013 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17014 }
17015 else
17016 {
17017 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17018 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
17019 }
17020 if (rs == NS_QQR)
17021 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
17022 else
17023 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
17024}
17025
17026static void
17027neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
477330fc 17028 unsigned immbits)
5287ad62
JB
17029{
17030 unsigned size = et.size >> 3;
17031 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17032 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17033 inst.instruction |= LOW4 (inst.operands[1].reg);
17034 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
17035 inst.instruction |= (isquad != 0) << 6;
17036 inst.instruction |= immbits << 16;
17037 inst.instruction |= (size >> 3) << 7;
17038 inst.instruction |= (size & 0x7) << 19;
17039 if (write_ubit)
17040 inst.instruction |= (uval != 0) << 24;
17041
88714cb8 17042 neon_dp_fixup (&inst);
5287ad62
JB
17043}
17044
17045static void
5150f0d8 17046do_neon_shl (void)
5287ad62 17047{
5b7c81bd 17048 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
17049 return;
17050
5287ad62
JB
17051 if (!inst.operands[2].isreg)
17052 {
5150f0d8
AV
17053 enum neon_shape rs;
17054 struct neon_type_el et;
17055 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17056 {
17057 rs = neon_select_shape (NS_QQI, NS_NULL);
17058 et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_MVE);
17059 }
17060 else
17061 {
17062 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
17063 et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
17064 }
cb3b1e65
JB
17065 int imm = inst.operands[2].imm;
17066
17067 constraint (imm < 0 || (unsigned)imm >= et.size,
17068 _("immediate out of range for shift"));
88714cb8 17069 NEON_ENCODE (IMMED, inst);
5b7c81bd 17070 neon_imm_shift (false, 0, neon_quad (rs), et, imm);
5287ad62
JB
17071 }
17072 else
17073 {
5150f0d8
AV
17074 enum neon_shape rs;
17075 struct neon_type_el et;
17076 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17077 {
17078 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17079 et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
17080 }
17081 else
17082 {
17083 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17084 et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
17085 }
17086
17087
17088 if (rs == NS_QQR)
17089 {
17090 constraint (inst.operands[0].reg != inst.operands[1].reg,
17091 _("invalid instruction shape"));
17092 if (inst.operands[2].reg == REG_SP)
17093 as_tsktsk (MVE_BAD_SP);
17094 else if (inst.operands[2].reg == REG_PC)
17095 as_tsktsk (MVE_BAD_PC);
17096
17097 inst.instruction = 0xee311e60;
17098 inst.instruction |= (et.type == NT_unsigned) << 28;
17099 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17100 inst.instruction |= neon_logbits (et.size) << 18;
17101 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17102 inst.instruction |= inst.operands[2].reg;
17103 inst.is_neon = 1;
17104 }
17105 else
17106 {
17107 unsigned int tmp;
17108
17109 /* VSHL/VQSHL 3-register variants have syntax such as:
17110 vshl.xx Dd, Dm, Dn
17111 whereas other 3-register operations encoded by neon_three_same have
17112 syntax like:
17113 vadd.xx Dd, Dn, Dm
17114 (i.e. with Dn & Dm reversed). Swap operands[1].reg and
17115 operands[2].reg here. */
17116 tmp = inst.operands[2].reg;
17117 inst.operands[2].reg = inst.operands[1].reg;
17118 inst.operands[1].reg = tmp;
17119 NEON_ENCODE (INTEGER, inst);
17120 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17121 }
5287ad62
JB
17122 }
17123}
17124
17125static void
5150f0d8 17126do_neon_qshl (void)
5287ad62 17127{
5b7c81bd 17128 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
17129 return;
17130
5287ad62
JB
17131 if (!inst.operands[2].isreg)
17132 {
5150f0d8
AV
17133 enum neon_shape rs;
17134 struct neon_type_el et;
17135 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17136 {
17137 rs = neon_select_shape (NS_QQI, NS_NULL);
17138 et = neon_check_type (2, rs, N_EQK, N_KEY | N_SU_MVE);
17139 }
17140 else
17141 {
17142 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
17143 et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
17144 }
cb3b1e65 17145 int imm = inst.operands[2].imm;
627907b7 17146
cb3b1e65
JB
17147 constraint (imm < 0 || (unsigned)imm >= et.size,
17148 _("immediate out of range for shift"));
88714cb8 17149 NEON_ENCODE (IMMED, inst);
5b7c81bd 17150 neon_imm_shift (true, et.type == NT_unsigned, neon_quad (rs), et, imm);
5287ad62
JB
17151 }
17152 else
17153 {
5150f0d8
AV
17154 enum neon_shape rs;
17155 struct neon_type_el et;
627907b7 17156
5150f0d8
AV
17157 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17158 {
17159 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17160 et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
17161 }
17162 else
17163 {
17164 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17165 et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
17166 }
17167
17168 if (rs == NS_QQR)
17169 {
17170 constraint (inst.operands[0].reg != inst.operands[1].reg,
17171 _("invalid instruction shape"));
17172 if (inst.operands[2].reg == REG_SP)
17173 as_tsktsk (MVE_BAD_SP);
17174 else if (inst.operands[2].reg == REG_PC)
17175 as_tsktsk (MVE_BAD_PC);
17176
17177 inst.instruction = 0xee311ee0;
17178 inst.instruction |= (et.type == NT_unsigned) << 28;
17179 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17180 inst.instruction |= neon_logbits (et.size) << 18;
17181 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17182 inst.instruction |= inst.operands[2].reg;
17183 inst.is_neon = 1;
17184 }
17185 else
17186 {
17187 unsigned int tmp;
17188
17189 /* See note in do_neon_shl. */
17190 tmp = inst.operands[2].reg;
17191 inst.operands[2].reg = inst.operands[1].reg;
17192 inst.operands[1].reg = tmp;
17193 NEON_ENCODE (INTEGER, inst);
17194 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17195 }
5287ad62
JB
17196 }
17197}
17198
627907b7
JB
17199static void
17200do_neon_rshl (void)
17201{
5b7c81bd 17202 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
1be7aba3
AV
17203 return;
17204
17205 enum neon_shape rs;
17206 struct neon_type_el et;
17207 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17208 {
17209 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
17210 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17211 }
17212 else
17213 {
17214 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17215 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
17216 }
17217
627907b7
JB
17218 unsigned int tmp;
17219
1be7aba3
AV
17220 if (rs == NS_QQR)
17221 {
17222 if (inst.operands[2].reg == REG_PC)
17223 as_tsktsk (MVE_BAD_PC);
17224 else if (inst.operands[2].reg == REG_SP)
17225 as_tsktsk (MVE_BAD_SP);
17226
17227 constraint (inst.operands[0].reg != inst.operands[1].reg,
17228 _("invalid instruction shape"));
17229
17230 if (inst.instruction == 0x0000510)
17231 /* We are dealing with vqrshl. */
17232 inst.instruction = 0xee331ee0;
17233 else
17234 /* We are dealing with vrshl. */
17235 inst.instruction = 0xee331e60;
17236
17237 inst.instruction |= (et.type == NT_unsigned) << 28;
17238 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17239 inst.instruction |= neon_logbits (et.size) << 18;
17240 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17241 inst.instruction |= inst.operands[2].reg;
17242 inst.is_neon = 1;
17243 }
17244 else
17245 {
17246 tmp = inst.operands[2].reg;
17247 inst.operands[2].reg = inst.operands[1].reg;
17248 inst.operands[1].reg = tmp;
17249 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17250 }
627907b7
JB
17251}
17252
5287ad62
JB
17253static int
17254neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
17255{
036dc3f7
PB
17256 /* Handle .I8 pseudo-instructions. */
17257 if (size == 8)
5287ad62 17258 {
5287ad62 17259 /* Unfortunately, this will make everything apart from zero out-of-range.
477330fc
RM
17260 FIXME is this the intended semantics? There doesn't seem much point in
17261 accepting .I8 if so. */
5287ad62
JB
17262 immediate |= immediate << 8;
17263 size = 16;
036dc3f7
PB
17264 }
17265
17266 if (size >= 32)
17267 {
17268 if (immediate == (immediate & 0x000000ff))
17269 {
17270 *immbits = immediate;
17271 return 0x1;
17272 }
17273 else if (immediate == (immediate & 0x0000ff00))
17274 {
17275 *immbits = immediate >> 8;
17276 return 0x3;
17277 }
17278 else if (immediate == (immediate & 0x00ff0000))
17279 {
17280 *immbits = immediate >> 16;
17281 return 0x5;
17282 }
17283 else if (immediate == (immediate & 0xff000000))
17284 {
17285 *immbits = immediate >> 24;
17286 return 0x7;
17287 }
17288 if ((immediate & 0xffff) != (immediate >> 16))
17289 goto bad_immediate;
17290 immediate &= 0xffff;
5287ad62
JB
17291 }
17292
17293 if (immediate == (immediate & 0x000000ff))
17294 {
17295 *immbits = immediate;
036dc3f7 17296 return 0x9;
5287ad62
JB
17297 }
17298 else if (immediate == (immediate & 0x0000ff00))
17299 {
17300 *immbits = immediate >> 8;
036dc3f7 17301 return 0xb;
5287ad62
JB
17302 }
17303
17304 bad_immediate:
dcbf9037 17305 first_error (_("immediate value out of range"));
5287ad62
JB
17306 return FAIL;
17307}
17308
5287ad62
JB
17309static void
17310do_neon_logic (void)
17311{
17312 if (inst.operands[2].present && inst.operands[2].isreg)
17313 {
037e8744 17314 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
f601a00c 17315 if (rs == NS_QQQ
5b7c81bd 17316 && !check_simd_pred_availability (false,
64c350f2 17317 NEON_CHECK_ARCH | NEON_CHECK_CC))
f601a00c
AV
17318 return;
17319 else if (rs != NS_QQQ
17320 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
17321 first_error (BAD_FPU);
17322
5287ad62
JB
17323 neon_check_type (3, rs, N_IGNORE_TYPE);
17324 /* U bit and size field were set as part of the bitmask. */
88714cb8 17325 NEON_ENCODE (INTEGER, inst);
037e8744 17326 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
17327 }
17328 else
17329 {
4316f0d2
DG
17330 const int three_ops_form = (inst.operands[2].present
17331 && !inst.operands[2].isreg);
17332 const int immoperand = (three_ops_form ? 2 : 1);
17333 enum neon_shape rs = (three_ops_form
17334 ? neon_select_shape (NS_DDI, NS_QQI, NS_NULL)
17335 : neon_select_shape (NS_DI, NS_QI, NS_NULL));
f601a00c
AV
17336 /* Because neon_select_shape makes the second operand a copy of the first
17337 if the second operand is not present. */
17338 if (rs == NS_QQI
5b7c81bd 17339 && !check_simd_pred_availability (false,
64c350f2 17340 NEON_CHECK_ARCH | NEON_CHECK_CC))
f601a00c
AV
17341 return;
17342 else if (rs != NS_QQI
17343 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
17344 first_error (BAD_FPU);
17345
17346 struct neon_type_el et;
17347 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17348 et = neon_check_type (2, rs, N_I32 | N_I16 | N_KEY, N_EQK);
17349 else
17350 et = neon_check_type (2, rs, N_I8 | N_I16 | N_I32 | N_I64 | N_F32
17351 | N_KEY, N_EQK);
17352
17353 if (et.type == NT_invtype)
17354 return;
21d799b5 17355 enum neon_opc opcode = (enum neon_opc) inst.instruction & 0x0fffffff;
5287ad62
JB
17356 unsigned immbits;
17357 int cmode;
5f4273c7 17358
5f4273c7 17359
4316f0d2
DG
17360 if (three_ops_form)
17361 constraint (inst.operands[0].reg != inst.operands[1].reg,
17362 _("first and second operands shall be the same register"));
17363
88714cb8 17364 NEON_ENCODE (IMMED, inst);
5287ad62 17365
4316f0d2 17366 immbits = inst.operands[immoperand].imm;
036dc3f7
PB
17367 if (et.size == 64)
17368 {
17369 /* .i64 is a pseudo-op, so the immediate must be a repeating
17370 pattern. */
4316f0d2
DG
17371 if (immbits != (inst.operands[immoperand].regisimm ?
17372 inst.operands[immoperand].reg : 0))
036dc3f7
PB
17373 {
17374 /* Set immbits to an invalid constant. */
17375 immbits = 0xdeadbeef;
17376 }
17377 }
17378
5287ad62 17379 switch (opcode)
477330fc
RM
17380 {
17381 case N_MNEM_vbic:
17382 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17383 break;
17384
17385 case N_MNEM_vorr:
17386 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17387 break;
17388
17389 case N_MNEM_vand:
17390 /* Pseudo-instruction for VBIC. */
17391 neon_invert_size (&immbits, 0, et.size);
17392 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17393 break;
17394
17395 case N_MNEM_vorn:
17396 /* Pseudo-instruction for VORR. */
17397 neon_invert_size (&immbits, 0, et.size);
17398 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17399 break;
17400
17401 default:
17402 abort ();
17403 }
5287ad62
JB
17404
17405 if (cmode == FAIL)
477330fc 17406 return;
5287ad62 17407
037e8744 17408 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
17409 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17410 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17411 inst.instruction |= cmode << 8;
17412 neon_write_immbits (immbits);
5f4273c7 17413
88714cb8 17414 neon_dp_fixup (&inst);
5287ad62
JB
17415 }
17416}
17417
17418static void
17419do_neon_bitfield (void)
17420{
037e8744 17421 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 17422 neon_check_type (3, rs, N_IGNORE_TYPE);
037e8744 17423 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
17424}
17425
17426static void
dcbf9037 17427neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types,
477330fc 17428 unsigned destbits)
5287ad62 17429{
5ee91343 17430 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
dcbf9037 17431 struct neon_type_el et = neon_check_type (3, rs, N_EQK | destbits, N_EQK,
477330fc 17432 types | N_KEY);
5287ad62
JB
17433 if (et.type == NT_float)
17434 {
88714cb8 17435 NEON_ENCODE (FLOAT, inst);
5ee91343 17436 if (rs == NS_QQR)
7df54120 17437 mve_encode_qqr (et.size, 0, 1);
5ee91343
AV
17438 else
17439 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
17440 }
17441 else
17442 {
88714cb8 17443 NEON_ENCODE (INTEGER, inst);
5ee91343 17444 if (rs == NS_QQR)
a8465a06 17445 mve_encode_qqr (et.size, et.type == ubit_meaning, 0);
5ee91343
AV
17446 else
17447 neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
5287ad62
JB
17448 }
17449}
17450
5287ad62
JB
17451
17452static void
17453do_neon_dyadic_if_su_d (void)
17454{
17455 /* This version only allow D registers, but that constraint is enforced during
17456 operand parsing so we don't need to do anything extra here. */
dcbf9037 17457 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
17458}
17459
5287ad62
JB
17460static void
17461do_neon_dyadic_if_i_d (void)
17462{
428e3f1f
PB
17463 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17464 affected if we specify unsigned args. */
17465 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
5287ad62
JB
17466}
17467
f5f10c66
AV
17468static void
17469do_mve_vstr_vldr_QI (int size, int elsize, int load)
17470{
17471 constraint (size < 32, BAD_ADDR_MODE);
17472 constraint (size != elsize, BAD_EL_TYPE);
17473 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
17474 constraint (!inst.operands[1].preind, BAD_ADDR_MODE);
17475 constraint (load && inst.operands[0].reg == inst.operands[1].reg,
17476 _("destination register and offset register may not be the"
17477 " same"));
17478
17479 int imm = inst.relocs[0].exp.X_add_number;
17480 int add = 1;
17481 if (imm < 0)
17482 {
17483 add = 0;
17484 imm = -imm;
17485 }
17486 constraint ((imm % (size / 8) != 0)
17487 || imm > (0x7f << neon_logbits (size)),
17488 (size == 32) ? _("immediate must be a multiple of 4 in the"
17489 " range of +/-[0,508]")
17490 : _("immediate must be a multiple of 8 in the"
17491 " range of +/-[0,1016]"));
17492 inst.instruction |= 0x11 << 24;
17493 inst.instruction |= add << 23;
17494 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17495 inst.instruction |= inst.operands[1].writeback << 21;
17496 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17497 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17498 inst.instruction |= 1 << 12;
17499 inst.instruction |= (size == 64) << 8;
17500 inst.instruction &= 0xffffff00;
17501 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17502 inst.instruction |= imm >> neon_logbits (size);
17503}
17504
17505static void
17506do_mve_vstr_vldr_RQ (int size, int elsize, int load)
17507{
17508 unsigned os = inst.operands[1].imm >> 5;
e449ea97 17509 unsigned type = inst.vectype.el[0].type;
f5f10c66
AV
17510 constraint (os != 0 && size == 8,
17511 _("can not shift offsets when accessing less than half-word"));
17512 constraint (os && os != neon_logbits (size),
17513 _("shift immediate must be 1, 2 or 3 for half-word, word"
17514 " or double-word accesses respectively"));
17515 if (inst.operands[1].reg == REG_PC)
17516 as_tsktsk (MVE_BAD_PC);
17517
17518 switch (size)
17519 {
17520 case 8:
17521 constraint (elsize >= 64, BAD_EL_TYPE);
17522 break;
17523 case 16:
17524 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
17525 break;
17526 case 32:
17527 case 64:
17528 constraint (elsize != size, BAD_EL_TYPE);
17529 break;
17530 default:
17531 break;
17532 }
17533 constraint (inst.operands[1].writeback || !inst.operands[1].preind,
17534 BAD_ADDR_MODE);
17535 if (load)
17536 {
17537 constraint (inst.operands[0].reg == (inst.operands[1].imm & 0x1f),
17538 _("destination register and offset register may not be"
17539 " the same"));
e449ea97
SP
17540 constraint (size == elsize && type == NT_signed, BAD_EL_TYPE);
17541 constraint (size != elsize && type != NT_unsigned && type != NT_signed,
f5f10c66 17542 BAD_EL_TYPE);
e449ea97 17543 inst.instruction |= ((size == elsize) || (type == NT_unsigned)) << 28;
f5f10c66
AV
17544 }
17545 else
17546 {
e449ea97 17547 constraint (type != NT_untyped, BAD_EL_TYPE);
f5f10c66
AV
17548 }
17549
17550 inst.instruction |= 1 << 23;
17551 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17552 inst.instruction |= inst.operands[1].reg << 16;
17553 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17554 inst.instruction |= neon_logbits (elsize) << 7;
17555 inst.instruction |= HI1 (inst.operands[1].imm) << 5;
17556 inst.instruction |= LOW4 (inst.operands[1].imm);
17557 inst.instruction |= !!os;
17558}
17559
17560static void
17561do_mve_vstr_vldr_RI (int size, int elsize, int load)
17562{
17563 enum neon_el_type type = inst.vectype.el[0].type;
17564
17565 constraint (size >= 64, BAD_ADDR_MODE);
17566 switch (size)
17567 {
17568 case 16:
17569 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
17570 break;
17571 case 32:
17572 constraint (elsize != size, BAD_EL_TYPE);
17573 break;
17574 default:
17575 break;
17576 }
17577 if (load)
17578 {
17579 constraint (elsize != size && type != NT_unsigned
17580 && type != NT_signed, BAD_EL_TYPE);
17581 }
17582 else
17583 {
17584 constraint (elsize != size && type != NT_untyped, BAD_EL_TYPE);
17585 }
17586
17587 int imm = inst.relocs[0].exp.X_add_number;
17588 int add = 1;
17589 if (imm < 0)
17590 {
17591 add = 0;
17592 imm = -imm;
17593 }
17594
17595 if ((imm % (size / 8) != 0) || imm > (0x7f << neon_logbits (size)))
17596 {
17597 switch (size)
17598 {
17599 case 8:
17600 constraint (1, _("immediate must be in the range of +/-[0,127]"));
17601 break;
17602 case 16:
17603 constraint (1, _("immediate must be a multiple of 2 in the"
17604 " range of +/-[0,254]"));
17605 break;
17606 case 32:
17607 constraint (1, _("immediate must be a multiple of 4 in the"
17608 " range of +/-[0,508]"));
17609 break;
17610 }
17611 }
17612
17613 if (size != elsize)
17614 {
17615 constraint (inst.operands[1].reg > 7, BAD_HIREG);
17616 constraint (inst.operands[0].reg > 14,
17617 _("MVE vector register in the range [Q0..Q7] expected"));
17618 inst.instruction |= (load && type == NT_unsigned) << 28;
17619 inst.instruction |= (size == 16) << 19;
17620 inst.instruction |= neon_logbits (elsize) << 7;
17621 }
17622 else
17623 {
17624 if (inst.operands[1].reg == REG_PC)
17625 as_tsktsk (MVE_BAD_PC);
17626 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
17627 as_tsktsk (MVE_BAD_SP);
17628 inst.instruction |= 1 << 12;
17629 inst.instruction |= neon_logbits (size) << 7;
17630 }
17631 inst.instruction |= inst.operands[1].preind << 24;
17632 inst.instruction |= add << 23;
17633 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17634 inst.instruction |= inst.operands[1].writeback << 21;
17635 inst.instruction |= inst.operands[1].reg << 16;
17636 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17637 inst.instruction &= 0xffffff80;
17638 inst.instruction |= imm >> neon_logbits (size);
17639
17640}
17641
17642static void
17643do_mve_vstr_vldr (void)
17644{
17645 unsigned size;
17646 int load = 0;
17647
17648 if (inst.cond > COND_ALWAYS)
17649 inst.pred_insn_type = INSIDE_VPT_INSN;
17650 else
17651 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17652
17653 switch (inst.instruction)
17654 {
17655 default:
17656 gas_assert (0);
17657 break;
17658 case M_MNEM_vldrb:
17659 load = 1;
17660 /* fall through. */
17661 case M_MNEM_vstrb:
17662 size = 8;
17663 break;
17664 case M_MNEM_vldrh:
17665 load = 1;
17666 /* fall through. */
17667 case M_MNEM_vstrh:
17668 size = 16;
17669 break;
17670 case M_MNEM_vldrw:
17671 load = 1;
17672 /* fall through. */
17673 case M_MNEM_vstrw:
17674 size = 32;
17675 break;
17676 case M_MNEM_vldrd:
17677 load = 1;
17678 /* fall through. */
17679 case M_MNEM_vstrd:
17680 size = 64;
17681 break;
17682 }
17683 unsigned elsize = inst.vectype.el[0].size;
17684
17685 if (inst.operands[1].isquad)
17686 {
17687 /* We are dealing with [Q, imm]{!} cases. */
17688 do_mve_vstr_vldr_QI (size, elsize, load);
17689 }
17690 else
17691 {
17692 if (inst.operands[1].immisreg == 2)
17693 {
17694 /* We are dealing with [R, Q, {UXTW #os}] cases. */
17695 do_mve_vstr_vldr_RQ (size, elsize, load);
17696 }
17697 else if (!inst.operands[1].immisreg)
17698 {
17699 /* We are dealing with [R, Imm]{!}/[R], Imm cases. */
17700 do_mve_vstr_vldr_RI (size, elsize, load);
17701 }
17702 else
17703 constraint (1, BAD_ADDR_MODE);
17704 }
17705
17706 inst.is_neon = 1;
17707}
17708
35c228db
AV
17709static void
17710do_mve_vst_vld (void)
17711{
17712 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17713 return;
17714
17715 constraint (!inst.operands[1].preind || inst.relocs[0].exp.X_add_symbol != 0
17716 || inst.relocs[0].exp.X_add_number != 0
17717 || inst.operands[1].immisreg != 0,
17718 BAD_ADDR_MODE);
17719 constraint (inst.vectype.el[0].size > 32, BAD_EL_TYPE);
17720 if (inst.operands[1].reg == REG_PC)
17721 as_tsktsk (MVE_BAD_PC);
17722 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
17723 as_tsktsk (MVE_BAD_SP);
17724
17725
17726 /* These instructions are one of the "exceptions" mentioned in
17727 handle_pred_state. They are MVE instructions that are not VPT compatible
17728 and do not accept a VPT code, thus appending such a code is a syntax
17729 error. */
17730 if (inst.cond > COND_ALWAYS)
17731 first_error (BAD_SYNTAX);
17732 /* If we append a scalar condition code we can set this to
17733 MVE_OUTSIDE_PRED_INSN as it will also lead to a syntax error. */
17734 else if (inst.cond < COND_ALWAYS)
17735 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17736 else
17737 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
17738
17739 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17740 inst.instruction |= inst.operands[1].writeback << 21;
17741 inst.instruction |= inst.operands[1].reg << 16;
17742 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17743 inst.instruction |= neon_logbits (inst.vectype.el[0].size) << 7;
17744 inst.is_neon = 1;
17745}
17746
26c1e780
AV
17747static void
17748do_mve_vaddlv (void)
17749{
17750 enum neon_shape rs = neon_select_shape (NS_RRQ, NS_NULL);
17751 struct neon_type_el et
17752 = neon_check_type (3, rs, N_EQK, N_EQK, N_S32 | N_U32 | N_KEY);
17753
17754 if (et.type == NT_invtype)
17755 first_error (BAD_EL_TYPE);
17756
17757 if (inst.cond > COND_ALWAYS)
17758 inst.pred_insn_type = INSIDE_VPT_INSN;
17759 else
17760 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17761
17762 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
17763
17764 inst.instruction |= (et.type == NT_unsigned) << 28;
17765 inst.instruction |= inst.operands[1].reg << 19;
17766 inst.instruction |= inst.operands[0].reg << 12;
17767 inst.instruction |= inst.operands[2].reg;
17768 inst.is_neon = 1;
17769}
17770
5287ad62 17771static void
5ee91343 17772do_neon_dyadic_if_su (void)
5287ad62 17773{
5ee91343
AV
17774 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
17775 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
17776 N_SUF_32 | N_KEY);
17777
935295b5
AV
17778 constraint ((inst.instruction == ((unsigned) N_MNEM_vmax)
17779 || inst.instruction == ((unsigned) N_MNEM_vmin))
17780 && et.type == NT_float
17781 && !ARM_CPU_HAS_FEATURE (cpu_variant,fpu_neon_ext_v1), BAD_FPU);
17782
64c350f2
AV
17783 if (!check_simd_pred_availability (et.type == NT_float,
17784 NEON_CHECK_ARCH | NEON_CHECK_CC))
037e8744
JB
17785 return;
17786
5ee91343
AV
17787 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
17788}
17789
17790static void
17791do_neon_addsub_if_i (void)
17792{
17793 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
17794 && try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
037e8744
JB
17795 return;
17796
5ee91343
AV
17797 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
17798 struct neon_type_el et = neon_check_type (3, rs, N_EQK,
17799 N_EQK, N_IF_32 | N_I64 | N_KEY);
17800
17801 constraint (rs == NS_QQR && et.size == 64, BAD_FPU);
17802 /* If we are parsing Q registers and the element types match MVE, which NEON
17803 also supports, then we must check whether this is an instruction that can
17804 be used by both MVE/NEON. This distinction can be made based on whether
17805 they are predicated or not. */
17806 if ((rs == NS_QQQ || rs == NS_QQR) && et.size != 64)
17807 {
64c350f2
AV
17808 if (!check_simd_pred_availability (et.type == NT_float,
17809 NEON_CHECK_ARCH | NEON_CHECK_CC))
5ee91343
AV
17810 return;
17811 }
17812 else
17813 {
17814 /* If they are either in a D register or are using an unsupported. */
17815 if (rs != NS_QQR
17816 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
17817 return;
17818 }
17819
5287ad62
JB
17820 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17821 affected if we specify unsigned args. */
dcbf9037 17822 neon_dyadic_misc (NT_untyped, N_IF_32 | N_I64, 0);
5287ad62
JB
17823}
17824
17825/* Swaps operands 1 and 2. If operand 1 (optional arg) was omitted, we want the
17826 result to be:
17827 V<op> A,B (A is operand 0, B is operand 2)
17828 to mean:
17829 V<op> A,B,A
17830 not:
17831 V<op> A,B,B
17832 so handle that case specially. */
17833
17834static void
17835neon_exchange_operands (void)
17836{
5287ad62
JB
17837 if (inst.operands[1].present)
17838 {
e1fa0163
NC
17839 void *scratch = xmalloc (sizeof (inst.operands[0]));
17840
5287ad62
JB
17841 /* Swap operands[1] and operands[2]. */
17842 memcpy (scratch, &inst.operands[1], sizeof (inst.operands[0]));
17843 inst.operands[1] = inst.operands[2];
17844 memcpy (&inst.operands[2], scratch, sizeof (inst.operands[0]));
e1fa0163 17845 free (scratch);
5287ad62
JB
17846 }
17847 else
17848 {
17849 inst.operands[1] = inst.operands[2];
17850 inst.operands[2] = inst.operands[0];
17851 }
17852}
17853
17854static void
17855neon_compare (unsigned regtypes, unsigned immtypes, int invert)
17856{
17857 if (inst.operands[2].isreg)
17858 {
17859 if (invert)
477330fc 17860 neon_exchange_operands ();
dcbf9037 17861 neon_dyadic_misc (NT_unsigned, regtypes, N_SIZ);
5287ad62
JB
17862 }
17863 else
17864 {
037e8744 17865 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
dcbf9037 17866 struct neon_type_el et = neon_check_type (2, rs,
477330fc 17867 N_EQK | N_SIZ, immtypes | N_KEY);
5287ad62 17868
88714cb8 17869 NEON_ENCODE (IMMED, inst);
5287ad62
JB
17870 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17871 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17872 inst.instruction |= LOW4 (inst.operands[1].reg);
17873 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 17874 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
17875 inst.instruction |= (et.type == NT_float) << 10;
17876 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 17877
88714cb8 17878 neon_dp_fixup (&inst);
5287ad62
JB
17879 }
17880}
17881
17882static void
17883do_neon_cmp (void)
17884{
5b7c81bd 17885 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, false);
5287ad62
JB
17886}
17887
17888static void
17889do_neon_cmp_inv (void)
17890{
5b7c81bd 17891 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, true);
5287ad62
JB
17892}
17893
17894static void
17895do_neon_ceq (void)
17896{
5b7c81bd 17897 neon_compare (N_IF_32, N_IF_32, false);
5287ad62
JB
17898}
17899
17900/* For multiply instructions, we have the possibility of 16-bit or 32-bit
17901 scalars, which are encoded in 5 bits, M : Rm.
17902 For 16-bit scalars, the register is encoded in Rm[2:0] and the index in
17903 M:Rm[3], and for 32-bit scalars, the register is encoded in Rm[3:0] and the
c604a79a
JW
17904 index in M.
17905
17906 Dot Product instructions are similar to multiply instructions except elsize
17907 should always be 32.
17908
17909 This function translates SCALAR, which is GAS's internal encoding of indexed
17910 scalar register, to raw encoding. There is also register and index range
17911 check based on ELSIZE. */
5287ad62
JB
17912
17913static unsigned
17914neon_scalar_for_mul (unsigned scalar, unsigned elsize)
17915{
dcbf9037
JB
17916 unsigned regno = NEON_SCALAR_REG (scalar);
17917 unsigned elno = NEON_SCALAR_INDEX (scalar);
5287ad62
JB
17918
17919 switch (elsize)
17920 {
17921 case 16:
17922 if (regno > 7 || elno > 3)
477330fc 17923 goto bad_scalar;
5287ad62 17924 return regno | (elno << 3);
5f4273c7 17925
5287ad62
JB
17926 case 32:
17927 if (regno > 15 || elno > 1)
477330fc 17928 goto bad_scalar;
5287ad62
JB
17929 return regno | (elno << 4);
17930
17931 default:
17932 bad_scalar:
dcbf9037 17933 first_error (_("scalar out of range for multiply instruction"));
5287ad62
JB
17934 }
17935
17936 return 0;
17937}
17938
17939/* Encode multiply / multiply-accumulate scalar instructions. */
17940
17941static void
17942neon_mul_mac (struct neon_type_el et, int ubit)
17943{
dcbf9037
JB
17944 unsigned scalar;
17945
17946 /* Give a more helpful error message if we have an invalid type. */
17947 if (et.type == NT_invtype)
17948 return;
5f4273c7 17949
dcbf9037 17950 scalar = neon_scalar_for_mul (inst.operands[2].reg, et.size);
5287ad62
JB
17951 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17952 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17953 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17954 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17955 inst.instruction |= LOW4 (scalar);
17956 inst.instruction |= HI1 (scalar) << 5;
17957 inst.instruction |= (et.type == NT_float) << 8;
17958 inst.instruction |= neon_logbits (et.size) << 20;
17959 inst.instruction |= (ubit != 0) << 24;
17960
88714cb8 17961 neon_dp_fixup (&inst);
5287ad62
JB
17962}
17963
17964static void
17965do_neon_mac_maybe_scalar (void)
17966{
037e8744
JB
17967 if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
17968 return;
17969
5b7c81bd 17970 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
17971 return;
17972
5287ad62
JB
17973 if (inst.operands[2].isscalar)
17974 {
a8465a06 17975 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 17976 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 17977 struct neon_type_el et = neon_check_type (3, rs,
589a7d88 17978 N_EQK, N_EQK, N_I16 | N_I32 | N_F_16_32 | N_KEY);
88714cb8 17979 NEON_ENCODE (SCALAR, inst);
037e8744 17980 neon_mul_mac (et, neon_quad (rs));
5287ad62 17981 }
a8465a06
AV
17982 else if (!inst.operands[2].isvec)
17983 {
17984 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
17985
17986 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
3e562e4b 17987 neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_I_MVE | N_KEY);
a8465a06 17988
3e562e4b 17989 neon_dyadic_misc (NT_untyped, N_SU_MVE | N_I_MVE, 0);
a8465a06 17990 }
5287ad62 17991 else
428e3f1f 17992 {
a8465a06 17993 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
428e3f1f
PB
17994 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17995 affected if we specify unsigned args. */
17996 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
17997 }
5287ad62
JB
17998}
17999
aab2c27d
MM
18000static void
18001do_bfloat_vfma (void)
18002{
18003 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
18004 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
18005 enum neon_shape rs;
18006 int t_bit = 0;
18007
18008 if (inst.instruction != B_MNEM_vfmab)
18009 {
18010 t_bit = 1;
18011 inst.instruction = B_MNEM_vfmat;
18012 }
18013
18014 if (inst.operands[2].isscalar)
18015 {
18016 rs = neon_select_shape (NS_QQS, NS_NULL);
18017 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
18018
18019 inst.instruction |= (1 << 25);
1db66fb6
JB
18020 int idx = inst.operands[2].reg & 0xf;
18021 constraint (!(idx < 4), _("index must be in the range 0 to 3"));
aab2c27d
MM
18022 inst.operands[2].reg >>= 4;
18023 constraint (!(inst.operands[2].reg < 8),
18024 _("indexed register must be less than 8"));
18025 neon_three_args (t_bit);
1db66fb6
JB
18026 inst.instruction |= ((idx & 1) << 3);
18027 inst.instruction |= ((idx & 2) << 4);
aab2c27d
MM
18028 }
18029 else
18030 {
18031 rs = neon_select_shape (NS_QQQ, NS_NULL);
18032 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
18033 neon_three_args (t_bit);
18034 }
18035
18036}
18037
62f3b8c8
PB
18038static void
18039do_neon_fmac (void)
18040{
d58196e0
AV
18041 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_fma)
18042 && try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS)
62f3b8c8
PB
18043 return;
18044
5b7c81bd 18045 if (!check_simd_pred_availability (true, NEON_CHECK_CC | NEON_CHECK_ARCH))
62f3b8c8
PB
18046 return;
18047
d58196e0
AV
18048 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
18049 {
18050 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
18051 struct neon_type_el et = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK,
18052 N_EQK);
18053
18054 if (rs == NS_QQR)
18055 {
aab2c27d 18056
d58196e0
AV
18057 if (inst.operands[2].reg == REG_SP)
18058 as_tsktsk (MVE_BAD_SP);
18059 else if (inst.operands[2].reg == REG_PC)
18060 as_tsktsk (MVE_BAD_PC);
18061
18062 inst.instruction = 0xee310e40;
18063 inst.instruction |= (et.size == 16) << 28;
18064 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18065 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
18066 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18067 inst.instruction |= HI1 (inst.operands[1].reg) << 6;
18068 inst.instruction |= inst.operands[2].reg;
18069 inst.is_neon = 1;
18070 return;
18071 }
18072 }
18073 else
18074 {
18075 constraint (!inst.operands[2].isvec, BAD_FPU);
18076 }
18077
62f3b8c8
PB
18078 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
18079}
18080
aab2c27d
MM
18081static void
18082do_mve_vfma (void)
18083{
18084 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_bf16) &&
18085 inst.cond == COND_ALWAYS)
18086 {
18087 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
18088 inst.instruction = N_MNEM_vfma;
18089 inst.pred_insn_type = INSIDE_VPT_INSN;
18090 inst.cond = 0xf;
18091 return do_neon_fmac();
18092 }
18093 else
18094 {
18095 do_bfloat_vfma();
18096 }
18097}
18098
5287ad62
JB
18099static void
18100do_neon_tst (void)
18101{
037e8744 18102 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
18103 struct neon_type_el et = neon_check_type (3, rs,
18104 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
037e8744 18105 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
18106}
18107
18108/* VMUL with 3 registers allows the P8 type. The scalar version supports the
18109 same types as the MAC equivalents. The polynomial type for this instruction
18110 is encoded the same as the integer type. */
18111
18112static void
18113do_neon_mul (void)
18114{
037e8744
JB
18115 if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
18116 return;
18117
5b7c81bd 18118 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
18119 return;
18120
5287ad62 18121 if (inst.operands[2].isscalar)
a8465a06
AV
18122 {
18123 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
18124 do_neon_mac_maybe_scalar ();
18125 }
5287ad62 18126 else
a8465a06
AV
18127 {
18128 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18129 {
18130 enum neon_shape rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
18131 struct neon_type_el et
18132 = neon_check_type (3, rs, N_EQK, N_EQK, N_I_MVE | N_F_MVE | N_KEY);
18133 if (et.type == NT_float)
18134 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
18135 BAD_FPU);
18136
18137 neon_dyadic_misc (NT_float, N_I_MVE | N_F_MVE, 0);
18138 }
18139 else
18140 {
18141 constraint (!inst.operands[2].isvec, BAD_FPU);
18142 neon_dyadic_misc (NT_poly,
18143 N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
18144 }
18145 }
5287ad62
JB
18146}
18147
18148static void
18149do_neon_qdmulh (void)
18150{
5b7c81bd 18151 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
42b16635
AV
18152 return;
18153
5287ad62
JB
18154 if (inst.operands[2].isscalar)
18155 {
42b16635 18156 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 18157 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 18158 struct neon_type_el et = neon_check_type (3, rs,
477330fc 18159 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 18160 NEON_ENCODE (SCALAR, inst);
037e8744 18161 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
18162 }
18163 else
18164 {
42b16635
AV
18165 enum neon_shape rs;
18166 struct neon_type_el et;
18167 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18168 {
18169 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
18170 et = neon_check_type (3, rs,
18171 N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18172 }
18173 else
18174 {
18175 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
18176 et = neon_check_type (3, rs,
18177 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18178 }
18179
88714cb8 18180 NEON_ENCODE (INTEGER, inst);
42b16635
AV
18181 if (rs == NS_QQR)
18182 mve_encode_qqr (et.size, 0, 0);
18183 else
18184 /* The U bit (rounding) comes from bit mask. */
18185 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
18186 }
18187}
18188
26c1e780
AV
18189static void
18190do_mve_vaddv (void)
18191{
18192 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18193 struct neon_type_el et
18194 = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
18195
18196 if (et.type == NT_invtype)
18197 first_error (BAD_EL_TYPE);
18198
18199 if (inst.cond > COND_ALWAYS)
18200 inst.pred_insn_type = INSIDE_VPT_INSN;
18201 else
18202 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18203
18204 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
18205
18206 mve_encode_rq (et.type == NT_unsigned, et.size);
18207}
18208
7df54120
AV
18209static void
18210do_mve_vhcadd (void)
18211{
18212 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
18213 struct neon_type_el et
18214 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18215
18216 if (inst.cond > COND_ALWAYS)
18217 inst.pred_insn_type = INSIDE_VPT_INSN;
18218 else
18219 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18220
18221 unsigned rot = inst.relocs[0].exp.X_add_number;
18222 constraint (rot != 90 && rot != 270, _("immediate out of range"));
18223
18224 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
18225 as_tsktsk (_("Warning: 32-bit element size and same first and third "
18226 "operand makes instruction UNPREDICTABLE"));
18227
18228 mve_encode_qqq (0, et.size);
18229 inst.instruction |= (rot == 270) << 12;
18230 inst.is_neon = 1;
18231}
18232
35d1cfc2
AV
18233static void
18234do_mve_vqdmull (void)
18235{
18236 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
18237 struct neon_type_el et
18238 = neon_check_type (3, rs, N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18239
18240 if (et.size == 32
18241 && (inst.operands[0].reg == inst.operands[1].reg
18242 || (rs == NS_QQQ && inst.operands[0].reg == inst.operands[2].reg)))
18243 as_tsktsk (BAD_MVE_SRCDEST);
18244
18245 if (inst.cond > COND_ALWAYS)
18246 inst.pred_insn_type = INSIDE_VPT_INSN;
18247 else
18248 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18249
18250 if (rs == NS_QQQ)
18251 {
18252 mve_encode_qqq (et.size == 32, 64);
18253 inst.instruction |= 1;
18254 }
18255 else
18256 {
18257 mve_encode_qqr (64, et.size == 32, 0);
18258 inst.instruction |= 0x3 << 5;
18259 }
18260}
18261
c2dafc2a
AV
18262static void
18263do_mve_vadc (void)
18264{
18265 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
18266 struct neon_type_el et
18267 = neon_check_type (3, rs, N_KEY | N_I32, N_EQK, N_EQK);
18268
18269 if (et.type == NT_invtype)
18270 first_error (BAD_EL_TYPE);
18271
18272 if (inst.cond > COND_ALWAYS)
18273 inst.pred_insn_type = INSIDE_VPT_INSN;
18274 else
18275 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18276
18277 mve_encode_qqq (0, 64);
18278}
18279
18280static void
18281do_mve_vbrsr (void)
18282{
18283 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18284 struct neon_type_el et
18285 = neon_check_type (3, rs, N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18286
18287 if (inst.cond > COND_ALWAYS)
18288 inst.pred_insn_type = INSIDE_VPT_INSN;
18289 else
18290 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18291
7df54120 18292 mve_encode_qqr (et.size, 0, 0);
c2dafc2a
AV
18293}
18294
18295static void
18296do_mve_vsbc (void)
18297{
18298 neon_check_type (3, NS_QQQ, N_EQK, N_EQK, N_I32 | N_KEY);
18299
18300 if (inst.cond > COND_ALWAYS)
18301 inst.pred_insn_type = INSIDE_VPT_INSN;
18302 else
18303 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18304
18305 mve_encode_qqq (1, 64);
18306}
18307
2d78f95b
AV
18308static void
18309do_mve_vmulh (void)
18310{
18311 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
18312 struct neon_type_el et
18313 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
18314
18315 if (inst.cond > COND_ALWAYS)
18316 inst.pred_insn_type = INSIDE_VPT_INSN;
18317 else
18318 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18319
18320 mve_encode_qqq (et.type == NT_unsigned, et.size);
18321}
18322
42b16635
AV
18323static void
18324do_mve_vqdmlah (void)
18325{
18326 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18327 struct neon_type_el et
23d188c7 18328 = neon_check_type (3, rs, N_EQK, N_EQK, N_S_32 | N_KEY);
42b16635
AV
18329
18330 if (inst.cond > COND_ALWAYS)
18331 inst.pred_insn_type = INSIDE_VPT_INSN;
18332 else
18333 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18334
18335 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
18336}
8b8b22a4
AV
18337
18338static void
18339do_mve_vqdmladh (void)
18340{
18341 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
18342 struct neon_type_el et
18343 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18344
18345 if (inst.cond > COND_ALWAYS)
18346 inst.pred_insn_type = INSIDE_VPT_INSN;
18347 else
18348 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18349
8b8b22a4
AV
18350 mve_encode_qqq (0, et.size);
18351}
18352
18353
886e1c73
AV
18354static void
18355do_mve_vmull (void)
18356{
18357
18358 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_DDS,
18359 NS_QQS, NS_QQQ, NS_QQR, NS_NULL);
fe05f369 18360 if (inst.cond == COND_ALWAYS
886e1c73
AV
18361 && ((unsigned)inst.instruction) == M_MNEM_vmullt)
18362 {
fe05f369 18363
886e1c73
AV
18364 if (rs == NS_QQQ)
18365 {
fe05f369 18366 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
886e1c73
AV
18367 goto neon_vmul;
18368 }
18369 else
18370 goto neon_vmul;
18371 }
18372
18373 constraint (rs != NS_QQQ, BAD_FPU);
18374 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
18375 N_SU_32 | N_P8 | N_P16 | N_KEY);
18376
18377 /* We are dealing with MVE's vmullt. */
18378 if (et.size == 32
18379 && (inst.operands[0].reg == inst.operands[1].reg
18380 || inst.operands[0].reg == inst.operands[2].reg))
18381 as_tsktsk (BAD_MVE_SRCDEST);
18382
18383 if (inst.cond > COND_ALWAYS)
18384 inst.pred_insn_type = INSIDE_VPT_INSN;
18385 else
18386 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18387
18388 if (et.type == NT_poly)
18389 mve_encode_qqq (neon_logbits (et.size), 64);
18390 else
18391 mve_encode_qqq (et.type == NT_unsigned, et.size);
18392
18393 return;
18394
dc1e8a47 18395 neon_vmul:
886e1c73
AV
18396 inst.instruction = N_MNEM_vmul;
18397 inst.cond = 0xb;
18398 if (thumb_mode)
18399 inst.pred_insn_type = INSIDE_IT_INSN;
18400 do_neon_mul ();
18401}
18402
a302e574
AV
18403static void
18404do_mve_vabav (void)
18405{
18406 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
18407
18408 if (rs == NS_NULL)
18409 return;
18410
18411 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18412 return;
18413
18414 struct neon_type_el et = neon_check_type (2, NS_NULL, N_EQK, N_KEY | N_S8
18415 | N_S16 | N_S32 | N_U8 | N_U16
18416 | N_U32);
18417
18418 if (inst.cond > COND_ALWAYS)
18419 inst.pred_insn_type = INSIDE_VPT_INSN;
18420 else
18421 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18422
18423 mve_encode_rqq (et.type == NT_unsigned, et.size);
18424}
18425
18426static void
18427do_mve_vmladav (void)
18428{
18429 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
18430 struct neon_type_el et = neon_check_type (3, rs,
18431 N_EQK, N_EQK, N_SU_MVE | N_KEY);
18432
18433 if (et.type == NT_unsigned
18434 && (inst.instruction == M_MNEM_vmladavx
18435 || inst.instruction == M_MNEM_vmladavax
18436 || inst.instruction == M_MNEM_vmlsdav
18437 || inst.instruction == M_MNEM_vmlsdava
18438 || inst.instruction == M_MNEM_vmlsdavx
18439 || inst.instruction == M_MNEM_vmlsdavax))
18440 first_error (BAD_SIMD_TYPE);
18441
18442 constraint (inst.operands[2].reg > 14,
18443 _("MVE vector register in the range [Q0..Q7] expected"));
18444
18445 if (inst.cond > COND_ALWAYS)
18446 inst.pred_insn_type = INSIDE_VPT_INSN;
18447 else
18448 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18449
18450 if (inst.instruction == M_MNEM_vmlsdav
18451 || inst.instruction == M_MNEM_vmlsdava
18452 || inst.instruction == M_MNEM_vmlsdavx
18453 || inst.instruction == M_MNEM_vmlsdavax)
18454 inst.instruction |= (et.size == 8) << 28;
18455 else
18456 inst.instruction |= (et.size == 8) << 8;
18457
18458 mve_encode_rqq (et.type == NT_unsigned, 64);
18459 inst.instruction |= (et.size == 32) << 16;
18460}
18461
93925576
AV
18462static void
18463do_mve_vmlaldav (void)
18464{
18465 enum neon_shape rs = neon_select_shape (NS_RRQQ, NS_NULL);
18466 struct neon_type_el et
18467 = neon_check_type (4, rs, N_EQK, N_EQK, N_EQK,
18468 N_S16 | N_S32 | N_U16 | N_U32 | N_KEY);
18469
18470 if (et.type == NT_unsigned
18471 && (inst.instruction == M_MNEM_vmlsldav
18472 || inst.instruction == M_MNEM_vmlsldava
18473 || inst.instruction == M_MNEM_vmlsldavx
18474 || inst.instruction == M_MNEM_vmlsldavax))
18475 first_error (BAD_SIMD_TYPE);
18476
18477 if (inst.cond > COND_ALWAYS)
18478 inst.pred_insn_type = INSIDE_VPT_INSN;
18479 else
18480 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18481
18482 mve_encode_rrqq (et.type == NT_unsigned, et.size);
18483}
18484
18485static void
18486do_mve_vrmlaldavh (void)
18487{
18488 struct neon_type_el et;
18489 if (inst.instruction == M_MNEM_vrmlsldavh
18490 || inst.instruction == M_MNEM_vrmlsldavha
18491 || inst.instruction == M_MNEM_vrmlsldavhx
18492 || inst.instruction == M_MNEM_vrmlsldavhax)
18493 {
18494 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
18495 if (inst.operands[1].reg == REG_SP)
18496 as_tsktsk (MVE_BAD_SP);
18497 }
18498 else
18499 {
18500 if (inst.instruction == M_MNEM_vrmlaldavhx
18501 || inst.instruction == M_MNEM_vrmlaldavhax)
18502 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
18503 else
18504 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK,
18505 N_U32 | N_S32 | N_KEY);
18506 /* vrmlaldavh's encoding with SP as the second, odd, GPR operand may alias
18507 with vmax/min instructions, making the use of SP in assembly really
18508 nonsensical, so instead of issuing a warning like we do for other uses
18509 of SP for the odd register operand we error out. */
18510 constraint (inst.operands[1].reg == REG_SP, BAD_SP);
18511 }
18512
18513 /* Make sure we still check the second operand is an odd one and that PC is
18514 disallowed. This because we are parsing for any GPR operand, to be able
18515 to distinguish between giving a warning or an error for SP as described
18516 above. */
18517 constraint ((inst.operands[1].reg % 2) != 1, BAD_EVEN);
18518 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
18519
18520 if (inst.cond > COND_ALWAYS)
18521 inst.pred_insn_type = INSIDE_VPT_INSN;
18522 else
18523 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18524
18525 mve_encode_rrqq (et.type == NT_unsigned, 0);
18526}
18527
18528
8cd78170
AV
18529static void
18530do_mve_vmaxnmv (void)
18531{
18532 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18533 struct neon_type_el et
18534 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
18535
18536 if (inst.cond > COND_ALWAYS)
18537 inst.pred_insn_type = INSIDE_VPT_INSN;
18538 else
18539 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18540
18541 if (inst.operands[0].reg == REG_SP)
18542 as_tsktsk (MVE_BAD_SP);
18543 else if (inst.operands[0].reg == REG_PC)
18544 as_tsktsk (MVE_BAD_PC);
18545
18546 mve_encode_rq (et.size == 16, 64);
18547}
18548
13ccd4c0
AV
18549static void
18550do_mve_vmaxv (void)
18551{
18552 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18553 struct neon_type_el et;
18554
18555 if (inst.instruction == M_MNEM_vmaxv || inst.instruction == M_MNEM_vminv)
18556 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
18557 else
18558 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18559
18560 if (inst.cond > COND_ALWAYS)
18561 inst.pred_insn_type = INSIDE_VPT_INSN;
18562 else
18563 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18564
18565 if (inst.operands[0].reg == REG_SP)
18566 as_tsktsk (MVE_BAD_SP);
18567 else if (inst.operands[0].reg == REG_PC)
18568 as_tsktsk (MVE_BAD_PC);
18569
18570 mve_encode_rq (et.type == NT_unsigned, et.size);
18571}
18572
18573
643afb90
MW
18574static void
18575do_neon_qrdmlah (void)
18576{
5b7c81bd 18577 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
42b16635
AV
18578 return;
18579 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
643afb90 18580 {
42b16635
AV
18581 /* Check we're on the correct architecture. */
18582 if (!mark_feature_used (&fpu_neon_ext_armv8))
18583 inst.error
18584 = _("instruction form not available on this architecture.");
18585 else if (!mark_feature_used (&fpu_neon_ext_v8_1))
18586 {
18587 as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
18588 record_feature_use (&fpu_neon_ext_v8_1);
18589 }
18590 if (inst.operands[2].isscalar)
18591 {
18592 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
18593 struct neon_type_el et = neon_check_type (3, rs,
18594 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18595 NEON_ENCODE (SCALAR, inst);
18596 neon_mul_mac (et, neon_quad (rs));
18597 }
18598 else
18599 {
18600 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
18601 struct neon_type_el et = neon_check_type (3, rs,
18602 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18603 NEON_ENCODE (INTEGER, inst);
18604 /* The U bit (rounding) comes from bit mask. */
18605 neon_three_same (neon_quad (rs), 0, et.size);
18606 }
643afb90
MW
18607 }
18608 else
18609 {
42b16635
AV
18610 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18611 struct neon_type_el et
23d188c7 18612 = neon_check_type (3, rs, N_EQK, N_EQK, N_S_32 | N_KEY);
42b16635 18613
643afb90 18614 NEON_ENCODE (INTEGER, inst);
42b16635 18615 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
643afb90
MW
18616 }
18617}
18618
5287ad62
JB
18619static void
18620do_neon_fcmp_absolute (void)
18621{
037e8744 18622 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
18623 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
18624 N_F_16_32 | N_KEY);
5287ad62 18625 /* Size field comes from bit mask. */
cc933301 18626 neon_three_same (neon_quad (rs), 1, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
18627}
18628
18629static void
18630do_neon_fcmp_absolute_inv (void)
18631{
18632 neon_exchange_operands ();
18633 do_neon_fcmp_absolute ();
18634}
18635
18636static void
18637do_neon_step (void)
18638{
037e8744 18639 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
18640 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
18641 N_F_16_32 | N_KEY);
18642 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
18643}
18644
18645static void
18646do_neon_abs_neg (void)
18647{
037e8744
JB
18648 enum neon_shape rs;
18649 struct neon_type_el et;
5f4273c7 18650
037e8744
JB
18651 if (try_vfp_nsyn (2, do_vfp_nsyn_abs_neg) == SUCCESS)
18652 return;
18653
037e8744 18654 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
cc933301 18655 et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
5f4273c7 18656
64c350f2
AV
18657 if (!check_simd_pred_availability (et.type == NT_float,
18658 NEON_CHECK_ARCH | NEON_CHECK_CC))
485dee97
AV
18659 return;
18660
5287ad62
JB
18661 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18662 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18663 inst.instruction |= LOW4 (inst.operands[1].reg);
18664 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 18665 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18666 inst.instruction |= (et.type == NT_float) << 10;
18667 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 18668
88714cb8 18669 neon_dp_fixup (&inst);
5287ad62
JB
18670}
18671
18672static void
18673do_neon_sli (void)
18674{
5b7c81bd 18675 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
18676 return;
18677
18678 enum neon_shape rs;
18679 struct neon_type_el et;
18680 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18681 {
18682 rs = neon_select_shape (NS_QQI, NS_NULL);
18683 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18684 }
18685 else
18686 {
18687 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18688 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18689 }
18690
18691
5287ad62
JB
18692 int imm = inst.operands[2].imm;
18693 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 18694 _("immediate out of range for insert"));
5b7c81bd 18695 neon_imm_shift (false, 0, neon_quad (rs), et, imm);
5287ad62
JB
18696}
18697
18698static void
18699do_neon_sri (void)
18700{
5b7c81bd 18701 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
18702 return;
18703
18704 enum neon_shape rs;
18705 struct neon_type_el et;
18706 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18707 {
18708 rs = neon_select_shape (NS_QQI, NS_NULL);
18709 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18710 }
18711 else
18712 {
18713 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18714 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18715 }
18716
5287ad62
JB
18717 int imm = inst.operands[2].imm;
18718 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18719 _("immediate out of range for insert"));
5b7c81bd 18720 neon_imm_shift (false, 0, neon_quad (rs), et, et.size - imm);
5287ad62
JB
18721}
18722
18723static void
18724do_neon_qshlu_imm (void)
18725{
5b7c81bd 18726 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
18727 return;
18728
18729 enum neon_shape rs;
18730 struct neon_type_el et;
18731 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18732 {
18733 rs = neon_select_shape (NS_QQI, NS_NULL);
18734 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18735 }
18736 else
18737 {
18738 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18739 et = neon_check_type (2, rs, N_EQK | N_UNS,
18740 N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
18741 }
18742
5287ad62
JB
18743 int imm = inst.operands[2].imm;
18744 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 18745 _("immediate out of range for shift"));
5287ad62
JB
18746 /* Only encodes the 'U present' variant of the instruction.
18747 In this case, signed types have OP (bit 8) set to 0.
18748 Unsigned types have OP set to 1. */
18749 inst.instruction |= (et.type == NT_unsigned) << 8;
18750 /* The rest of the bits are the same as other immediate shifts. */
5b7c81bd 18751 neon_imm_shift (false, 0, neon_quad (rs), et, imm);
5287ad62
JB
18752}
18753
18754static void
18755do_neon_qmovn (void)
18756{
18757 struct neon_type_el et = neon_check_type (2, NS_DQ,
18758 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
18759 /* Saturating move where operands can be signed or unsigned, and the
18760 destination has the same signedness. */
88714cb8 18761 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18762 if (et.type == NT_unsigned)
18763 inst.instruction |= 0xc0;
18764 else
18765 inst.instruction |= 0x80;
18766 neon_two_same (0, 1, et.size / 2);
18767}
18768
18769static void
18770do_neon_qmovun (void)
18771{
18772 struct neon_type_el et = neon_check_type (2, NS_DQ,
18773 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
18774 /* Saturating move with unsigned results. Operands must be signed. */
88714cb8 18775 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18776 neon_two_same (0, 1, et.size / 2);
18777}
18778
18779static void
18780do_neon_rshift_sat_narrow (void)
18781{
18782 /* FIXME: Types for narrowing. If operands are signed, results can be signed
18783 or unsigned. If operands are unsigned, results must also be unsigned. */
18784 struct neon_type_el et = neon_check_type (2, NS_DQI,
18785 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
18786 int imm = inst.operands[2].imm;
18787 /* This gets the bounds check, size encoding and immediate bits calculation
18788 right. */
18789 et.size /= 2;
5f4273c7 18790
5287ad62
JB
18791 /* VQ{R}SHRN.I<size> <Dd>, <Qm>, #0 is a synonym for
18792 VQMOVN.I<size> <Dd>, <Qm>. */
18793 if (imm == 0)
18794 {
18795 inst.operands[2].present = 0;
18796 inst.instruction = N_MNEM_vqmovn;
18797 do_neon_qmovn ();
18798 return;
18799 }
5f4273c7 18800
5287ad62 18801 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18802 _("immediate out of range"));
5b7c81bd 18803 neon_imm_shift (true, et.type == NT_unsigned, 0, et, et.size - imm);
5287ad62
JB
18804}
18805
18806static void
18807do_neon_rshift_sat_narrow_u (void)
18808{
18809 /* FIXME: Types for narrowing. If operands are signed, results can be signed
18810 or unsigned. If operands are unsigned, results must also be unsigned. */
18811 struct neon_type_el et = neon_check_type (2, NS_DQI,
18812 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
18813 int imm = inst.operands[2].imm;
18814 /* This gets the bounds check, size encoding and immediate bits calculation
18815 right. */
18816 et.size /= 2;
18817
18818 /* VQSHRUN.I<size> <Dd>, <Qm>, #0 is a synonym for
18819 VQMOVUN.I<size> <Dd>, <Qm>. */
18820 if (imm == 0)
18821 {
18822 inst.operands[2].present = 0;
18823 inst.instruction = N_MNEM_vqmovun;
18824 do_neon_qmovun ();
18825 return;
18826 }
18827
18828 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18829 _("immediate out of range"));
5287ad62
JB
18830 /* FIXME: The manual is kind of unclear about what value U should have in
18831 VQ{R}SHRUN instructions, but U=0, op=0 definitely encodes VRSHR, so it
18832 must be 1. */
5b7c81bd 18833 neon_imm_shift (true, 1, 0, et, et.size - imm);
5287ad62
JB
18834}
18835
18836static void
18837do_neon_movn (void)
18838{
18839 struct neon_type_el et = neon_check_type (2, NS_DQ,
18840 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
88714cb8 18841 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18842 neon_two_same (0, 1, et.size / 2);
18843}
18844
18845static void
18846do_neon_rshift_narrow (void)
18847{
18848 struct neon_type_el et = neon_check_type (2, NS_DQI,
18849 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
18850 int imm = inst.operands[2].imm;
18851 /* This gets the bounds check, size encoding and immediate bits calculation
18852 right. */
18853 et.size /= 2;
5f4273c7 18854
5287ad62
JB
18855 /* If immediate is zero then we are a pseudo-instruction for
18856 VMOVN.I<size> <Dd>, <Qm> */
18857 if (imm == 0)
18858 {
18859 inst.operands[2].present = 0;
18860 inst.instruction = N_MNEM_vmovn;
18861 do_neon_movn ();
18862 return;
18863 }
5f4273c7 18864
5287ad62 18865 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18866 _("immediate out of range for narrowing operation"));
5b7c81bd 18867 neon_imm_shift (false, 0, 0, et, et.size - imm);
5287ad62
JB
18868}
18869
18870static void
18871do_neon_shll (void)
18872{
18873 /* FIXME: Type checking when lengthening. */
18874 struct neon_type_el et = neon_check_type (2, NS_QDI,
18875 N_EQK | N_DBL, N_I8 | N_I16 | N_I32 | N_KEY);
18876 unsigned imm = inst.operands[2].imm;
18877
18878 if (imm == et.size)
18879 {
18880 /* Maximum shift variant. */
88714cb8 18881 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18882 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18883 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18884 inst.instruction |= LOW4 (inst.operands[1].reg);
18885 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18886 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 18887
88714cb8 18888 neon_dp_fixup (&inst);
5287ad62
JB
18889 }
18890 else
18891 {
18892 /* A more-specific type check for non-max versions. */
18893 et = neon_check_type (2, NS_QDI,
477330fc 18894 N_EQK | N_DBL, N_SU_32 | N_KEY);
88714cb8 18895 NEON_ENCODE (IMMED, inst);
5b7c81bd 18896 neon_imm_shift (true, et.type == NT_unsigned, 0, et, imm);
5287ad62
JB
18897 }
18898}
18899
037e8744 18900/* Check the various types for the VCVT instruction, and return which version
5287ad62
JB
18901 the current instruction is. */
18902
6b9a8b67
MGD
18903#define CVT_FLAVOUR_VAR \
18904 CVT_VAR (s32_f32, N_S32, N_F32, whole_reg, "ftosls", "ftosis", "ftosizs") \
18905 CVT_VAR (u32_f32, N_U32, N_F32, whole_reg, "ftouls", "ftouis", "ftouizs") \
18906 CVT_VAR (f32_s32, N_F32, N_S32, whole_reg, "fsltos", "fsitos", NULL) \
18907 CVT_VAR (f32_u32, N_F32, N_U32, whole_reg, "fultos", "fuitos", NULL) \
18908 /* Half-precision conversions. */ \
cc933301
JW
18909 CVT_VAR (s16_f16, N_S16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
18910 CVT_VAR (u16_f16, N_U16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
18911 CVT_VAR (f16_s16, N_F16 | N_KEY, N_S16, whole_reg, NULL, NULL, NULL) \
18912 CVT_VAR (f16_u16, N_F16 | N_KEY, N_U16, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
18913 CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
18914 CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
9db2f6b4
RL
18915 /* New VCVT instructions introduced by ARMv8.2 fp16 extension. \
18916 Compared with single/double precision variants, only the co-processor \
18917 field is different, so the encoding flow is reused here. */ \
18918 CVT_VAR (f16_s32, N_F16 | N_KEY, N_S32, N_VFP, "fsltos", "fsitos", NULL) \
18919 CVT_VAR (f16_u32, N_F16 | N_KEY, N_U32, N_VFP, "fultos", "fuitos", NULL) \
18920 CVT_VAR (u32_f16, N_U32, N_F16 | N_KEY, N_VFP, "ftouls", "ftouis", "ftouizs")\
18921 CVT_VAR (s32_f16, N_S32, N_F16 | N_KEY, N_VFP, "ftosls", "ftosis", "ftosizs")\
aab2c27d 18922 CVT_VAR (bf16_f32, N_BF16, N_F32, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
18923 /* VFP instructions. */ \
18924 CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
18925 CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
18926 CVT_VAR (s32_f64, N_S32, N_F64 | key, N_VFP, "ftosld", "ftosid", "ftosizd") \
18927 CVT_VAR (u32_f64, N_U32, N_F64 | key, N_VFP, "ftould", "ftouid", "ftouizd") \
18928 CVT_VAR (f64_s32, N_F64 | key, N_S32, N_VFP, "fsltod", "fsitod", NULL) \
18929 CVT_VAR (f64_u32, N_F64 | key, N_U32, N_VFP, "fultod", "fuitod", NULL) \
18930 /* VFP instructions with bitshift. */ \
18931 CVT_VAR (f32_s16, N_F32 | key, N_S16, N_VFP, "fshtos", NULL, NULL) \
18932 CVT_VAR (f32_u16, N_F32 | key, N_U16, N_VFP, "fuhtos", NULL, NULL) \
18933 CVT_VAR (f64_s16, N_F64 | key, N_S16, N_VFP, "fshtod", NULL, NULL) \
18934 CVT_VAR (f64_u16, N_F64 | key, N_U16, N_VFP, "fuhtod", NULL, NULL) \
18935 CVT_VAR (s16_f32, N_S16, N_F32 | key, N_VFP, "ftoshs", NULL, NULL) \
18936 CVT_VAR (u16_f32, N_U16, N_F32 | key, N_VFP, "ftouhs", NULL, NULL) \
18937 CVT_VAR (s16_f64, N_S16, N_F64 | key, N_VFP, "ftoshd", NULL, NULL) \
18938 CVT_VAR (u16_f64, N_U16, N_F64 | key, N_VFP, "ftouhd", NULL, NULL)
18939
18940#define CVT_VAR(C, X, Y, R, BSN, CN, ZN) \
18941 neon_cvt_flavour_##C,
18942
18943/* The different types of conversions we can do. */
18944enum neon_cvt_flavour
18945{
18946 CVT_FLAVOUR_VAR
18947 neon_cvt_flavour_invalid,
18948 neon_cvt_flavour_first_fp = neon_cvt_flavour_f32_f64
18949};
18950
18951#undef CVT_VAR
18952
18953static enum neon_cvt_flavour
18954get_neon_cvt_flavour (enum neon_shape rs)
5287ad62 18955{
6b9a8b67
MGD
18956#define CVT_VAR(C,X,Y,R,BSN,CN,ZN) \
18957 et = neon_check_type (2, rs, (R) | (X), (R) | (Y)); \
18958 if (et.type != NT_invtype) \
18959 { \
18960 inst.error = NULL; \
18961 return (neon_cvt_flavour_##C); \
5287ad62 18962 }
6b9a8b67 18963
5287ad62 18964 struct neon_type_el et;
037e8744 18965 unsigned whole_reg = (rs == NS_FFI || rs == NS_FD || rs == NS_DF
477330fc 18966 || rs == NS_FF) ? N_VFP : 0;
037e8744
JB
18967 /* The instruction versions which take an immediate take one register
18968 argument, which is extended to the width of the full register. Thus the
18969 "source" and "destination" registers must have the same width. Hack that
18970 here by making the size equal to the key (wider, in this case) operand. */
18971 unsigned key = (rs == NS_QQI || rs == NS_DDI || rs == NS_FFI) ? N_KEY : 0;
5f4273c7 18972
6b9a8b67
MGD
18973 CVT_FLAVOUR_VAR;
18974
18975 return neon_cvt_flavour_invalid;
5287ad62
JB
18976#undef CVT_VAR
18977}
18978
7e8e6784
MGD
18979enum neon_cvt_mode
18980{
18981 neon_cvt_mode_a,
18982 neon_cvt_mode_n,
18983 neon_cvt_mode_p,
18984 neon_cvt_mode_m,
18985 neon_cvt_mode_z,
30bdf752
MGD
18986 neon_cvt_mode_x,
18987 neon_cvt_mode_r
7e8e6784
MGD
18988};
18989
037e8744
JB
18990/* Neon-syntax VFP conversions. */
18991
5287ad62 18992static void
6b9a8b67 18993do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
5287ad62 18994{
037e8744 18995 const char *opname = 0;
5f4273c7 18996
d54af2d0
RL
18997 if (rs == NS_DDI || rs == NS_QQI || rs == NS_FFI
18998 || rs == NS_FHI || rs == NS_HFI)
5287ad62 18999 {
037e8744
JB
19000 /* Conversions with immediate bitshift. */
19001 const char *enc[] =
477330fc 19002 {
6b9a8b67
MGD
19003#define CVT_VAR(C,A,B,R,BSN,CN,ZN) BSN,
19004 CVT_FLAVOUR_VAR
19005 NULL
19006#undef CVT_VAR
477330fc 19007 };
037e8744 19008
6b9a8b67 19009 if (flavour < (int) ARRAY_SIZE (enc))
477330fc
RM
19010 {
19011 opname = enc[flavour];
19012 constraint (inst.operands[0].reg != inst.operands[1].reg,
19013 _("operands 0 and 1 must be the same register"));
19014 inst.operands[1] = inst.operands[2];
19015 memset (&inst.operands[2], '\0', sizeof (inst.operands[2]));
19016 }
5287ad62
JB
19017 }
19018 else
19019 {
037e8744
JB
19020 /* Conversions without bitshift. */
19021 const char *enc[] =
477330fc 19022 {
6b9a8b67
MGD
19023#define CVT_VAR(C,A,B,R,BSN,CN,ZN) CN,
19024 CVT_FLAVOUR_VAR
19025 NULL
19026#undef CVT_VAR
477330fc 19027 };
037e8744 19028
6b9a8b67 19029 if (flavour < (int) ARRAY_SIZE (enc))
477330fc 19030 opname = enc[flavour];
037e8744
JB
19031 }
19032
19033 if (opname)
19034 do_vfp_nsyn_opcode (opname);
9db2f6b4
RL
19035
19036 /* ARMv8.2 fp16 VCVT instruction. */
19037 if (flavour == neon_cvt_flavour_s32_f16
19038 || flavour == neon_cvt_flavour_u32_f16
19039 || flavour == neon_cvt_flavour_f16_u32
19040 || flavour == neon_cvt_flavour_f16_s32)
19041 do_scalar_fp16_v82_encode ();
037e8744
JB
19042}
19043
19044static void
19045do_vfp_nsyn_cvtz (void)
19046{
d54af2d0 19047 enum neon_shape rs = neon_select_shape (NS_FH, NS_FF, NS_FD, NS_NULL);
6b9a8b67 19048 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744
JB
19049 const char *enc[] =
19050 {
6b9a8b67
MGD
19051#define CVT_VAR(C,A,B,R,BSN,CN,ZN) ZN,
19052 CVT_FLAVOUR_VAR
19053 NULL
19054#undef CVT_VAR
037e8744
JB
19055 };
19056
6b9a8b67 19057 if (flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
037e8744
JB
19058 do_vfp_nsyn_opcode (enc[flavour]);
19059}
f31fef98 19060
037e8744 19061static void
bacebabc 19062do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
7e8e6784
MGD
19063 enum neon_cvt_mode mode)
19064{
19065 int sz, op;
19066 int rm;
19067
a715796b
TG
19068 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
19069 D register operands. */
19070 if (flavour == neon_cvt_flavour_s32_f64
19071 || flavour == neon_cvt_flavour_u32_f64)
19072 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19073 _(BAD_FPU));
19074
9db2f6b4
RL
19075 if (flavour == neon_cvt_flavour_s32_f16
19076 || flavour == neon_cvt_flavour_u32_f16)
19077 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
19078 _(BAD_FP16));
19079
5ee91343 19080 set_pred_insn_type (OUTSIDE_PRED_INSN);
7e8e6784
MGD
19081
19082 switch (flavour)
19083 {
19084 case neon_cvt_flavour_s32_f64:
19085 sz = 1;
827f64ff 19086 op = 1;
7e8e6784
MGD
19087 break;
19088 case neon_cvt_flavour_s32_f32:
19089 sz = 0;
19090 op = 1;
19091 break;
9db2f6b4
RL
19092 case neon_cvt_flavour_s32_f16:
19093 sz = 0;
19094 op = 1;
19095 break;
7e8e6784
MGD
19096 case neon_cvt_flavour_u32_f64:
19097 sz = 1;
19098 op = 0;
19099 break;
19100 case neon_cvt_flavour_u32_f32:
19101 sz = 0;
19102 op = 0;
19103 break;
9db2f6b4
RL
19104 case neon_cvt_flavour_u32_f16:
19105 sz = 0;
19106 op = 0;
19107 break;
7e8e6784
MGD
19108 default:
19109 first_error (_("invalid instruction shape"));
19110 return;
19111 }
19112
19113 switch (mode)
19114 {
19115 case neon_cvt_mode_a: rm = 0; break;
19116 case neon_cvt_mode_n: rm = 1; break;
19117 case neon_cvt_mode_p: rm = 2; break;
19118 case neon_cvt_mode_m: rm = 3; break;
19119 default: first_error (_("invalid rounding mode")); return;
19120 }
19121
19122 NEON_ENCODE (FPV8, inst);
19123 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
19124 encode_arm_vfp_reg (inst.operands[1].reg, sz == 1 ? VFP_REG_Dm : VFP_REG_Sm);
19125 inst.instruction |= sz << 8;
9db2f6b4
RL
19126
19127 /* ARMv8.2 fp16 VCVT instruction. */
19128 if (flavour == neon_cvt_flavour_s32_f16
19129 ||flavour == neon_cvt_flavour_u32_f16)
19130 do_scalar_fp16_v82_encode ();
7e8e6784
MGD
19131 inst.instruction |= op << 7;
19132 inst.instruction |= rm << 16;
19133 inst.instruction |= 0xf0000000;
5b7c81bd 19134 inst.is_neon = true;
7e8e6784
MGD
19135}
19136
19137static void
19138do_neon_cvt_1 (enum neon_cvt_mode mode)
037e8744
JB
19139{
19140 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
d54af2d0
RL
19141 NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ,
19142 NS_FH, NS_HF, NS_FHI, NS_HFI,
19143 NS_NULL);
6b9a8b67 19144 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744 19145
cc933301
JW
19146 if (flavour == neon_cvt_flavour_invalid)
19147 return;
19148
e3e535bc 19149 /* PR11109: Handle round-to-zero for VCVT conversions. */
7e8e6784 19150 if (mode == neon_cvt_mode_z
e3e535bc 19151 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
cc933301
JW
19152 && (flavour == neon_cvt_flavour_s16_f16
19153 || flavour == neon_cvt_flavour_u16_f16
19154 || flavour == neon_cvt_flavour_s32_f32
bacebabc
RM
19155 || flavour == neon_cvt_flavour_u32_f32
19156 || flavour == neon_cvt_flavour_s32_f64
6b9a8b67 19157 || flavour == neon_cvt_flavour_u32_f64)
e3e535bc
NC
19158 && (rs == NS_FD || rs == NS_FF))
19159 {
19160 do_vfp_nsyn_cvtz ();
19161 return;
19162 }
19163
9db2f6b4
RL
19164 /* ARMv8.2 fp16 VCVT conversions. */
19165 if (mode == neon_cvt_mode_z
19166 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16)
19167 && (flavour == neon_cvt_flavour_s32_f16
19168 || flavour == neon_cvt_flavour_u32_f16)
19169 && (rs == NS_FH))
19170 {
19171 do_vfp_nsyn_cvtz ();
19172 do_scalar_fp16_v82_encode ();
19173 return;
19174 }
19175
037e8744 19176 /* VFP rather than Neon conversions. */
6b9a8b67 19177 if (flavour >= neon_cvt_flavour_first_fp)
037e8744 19178 {
7e8e6784
MGD
19179 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
19180 do_vfp_nsyn_cvt (rs, flavour);
19181 else
19182 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
19183
037e8744
JB
19184 return;
19185 }
19186
19187 switch (rs)
19188 {
037e8744 19189 case NS_QQI:
dd9634d9
AV
19190 if (mode == neon_cvt_mode_z
19191 && (flavour == neon_cvt_flavour_f16_s16
19192 || flavour == neon_cvt_flavour_f16_u16
19193 || flavour == neon_cvt_flavour_s16_f16
19194 || flavour == neon_cvt_flavour_u16_f16
19195 || flavour == neon_cvt_flavour_f32_u32
19196 || flavour == neon_cvt_flavour_f32_s32
19197 || flavour == neon_cvt_flavour_s32_f32
19198 || flavour == neon_cvt_flavour_u32_f32))
19199 {
5b7c81bd 19200 if (!check_simd_pred_availability (true,
64c350f2 19201 NEON_CHECK_CC | NEON_CHECK_ARCH))
dd9634d9
AV
19202 return;
19203 }
dd9634d9
AV
19204 /* fall through. */
19205 case NS_DDI:
037e8744 19206 {
477330fc 19207 unsigned immbits;
cc933301
JW
19208 unsigned enctab[] = {0x0000100, 0x1000100, 0x0, 0x1000000,
19209 0x0000100, 0x1000100, 0x0, 0x1000000};
35997600 19210
dd9634d9
AV
19211 if ((rs != NS_QQI || !ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19212 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19213 return;
19214
19215 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19216 {
19217 constraint (inst.operands[2].present && inst.operands[2].imm == 0,
19218 _("immediate value out of range"));
19219 switch (flavour)
19220 {
19221 case neon_cvt_flavour_f16_s16:
19222 case neon_cvt_flavour_f16_u16:
19223 case neon_cvt_flavour_s16_f16:
19224 case neon_cvt_flavour_u16_f16:
19225 constraint (inst.operands[2].imm > 16,
19226 _("immediate value out of range"));
19227 break;
19228 case neon_cvt_flavour_f32_u32:
19229 case neon_cvt_flavour_f32_s32:
19230 case neon_cvt_flavour_s32_f32:
19231 case neon_cvt_flavour_u32_f32:
19232 constraint (inst.operands[2].imm > 32,
19233 _("immediate value out of range"));
19234 break;
19235 default:
19236 inst.error = BAD_FPU;
19237 return;
19238 }
19239 }
037e8744 19240
477330fc
RM
19241 /* Fixed-point conversion with #0 immediate is encoded as an
19242 integer conversion. */
19243 if (inst.operands[2].present && inst.operands[2].imm == 0)
19244 goto int_encode;
477330fc
RM
19245 NEON_ENCODE (IMMED, inst);
19246 if (flavour != neon_cvt_flavour_invalid)
19247 inst.instruction |= enctab[flavour];
19248 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19249 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19250 inst.instruction |= LOW4 (inst.operands[1].reg);
19251 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19252 inst.instruction |= neon_quad (rs) << 6;
19253 inst.instruction |= 1 << 21;
cc933301
JW
19254 if (flavour < neon_cvt_flavour_s16_f16)
19255 {
19256 inst.instruction |= 1 << 21;
19257 immbits = 32 - inst.operands[2].imm;
19258 inst.instruction |= immbits << 16;
19259 }
19260 else
19261 {
19262 inst.instruction |= 3 << 20;
19263 immbits = 16 - inst.operands[2].imm;
19264 inst.instruction |= immbits << 16;
19265 inst.instruction &= ~(1 << 9);
19266 }
477330fc
RM
19267
19268 neon_dp_fixup (&inst);
037e8744
JB
19269 }
19270 break;
19271
037e8744 19272 case NS_QQ:
dd9634d9
AV
19273 if ((mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
19274 || mode == neon_cvt_mode_m || mode == neon_cvt_mode_p)
19275 && (flavour == neon_cvt_flavour_s16_f16
19276 || flavour == neon_cvt_flavour_u16_f16
19277 || flavour == neon_cvt_flavour_s32_f32
19278 || flavour == neon_cvt_flavour_u32_f32))
19279 {
5b7c81bd 19280 if (!check_simd_pred_availability (true,
64c350f2 19281 NEON_CHECK_CC | NEON_CHECK_ARCH8))
dd9634d9
AV
19282 return;
19283 }
19284 else if (mode == neon_cvt_mode_z
19285 && (flavour == neon_cvt_flavour_f16_s16
19286 || flavour == neon_cvt_flavour_f16_u16
19287 || flavour == neon_cvt_flavour_s16_f16
19288 || flavour == neon_cvt_flavour_u16_f16
19289 || flavour == neon_cvt_flavour_f32_u32
19290 || flavour == neon_cvt_flavour_f32_s32
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_ARCH))
dd9634d9
AV
19296 return;
19297 }
19298 /* fall through. */
19299 case NS_DD:
7e8e6784
MGD
19300 if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
19301 {
7e8e6784 19302
dd9634d9 19303 NEON_ENCODE (FLOAT, inst);
5b7c81bd 19304 if (!check_simd_pred_availability (true,
64c350f2 19305 NEON_CHECK_CC | NEON_CHECK_ARCH8))
7e8e6784
MGD
19306 return;
19307
19308 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19309 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19310 inst.instruction |= LOW4 (inst.operands[1].reg);
19311 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19312 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
19313 inst.instruction |= (flavour == neon_cvt_flavour_u16_f16
19314 || flavour == neon_cvt_flavour_u32_f32) << 7;
7e8e6784 19315 inst.instruction |= mode << 8;
cc933301
JW
19316 if (flavour == neon_cvt_flavour_u16_f16
19317 || flavour == neon_cvt_flavour_s16_f16)
19318 /* Mask off the original size bits and reencode them. */
19319 inst.instruction = ((inst.instruction & 0xfff3ffff) | (1 << 18));
19320
7e8e6784
MGD
19321 if (thumb_mode)
19322 inst.instruction |= 0xfc000000;
19323 else
19324 inst.instruction |= 0xf0000000;
19325 }
19326 else
19327 {
037e8744 19328 int_encode:
7e8e6784 19329 {
cc933301
JW
19330 unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080,
19331 0x100, 0x180, 0x0, 0x080};
037e8744 19332
7e8e6784 19333 NEON_ENCODE (INTEGER, inst);
037e8744 19334
dd9634d9
AV
19335 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19336 {
19337 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19338 return;
19339 }
037e8744 19340
7e8e6784
MGD
19341 if (flavour != neon_cvt_flavour_invalid)
19342 inst.instruction |= enctab[flavour];
037e8744 19343
7e8e6784
MGD
19344 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19345 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19346 inst.instruction |= LOW4 (inst.operands[1].reg);
19347 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19348 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
19349 if (flavour >= neon_cvt_flavour_s16_f16
19350 && flavour <= neon_cvt_flavour_f16_u16)
19351 /* Half precision. */
19352 inst.instruction |= 1 << 18;
19353 else
19354 inst.instruction |= 2 << 18;
037e8744 19355
7e8e6784
MGD
19356 neon_dp_fixup (&inst);
19357 }
19358 }
19359 break;
037e8744 19360
8e79c3df
CM
19361 /* Half-precision conversions for Advanced SIMD -- neon. */
19362 case NS_QD:
19363 case NS_DQ:
bc52d49c
MM
19364 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19365 return;
8e79c3df
CM
19366
19367 if ((rs == NS_DQ)
19368 && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
19369 {
19370 as_bad (_("operand size must match register width"));
19371 break;
19372 }
19373
19374 if ((rs == NS_QD)
19375 && ((inst.vectype.el[0].size != 32 || inst.vectype.el[1].size != 16)))
19376 {
19377 as_bad (_("operand size must match register width"));
19378 break;
19379 }
19380
19381 if (rs == NS_DQ)
aab2c27d
MM
19382 {
19383 if (flavour == neon_cvt_flavour_bf16_f32)
19384 {
19385 if (vfp_or_neon_is_neon (NEON_CHECK_ARCH8) == FAIL)
19386 return;
19387 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
19388 /* VCVT.bf16.f32. */
19389 inst.instruction = 0x11b60640;
19390 }
19391 else
19392 /* VCVT.f16.f32. */
19393 inst.instruction = 0x3b60600;
19394 }
8e79c3df 19395 else
aab2c27d 19396 /* VCVT.f32.f16. */
8e79c3df
CM
19397 inst.instruction = 0x3b60700;
19398
19399 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19400 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19401 inst.instruction |= LOW4 (inst.operands[1].reg);
19402 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
88714cb8 19403 neon_dp_fixup (&inst);
8e79c3df
CM
19404 break;
19405
037e8744
JB
19406 default:
19407 /* Some VFP conversions go here (s32 <-> f32, u32 <-> f32). */
7e8e6784
MGD
19408 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
19409 do_vfp_nsyn_cvt (rs, flavour);
19410 else
19411 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
5287ad62 19412 }
5287ad62
JB
19413}
19414
e3e535bc
NC
19415static void
19416do_neon_cvtr (void)
19417{
7e8e6784 19418 do_neon_cvt_1 (neon_cvt_mode_x);
e3e535bc
NC
19419}
19420
19421static void
19422do_neon_cvt (void)
19423{
7e8e6784
MGD
19424 do_neon_cvt_1 (neon_cvt_mode_z);
19425}
19426
19427static void
19428do_neon_cvta (void)
19429{
19430 do_neon_cvt_1 (neon_cvt_mode_a);
19431}
19432
19433static void
19434do_neon_cvtn (void)
19435{
19436 do_neon_cvt_1 (neon_cvt_mode_n);
19437}
19438
19439static void
19440do_neon_cvtp (void)
19441{
19442 do_neon_cvt_1 (neon_cvt_mode_p);
19443}
19444
19445static void
19446do_neon_cvtm (void)
19447{
19448 do_neon_cvt_1 (neon_cvt_mode_m);
e3e535bc
NC
19449}
19450
8e79c3df 19451static void
5b7c81bd 19452do_neon_cvttb_2 (bool t, bool to, bool is_double)
8e79c3df 19453{
c70a8987
MGD
19454 if (is_double)
19455 mark_feature_used (&fpu_vfp_ext_armv8);
8e79c3df 19456
c70a8987
MGD
19457 encode_arm_vfp_reg (inst.operands[0].reg,
19458 (is_double && !to) ? VFP_REG_Dd : VFP_REG_Sd);
19459 encode_arm_vfp_reg (inst.operands[1].reg,
19460 (is_double && to) ? VFP_REG_Dm : VFP_REG_Sm);
19461 inst.instruction |= to ? 0x10000 : 0;
19462 inst.instruction |= t ? 0x80 : 0;
19463 inst.instruction |= is_double ? 0x100 : 0;
19464 do_vfp_cond_or_thumb ();
19465}
8e79c3df 19466
c70a8987 19467static void
5b7c81bd 19468do_neon_cvttb_1 (bool t)
c70a8987 19469{
d54af2d0 19470 enum neon_shape rs = neon_select_shape (NS_HF, NS_HD, NS_FH, NS_FF, NS_FD,
dd9634d9 19471 NS_DF, NS_DH, NS_QQ, NS_QQI, NS_NULL);
8e79c3df 19472
c70a8987
MGD
19473 if (rs == NS_NULL)
19474 return;
dd9634d9
AV
19475 else if (rs == NS_QQ || rs == NS_QQI)
19476 {
19477 int single_to_half = 0;
5b7c81bd 19478 if (!check_simd_pred_availability (true, NEON_CHECK_ARCH))
dd9634d9
AV
19479 return;
19480
19481 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
19482
19483 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19484 && (flavour == neon_cvt_flavour_u16_f16
19485 || flavour == neon_cvt_flavour_s16_f16
19486 || flavour == neon_cvt_flavour_f16_s16
19487 || flavour == neon_cvt_flavour_f16_u16
19488 || flavour == neon_cvt_flavour_u32_f32
19489 || flavour == neon_cvt_flavour_s32_f32
19490 || flavour == neon_cvt_flavour_f32_s32
19491 || flavour == neon_cvt_flavour_f32_u32))
19492 {
19493 inst.cond = 0xf;
19494 inst.instruction = N_MNEM_vcvt;
19495 set_pred_insn_type (INSIDE_VPT_INSN);
19496 do_neon_cvt_1 (neon_cvt_mode_z);
19497 return;
19498 }
19499 else if (rs == NS_QQ && flavour == neon_cvt_flavour_f32_f16)
19500 single_to_half = 1;
19501 else if (rs == NS_QQ && flavour != neon_cvt_flavour_f16_f32)
19502 {
19503 first_error (BAD_FPU);
19504 return;
19505 }
19506
19507 inst.instruction = 0xee3f0e01;
19508 inst.instruction |= single_to_half << 28;
19509 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19510 inst.instruction |= LOW4 (inst.operands[0].reg) << 13;
19511 inst.instruction |= t << 12;
19512 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19513 inst.instruction |= LOW4 (inst.operands[1].reg) << 1;
19514 inst.is_neon = 1;
19515 }
c70a8987
MGD
19516 else if (neon_check_type (2, rs, N_F16, N_F32 | N_VFP).type != NT_invtype)
19517 {
19518 inst.error = NULL;
5b7c81bd 19519 do_neon_cvttb_2 (t, /*to=*/true, /*is_double=*/false);
c70a8987
MGD
19520 }
19521 else if (neon_check_type (2, rs, N_F32 | N_VFP, N_F16).type != NT_invtype)
19522 {
19523 inst.error = NULL;
5b7c81bd 19524 do_neon_cvttb_2 (t, /*to=*/false, /*is_double=*/false);
c70a8987
MGD
19525 }
19526 else if (neon_check_type (2, rs, N_F16, N_F64 | N_VFP).type != NT_invtype)
19527 {
a715796b
TG
19528 /* The VCVTB and VCVTT instructions with D-register operands
19529 don't work for SP only targets. */
19530 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19531 _(BAD_FPU));
19532
c70a8987 19533 inst.error = NULL;
5b7c81bd 19534 do_neon_cvttb_2 (t, /*to=*/true, /*is_double=*/true);
c70a8987
MGD
19535 }
19536 else if (neon_check_type (2, rs, N_F64 | N_VFP, N_F16).type != NT_invtype)
19537 {
a715796b
TG
19538 /* The VCVTB and VCVTT instructions with D-register operands
19539 don't work for SP only targets. */
19540 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19541 _(BAD_FPU));
19542
c70a8987 19543 inst.error = NULL;
5b7c81bd 19544 do_neon_cvttb_2 (t, /*to=*/false, /*is_double=*/true);
c70a8987 19545 }
aab2c27d
MM
19546 else if (neon_check_type (2, rs, N_BF16 | N_VFP, N_F32).type != NT_invtype)
19547 {
19548 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
19549 inst.error = NULL;
19550 inst.instruction |= (1 << 8);
19551 inst.instruction &= ~(1 << 9);
5b7c81bd 19552 do_neon_cvttb_2 (t, /*to=*/true, /*is_double=*/false);
aab2c27d 19553 }
c70a8987
MGD
19554 else
19555 return;
19556}
19557
19558static void
19559do_neon_cvtb (void)
19560{
5b7c81bd 19561 do_neon_cvttb_1 (false);
8e79c3df
CM
19562}
19563
19564
19565static void
19566do_neon_cvtt (void)
19567{
5b7c81bd 19568 do_neon_cvttb_1 (true);
8e79c3df
CM
19569}
19570
5287ad62
JB
19571static void
19572neon_move_immediate (void)
19573{
037e8744
JB
19574 enum neon_shape rs = neon_select_shape (NS_DI, NS_QI, NS_NULL);
19575 struct neon_type_el et = neon_check_type (2, rs,
19576 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
5287ad62 19577 unsigned immlo, immhi = 0, immbits;
c96612cc 19578 int op, cmode, float_p;
5287ad62 19579
037e8744 19580 constraint (et.type == NT_invtype,
477330fc 19581 _("operand size must be specified for immediate VMOV"));
037e8744 19582
5287ad62
JB
19583 /* We start out as an MVN instruction if OP = 1, MOV otherwise. */
19584 op = (inst.instruction & (1 << 5)) != 0;
19585
19586 immlo = inst.operands[1].imm;
19587 if (inst.operands[1].regisimm)
19588 immhi = inst.operands[1].reg;
19589
19590 constraint (et.size < 32 && (immlo & ~((1 << et.size) - 1)) != 0,
477330fc 19591 _("immediate has bits set outside the operand size"));
5287ad62 19592
c96612cc
JB
19593 float_p = inst.operands[1].immisfloat;
19594
19595 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits, &op,
477330fc 19596 et.size, et.type)) == FAIL)
5287ad62
JB
19597 {
19598 /* Invert relevant bits only. */
19599 neon_invert_size (&immlo, &immhi, et.size);
19600 /* Flip from VMOV/VMVN to VMVN/VMOV. Some immediate types are unavailable
477330fc
RM
19601 with one or the other; those cases are caught by
19602 neon_cmode_for_move_imm. */
5287ad62 19603 op = !op;
c96612cc
JB
19604 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits,
19605 &op, et.size, et.type)) == FAIL)
477330fc
RM
19606 {
19607 first_error (_("immediate out of range"));
19608 return;
19609 }
5287ad62
JB
19610 }
19611
19612 inst.instruction &= ~(1 << 5);
19613 inst.instruction |= op << 5;
19614
19615 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19616 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
037e8744 19617 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
19618 inst.instruction |= cmode << 8;
19619
19620 neon_write_immbits (immbits);
19621}
19622
19623static void
19624do_neon_mvn (void)
19625{
5b7c81bd 19626 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
1a186d29
AV
19627 return;
19628
5287ad62
JB
19629 if (inst.operands[1].isreg)
19630 {
1a186d29
AV
19631 enum neon_shape rs;
19632 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19633 rs = neon_select_shape (NS_QQ, NS_NULL);
19634 else
19635 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5f4273c7 19636
250dd99f
AM
19637 if (rs == NS_NULL)
19638 return;
19639
88714cb8 19640 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
19641 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19642 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19643 inst.instruction |= LOW4 (inst.operands[1].reg);
19644 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 19645 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
19646 }
19647 else
19648 {
88714cb8 19649 NEON_ENCODE (IMMED, inst);
5287ad62
JB
19650 neon_move_immediate ();
19651 }
19652
88714cb8 19653 neon_dp_fixup (&inst);
1a186d29
AV
19654
19655 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19656 {
19657 constraint (!inst.operands[1].isreg && !inst.operands[0].isquad, BAD_FPU);
1a186d29 19658 }
5287ad62
JB
19659}
19660
19661/* Encode instructions of form:
19662
19663 |28/24|23|22|21 20|19 16|15 12|11 8|7|6|5|4|3 0|
5f4273c7 19664 | U |x |D |size | Rn | Rd |x x x x|N|x|M|x| Rm | */
5287ad62
JB
19665
19666static void
19667neon_mixed_length (struct neon_type_el et, unsigned size)
19668{
19669 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19670 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19671 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19672 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19673 inst.instruction |= LOW4 (inst.operands[2].reg);
19674 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
19675 inst.instruction |= (et.type == NT_unsigned) << 24;
19676 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 19677
88714cb8 19678 neon_dp_fixup (&inst);
5287ad62
JB
19679}
19680
19681static void
19682do_neon_dyadic_long (void)
19683{
66d1f7cc 19684 enum neon_shape rs = neon_select_shape (NS_QDD, NS_HHH, NS_FFF, NS_DDD, NS_NULL);
5ee91343
AV
19685 if (rs == NS_QDD)
19686 {
19687 if (vfp_or_neon_is_neon (NEON_CHECK_ARCH | NEON_CHECK_CC) == FAIL)
19688 return;
19689
19690 NEON_ENCODE (INTEGER, inst);
19691 /* FIXME: Type checking for lengthening op. */
19692 struct neon_type_el et = neon_check_type (3, NS_QDD,
19693 N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
19694 neon_mixed_length (et, et.size);
19695 }
19696 else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19697 && (inst.cond == 0xf || inst.cond == 0x10))
19698 {
19699 /* If parsing for MVE, vaddl/vsubl/vabdl{e,t} can only be vadd/vsub/vabd
19700 in an IT block with le/lt conditions. */
19701
19702 if (inst.cond == 0xf)
19703 inst.cond = 0xb;
19704 else if (inst.cond == 0x10)
19705 inst.cond = 0xd;
19706
19707 inst.pred_insn_type = INSIDE_IT_INSN;
19708
19709 if (inst.instruction == N_MNEM_vaddl)
19710 {
19711 inst.instruction = N_MNEM_vadd;
19712 do_neon_addsub_if_i ();
19713 }
19714 else if (inst.instruction == N_MNEM_vsubl)
19715 {
19716 inst.instruction = N_MNEM_vsub;
19717 do_neon_addsub_if_i ();
19718 }
19719 else if (inst.instruction == N_MNEM_vabdl)
19720 {
19721 inst.instruction = N_MNEM_vabd;
19722 do_neon_dyadic_if_su ();
19723 }
19724 }
19725 else
19726 first_error (BAD_FPU);
5287ad62
JB
19727}
19728
19729static void
19730do_neon_abal (void)
19731{
19732 struct neon_type_el et = neon_check_type (3, NS_QDD,
19733 N_EQK | N_INT | N_DBL, N_EQK, N_SU_32 | N_KEY);
19734 neon_mixed_length (et, et.size);
19735}
19736
19737static void
19738neon_mac_reg_scalar_long (unsigned regtypes, unsigned scalartypes)
19739{
19740 if (inst.operands[2].isscalar)
19741 {
dcbf9037 19742 struct neon_type_el et = neon_check_type (3, NS_QDS,
477330fc 19743 N_EQK | N_DBL, N_EQK, regtypes | N_KEY);
88714cb8 19744 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
19745 neon_mul_mac (et, et.type == NT_unsigned);
19746 }
19747 else
19748 {
19749 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 19750 N_EQK | N_DBL, N_EQK, scalartypes | N_KEY);
88714cb8 19751 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
19752 neon_mixed_length (et, et.size);
19753 }
19754}
19755
19756static void
19757do_neon_mac_maybe_scalar_long (void)
19758{
19759 neon_mac_reg_scalar_long (N_S16 | N_S32 | N_U16 | N_U32, N_SU_32);
19760}
19761
dec41383
JW
19762/* Like neon_scalar_for_mul, this function generate Rm encoding from GAS's
19763 internal SCALAR. QUAD_P is 1 if it's for Q format, otherwise it's 0. */
19764
19765static unsigned
19766neon_scalar_for_fmac_fp16_long (unsigned scalar, unsigned quad_p)
19767{
19768 unsigned regno = NEON_SCALAR_REG (scalar);
19769 unsigned elno = NEON_SCALAR_INDEX (scalar);
19770
19771 if (quad_p)
19772 {
19773 if (regno > 7 || elno > 3)
19774 goto bad_scalar;
19775
19776 return ((regno & 0x7)
19777 | ((elno & 0x1) << 3)
19778 | (((elno >> 1) & 0x1) << 5));
19779 }
19780 else
19781 {
19782 if (regno > 15 || elno > 1)
19783 goto bad_scalar;
19784
19785 return (((regno & 0x1) << 5)
19786 | ((regno >> 1) & 0x7)
19787 | ((elno & 0x1) << 3));
19788 }
19789
dc1e8a47 19790 bad_scalar:
dec41383
JW
19791 first_error (_("scalar out of range for multiply instruction"));
19792 return 0;
19793}
19794
19795static void
19796do_neon_fmac_maybe_scalar_long (int subtype)
19797{
19798 enum neon_shape rs;
19799 int high8;
19800 /* NOTE: vfmal/vfmsl use slightly different NEON three-same encoding. 'size"
19801 field (bits[21:20]) has different meaning. For scalar index variant, it's
19802 used to differentiate add and subtract, otherwise it's with fixed value
19803 0x2. */
19804 int size = -1;
19805
dec41383
JW
19806 /* vfmal/vfmsl are in three-same D/Q register format or the third operand can
19807 be a scalar index register. */
19808 if (inst.operands[2].isscalar)
19809 {
19810 high8 = 0xfe000000;
19811 if (subtype)
19812 size = 16;
19813 rs = neon_select_shape (NS_DHS, NS_QDS, NS_NULL);
19814 }
19815 else
19816 {
19817 high8 = 0xfc000000;
19818 size = 32;
19819 if (subtype)
19820 inst.instruction |= (0x1 << 23);
19821 rs = neon_select_shape (NS_DHH, NS_QDD, NS_NULL);
19822 }
19823
aab2c27d
MM
19824
19825 if (inst.cond != COND_ALWAYS)
19826 as_warn (_("vfmal/vfmsl with FP16 type cannot be conditional, the "
19827 "behaviour is UNPREDICTABLE"));
19828
19829 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16_fml),
19830 _(BAD_FP16));
19831
19832 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
19833 _(BAD_FPU));
dec41383
JW
19834
19835 /* "opcode" from template has included "ubit", so simply pass 0 here. Also,
19836 the "S" bit in size field has been reused to differentiate vfmal and vfmsl,
19837 so we simply pass -1 as size. */
19838 unsigned quad_p = (rs == NS_QDD || rs == NS_QDS);
19839 neon_three_same (quad_p, 0, size);
19840
19841 /* Undo neon_dp_fixup. Redo the high eight bits. */
19842 inst.instruction &= 0x00ffffff;
19843 inst.instruction |= high8;
19844
dec41383
JW
19845 /* Unlike usually NEON three-same, encoding for Vn and Vm will depend on
19846 whether the instruction is in Q form and whether Vm is a scalar indexed
19847 operand. */
19848 if (inst.operands[2].isscalar)
19849 {
19850 unsigned rm
19851 = neon_scalar_for_fmac_fp16_long (inst.operands[2].reg, quad_p);
19852 inst.instruction &= 0xffffffd0;
19853 inst.instruction |= rm;
19854
19855 if (!quad_p)
19856 {
19857 /* Redo Rn as well. */
19858 inst.instruction &= 0xfff0ff7f;
19859 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
19860 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
19861 }
19862 }
19863 else if (!quad_p)
19864 {
19865 /* Redo Rn and Rm. */
19866 inst.instruction &= 0xfff0ff50;
19867 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
19868 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
19869 inst.instruction |= HI4 (inst.operands[2].reg);
19870 inst.instruction |= LOW1 (inst.operands[2].reg) << 5;
19871 }
19872}
19873
19874static void
19875do_neon_vfmal (void)
19876{
19877 return do_neon_fmac_maybe_scalar_long (0);
19878}
19879
19880static void
19881do_neon_vfmsl (void)
19882{
19883 return do_neon_fmac_maybe_scalar_long (1);
19884}
19885
5287ad62
JB
19886static void
19887do_neon_dyadic_wide (void)
19888{
19889 struct neon_type_el et = neon_check_type (3, NS_QQD,
19890 N_EQK | N_DBL, N_EQK | N_DBL, N_SU_32 | N_KEY);
19891 neon_mixed_length (et, et.size);
19892}
19893
19894static void
19895do_neon_dyadic_narrow (void)
19896{
19897 struct neon_type_el et = neon_check_type (3, NS_QDD,
19898 N_EQK | N_DBL, N_EQK, N_I16 | N_I32 | N_I64 | N_KEY);
428e3f1f
PB
19899 /* Operand sign is unimportant, and the U bit is part of the opcode,
19900 so force the operand type to integer. */
19901 et.type = NT_integer;
5287ad62
JB
19902 neon_mixed_length (et, et.size / 2);
19903}
19904
19905static void
19906do_neon_mul_sat_scalar_long (void)
19907{
19908 neon_mac_reg_scalar_long (N_S16 | N_S32, N_S16 | N_S32);
19909}
19910
19911static void
19912do_neon_vmull (void)
19913{
19914 if (inst.operands[2].isscalar)
19915 do_neon_mac_maybe_scalar_long ();
19916 else
19917 {
19918 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 19919 N_EQK | N_DBL, N_EQK, N_SU_32 | N_P8 | N_P64 | N_KEY);
4f51b4bd 19920
5287ad62 19921 if (et.type == NT_poly)
477330fc 19922 NEON_ENCODE (POLY, inst);
5287ad62 19923 else
477330fc 19924 NEON_ENCODE (INTEGER, inst);
4f51b4bd
MGD
19925
19926 /* For polynomial encoding the U bit must be zero, and the size must
19927 be 8 (encoded as 0b00) or, on ARMv8 or later 64 (encoded, non
19928 obviously, as 0b10). */
19929 if (et.size == 64)
19930 {
19931 /* Check we're on the correct architecture. */
19932 if (!mark_feature_used (&fpu_crypto_ext_armv8))
19933 inst.error =
19934 _("Instruction form not available on this architecture.");
19935
19936 et.size = 32;
19937 }
19938
5287ad62
JB
19939 neon_mixed_length (et, et.size);
19940 }
19941}
19942
19943static void
19944do_neon_ext (void)
19945{
037e8744 19946 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
5287ad62
JB
19947 struct neon_type_el et = neon_check_type (3, rs,
19948 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
19949 unsigned imm = (inst.operands[3].imm * et.size) / 8;
35997600
NC
19950
19951 constraint (imm >= (unsigned) (neon_quad (rs) ? 16 : 8),
19952 _("shift out of range"));
5287ad62
JB
19953 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19954 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19955 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19956 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19957 inst.instruction |= LOW4 (inst.operands[2].reg);
19958 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
037e8744 19959 inst.instruction |= neon_quad (rs) << 6;
5287ad62 19960 inst.instruction |= imm << 8;
5f4273c7 19961
88714cb8 19962 neon_dp_fixup (&inst);
5287ad62
JB
19963}
19964
19965static void
19966do_neon_rev (void)
19967{
5b7c81bd 19968 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
19969 return;
19970
19971 enum neon_shape rs;
19972 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19973 rs = neon_select_shape (NS_QQ, NS_NULL);
19974 else
19975 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
19976
5287ad62
JB
19977 struct neon_type_el et = neon_check_type (2, rs,
19978 N_EQK, N_8 | N_16 | N_32 | N_KEY);
4401c241 19979
5287ad62
JB
19980 unsigned op = (inst.instruction >> 7) & 3;
19981 /* N (width of reversed regions) is encoded as part of the bitmask. We
19982 extract it here to check the elements to be reversed are smaller.
19983 Otherwise we'd get a reserved instruction. */
19984 unsigned elsize = (op == 2) ? 16 : (op == 1) ? 32 : (op == 0) ? 64 : 0;
4401c241
AV
19985
19986 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext) && elsize == 64
19987 && inst.operands[0].reg == inst.operands[1].reg)
19988 as_tsktsk (_("Warning: 64-bit element size and same destination and source"
19989 " operands makes instruction UNPREDICTABLE"));
19990
9c2799c2 19991 gas_assert (elsize != 0);
5287ad62 19992 constraint (et.size >= elsize,
477330fc 19993 _("elements must be smaller than reversal region"));
037e8744 19994 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19995}
19996
19997static void
19998do_neon_dup (void)
19999{
20000 if (inst.operands[1].isscalar)
20001 {
b409bdb6
AV
20002 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
20003 BAD_FPU);
037e8744 20004 enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
dcbf9037 20005 struct neon_type_el et = neon_check_type (2, rs,
477330fc 20006 N_EQK, N_8 | N_16 | N_32 | N_KEY);
5287ad62 20007 unsigned sizebits = et.size >> 3;
dcbf9037 20008 unsigned dm = NEON_SCALAR_REG (inst.operands[1].reg);
5287ad62 20009 int logsize = neon_logbits (et.size);
dcbf9037 20010 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg) << logsize;
037e8744
JB
20011
20012 if (vfp_or_neon_is_neon (NEON_CHECK_CC) == FAIL)
477330fc 20013 return;
037e8744 20014
88714cb8 20015 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
20016 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20017 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20018 inst.instruction |= LOW4 (dm);
20019 inst.instruction |= HI1 (dm) << 5;
037e8744 20020 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
20021 inst.instruction |= x << 17;
20022 inst.instruction |= sizebits << 16;
5f4273c7 20023
88714cb8 20024 neon_dp_fixup (&inst);
5287ad62
JB
20025 }
20026 else
20027 {
037e8744
JB
20028 enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
20029 struct neon_type_el et = neon_check_type (2, rs,
477330fc 20030 N_8 | N_16 | N_32 | N_KEY, N_EQK);
b409bdb6
AV
20031 if (rs == NS_QR)
20032 {
5b7c81bd 20033 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH))
b409bdb6
AV
20034 return;
20035 }
20036 else
20037 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
20038 BAD_FPU);
20039
20040 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20041 {
20042 if (inst.operands[1].reg == REG_SP)
20043 as_tsktsk (MVE_BAD_SP);
20044 else if (inst.operands[1].reg == REG_PC)
20045 as_tsktsk (MVE_BAD_PC);
20046 }
20047
5287ad62 20048 /* Duplicate ARM register to lanes of vector. */
88714cb8 20049 NEON_ENCODE (ARMREG, inst);
5287ad62 20050 switch (et.size)
477330fc
RM
20051 {
20052 case 8: inst.instruction |= 0x400000; break;
20053 case 16: inst.instruction |= 0x000020; break;
20054 case 32: inst.instruction |= 0x000000; break;
20055 default: break;
20056 }
5287ad62
JB
20057 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
20058 inst.instruction |= LOW4 (inst.operands[0].reg) << 16;
20059 inst.instruction |= HI1 (inst.operands[0].reg) << 7;
037e8744 20060 inst.instruction |= neon_quad (rs) << 21;
5287ad62 20061 /* The encoding for this instruction is identical for the ARM and Thumb
477330fc 20062 variants, except for the condition field. */
037e8744 20063 do_vfp_cond_or_thumb ();
5287ad62
JB
20064 }
20065}
20066
57785aa2
AV
20067static void
20068do_mve_mov (int toQ)
20069{
20070 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20071 return;
20072 if (inst.cond > COND_ALWAYS)
20073 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
20074
20075 unsigned Rt = 0, Rt2 = 1, Q0 = 2, Q1 = 3;
20076 if (toQ)
20077 {
20078 Q0 = 0;
20079 Q1 = 1;
20080 Rt = 2;
20081 Rt2 = 3;
20082 }
20083
20084 constraint (inst.operands[Q0].reg != inst.operands[Q1].reg + 2,
20085 _("Index one must be [2,3] and index two must be two less than"
20086 " index one."));
e683cb41
AC
20087 constraint (!toQ && inst.operands[Rt].reg == inst.operands[Rt2].reg,
20088 _("Destination registers may not be the same"));
57785aa2
AV
20089 constraint (inst.operands[Rt].reg == REG_SP
20090 || inst.operands[Rt2].reg == REG_SP,
20091 BAD_SP);
20092 constraint (inst.operands[Rt].reg == REG_PC
20093 || inst.operands[Rt2].reg == REG_PC,
20094 BAD_PC);
20095
20096 inst.instruction = 0xec000f00;
20097 inst.instruction |= HI1 (inst.operands[Q1].reg / 32) << 23;
20098 inst.instruction |= !!toQ << 20;
20099 inst.instruction |= inst.operands[Rt2].reg << 16;
20100 inst.instruction |= LOW4 (inst.operands[Q1].reg / 32) << 13;
20101 inst.instruction |= (inst.operands[Q1].reg % 4) << 4;
20102 inst.instruction |= inst.operands[Rt].reg;
20103}
20104
20105static void
20106do_mve_movn (void)
20107{
20108 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20109 return;
20110
20111 if (inst.cond > COND_ALWAYS)
20112 inst.pred_insn_type = INSIDE_VPT_INSN;
20113 else
20114 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
20115
20116 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_I16 | N_I32
20117 | N_KEY);
20118
20119 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20120 inst.instruction |= (neon_logbits (et.size) - 1) << 18;
20121 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20122 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20123 inst.instruction |= LOW4 (inst.operands[1].reg);
20124 inst.is_neon = 1;
20125
20126}
20127
5287ad62
JB
20128/* VMOV has particularly many variations. It can be one of:
20129 0. VMOV<c><q> <Qd>, <Qm>
20130 1. VMOV<c><q> <Dd>, <Dm>
20131 (Register operations, which are VORR with Rm = Rn.)
20132 2. VMOV<c><q>.<dt> <Qd>, #<imm>
20133 3. VMOV<c><q>.<dt> <Dd>, #<imm>
20134 (Immediate loads.)
20135 4. VMOV<c><q>.<size> <Dn[x]>, <Rd>
20136 (ARM register to scalar.)
20137 5. VMOV<c><q> <Dm>, <Rd>, <Rn>
20138 (Two ARM registers to vector.)
20139 6. VMOV<c><q>.<dt> <Rd>, <Dn[x]>
20140 (Scalar to ARM register.)
20141 7. VMOV<c><q> <Rd>, <Rn>, <Dm>
20142 (Vector to two ARM registers.)
037e8744
JB
20143 8. VMOV.F32 <Sd>, <Sm>
20144 9. VMOV.F64 <Dd>, <Dm>
20145 (VFP register moves.)
20146 10. VMOV.F32 <Sd>, #imm
20147 11. VMOV.F64 <Dd>, #imm
20148 (VFP float immediate load.)
20149 12. VMOV <Rd>, <Sm>
20150 (VFP single to ARM reg.)
20151 13. VMOV <Sd>, <Rm>
20152 (ARM reg to VFP single.)
20153 14. VMOV <Rd>, <Re>, <Sn>, <Sm>
20154 (Two ARM regs to two VFP singles.)
20155 15. VMOV <Sd>, <Se>, <Rn>, <Rm>
20156 (Two VFP singles to two ARM regs.)
57785aa2
AV
20157 16. VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]>
20158 17. VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2>
20159 18. VMOV<c>.<dt> <Rt>, <Qn[idx]>
20160 19. VMOV<c>.<dt> <Qd[idx]>, <Rt>
5f4273c7 20161
037e8744
JB
20162 These cases can be disambiguated using neon_select_shape, except cases 1/9
20163 and 3/11 which depend on the operand type too.
5f4273c7 20164
5287ad62 20165 All the encoded bits are hardcoded by this function.
5f4273c7 20166
b7fc2769
JB
20167 Cases 4, 6 may be used with VFPv1 and above (only 32-bit transfers!).
20168 Cases 5, 7 may be used with VFPv2 and above.
5f4273c7 20169
5287ad62 20170 FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
5f4273c7 20171 can specify a type where it doesn't make sense to, and is ignored). */
5287ad62
JB
20172
20173static void
20174do_neon_mov (void)
20175{
57785aa2
AV
20176 enum neon_shape rs = neon_select_shape (NS_RRSS, NS_SSRR, NS_RRFF, NS_FFRR,
20177 NS_DRR, NS_RRD, NS_QQ, NS_DD, NS_QI,
20178 NS_DI, NS_SR, NS_RS, NS_FF, NS_FI,
20179 NS_RF, NS_FR, NS_HR, NS_RH, NS_HI,
20180 NS_NULL);
037e8744
JB
20181 struct neon_type_el et;
20182 const char *ldconst = 0;
5287ad62 20183
037e8744 20184 switch (rs)
5287ad62 20185 {
037e8744
JB
20186 case NS_DD: /* case 1/9. */
20187 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
20188 /* It is not an error here if no type is given. */
20189 inst.error = NULL;
1c1e0fe5
SP
20190
20191 /* In MVE we interpret the following instructions as same, so ignoring
20192 the following type (float) and size (64) checks.
20193 a: VMOV<c><q> <Dd>, <Dm>
20194 b: VMOV<c><q>.F64 <Dd>, <Dm>. */
20195 if ((et.type == NT_float && et.size == 64)
20196 || (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)))
477330fc
RM
20197 {
20198 do_vfp_nsyn_opcode ("fcpyd");
20199 break;
20200 }
037e8744 20201 /* fall through. */
5287ad62 20202
037e8744
JB
20203 case NS_QQ: /* case 0/1. */
20204 {
5b7c81bd 20205 if (!check_simd_pred_availability (false,
64c350f2 20206 NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc
RM
20207 return;
20208 /* The architecture manual I have doesn't explicitly state which
20209 value the U bit should have for register->register moves, but
20210 the equivalent VORR instruction has U = 0, so do that. */
20211 inst.instruction = 0x0200110;
20212 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20213 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20214 inst.instruction |= LOW4 (inst.operands[1].reg);
20215 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20216 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20217 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20218 inst.instruction |= neon_quad (rs) << 6;
20219
20220 neon_dp_fixup (&inst);
037e8744
JB
20221 }
20222 break;
5f4273c7 20223
037e8744
JB
20224 case NS_DI: /* case 3/11. */
20225 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
20226 inst.error = NULL;
20227 if (et.type == NT_float && et.size == 64)
477330fc
RM
20228 {
20229 /* case 11 (fconstd). */
20230 ldconst = "fconstd";
20231 goto encode_fconstd;
20232 }
037e8744
JB
20233 /* fall through. */
20234
20235 case NS_QI: /* case 2/3. */
5b7c81bd 20236 if (!check_simd_pred_availability (false,
64c350f2 20237 NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc 20238 return;
037e8744
JB
20239 inst.instruction = 0x0800010;
20240 neon_move_immediate ();
88714cb8 20241 neon_dp_fixup (&inst);
5287ad62 20242 break;
5f4273c7 20243
037e8744
JB
20244 case NS_SR: /* case 4. */
20245 {
477330fc
RM
20246 unsigned bcdebits = 0;
20247 int logsize;
20248 unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
20249 unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
037e8744 20250
05ac0ffb
JB
20251 /* .<size> is optional here, defaulting to .32. */
20252 if (inst.vectype.elems == 0
20253 && inst.operands[0].vectype.type == NT_invtype
20254 && inst.operands[1].vectype.type == NT_invtype)
20255 {
20256 inst.vectype.el[0].type = NT_untyped;
20257 inst.vectype.el[0].size = 32;
20258 inst.vectype.elems = 1;
20259 }
20260
477330fc
RM
20261 et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
20262 logsize = neon_logbits (et.size);
20263
57785aa2
AV
20264 if (et.size != 32)
20265 {
20266 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
20267 && vfp_or_neon_is_neon (NEON_CHECK_ARCH) == FAIL)
20268 return;
20269 }
20270 else
20271 {
20272 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
20273 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20274 _(BAD_FPU));
20275 }
20276
20277 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20278 {
20279 if (inst.operands[1].reg == REG_SP)
20280 as_tsktsk (MVE_BAD_SP);
20281 else if (inst.operands[1].reg == REG_PC)
20282 as_tsktsk (MVE_BAD_PC);
20283 }
20284 unsigned size = inst.operands[0].isscalar == 1 ? 64 : 128;
20285
477330fc 20286 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2
AV
20287 constraint (x >= size / et.size, _("scalar index out of range"));
20288
477330fc
RM
20289
20290 switch (et.size)
20291 {
20292 case 8: bcdebits = 0x8; break;
20293 case 16: bcdebits = 0x1; break;
20294 case 32: bcdebits = 0x0; break;
20295 default: ;
20296 }
20297
57785aa2 20298 bcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
20299
20300 inst.instruction = 0xe000b10;
20301 do_vfp_cond_or_thumb ();
20302 inst.instruction |= LOW4 (dn) << 16;
20303 inst.instruction |= HI1 (dn) << 7;
20304 inst.instruction |= inst.operands[1].reg << 12;
20305 inst.instruction |= (bcdebits & 3) << 5;
57785aa2
AV
20306 inst.instruction |= ((bcdebits >> 2) & 3) << 21;
20307 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
20308 }
20309 break;
5f4273c7 20310
037e8744 20311 case NS_DRR: /* case 5 (fmdrr). */
57785aa2
AV
20312 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20313 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 20314 _(BAD_FPU));
b7fc2769 20315
037e8744
JB
20316 inst.instruction = 0xc400b10;
20317 do_vfp_cond_or_thumb ();
20318 inst.instruction |= LOW4 (inst.operands[0].reg);
20319 inst.instruction |= HI1 (inst.operands[0].reg) << 5;
20320 inst.instruction |= inst.operands[1].reg << 12;
20321 inst.instruction |= inst.operands[2].reg << 16;
20322 break;
5f4273c7 20323
037e8744
JB
20324 case NS_RS: /* case 6. */
20325 {
477330fc
RM
20326 unsigned logsize;
20327 unsigned dn = NEON_SCALAR_REG (inst.operands[1].reg);
20328 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
20329 unsigned abcdebits = 0;
037e8744 20330
05ac0ffb
JB
20331 /* .<dt> is optional here, defaulting to .32. */
20332 if (inst.vectype.elems == 0
20333 && inst.operands[0].vectype.type == NT_invtype
20334 && inst.operands[1].vectype.type == NT_invtype)
20335 {
20336 inst.vectype.el[0].type = NT_untyped;
20337 inst.vectype.el[0].size = 32;
20338 inst.vectype.elems = 1;
20339 }
20340
91d6fa6a
NC
20341 et = neon_check_type (2, NS_NULL,
20342 N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
477330fc
RM
20343 logsize = neon_logbits (et.size);
20344
57785aa2
AV
20345 if (et.size != 32)
20346 {
20347 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
20348 && vfp_or_neon_is_neon (NEON_CHECK_CC
20349 | NEON_CHECK_ARCH) == FAIL)
20350 return;
20351 }
20352 else
20353 {
20354 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
20355 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20356 _(BAD_FPU));
20357 }
20358
20359 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20360 {
20361 if (inst.operands[0].reg == REG_SP)
20362 as_tsktsk (MVE_BAD_SP);
20363 else if (inst.operands[0].reg == REG_PC)
20364 as_tsktsk (MVE_BAD_PC);
20365 }
20366
20367 unsigned size = inst.operands[1].isscalar == 1 ? 64 : 128;
20368
477330fc 20369 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2 20370 constraint (x >= size / et.size, _("scalar index out of range"));
477330fc
RM
20371
20372 switch (et.size)
20373 {
20374 case 8: abcdebits = (et.type == NT_signed) ? 0x08 : 0x18; break;
20375 case 16: abcdebits = (et.type == NT_signed) ? 0x01 : 0x11; break;
20376 case 32: abcdebits = 0x00; break;
20377 default: ;
20378 }
20379
57785aa2 20380 abcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
20381 inst.instruction = 0xe100b10;
20382 do_vfp_cond_or_thumb ();
20383 inst.instruction |= LOW4 (dn) << 16;
20384 inst.instruction |= HI1 (dn) << 7;
20385 inst.instruction |= inst.operands[0].reg << 12;
20386 inst.instruction |= (abcdebits & 3) << 5;
20387 inst.instruction |= (abcdebits >> 2) << 21;
57785aa2 20388 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
20389 }
20390 break;
5f4273c7 20391
037e8744 20392 case NS_RRD: /* case 7 (fmrrd). */
57785aa2
AV
20393 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20394 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 20395 _(BAD_FPU));
037e8744
JB
20396
20397 inst.instruction = 0xc500b10;
20398 do_vfp_cond_or_thumb ();
20399 inst.instruction |= inst.operands[0].reg << 12;
20400 inst.instruction |= inst.operands[1].reg << 16;
20401 inst.instruction |= LOW4 (inst.operands[2].reg);
20402 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20403 break;
5f4273c7 20404
037e8744
JB
20405 case NS_FF: /* case 8 (fcpys). */
20406 do_vfp_nsyn_opcode ("fcpys");
20407 break;
5f4273c7 20408
9db2f6b4 20409 case NS_HI:
037e8744
JB
20410 case NS_FI: /* case 10 (fconsts). */
20411 ldconst = "fconsts";
4ef4710f 20412 encode_fconstd:
58ed5c38
TC
20413 if (!inst.operands[1].immisfloat)
20414 {
4ef4710f 20415 unsigned new_imm;
58ed5c38 20416 /* Immediate has to fit in 8 bits so float is enough. */
4ef4710f
NC
20417 float imm = (float) inst.operands[1].imm;
20418 memcpy (&new_imm, &imm, sizeof (float));
20419 /* But the assembly may have been written to provide an integer
20420 bit pattern that equates to a float, so check that the
20421 conversion has worked. */
20422 if (is_quarter_float (new_imm))
20423 {
20424 if (is_quarter_float (inst.operands[1].imm))
20425 as_warn (_("immediate constant is valid both as a bit-pattern and a floating point value (using the fp value)"));
20426
20427 inst.operands[1].imm = new_imm;
20428 inst.operands[1].immisfloat = 1;
20429 }
58ed5c38
TC
20430 }
20431
037e8744 20432 if (is_quarter_float (inst.operands[1].imm))
477330fc
RM
20433 {
20434 inst.operands[1].imm = neon_qfloat_bits (inst.operands[1].imm);
20435 do_vfp_nsyn_opcode (ldconst);
9db2f6b4
RL
20436
20437 /* ARMv8.2 fp16 vmov.f16 instruction. */
20438 if (rs == NS_HI)
20439 do_scalar_fp16_v82_encode ();
477330fc 20440 }
5287ad62 20441 else
477330fc 20442 first_error (_("immediate out of range"));
037e8744 20443 break;
5f4273c7 20444
9db2f6b4 20445 case NS_RH:
037e8744
JB
20446 case NS_RF: /* case 12 (fmrs). */
20447 do_vfp_nsyn_opcode ("fmrs");
9db2f6b4
RL
20448 /* ARMv8.2 fp16 vmov.f16 instruction. */
20449 if (rs == NS_RH)
20450 do_scalar_fp16_v82_encode ();
037e8744 20451 break;
5f4273c7 20452
9db2f6b4 20453 case NS_HR:
037e8744
JB
20454 case NS_FR: /* case 13 (fmsr). */
20455 do_vfp_nsyn_opcode ("fmsr");
9db2f6b4
RL
20456 /* ARMv8.2 fp16 vmov.f16 instruction. */
20457 if (rs == NS_HR)
20458 do_scalar_fp16_v82_encode ();
037e8744 20459 break;
5f4273c7 20460
57785aa2
AV
20461 case NS_RRSS:
20462 do_mve_mov (0);
20463 break;
20464 case NS_SSRR:
20465 do_mve_mov (1);
20466 break;
20467
037e8744
JB
20468 /* The encoders for the fmrrs and fmsrr instructions expect three operands
20469 (one of which is a list), but we have parsed four. Do some fiddling to
20470 make the operands what do_vfp_reg2_from_sp2 and do_vfp_sp2_from_reg2
20471 expect. */
20472 case NS_RRFF: /* case 14 (fmrrs). */
57785aa2
AV
20473 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20474 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20475 _(BAD_FPU));
037e8744 20476 constraint (inst.operands[3].reg != inst.operands[2].reg + 1,
477330fc 20477 _("VFP registers must be adjacent"));
037e8744
JB
20478 inst.operands[2].imm = 2;
20479 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
20480 do_vfp_nsyn_opcode ("fmrrs");
20481 break;
5f4273c7 20482
037e8744 20483 case NS_FFRR: /* case 15 (fmsrr). */
57785aa2
AV
20484 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20485 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20486 _(BAD_FPU));
037e8744 20487 constraint (inst.operands[1].reg != inst.operands[0].reg + 1,
477330fc 20488 _("VFP registers must be adjacent"));
037e8744
JB
20489 inst.operands[1] = inst.operands[2];
20490 inst.operands[2] = inst.operands[3];
20491 inst.operands[0].imm = 2;
20492 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
20493 do_vfp_nsyn_opcode ("fmsrr");
5287ad62 20494 break;
5f4273c7 20495
4c261dff
NC
20496 case NS_NULL:
20497 /* neon_select_shape has determined that the instruction
20498 shape is wrong and has already set the error message. */
20499 break;
20500
5287ad62
JB
20501 default:
20502 abort ();
20503 }
20504}
20505
57785aa2
AV
20506static void
20507do_mve_movl (void)
20508{
20509 if (!(inst.operands[0].present && inst.operands[0].isquad
20510 && inst.operands[1].present && inst.operands[1].isquad
20511 && !inst.operands[2].present))
20512 {
20513 inst.instruction = 0;
20514 inst.cond = 0xb;
20515 if (thumb_mode)
20516 set_pred_insn_type (INSIDE_IT_INSN);
20517 do_neon_mov ();
20518 return;
20519 }
20520
20521 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20522 return;
20523
20524 if (inst.cond != COND_ALWAYS)
20525 inst.pred_insn_type = INSIDE_VPT_INSN;
20526
20527 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_S8 | N_U8
20528 | N_S16 | N_U16 | N_KEY);
20529
20530 inst.instruction |= (et.type == NT_unsigned) << 28;
20531 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20532 inst.instruction |= (neon_logbits (et.size) + 1) << 19;
20533 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20534 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20535 inst.instruction |= LOW4 (inst.operands[1].reg);
20536 inst.is_neon = 1;
20537}
20538
5287ad62
JB
20539static void
20540do_neon_rshift_round_imm (void)
20541{
5b7c81bd 20542 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
20543 return;
20544
20545 enum neon_shape rs;
20546 struct neon_type_el et;
20547
20548 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20549 {
20550 rs = neon_select_shape (NS_QQI, NS_NULL);
20551 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
20552 }
20553 else
20554 {
20555 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
20556 et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
20557 }
5287ad62
JB
20558 int imm = inst.operands[2].imm;
20559
20560 /* imm == 0 case is encoded as VMOV for V{R}SHR. */
20561 if (imm == 0)
20562 {
20563 inst.operands[2].present = 0;
20564 do_neon_mov ();
20565 return;
20566 }
20567
20568 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 20569 _("immediate out of range for shift"));
5b7c81bd 20570 neon_imm_shift (true, et.type == NT_unsigned, neon_quad (rs), et,
477330fc 20571 et.size - imm);
5287ad62
JB
20572}
20573
9db2f6b4
RL
20574static void
20575do_neon_movhf (void)
20576{
20577 enum neon_shape rs = neon_select_shape (NS_HH, NS_NULL);
20578 constraint (rs != NS_HH, _("invalid suffix"));
20579
7bdf778b
ASDV
20580 if (inst.cond != COND_ALWAYS)
20581 {
20582 if (thumb_mode)
20583 {
55e0daa3 20584 as_warn (_("scalar fp16 instruction cannot be conditional,"
7bdf778b
ASDV
20585 " the behaviour is UNPREDICTABLE"));
20586 }
20587 else
20588 {
20589 inst.error = BAD_COND;
20590 return;
20591 }
20592 }
20593
9db2f6b4
RL
20594 do_vfp_sp_monadic ();
20595
20596 inst.is_neon = 1;
20597 inst.instruction |= 0xf0000000;
20598}
20599
5287ad62
JB
20600static void
20601do_neon_movl (void)
20602{
20603 struct neon_type_el et = neon_check_type (2, NS_QD,
20604 N_EQK | N_DBL, N_SU_32 | N_KEY);
20605 unsigned sizebits = et.size >> 3;
20606 inst.instruction |= sizebits << 19;
20607 neon_two_same (0, et.type == NT_unsigned, -1);
20608}
20609
20610static void
20611do_neon_trn (void)
20612{
037e8744 20613 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20614 struct neon_type_el et = neon_check_type (2, rs,
20615 N_EQK, N_8 | N_16 | N_32 | N_KEY);
88714cb8 20616 NEON_ENCODE (INTEGER, inst);
037e8744 20617 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20618}
20619
20620static void
20621do_neon_zip_uzp (void)
20622{
037e8744 20623 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20624 struct neon_type_el et = neon_check_type (2, rs,
20625 N_EQK, N_8 | N_16 | N_32 | N_KEY);
20626 if (rs == NS_DD && et.size == 32)
20627 {
20628 /* Special case: encode as VTRN.32 <Dd>, <Dm>. */
20629 inst.instruction = N_MNEM_vtrn;
20630 do_neon_trn ();
20631 return;
20632 }
037e8744 20633 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20634}
20635
20636static void
20637do_neon_sat_abs_neg (void)
20638{
5b7c81bd 20639 if (!check_simd_pred_availability (false, NEON_CHECK_CC | NEON_CHECK_ARCH))
1a186d29
AV
20640 return;
20641
20642 enum neon_shape rs;
20643 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20644 rs = neon_select_shape (NS_QQ, NS_NULL);
20645 else
20646 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20647 struct neon_type_el et = neon_check_type (2, rs,
20648 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 20649 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20650}
20651
20652static void
20653do_neon_pair_long (void)
20654{
037e8744 20655 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20656 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
20657 /* Unsigned is encoded in OP field (bit 7) for these instruction. */
20658 inst.instruction |= (et.type == NT_unsigned) << 7;
037e8744 20659 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20660}
20661
20662static void
20663do_neon_recip_est (void)
20664{
037e8744 20665 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62 20666 struct neon_type_el et = neon_check_type (2, rs,
cc933301 20667 N_EQK | N_FLT, N_F_16_32 | N_U32 | N_KEY);
5287ad62 20668 inst.instruction |= (et.type == NT_float) << 8;
037e8744 20669 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20670}
20671
20672static void
20673do_neon_cls (void)
20674{
5b7c81bd 20675 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
f30ee27c
AV
20676 return;
20677
20678 enum neon_shape rs;
20679 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20680 rs = neon_select_shape (NS_QQ, NS_NULL);
20681 else
20682 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20683
5287ad62
JB
20684 struct neon_type_el et = neon_check_type (2, rs,
20685 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 20686 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20687}
20688
20689static void
20690do_neon_clz (void)
20691{
5b7c81bd 20692 if (!check_simd_pred_availability (false, NEON_CHECK_ARCH | NEON_CHECK_CC))
f30ee27c
AV
20693 return;
20694
20695 enum neon_shape rs;
20696 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20697 rs = neon_select_shape (NS_QQ, NS_NULL);
20698 else
20699 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20700
5287ad62
JB
20701 struct neon_type_el et = neon_check_type (2, rs,
20702 N_EQK, N_I8 | N_I16 | N_I32 | N_KEY);
037e8744 20703 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20704}
20705
20706static void
20707do_neon_cnt (void)
20708{
037e8744 20709 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20710 struct neon_type_el et = neon_check_type (2, rs,
20711 N_EQK | N_INT, N_8 | N_KEY);
037e8744 20712 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20713}
20714
20715static void
20716do_neon_swp (void)
20717{
037e8744 20718 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
250dd99f
AM
20719 if (rs == NS_NULL)
20720 return;
037e8744 20721 neon_two_same (neon_quad (rs), 1, -1);
5287ad62
JB
20722}
20723
20724static void
20725do_neon_tbl_tbx (void)
20726{
20727 unsigned listlenbits;
dcbf9037 20728 neon_check_type (3, NS_DLD, N_EQK, N_EQK, N_8 | N_KEY);
5f4273c7 20729
5287ad62
JB
20730 if (inst.operands[1].imm < 1 || inst.operands[1].imm > 4)
20731 {
dcbf9037 20732 first_error (_("bad list length for table lookup"));
5287ad62
JB
20733 return;
20734 }
5f4273c7 20735
5287ad62
JB
20736 listlenbits = inst.operands[1].imm - 1;
20737 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20738 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20739 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20740 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20741 inst.instruction |= LOW4 (inst.operands[2].reg);
20742 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20743 inst.instruction |= listlenbits << 8;
5f4273c7 20744
88714cb8 20745 neon_dp_fixup (&inst);
5287ad62
JB
20746}
20747
20748static void
20749do_neon_ldm_stm (void)
20750{
ef8f595f
MI
20751 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
20752 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20753 _(BAD_FPU));
5287ad62
JB
20754 /* P, U and L bits are part of bitmask. */
20755 int is_dbmode = (inst.instruction & (1 << 24)) != 0;
20756 unsigned offsetbits = inst.operands[1].imm * 2;
20757
037e8744
JB
20758 if (inst.operands[1].issingle)
20759 {
20760 do_vfp_nsyn_ldm_stm (is_dbmode);
20761 return;
20762 }
20763
5287ad62 20764 constraint (is_dbmode && !inst.operands[0].writeback,
477330fc 20765 _("writeback (!) must be used for VLDMDB and VSTMDB"));
5287ad62
JB
20766
20767 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
477330fc
RM
20768 _("register list must contain at least 1 and at most 16 "
20769 "registers"));
5287ad62
JB
20770
20771 inst.instruction |= inst.operands[0].reg << 16;
20772 inst.instruction |= inst.operands[0].writeback << 21;
20773 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
20774 inst.instruction |= HI1 (inst.operands[1].reg) << 22;
20775
20776 inst.instruction |= offsetbits;
5f4273c7 20777
037e8744 20778 do_vfp_cond_or_thumb ();
5287ad62
JB
20779}
20780
d6dc01ba
MK
20781static void
20782do_vfp_nsyn_push_pop_check (void)
20783{
20784 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd), _(BAD_FPU));
20785
20786 if (inst.operands[1].issingle)
20787 {
20788 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 32,
20789 _("register list must contain at least 1 and at most 32 registers"));
20790 }
20791 else
20792 {
20793 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
20794 _("register list must contain at least 1 and at most 16 registers"));
20795 }
20796}
20797
ef8f595f
MI
20798static void
20799do_vfp_nsyn_pop (void)
20800{
20801 nsyn_insert_sp ();
ef8f595f 20802
d6dc01ba
MK
20803 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20804 return do_vfp_nsyn_opcode ("vldm");
ef8f595f 20805
d6dc01ba 20806 do_vfp_nsyn_push_pop_check ();
ef8f595f
MI
20807
20808 if (inst.operands[1].issingle)
20809 do_vfp_nsyn_opcode ("fldmias");
20810 else
20811 do_vfp_nsyn_opcode ("fldmiad");
20812}
20813
20814static void
20815do_vfp_nsyn_push (void)
20816{
20817 nsyn_insert_sp ();
ef8f595f 20818
d6dc01ba
MK
20819 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20820 return do_vfp_nsyn_opcode ("vstmdb");
ef8f595f 20821
d6dc01ba 20822 do_vfp_nsyn_push_pop_check ();
ef8f595f
MI
20823
20824 if (inst.operands[1].issingle)
20825 do_vfp_nsyn_opcode ("fstmdbs");
20826 else
20827 do_vfp_nsyn_opcode ("fstmdbd");
20828}
20829
5287ad62
JB
20830static void
20831do_neon_ldr_str (void)
20832{
5287ad62 20833 int is_ldr = (inst.instruction & (1 << 20)) != 0;
5f4273c7 20834
6844b2c2
MGD
20835 /* Use of PC in vstr in ARM mode is deprecated in ARMv7.
20836 And is UNPREDICTABLE in thumb mode. */
fa94de6b 20837 if (!is_ldr
6844b2c2 20838 && inst.operands[1].reg == REG_PC
ba86b375 20839 && (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7) || thumb_mode))
6844b2c2 20840 {
94dcf8bf 20841 if (thumb_mode)
6844b2c2 20842 inst.error = _("Use of PC here is UNPREDICTABLE");
94dcf8bf 20843 else if (warn_on_deprecated)
5c3696f8 20844 as_tsktsk (_("Use of PC here is deprecated"));
6844b2c2
MGD
20845 }
20846
037e8744
JB
20847 if (inst.operands[0].issingle)
20848 {
cd2f129f 20849 if (is_ldr)
477330fc 20850 do_vfp_nsyn_opcode ("flds");
cd2f129f 20851 else
477330fc 20852 do_vfp_nsyn_opcode ("fsts");
9db2f6b4
RL
20853
20854 /* ARMv8.2 vldr.16/vstr.16 instruction. */
20855 if (inst.vectype.el[0].size == 16)
20856 do_scalar_fp16_v82_encode ();
5287ad62
JB
20857 }
20858 else
5287ad62 20859 {
cd2f129f 20860 if (is_ldr)
477330fc 20861 do_vfp_nsyn_opcode ("fldd");
5287ad62 20862 else
477330fc 20863 do_vfp_nsyn_opcode ("fstd");
5287ad62 20864 }
5287ad62
JB
20865}
20866
32c36c3c
AV
20867static void
20868do_t_vldr_vstr_sysreg (void)
20869{
20870 int fp_vldr_bitno = 20, sysreg_vldr_bitno = 20;
5b7c81bd 20871 bool is_vldr = ((inst.instruction & (1 << fp_vldr_bitno)) != 0);
32c36c3c
AV
20872
20873 /* Use of PC is UNPREDICTABLE. */
20874 if (inst.operands[1].reg == REG_PC)
20875 inst.error = _("Use of PC here is UNPREDICTABLE");
20876
20877 if (inst.operands[1].immisreg)
20878 inst.error = _("instruction does not accept register index");
20879
20880 if (!inst.operands[1].isreg)
20881 inst.error = _("instruction does not accept PC-relative addressing");
20882
20883 if (abs (inst.operands[1].imm) >= (1 << 7))
20884 inst.error = _("immediate value out of range");
20885
20886 inst.instruction = 0xec000f80;
20887 if (is_vldr)
20888 inst.instruction |= 1 << sysreg_vldr_bitno;
5b7c81bd 20889 encode_arm_cp_address (1, true, false, BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM);
32c36c3c
AV
20890 inst.instruction |= (inst.operands[0].imm & 0x7) << 13;
20891 inst.instruction |= (inst.operands[0].imm & 0x8) << 19;
20892}
20893
20894static void
20895do_vldr_vstr (void)
20896{
5b7c81bd 20897 bool sysreg_op = !inst.operands[0].isreg;
32c36c3c
AV
20898
20899 /* VLDR/VSTR (System Register). */
20900 if (sysreg_op)
20901 {
20902 if (!mark_feature_used (&arm_ext_v8_1m_main))
20903 as_bad (_("Instruction not permitted on this architecture"));
20904
20905 do_t_vldr_vstr_sysreg ();
20906 }
20907 /* VLDR/VSTR. */
20908 else
20909 {
ef8f595f
MI
20910 if (!mark_feature_used (&fpu_vfp_ext_v1xd)
20911 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
32c36c3c
AV
20912 as_bad (_("Instruction not permitted on this architecture"));
20913 do_neon_ldr_str ();
20914 }
20915}
20916
5287ad62
JB
20917/* "interleave" version also handles non-interleaving register VLD1/VST1
20918 instructions. */
20919
20920static void
20921do_neon_ld_st_interleave (void)
20922{
037e8744 20923 struct neon_type_el et = neon_check_type (1, NS_NULL,
477330fc 20924 N_8 | N_16 | N_32 | N_64);
5287ad62
JB
20925 unsigned alignbits = 0;
20926 unsigned idx;
20927 /* The bits in this table go:
20928 0: register stride of one (0) or two (1)
20929 1,2: register list length, minus one (1, 2, 3, 4).
20930 3,4: <n> in instruction type, minus one (VLD<n> / VST<n>).
20931 We use -1 for invalid entries. */
20932 const int typetable[] =
20933 {
20934 0x7, -1, 0xa, -1, 0x6, -1, 0x2, -1, /* VLD1 / VST1. */
20935 -1, -1, 0x8, 0x9, -1, -1, 0x3, -1, /* VLD2 / VST2. */
20936 -1, -1, -1, -1, 0x4, 0x5, -1, -1, /* VLD3 / VST3. */
20937 -1, -1, -1, -1, -1, -1, 0x0, 0x1 /* VLD4 / VST4. */
20938 };
20939 int typebits;
20940
dcbf9037
JB
20941 if (et.type == NT_invtype)
20942 return;
20943
5287ad62
JB
20944 if (inst.operands[1].immisalign)
20945 switch (inst.operands[1].imm >> 8)
20946 {
20947 case 64: alignbits = 1; break;
20948 case 128:
477330fc 20949 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2
e23c0ad8 20950 && NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
477330fc
RM
20951 goto bad_alignment;
20952 alignbits = 2;
20953 break;
5287ad62 20954 case 256:
477330fc
RM
20955 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
20956 goto bad_alignment;
20957 alignbits = 3;
20958 break;
5287ad62
JB
20959 default:
20960 bad_alignment:
477330fc
RM
20961 first_error (_("bad alignment"));
20962 return;
5287ad62
JB
20963 }
20964
20965 inst.instruction |= alignbits << 4;
20966 inst.instruction |= neon_logbits (et.size) << 6;
20967
20968 /* Bits [4:6] of the immediate in a list specifier encode register stride
20969 (minus 1) in bit 4, and list length in bits [5:6]. We put the <n> of
20970 VLD<n>/VST<n> in bits [9:8] of the initial bitmask. Suck it out here, look
20971 up the right value for "type" in a table based on this value and the given
20972 list style, then stick it back. */
20973 idx = ((inst.operands[0].imm >> 4) & 7)
477330fc 20974 | (((inst.instruction >> 8) & 3) << 3);
5287ad62
JB
20975
20976 typebits = typetable[idx];
5f4273c7 20977
5287ad62 20978 constraint (typebits == -1, _("bad list type for instruction"));
1d50d57c 20979 constraint (((inst.instruction >> 8) & 3) && et.size == 64,
35c228db 20980 BAD_EL_TYPE);
5287ad62
JB
20981
20982 inst.instruction &= ~0xf00;
20983 inst.instruction |= typebits << 8;
20984}
20985
20986/* Check alignment is valid for do_neon_ld_st_lane and do_neon_ld_dup.
20987 *DO_ALIGN is set to 1 if the relevant alignment bit should be set, 0
20988 otherwise. The variable arguments are a list of pairs of legal (size, align)
20989 values, terminated with -1. */
20990
20991static int
aa8a0863 20992neon_alignment_bit (int size, int align, int *do_alignment, ...)
5287ad62
JB
20993{
20994 va_list ap;
20995 int result = FAIL, thissize, thisalign;
5f4273c7 20996
5287ad62
JB
20997 if (!inst.operands[1].immisalign)
20998 {
aa8a0863 20999 *do_alignment = 0;
5287ad62
JB
21000 return SUCCESS;
21001 }
5f4273c7 21002
aa8a0863 21003 va_start (ap, do_alignment);
5287ad62
JB
21004
21005 do
21006 {
21007 thissize = va_arg (ap, int);
21008 if (thissize == -1)
477330fc 21009 break;
5287ad62
JB
21010 thisalign = va_arg (ap, int);
21011
21012 if (size == thissize && align == thisalign)
477330fc 21013 result = SUCCESS;
5287ad62
JB
21014 }
21015 while (result != SUCCESS);
21016
21017 va_end (ap);
21018
21019 if (result == SUCCESS)
aa8a0863 21020 *do_alignment = 1;
5287ad62 21021 else
dcbf9037 21022 first_error (_("unsupported alignment for instruction"));
5f4273c7 21023
5287ad62
JB
21024 return result;
21025}
21026
21027static void
21028do_neon_ld_st_lane (void)
21029{
037e8744 21030 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 21031 int align_good, do_alignment = 0;
5287ad62
JB
21032 int logsize = neon_logbits (et.size);
21033 int align = inst.operands[1].imm >> 8;
21034 int n = (inst.instruction >> 8) & 3;
21035 int max_el = 64 / et.size;
5f4273c7 21036
dcbf9037
JB
21037 if (et.type == NT_invtype)
21038 return;
5f4273c7 21039
5287ad62 21040 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != n + 1,
477330fc 21041 _("bad list length"));
5287ad62 21042 constraint (NEON_LANE (inst.operands[0].imm) >= max_el,
477330fc 21043 _("scalar index out of range"));
5287ad62 21044 constraint (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2
477330fc
RM
21045 && et.size == 8,
21046 _("stride of 2 unavailable when element size is 8"));
5f4273c7 21047
5287ad62
JB
21048 switch (n)
21049 {
21050 case 0: /* VLD1 / VST1. */
aa8a0863 21051 align_good = neon_alignment_bit (et.size, align, &do_alignment, 16, 16,
477330fc 21052 32, 32, -1);
5287ad62 21053 if (align_good == FAIL)
477330fc 21054 return;
aa8a0863 21055 if (do_alignment)
477330fc
RM
21056 {
21057 unsigned alignbits = 0;
21058 switch (et.size)
21059 {
21060 case 16: alignbits = 0x1; break;
21061 case 32: alignbits = 0x3; break;
21062 default: ;
21063 }
21064 inst.instruction |= alignbits << 4;
21065 }
5287ad62
JB
21066 break;
21067
21068 case 1: /* VLD2 / VST2. */
aa8a0863
TS
21069 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 16,
21070 16, 32, 32, 64, -1);
5287ad62 21071 if (align_good == FAIL)
477330fc 21072 return;
aa8a0863 21073 if (do_alignment)
477330fc 21074 inst.instruction |= 1 << 4;
5287ad62
JB
21075 break;
21076
21077 case 2: /* VLD3 / VST3. */
21078 constraint (inst.operands[1].immisalign,
477330fc 21079 _("can't use alignment with this instruction"));
5287ad62
JB
21080 break;
21081
21082 case 3: /* VLD4 / VST4. */
aa8a0863 21083 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc 21084 16, 64, 32, 64, 32, 128, -1);
5287ad62 21085 if (align_good == FAIL)
477330fc 21086 return;
aa8a0863 21087 if (do_alignment)
477330fc
RM
21088 {
21089 unsigned alignbits = 0;
21090 switch (et.size)
21091 {
21092 case 8: alignbits = 0x1; break;
21093 case 16: alignbits = 0x1; break;
21094 case 32: alignbits = (align == 64) ? 0x1 : 0x2; break;
21095 default: ;
21096 }
21097 inst.instruction |= alignbits << 4;
21098 }
5287ad62
JB
21099 break;
21100
21101 default: ;
21102 }
21103
21104 /* Reg stride of 2 is encoded in bit 5 when size==16, bit 6 when size==32. */
21105 if (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2)
21106 inst.instruction |= 1 << (4 + logsize);
5f4273c7 21107
5287ad62
JB
21108 inst.instruction |= NEON_LANE (inst.operands[0].imm) << (logsize + 5);
21109 inst.instruction |= logsize << 10;
21110}
21111
21112/* Encode single n-element structure to all lanes VLD<n> instructions. */
21113
21114static void
21115do_neon_ld_dup (void)
21116{
037e8744 21117 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 21118 int align_good, do_alignment = 0;
5287ad62 21119
dcbf9037
JB
21120 if (et.type == NT_invtype)
21121 return;
21122
5287ad62
JB
21123 switch ((inst.instruction >> 8) & 3)
21124 {
21125 case 0: /* VLD1. */
9c2799c2 21126 gas_assert (NEON_REG_STRIDE (inst.operands[0].imm) != 2);
5287ad62 21127 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863 21128 &do_alignment, 16, 16, 32, 32, -1);
5287ad62 21129 if (align_good == FAIL)
477330fc 21130 return;
5287ad62 21131 switch (NEON_REGLIST_LENGTH (inst.operands[0].imm))
477330fc
RM
21132 {
21133 case 1: break;
21134 case 2: inst.instruction |= 1 << 5; break;
21135 default: first_error (_("bad list length")); return;
21136 }
5287ad62
JB
21137 inst.instruction |= neon_logbits (et.size) << 6;
21138 break;
21139
21140 case 1: /* VLD2. */
21141 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863
TS
21142 &do_alignment, 8, 16, 16, 32, 32, 64,
21143 -1);
5287ad62 21144 if (align_good == FAIL)
477330fc 21145 return;
5287ad62 21146 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2,
477330fc 21147 _("bad list length"));
5287ad62 21148 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 21149 inst.instruction |= 1 << 5;
5287ad62
JB
21150 inst.instruction |= neon_logbits (et.size) << 6;
21151 break;
21152
21153 case 2: /* VLD3. */
21154 constraint (inst.operands[1].immisalign,
477330fc 21155 _("can't use alignment with this instruction"));
5287ad62 21156 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 3,
477330fc 21157 _("bad list length"));
5287ad62 21158 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 21159 inst.instruction |= 1 << 5;
5287ad62
JB
21160 inst.instruction |= neon_logbits (et.size) << 6;
21161 break;
21162
21163 case 3: /* VLD4. */
21164 {
477330fc 21165 int align = inst.operands[1].imm >> 8;
aa8a0863 21166 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc
RM
21167 16, 64, 32, 64, 32, 128, -1);
21168 if (align_good == FAIL)
21169 return;
21170 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4,
21171 _("bad list length"));
21172 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
21173 inst.instruction |= 1 << 5;
21174 if (et.size == 32 && align == 128)
21175 inst.instruction |= 0x3 << 6;
21176 else
21177 inst.instruction |= neon_logbits (et.size) << 6;
5287ad62
JB
21178 }
21179 break;
21180
21181 default: ;
21182 }
21183
aa8a0863 21184 inst.instruction |= do_alignment << 4;
5287ad62
JB
21185}
21186
21187/* Disambiguate VLD<n> and VST<n> instructions, and fill in common bits (those
21188 apart from bits [11:4]. */
21189
21190static void
21191do_neon_ldx_stx (void)
21192{
b1a769ed
DG
21193 if (inst.operands[1].isreg)
21194 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
21195
5287ad62
JB
21196 switch (NEON_LANE (inst.operands[0].imm))
21197 {
21198 case NEON_INTERLEAVE_LANES:
88714cb8 21199 NEON_ENCODE (INTERLV, inst);
5287ad62
JB
21200 do_neon_ld_st_interleave ();
21201 break;
5f4273c7 21202
5287ad62 21203 case NEON_ALL_LANES:
88714cb8 21204 NEON_ENCODE (DUP, inst);
2d51fb74
JB
21205 if (inst.instruction == N_INV)
21206 {
21207 first_error ("only loads support such operands");
21208 break;
21209 }
5287ad62
JB
21210 do_neon_ld_dup ();
21211 break;
5f4273c7 21212
5287ad62 21213 default:
88714cb8 21214 NEON_ENCODE (LANE, inst);
5287ad62
JB
21215 do_neon_ld_st_lane ();
21216 }
21217
21218 /* L bit comes from bit mask. */
21219 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21220 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21221 inst.instruction |= inst.operands[1].reg << 16;
5f4273c7 21222
5287ad62
JB
21223 if (inst.operands[1].postind)
21224 {
21225 int postreg = inst.operands[1].imm & 0xf;
21226 constraint (!inst.operands[1].immisreg,
477330fc 21227 _("post-index must be a register"));
5287ad62 21228 constraint (postreg == 0xd || postreg == 0xf,
477330fc 21229 _("bad register for post-index"));
5287ad62
JB
21230 inst.instruction |= postreg;
21231 }
4f2374c7 21232 else
5287ad62 21233 {
4f2374c7 21234 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
e2b0ab59
AV
21235 constraint (inst.relocs[0].exp.X_op != O_constant
21236 || inst.relocs[0].exp.X_add_number != 0,
4f2374c7
WN
21237 BAD_ADDR_MODE);
21238
21239 if (inst.operands[1].writeback)
21240 {
21241 inst.instruction |= 0xd;
21242 }
21243 else
21244 inst.instruction |= 0xf;
5287ad62 21245 }
5f4273c7 21246
5287ad62
JB
21247 if (thumb_mode)
21248 inst.instruction |= 0xf9000000;
21249 else
21250 inst.instruction |= 0xf4000000;
21251}
33399f07
MGD
21252
21253/* FP v8. */
21254static void
21255do_vfp_nsyn_fpv8 (enum neon_shape rs)
21256{
a715796b
TG
21257 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
21258 D register operands. */
21259 if (neon_shape_class[rs] == SC_DOUBLE)
21260 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
21261 _(BAD_FPU));
21262
33399f07
MGD
21263 NEON_ENCODE (FPV8, inst);
21264
9db2f6b4
RL
21265 if (rs == NS_FFF || rs == NS_HHH)
21266 {
21267 do_vfp_sp_dyadic ();
21268
21269 /* ARMv8.2 fp16 instruction. */
21270 if (rs == NS_HHH)
21271 do_scalar_fp16_v82_encode ();
21272 }
33399f07
MGD
21273 else
21274 do_vfp_dp_rd_rn_rm ();
21275
21276 if (rs == NS_DDD)
21277 inst.instruction |= 0x100;
21278
21279 inst.instruction |= 0xf0000000;
21280}
21281
21282static void
21283do_vsel (void)
21284{
5ee91343 21285 set_pred_insn_type (OUTSIDE_PRED_INSN);
33399f07
MGD
21286
21287 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
21288 first_error (_("invalid instruction shape"));
21289}
21290
73924fbc
MGD
21291static void
21292do_vmaxnm (void)
21293{
935295b5
AV
21294 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
21295 set_pred_insn_type (OUTSIDE_PRED_INSN);
73924fbc
MGD
21296
21297 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
21298 return;
21299
5b7c81bd 21300 if (!check_simd_pred_availability (true, NEON_CHECK_CC | NEON_CHECK_ARCH8))
73924fbc
MGD
21301 return;
21302
cc933301 21303 neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
73924fbc
MGD
21304}
21305
30bdf752
MGD
21306static void
21307do_vrint_1 (enum neon_cvt_mode mode)
21308{
9db2f6b4 21309 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_QQ, NS_NULL);
30bdf752
MGD
21310 struct neon_type_el et;
21311
21312 if (rs == NS_NULL)
21313 return;
21314
a715796b
TG
21315 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
21316 D register operands. */
21317 if (neon_shape_class[rs] == SC_DOUBLE)
21318 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
21319 _(BAD_FPU));
21320
9db2f6b4
RL
21321 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY
21322 | N_VFP);
30bdf752
MGD
21323 if (et.type != NT_invtype)
21324 {
21325 /* VFP encodings. */
21326 if (mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
21327 || mode == neon_cvt_mode_p || mode == neon_cvt_mode_m)
5ee91343 21328 set_pred_insn_type (OUTSIDE_PRED_INSN);
30bdf752
MGD
21329
21330 NEON_ENCODE (FPV8, inst);
9db2f6b4 21331 if (rs == NS_FF || rs == NS_HH)
30bdf752
MGD
21332 do_vfp_sp_monadic ();
21333 else
21334 do_vfp_dp_rd_rm ();
21335
21336 switch (mode)
21337 {
21338 case neon_cvt_mode_r: inst.instruction |= 0x00000000; break;
21339 case neon_cvt_mode_z: inst.instruction |= 0x00000080; break;
21340 case neon_cvt_mode_x: inst.instruction |= 0x00010000; break;
21341 case neon_cvt_mode_a: inst.instruction |= 0xf0000000; break;
21342 case neon_cvt_mode_n: inst.instruction |= 0xf0010000; break;
21343 case neon_cvt_mode_p: inst.instruction |= 0xf0020000; break;
21344 case neon_cvt_mode_m: inst.instruction |= 0xf0030000; break;
21345 default: abort ();
21346 }
21347
21348 inst.instruction |= (rs == NS_DD) << 8;
21349 do_vfp_cond_or_thumb ();
9db2f6b4
RL
21350
21351 /* ARMv8.2 fp16 vrint instruction. */
21352 if (rs == NS_HH)
21353 do_scalar_fp16_v82_encode ();
30bdf752
MGD
21354 }
21355 else
21356 {
21357 /* Neon encodings (or something broken...). */
21358 inst.error = NULL;
cc933301 21359 et = neon_check_type (2, rs, N_EQK, N_F_16_32 | N_KEY);
30bdf752
MGD
21360
21361 if (et.type == NT_invtype)
21362 return;
21363
5b7c81bd 21364 if (!check_simd_pred_availability (true,
64c350f2 21365 NEON_CHECK_CC | NEON_CHECK_ARCH8))
30bdf752
MGD
21366 return;
21367
a710b305
AV
21368 NEON_ENCODE (FLOAT, inst);
21369
30bdf752
MGD
21370 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21371 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21372 inst.instruction |= LOW4 (inst.operands[1].reg);
21373 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
21374 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
21375 /* Mask off the original size bits and reencode them. */
21376 inst.instruction = ((inst.instruction & 0xfff3ffff)
21377 | neon_logbits (et.size) << 18);
21378
30bdf752
MGD
21379 switch (mode)
21380 {
21381 case neon_cvt_mode_z: inst.instruction |= 3 << 7; break;
21382 case neon_cvt_mode_x: inst.instruction |= 1 << 7; break;
21383 case neon_cvt_mode_a: inst.instruction |= 2 << 7; break;
21384 case neon_cvt_mode_n: inst.instruction |= 0 << 7; break;
21385 case neon_cvt_mode_p: inst.instruction |= 7 << 7; break;
21386 case neon_cvt_mode_m: inst.instruction |= 5 << 7; break;
21387 case neon_cvt_mode_r: inst.error = _("invalid rounding mode"); break;
21388 default: abort ();
21389 }
21390
21391 if (thumb_mode)
21392 inst.instruction |= 0xfc000000;
21393 else
21394 inst.instruction |= 0xf0000000;
21395 }
21396}
21397
21398static void
21399do_vrintx (void)
21400{
21401 do_vrint_1 (neon_cvt_mode_x);
21402}
21403
21404static void
21405do_vrintz (void)
21406{
21407 do_vrint_1 (neon_cvt_mode_z);
21408}
21409
21410static void
21411do_vrintr (void)
21412{
21413 do_vrint_1 (neon_cvt_mode_r);
21414}
21415
21416static void
21417do_vrinta (void)
21418{
21419 do_vrint_1 (neon_cvt_mode_a);
21420}
21421
21422static void
21423do_vrintn (void)
21424{
21425 do_vrint_1 (neon_cvt_mode_n);
21426}
21427
21428static void
21429do_vrintp (void)
21430{
21431 do_vrint_1 (neon_cvt_mode_p);
21432}
21433
21434static void
21435do_vrintm (void)
21436{
21437 do_vrint_1 (neon_cvt_mode_m);
21438}
21439
c28eeff2
SN
21440static unsigned
21441neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
21442{
21443 unsigned regno = NEON_SCALAR_REG (opnd);
21444 unsigned elno = NEON_SCALAR_INDEX (opnd);
21445
21446 if (elsize == 16 && elno < 2 && regno < 16)
21447 return regno | (elno << 4);
21448 else if (elsize == 32 && elno == 0)
21449 return regno;
21450
21451 first_error (_("scalar out of range"));
21452 return 0;
21453}
21454
21455static void
21456do_vcmla (void)
21457{
5d281bf0
AV
21458 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext)
21459 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
21460 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
21461 constraint (inst.relocs[0].exp.X_op != O_constant,
21462 _("expression too complex"));
21463 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
21464 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
21465 _("immediate out of range"));
21466 rot /= 90;
5d281bf0 21467
5b7c81bd 21468 if (!check_simd_pred_availability (true,
64c350f2 21469 NEON_CHECK_ARCH8 | NEON_CHECK_CC))
5d281bf0
AV
21470 return;
21471
c28eeff2
SN
21472 if (inst.operands[2].isscalar)
21473 {
5d281bf0
AV
21474 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
21475 first_error (_("invalid instruction shape"));
c28eeff2
SN
21476 enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
21477 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
21478 N_KEY | N_F16 | N_F32).size;
21479 unsigned m = neon_scalar_for_vcmla (inst.operands[2].reg, size);
21480 inst.is_neon = 1;
21481 inst.instruction = 0xfe000800;
21482 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21483 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21484 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
21485 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
21486 inst.instruction |= LOW4 (m);
21487 inst.instruction |= HI1 (m) << 5;
21488 inst.instruction |= neon_quad (rs) << 6;
21489 inst.instruction |= rot << 20;
21490 inst.instruction |= (size == 32) << 23;
21491 }
21492 else
21493 {
5d281bf0
AV
21494 enum neon_shape rs;
21495 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
21496 rs = neon_select_shape (NS_QQQI, NS_NULL);
21497 else
21498 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
21499
c28eeff2
SN
21500 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
21501 N_KEY | N_F16 | N_F32).size;
5d281bf0
AV
21502 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext) && size == 32
21503 && (inst.operands[0].reg == inst.operands[1].reg
21504 || inst.operands[0].reg == inst.operands[2].reg))
21505 as_tsktsk (BAD_MVE_SRCDEST);
21506
c28eeff2
SN
21507 neon_three_same (neon_quad (rs), 0, -1);
21508 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
21509 inst.instruction |= 0xfc200800;
21510 inst.instruction |= rot << 23;
21511 inst.instruction |= (size == 32) << 20;
21512 }
21513}
21514
21515static void
21516do_vcadd (void)
21517{
5d281bf0
AV
21518 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
21519 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
21520 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
21521 constraint (inst.relocs[0].exp.X_op != O_constant,
21522 _("expression too complex"));
5d281bf0 21523
e2b0ab59 21524 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2 21525 constraint (rot != 90 && rot != 270, _("immediate out of range"));
5d281bf0
AV
21526 enum neon_shape rs;
21527 struct neon_type_el et;
21528 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
21529 {
21530 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
21531 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32);
21532 }
21533 else
21534 {
21535 rs = neon_select_shape (NS_QQQI, NS_NULL);
21536 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32 | N_I8
21537 | N_I16 | N_I32);
21538 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
21539 as_tsktsk (_("Warning: 32-bit element size and same first and third "
21540 "operand makes instruction UNPREDICTABLE"));
21541 }
21542
21543 if (et.type == NT_invtype)
21544 return;
21545
64c350f2
AV
21546 if (!check_simd_pred_availability (et.type == NT_float,
21547 NEON_CHECK_ARCH8 | NEON_CHECK_CC))
5d281bf0
AV
21548 return;
21549
21550 if (et.type == NT_float)
21551 {
21552 neon_three_same (neon_quad (rs), 0, -1);
21553 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
21554 inst.instruction |= 0xfc800800;
21555 inst.instruction |= (rot == 270) << 24;
21556 inst.instruction |= (et.size == 32) << 20;
21557 }
21558 else
21559 {
21560 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
21561 inst.instruction = 0xfe000f00;
21562 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21563 inst.instruction |= neon_logbits (et.size) << 20;
21564 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
21565 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21566 inst.instruction |= (rot == 270) << 12;
21567 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
21568 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
21569 inst.instruction |= LOW4 (inst.operands[2].reg);
21570 inst.is_neon = 1;
21571 }
c28eeff2
SN
21572}
21573
c604a79a
JW
21574/* Dot Product instructions encoding support. */
21575
21576static void
21577do_neon_dotproduct (int unsigned_p)
21578{
21579 enum neon_shape rs;
21580 unsigned scalar_oprd2 = 0;
21581 int high8;
21582
21583 if (inst.cond != COND_ALWAYS)
21584 as_warn (_("Dot Product instructions cannot be conditional, the behaviour "
21585 "is UNPREDICTABLE"));
21586
21587 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
21588 _(BAD_FPU));
21589
21590 /* Dot Product instructions are in three-same D/Q register format or the third
21591 operand can be a scalar index register. */
21592 if (inst.operands[2].isscalar)
21593 {
21594 scalar_oprd2 = neon_scalar_for_mul (inst.operands[2].reg, 32);
21595 high8 = 0xfe000000;
21596 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21597 }
21598 else
21599 {
21600 high8 = 0xfc000000;
21601 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
21602 }
21603
21604 if (unsigned_p)
21605 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_U8);
21606 else
21607 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_S8);
21608
21609 /* The "U" bit in traditional Three Same encoding is fixed to 0 for Dot
21610 Product instruction, so we pass 0 as the "ubit" parameter. And the
21611 "Size" field are fixed to 0x2, so we pass 32 as the "size" parameter. */
21612 neon_three_same (neon_quad (rs), 0, 32);
21613
21614 /* Undo neon_dp_fixup. Dot Product instructions are using a slightly
21615 different NEON three-same encoding. */
21616 inst.instruction &= 0x00ffffff;
21617 inst.instruction |= high8;
21618 /* Encode 'U' bit which indicates signedness. */
21619 inst.instruction |= (unsigned_p ? 1 : 0) << 4;
21620 /* Re-encode operand2 if it's indexed scalar operand. What has been encoded
21621 from inst.operand[2].reg in neon_three_same is GAS's internal encoding, not
21622 the instruction encoding. */
21623 if (inst.operands[2].isscalar)
21624 {
21625 inst.instruction &= 0xffffffd0;
21626 inst.instruction |= LOW4 (scalar_oprd2);
21627 inst.instruction |= HI1 (scalar_oprd2) << 5;
21628 }
21629}
21630
21631/* Dot Product instructions for signed integer. */
21632
21633static void
21634do_neon_dotproduct_s (void)
21635{
21636 return do_neon_dotproduct (0);
21637}
21638
21639/* Dot Product instructions for unsigned integer. */
21640
21641static void
21642do_neon_dotproduct_u (void)
21643{
21644 return do_neon_dotproduct (1);
21645}
21646
616ce08e
MM
21647static void
21648do_vusdot (void)
21649{
21650 enum neon_shape rs;
21651 set_pred_insn_type (OUTSIDE_PRED_INSN);
21652 if (inst.operands[2].isscalar)
21653 {
21654 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21655 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21656
21657 inst.instruction |= (1 << 25);
1db66fb6
JB
21658 int idx = inst.operands[2].reg & 0xf;
21659 constraint ((idx != 1 && idx != 0), _("index must be 0 or 1"));
616ce08e
MM
21660 inst.operands[2].reg >>= 4;
21661 constraint (!(inst.operands[2].reg < 16),
21662 _("indexed register must be less than 16"));
21663 neon_three_args (rs == NS_QQS);
1db66fb6 21664 inst.instruction |= (idx << 5);
616ce08e
MM
21665 }
21666 else
21667 {
21668 inst.instruction |= (1 << 21);
21669 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
21670 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21671 neon_three_args (rs == NS_QQQ);
21672 }
21673}
21674
21675static void
21676do_vsudot (void)
21677{
21678 enum neon_shape rs;
21679 set_pred_insn_type (OUTSIDE_PRED_INSN);
21680 if (inst.operands[2].isscalar)
21681 {
21682 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21683 neon_check_type (3, rs, N_EQK, N_EQK, N_U8 | N_KEY);
21684
21685 inst.instruction |= (1 << 25);
1db66fb6
JB
21686 int idx = inst.operands[2].reg & 0xf;
21687 constraint ((idx != 1 && idx != 0), _("index must be 0 or 1"));
616ce08e
MM
21688 inst.operands[2].reg >>= 4;
21689 constraint (!(inst.operands[2].reg < 16),
21690 _("indexed register must be less than 16"));
21691 neon_three_args (rs == NS_QQS);
1db66fb6 21692 inst.instruction |= (idx << 5);
616ce08e
MM
21693 }
21694}
21695
21696static void
21697do_vsmmla (void)
21698{
21699 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
21700 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21701
21702 set_pred_insn_type (OUTSIDE_PRED_INSN);
21703
21704 neon_three_args (1);
21705
21706}
21707
21708static void
21709do_vummla (void)
21710{
21711 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
21712 neon_check_type (3, rs, N_EQK, N_EQK, N_U8 | N_KEY);
21713
21714 set_pred_insn_type (OUTSIDE_PRED_INSN);
21715
21716 neon_three_args (1);
21717
21718}
21719
4934a27c 21720static void
1db66fb6 21721check_cde_operand (size_t idx, int is_dual)
4934a27c 21722{
1db66fb6
JB
21723 unsigned Rx = inst.operands[idx].reg;
21724 bool isvec = inst.operands[idx].isvec;
4934a27c
MM
21725 if (is_dual == 0 && thumb_mode)
21726 constraint (
21727 !((Rx <= 14 && Rx != 13) || (Rx == REG_PC && isvec)),
21728 _("Register must be r0-r14 except r13, or APSR_nzcv."));
21729 else
21730 constraint ( !((Rx <= 10 && Rx % 2 == 0 )),
21731 _("Register must be an even register between r0-r10."));
21732}
21733
5b7c81bd 21734static bool
4934a27c
MM
21735cde_coproc_enabled (unsigned coproc)
21736{
21737 switch (coproc)
21738 {
21739 case 0: return mark_feature_used (&arm_ext_cde0);
21740 case 1: return mark_feature_used (&arm_ext_cde1);
21741 case 2: return mark_feature_used (&arm_ext_cde2);
21742 case 3: return mark_feature_used (&arm_ext_cde3);
21743 case 4: return mark_feature_used (&arm_ext_cde4);
21744 case 5: return mark_feature_used (&arm_ext_cde5);
21745 case 6: return mark_feature_used (&arm_ext_cde6);
21746 case 7: return mark_feature_used (&arm_ext_cde7);
5b7c81bd 21747 default: return false;
4934a27c
MM
21748 }
21749}
21750
21751#define cde_coproc_pos 8
21752static void
21753cde_handle_coproc (void)
21754{
21755 unsigned coproc = inst.operands[0].reg;
21756 constraint (coproc > 7, _("CDE Coprocessor must be in range 0-7"));
21757 constraint (!(cde_coproc_enabled (coproc)), BAD_CDE_COPROC);
21758 inst.instruction |= coproc << cde_coproc_pos;
21759}
21760#undef cde_coproc_pos
21761
21762static void
5b7c81bd 21763cxn_handle_predication (bool is_accum)
4934a27c 21764{
cceb53b8
MM
21765 if (is_accum && conditional_insn ())
21766 set_pred_insn_type (INSIDE_IT_INSN);
21767 else if (conditional_insn ())
21768 /* conditional_insn essentially checks for a suffix, not whether the
21769 instruction is inside an IT block or not.
21770 The non-accumulator versions should not have suffixes. */
4934a27c 21771 inst.error = BAD_SYNTAX;
4934a27c
MM
21772 else
21773 set_pred_insn_type (OUTSIDE_PRED_INSN);
21774}
21775
21776static void
5b7c81bd 21777do_custom_instruction_1 (int is_dual, bool is_accum)
4934a27c
MM
21778{
21779
21780 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21781
21782 unsigned imm, Rd;
21783
21784 Rd = inst.operands[1].reg;
21785 check_cde_operand (1, is_dual);
21786
21787 if (is_dual == 1)
21788 {
21789 constraint (inst.operands[2].reg != Rd + 1,
21790 _("cx1d requires consecutive destination registers."));
21791 imm = inst.operands[3].imm;
21792 }
21793 else if (is_dual == 0)
21794 imm = inst.operands[2].imm;
21795 else
21796 abort ();
21797
21798 inst.instruction |= Rd << 12;
21799 inst.instruction |= (imm & 0x1F80) << 9;
21800 inst.instruction |= (imm & 0x0040) << 1;
21801 inst.instruction |= (imm & 0x003f);
21802
21803 cde_handle_coproc ();
21804 cxn_handle_predication (is_accum);
21805}
21806
21807static void
5b7c81bd 21808do_custom_instruction_2 (int is_dual, bool is_accum)
4934a27c
MM
21809{
21810
21811 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21812
21813 unsigned imm, Rd, Rn;
21814
21815 Rd = inst.operands[1].reg;
21816
21817 if (is_dual == 1)
21818 {
21819 constraint (inst.operands[2].reg != Rd + 1,
21820 _("cx2d requires consecutive destination registers."));
21821 imm = inst.operands[4].imm;
21822 Rn = inst.operands[3].reg;
21823 }
21824 else if (is_dual == 0)
21825 {
21826 imm = inst.operands[3].imm;
21827 Rn = inst.operands[2].reg;
21828 }
21829 else
21830 abort ();
21831
21832 check_cde_operand (2 + is_dual, /* is_dual = */0);
21833 check_cde_operand (1, is_dual);
21834
21835 inst.instruction |= Rd << 12;
21836 inst.instruction |= Rn << 16;
21837
21838 inst.instruction |= (imm & 0x0380) << 13;
21839 inst.instruction |= (imm & 0x0040) << 1;
21840 inst.instruction |= (imm & 0x003f);
21841
21842 cde_handle_coproc ();
21843 cxn_handle_predication (is_accum);
21844}
21845
21846static void
5b7c81bd 21847do_custom_instruction_3 (int is_dual, bool is_accum)
4934a27c
MM
21848{
21849
21850 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21851
21852 unsigned imm, Rd, Rn, Rm;
21853
21854 Rd = inst.operands[1].reg;
21855
21856 if (is_dual == 1)
21857 {
21858 constraint (inst.operands[2].reg != Rd + 1,
21859 _("cx3d requires consecutive destination registers."));
21860 imm = inst.operands[5].imm;
21861 Rn = inst.operands[3].reg;
21862 Rm = inst.operands[4].reg;
21863 }
21864 else if (is_dual == 0)
21865 {
21866 imm = inst.operands[4].imm;
21867 Rn = inst.operands[2].reg;
21868 Rm = inst.operands[3].reg;
21869 }
21870 else
21871 abort ();
21872
21873 check_cde_operand (1, is_dual);
21874 check_cde_operand (2 + is_dual, /* is_dual = */0);
21875 check_cde_operand (3 + is_dual, /* is_dual = */0);
21876
21877 inst.instruction |= Rd;
21878 inst.instruction |= Rn << 16;
21879 inst.instruction |= Rm << 12;
21880
21881 inst.instruction |= (imm & 0x0038) << 17;
21882 inst.instruction |= (imm & 0x0004) << 5;
21883 inst.instruction |= (imm & 0x0003) << 4;
21884
21885 cde_handle_coproc ();
21886 cxn_handle_predication (is_accum);
21887}
21888
21889static void
21890do_cx1 (void)
21891{
21892 return do_custom_instruction_1 (0, 0);
21893}
21894
21895static void
21896do_cx1a (void)
21897{
21898 return do_custom_instruction_1 (0, 1);
21899}
21900
21901static void
21902do_cx1d (void)
21903{
21904 return do_custom_instruction_1 (1, 0);
21905}
21906
21907static void
21908do_cx1da (void)
21909{
21910 return do_custom_instruction_1 (1, 1);
21911}
21912
21913static void
21914do_cx2 (void)
21915{
21916 return do_custom_instruction_2 (0, 0);
21917}
21918
21919static void
21920do_cx2a (void)
21921{
21922 return do_custom_instruction_2 (0, 1);
21923}
21924
21925static void
21926do_cx2d (void)
21927{
21928 return do_custom_instruction_2 (1, 0);
21929}
21930
21931static void
21932do_cx2da (void)
21933{
21934 return do_custom_instruction_2 (1, 1);
21935}
21936
21937static void
21938do_cx3 (void)
21939{
21940 return do_custom_instruction_3 (0, 0);
21941}
21942
21943static void
21944do_cx3a (void)
21945{
21946 return do_custom_instruction_3 (0, 1);
21947}
21948
21949static void
21950do_cx3d (void)
21951{
21952 return do_custom_instruction_3 (1, 0);
21953}
21954
21955static void
21956do_cx3da (void)
21957{
21958 return do_custom_instruction_3 (1, 1);
21959}
21960
5aae9ae9
MM
21961static void
21962vcx_assign_vec_d (unsigned regnum)
21963{
21964 inst.instruction |= HI4 (regnum) << 12;
21965 inst.instruction |= LOW1 (regnum) << 22;
21966}
21967
21968static void
21969vcx_assign_vec_m (unsigned regnum)
21970{
21971 inst.instruction |= HI4 (regnum);
21972 inst.instruction |= LOW1 (regnum) << 5;
21973}
21974
21975static void
21976vcx_assign_vec_n (unsigned regnum)
21977{
21978 inst.instruction |= HI4 (regnum) << 16;
21979 inst.instruction |= LOW1 (regnum) << 7;
21980}
21981
21982enum vcx_reg_type {
21983 q_reg,
21984 d_reg,
21985 s_reg
21986};
21987
21988static enum vcx_reg_type
21989vcx_get_reg_type (enum neon_shape ns)
21990{
21991 gas_assert (ns == NS_PQI
21992 || ns == NS_PDI
21993 || ns == NS_PFI
21994 || ns == NS_PQQI
21995 || ns == NS_PDDI
21996 || ns == NS_PFFI
21997 || ns == NS_PQQQI
21998 || ns == NS_PDDDI
21999 || ns == NS_PFFFI);
22000 if (ns == NS_PQI || ns == NS_PQQI || ns == NS_PQQQI)
22001 return q_reg;
22002 if (ns == NS_PDI || ns == NS_PDDI || ns == NS_PDDDI)
22003 return d_reg;
22004 return s_reg;
22005}
22006
22007#define vcx_size_pos 24
22008#define vcx_vec_pos 6
22009static unsigned
22010vcx_handle_shape (enum vcx_reg_type reg_type)
22011{
22012 unsigned mult = 2;
22013 if (reg_type == q_reg)
22014 inst.instruction |= 1 << vcx_vec_pos;
22015 else if (reg_type == d_reg)
22016 inst.instruction |= 1 << vcx_size_pos;
22017 else
22018 mult = 1;
22019 /* NOTE:
22020 The documentation says that the Q registers are encoded as 2*N in the D:Vd
22021 bits (or equivalent for N and M registers).
22022 Similarly the D registers are encoded as N in D:Vd bits.
22023 While the S registers are encoded as N in the Vd:D bits.
22024
22025 Taking into account the maximum values of these registers we can see a
22026 nicer pattern for calculation:
22027 Q -> 7, D -> 15, S -> 31
22028
22029 If we say that everything is encoded in the Vd:D bits, then we can say
22030 that Q is encoded as 4*N, and D is encoded as 2*N.
22031 This way the bits will end up the same, and calculation is simpler.
22032 (calculation is now:
22033 1. Multiply by a number determined by the register letter.
22034 2. Encode resulting number in Vd:D bits.)
22035
22036 This is made a little more complicated by automatic handling of 'Q'
22037 registers elsewhere, which means the register number is already 2*N where
22038 N is the number the user wrote after the register letter.
22039 */
22040 return mult;
22041}
22042#undef vcx_vec_pos
22043#undef vcx_size_pos
22044
22045static void
22046vcx_ensure_register_in_range (unsigned R, enum vcx_reg_type reg_type)
22047{
22048 if (reg_type == q_reg)
22049 {
22050 gas_assert (R % 2 == 0);
22051 constraint (R >= 16, _("'q' register must be in range 0-7"));
22052 }
22053 else if (reg_type == d_reg)
22054 constraint (R >= 16, _("'d' register must be in range 0-15"));
22055 else
22056 constraint (R >= 32, _("'s' register must be in range 0-31"));
22057}
22058
22059static void (*vcx_assign_vec[3]) (unsigned) = {
22060 vcx_assign_vec_d,
22061 vcx_assign_vec_m,
22062 vcx_assign_vec_n
22063};
22064
22065static void
22066vcx_handle_register_arguments (unsigned num_registers,
22067 enum vcx_reg_type reg_type)
22068{
1ed818b4 22069 unsigned R, i;
5aae9ae9 22070 unsigned reg_mult = vcx_handle_shape (reg_type);
1ed818b4 22071 for (i = 0; i < num_registers; i++)
5aae9ae9
MM
22072 {
22073 R = inst.operands[i+1].reg;
22074 vcx_ensure_register_in_range (R, reg_type);
22075 if (num_registers == 3 && i > 0)
22076 {
22077 if (i == 2)
22078 vcx_assign_vec[1] (R * reg_mult);
22079 else
22080 vcx_assign_vec[2] (R * reg_mult);
22081 continue;
22082 }
22083 vcx_assign_vec[i](R * reg_mult);
22084 }
22085}
22086
22087static void
22088vcx_handle_insn_block (enum vcx_reg_type reg_type)
22089{
22090 if (reg_type == q_reg)
22091 if (inst.cond > COND_ALWAYS)
22092 inst.pred_insn_type = INSIDE_VPT_INSN;
22093 else
22094 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
22095 else if (inst.cond == COND_ALWAYS)
22096 inst.pred_insn_type = OUTSIDE_PRED_INSN;
22097 else
22098 inst.error = BAD_NOT_IT;
22099}
22100
22101static void
22102vcx_handle_common_checks (unsigned num_args, enum neon_shape rs)
22103{
22104 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
22105 cde_handle_coproc ();
22106 enum vcx_reg_type reg_type = vcx_get_reg_type (rs);
22107 vcx_handle_register_arguments (num_args, reg_type);
22108 vcx_handle_insn_block (reg_type);
22109 if (reg_type == q_reg)
22110 constraint (!mark_feature_used (&mve_ext),
22111 _("vcx instructions with Q registers require MVE"));
22112 else
22113 constraint (!(ARM_FSET_CPU_SUBSET (armv8m_fp, cpu_variant)
22114 && mark_feature_used (&armv8m_fp))
22115 && !mark_feature_used (&mve_ext),
22116 _("vcx instructions with S or D registers require either MVE"
ddc73fa9 22117 " or Armv8-M floating point extension."));
5aae9ae9
MM
22118}
22119
22120static void
22121do_vcx1 (void)
22122{
22123 enum neon_shape rs = neon_select_shape (NS_PQI, NS_PDI, NS_PFI, NS_NULL);
22124 vcx_handle_common_checks (1, rs);
22125
22126 unsigned imm = inst.operands[2].imm;
22127 inst.instruction |= (imm & 0x03f);
22128 inst.instruction |= (imm & 0x040) << 1;
22129 inst.instruction |= (imm & 0x780) << 9;
22130 if (rs != NS_PQI)
22131 constraint (imm >= 2048,
22132 _("vcx1 with S or D registers takes immediate within 0-2047"));
22133 inst.instruction |= (imm & 0x800) << 13;
22134}
22135
22136static void
22137do_vcx2 (void)
22138{
22139 enum neon_shape rs = neon_select_shape (NS_PQQI, NS_PDDI, NS_PFFI, NS_NULL);
22140 vcx_handle_common_checks (2, rs);
22141
22142 unsigned imm = inst.operands[3].imm;
22143 inst.instruction |= (imm & 0x01) << 4;
22144 inst.instruction |= (imm & 0x02) << 6;
22145 inst.instruction |= (imm & 0x3c) << 14;
22146 if (rs != NS_PQQI)
22147 constraint (imm >= 64,
22148 _("vcx2 with S or D registers takes immediate within 0-63"));
22149 inst.instruction |= (imm & 0x40) << 18;
22150}
22151
22152static void
22153do_vcx3 (void)
22154{
22155 enum neon_shape rs = neon_select_shape (NS_PQQQI, NS_PDDDI, NS_PFFFI, NS_NULL);
22156 vcx_handle_common_checks (3, rs);
22157
22158 unsigned imm = inst.operands[4].imm;
22159 inst.instruction |= (imm & 0x1) << 4;
22160 inst.instruction |= (imm & 0x6) << 19;
22161 if (rs != NS_PQQQI)
22162 constraint (imm >= 8,
22163 _("vcx2 with S or D registers takes immediate within 0-7"));
22164 inst.instruction |= (imm & 0x8) << 21;
22165}
22166
91ff7894
MGD
22167/* Crypto v1 instructions. */
22168static void
22169do_crypto_2op_1 (unsigned elttype, int op)
22170{
5ee91343 22171 set_pred_insn_type (OUTSIDE_PRED_INSN);
91ff7894
MGD
22172
22173 if (neon_check_type (2, NS_QQ, N_EQK | N_UNT, elttype | N_UNT | N_KEY).type
22174 == NT_invtype)
22175 return;
22176
22177 inst.error = NULL;
22178
22179 NEON_ENCODE (INTEGER, inst);
22180 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
22181 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
22182 inst.instruction |= LOW4 (inst.operands[1].reg);
22183 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
22184 if (op != -1)
22185 inst.instruction |= op << 6;
22186
22187 if (thumb_mode)
22188 inst.instruction |= 0xfc000000;
22189 else
22190 inst.instruction |= 0xf0000000;
22191}
22192
48adcd8e
MGD
22193static void
22194do_crypto_3op_1 (int u, int op)
22195{
5ee91343 22196 set_pred_insn_type (OUTSIDE_PRED_INSN);
48adcd8e
MGD
22197
22198 if (neon_check_type (3, NS_QQQ, N_EQK | N_UNT, N_EQK | N_UNT,
22199 N_32 | N_UNT | N_KEY).type == NT_invtype)
22200 return;
22201
22202 inst.error = NULL;
22203
22204 NEON_ENCODE (INTEGER, inst);
22205 neon_three_same (1, u, 8 << op);
22206}
22207
91ff7894
MGD
22208static void
22209do_aese (void)
22210{
22211 do_crypto_2op_1 (N_8, 0);
22212}
22213
22214static void
22215do_aesd (void)
22216{
22217 do_crypto_2op_1 (N_8, 1);
22218}
22219
22220static void
22221do_aesmc (void)
22222{
22223 do_crypto_2op_1 (N_8, 2);
22224}
22225
22226static void
22227do_aesimc (void)
22228{
22229 do_crypto_2op_1 (N_8, 3);
22230}
22231
48adcd8e
MGD
22232static void
22233do_sha1c (void)
22234{
22235 do_crypto_3op_1 (0, 0);
22236}
22237
22238static void
22239do_sha1p (void)
22240{
22241 do_crypto_3op_1 (0, 1);
22242}
22243
22244static void
22245do_sha1m (void)
22246{
22247 do_crypto_3op_1 (0, 2);
22248}
22249
22250static void
22251do_sha1su0 (void)
22252{
22253 do_crypto_3op_1 (0, 3);
22254}
91ff7894 22255
48adcd8e
MGD
22256static void
22257do_sha256h (void)
22258{
22259 do_crypto_3op_1 (1, 0);
22260}
22261
22262static void
22263do_sha256h2 (void)
22264{
22265 do_crypto_3op_1 (1, 1);
22266}
22267
22268static void
22269do_sha256su1 (void)
22270{
22271 do_crypto_3op_1 (1, 2);
22272}
3c9017d2
MGD
22273
22274static void
22275do_sha1h (void)
22276{
22277 do_crypto_2op_1 (N_32, -1);
22278}
22279
22280static void
22281do_sha1su1 (void)
22282{
22283 do_crypto_2op_1 (N_32, 0);
22284}
22285
22286static void
22287do_sha256su0 (void)
22288{
22289 do_crypto_2op_1 (N_32, 1);
22290}
dd5181d5
KT
22291
22292static void
22293do_crc32_1 (unsigned int poly, unsigned int sz)
22294{
22295 unsigned int Rd = inst.operands[0].reg;
22296 unsigned int Rn = inst.operands[1].reg;
22297 unsigned int Rm = inst.operands[2].reg;
22298
5ee91343 22299 set_pred_insn_type (OUTSIDE_PRED_INSN);
dd5181d5
KT
22300 inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
22301 inst.instruction |= LOW4 (Rn) << 16;
22302 inst.instruction |= LOW4 (Rm);
22303 inst.instruction |= sz << (thumb_mode ? 4 : 21);
22304 inst.instruction |= poly << (thumb_mode ? 20 : 9);
22305
22306 if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
22307 as_warn (UNPRED_REG ("r15"));
dd5181d5
KT
22308}
22309
22310static void
22311do_crc32b (void)
22312{
22313 do_crc32_1 (0, 0);
22314}
22315
22316static void
22317do_crc32h (void)
22318{
22319 do_crc32_1 (0, 1);
22320}
22321
22322static void
22323do_crc32w (void)
22324{
22325 do_crc32_1 (0, 2);
22326}
22327
22328static void
22329do_crc32cb (void)
22330{
22331 do_crc32_1 (1, 0);
22332}
22333
22334static void
22335do_crc32ch (void)
22336{
22337 do_crc32_1 (1, 1);
22338}
22339
22340static void
22341do_crc32cw (void)
22342{
22343 do_crc32_1 (1, 2);
22344}
22345
49e8a725
SN
22346static void
22347do_vjcvt (void)
22348{
22349 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
22350 _(BAD_FPU));
22351 neon_check_type (2, NS_FD, N_S32, N_F64);
22352 do_vfp_sp_dp_cvt ();
22353 do_vfp_cond_or_thumb ();
22354}
22355
aab2c27d
MM
22356static void
22357do_vdot (void)
22358{
22359 enum neon_shape rs;
22360 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
22361 set_pred_insn_type (OUTSIDE_PRED_INSN);
22362 if (inst.operands[2].isscalar)
22363 {
22364 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
22365 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22366
22367 inst.instruction |= (1 << 25);
1db66fb6
JB
22368 int idx = inst.operands[2].reg & 0xf;
22369 constraint ((idx != 1 && idx != 0), _("index must be 0 or 1"));
aab2c27d
MM
22370 inst.operands[2].reg >>= 4;
22371 constraint (!(inst.operands[2].reg < 16),
22372 _("indexed register must be less than 16"));
22373 neon_three_args (rs == NS_QQS);
1db66fb6 22374 inst.instruction |= (idx << 5);
aab2c27d
MM
22375 }
22376 else
22377 {
22378 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
22379 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22380 neon_three_args (rs == NS_QQQ);
22381 }
22382}
22383
22384static void
22385do_vmmla (void)
22386{
22387 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
22388 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22389
22390 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
22391 set_pred_insn_type (OUTSIDE_PRED_INSN);
22392
22393 neon_three_args (1);
22394}
22395
f1e1d7f3
AC
22396static void
22397do_t_pacbti (void)
22398{
22399 inst.instruction = THUMB_OP32 (inst.instruction);
22400}
22401
e07352fa
AC
22402static void
22403do_t_pacbti_nonop (void)
22404{
22405 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, pacbti_ext),
22406 _(BAD_PACBTI));
22407
22408 inst.instruction = THUMB_OP32 (inst.instruction);
22409 inst.instruction |= inst.operands[0].reg << 12;
22410 inst.instruction |= inst.operands[1].reg << 16;
22411 inst.instruction |= inst.operands[2].reg;
22412}
22413
5c43020d
AC
22414static void
22415do_t_pacbti_pacg (void)
22416{
22417 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, pacbti_ext),
22418 _(BAD_PACBTI));
22419
22420 inst.instruction = THUMB_OP32 (inst.instruction);
22421 inst.instruction |= inst.operands[0].reg << 8;
22422 inst.instruction |= inst.operands[1].reg << 16;
22423 inst.instruction |= inst.operands[2].reg;
22424}
22425
5287ad62
JB
22426\f
22427/* Overall per-instruction processing. */
22428
22429/* We need to be able to fix up arbitrary expressions in some statements.
22430 This is so that we can handle symbols that are an arbitrary distance from
22431 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
22432 which returns part of an address in a form which will be valid for
22433 a data instruction. We do this by pushing the expression into a symbol
22434 in the expr_section, and creating a fix for that. */
22435
22436static void
22437fix_new_arm (fragS * frag,
22438 int where,
22439 short int size,
22440 expressionS * exp,
22441 int pc_rel,
22442 int reloc)
22443{
22444 fixS * new_fix;
22445
22446 switch (exp->X_op)
22447 {
22448 case O_constant:
6e7ce2cd
PB
22449 if (pc_rel)
22450 {
22451 /* Create an absolute valued symbol, so we have something to
477330fc
RM
22452 refer to in the object file. Unfortunately for us, gas's
22453 generic expression parsing will already have folded out
22454 any use of .set foo/.type foo %function that may have
22455 been used to set type information of the target location,
22456 that's being specified symbolically. We have to presume
22457 the user knows what they are doing. */
6e7ce2cd
PB
22458 char name[16 + 8];
22459 symbolS *symbol;
22460
22461 sprintf (name, "*ABS*0x%lx", (unsigned long)exp->X_add_number);
22462
22463 symbol = symbol_find_or_make (name);
22464 S_SET_SEGMENT (symbol, absolute_section);
22465 symbol_set_frag (symbol, &zero_address_frag);
22466 S_SET_VALUE (symbol, exp->X_add_number);
22467 exp->X_op = O_symbol;
22468 exp->X_add_symbol = symbol;
22469 exp->X_add_number = 0;
22470 }
22471 /* FALLTHROUGH */
5287ad62
JB
22472 case O_symbol:
22473 case O_add:
22474 case O_subtract:
21d799b5 22475 new_fix = fix_new_exp (frag, where, size, exp, pc_rel,
477330fc 22476 (enum bfd_reloc_code_real) reloc);
5287ad62
JB
22477 break;
22478
22479 default:
21d799b5 22480 new_fix = (fixS *) fix_new (frag, where, size, make_expr_symbol (exp), 0,
477330fc 22481 pc_rel, (enum bfd_reloc_code_real) reloc);
5287ad62
JB
22482 break;
22483 }
22484
22485 /* Mark whether the fix is to a THUMB instruction, or an ARM
22486 instruction. */
22487 new_fix->tc_fix_data = thumb_mode;
22488}
22489
22490/* Create a frg for an instruction requiring relaxation. */
22491static void
22492output_relax_insn (void)
22493{
22494 char * to;
22495 symbolS *sym;
0110f2b8
PB
22496 int offset;
22497
6e1cb1a6
PB
22498 /* The size of the instruction is unknown, so tie the debug info to the
22499 start of the instruction. */
22500 dwarf2_emit_insn (0);
6e1cb1a6 22501
e2b0ab59 22502 switch (inst.relocs[0].exp.X_op)
0110f2b8
PB
22503 {
22504 case O_symbol:
e2b0ab59
AV
22505 sym = inst.relocs[0].exp.X_add_symbol;
22506 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
22507 break;
22508 case O_constant:
22509 sym = NULL;
e2b0ab59 22510 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
22511 break;
22512 default:
e2b0ab59 22513 sym = make_expr_symbol (&inst.relocs[0].exp);
0110f2b8
PB
22514 offset = 0;
22515 break;
22516 }
22517 to = frag_var (rs_machine_dependent, INSN_SIZE, THUMB_SIZE,
22518 inst.relax, sym, offset, NULL/*offset, opcode*/);
22519 md_number_to_chars (to, inst.instruction, THUMB_SIZE);
0110f2b8
PB
22520}
22521
22522/* Write a 32-bit thumb instruction to buf. */
22523static void
22524put_thumb32_insn (char * buf, unsigned long insn)
22525{
22526 md_number_to_chars (buf, insn >> 16, THUMB_SIZE);
22527 md_number_to_chars (buf + THUMB_SIZE, insn, THUMB_SIZE);
22528}
22529
b99bd4ef 22530static void
c19d1205 22531output_inst (const char * str)
b99bd4ef 22532{
c19d1205 22533 char * to = NULL;
b99bd4ef 22534
c19d1205 22535 if (inst.error)
b99bd4ef 22536 {
c19d1205 22537 as_bad ("%s -- `%s'", inst.error, str);
b99bd4ef
NC
22538 return;
22539 }
5f4273c7
NC
22540 if (inst.relax)
22541 {
22542 output_relax_insn ();
0110f2b8 22543 return;
5f4273c7 22544 }
c19d1205
ZW
22545 if (inst.size == 0)
22546 return;
b99bd4ef 22547
c19d1205 22548 to = frag_more (inst.size);
8dc2430f
NC
22549 /* PR 9814: Record the thumb mode into the current frag so that we know
22550 what type of NOP padding to use, if necessary. We override any previous
22551 setting so that if the mode has changed then the NOPS that we use will
22552 match the encoding of the last instruction in the frag. */
cd000bff 22553 frag_now->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
c19d1205
ZW
22554
22555 if (thumb_mode && (inst.size > THUMB_SIZE))
b99bd4ef 22556 {
9c2799c2 22557 gas_assert (inst.size == (2 * THUMB_SIZE));
0110f2b8 22558 put_thumb32_insn (to, inst.instruction);
b99bd4ef 22559 }
c19d1205 22560 else if (inst.size > INSN_SIZE)
b99bd4ef 22561 {
9c2799c2 22562 gas_assert (inst.size == (2 * INSN_SIZE));
c19d1205
ZW
22563 md_number_to_chars (to, inst.instruction, INSN_SIZE);
22564 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
b99bd4ef 22565 }
c19d1205
ZW
22566 else
22567 md_number_to_chars (to, inst.instruction, inst.size);
b99bd4ef 22568
e2b0ab59
AV
22569 int r;
22570 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
22571 {
22572 if (inst.relocs[r].type != BFD_RELOC_UNUSED)
22573 fix_new_arm (frag_now, to - frag_now->fr_literal,
22574 inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
22575 inst.relocs[r].type);
22576 }
b99bd4ef 22577
c19d1205 22578 dwarf2_emit_insn (inst.size);
c19d1205 22579}
b99bd4ef 22580
e07e6e58
NC
22581static char *
22582output_it_inst (int cond, int mask, char * to)
22583{
22584 unsigned long instruction = 0xbf00;
22585
22586 mask &= 0xf;
22587 instruction |= mask;
22588 instruction |= cond << 4;
22589
22590 if (to == NULL)
22591 {
22592 to = frag_more (2);
22593#ifdef OBJ_ELF
22594 dwarf2_emit_insn (2);
22595#endif
22596 }
22597
22598 md_number_to_chars (to, instruction, 2);
22599
22600 return to;
22601}
22602
c19d1205
ZW
22603/* Tag values used in struct asm_opcode's tag field. */
22604enum opcode_tag
22605{
22606 OT_unconditional, /* Instruction cannot be conditionalized.
22607 The ARM condition field is still 0xE. */
22608 OT_unconditionalF, /* Instruction cannot be conditionalized
22609 and carries 0xF in its ARM condition field. */
22610 OT_csuffix, /* Instruction takes a conditional suffix. */
5ee91343
AV
22611 OT_csuffixF, /* Some forms of the instruction take a scalar
22612 conditional suffix, others place 0xF where the
22613 condition field would be, others take a vector
22614 conditional suffix. */
c19d1205
ZW
22615 OT_cinfix3, /* Instruction takes a conditional infix,
22616 beginning at character index 3. (In
22617 unified mode, it becomes a suffix.) */
088fa78e
KH
22618 OT_cinfix3_deprecated, /* The same as OT_cinfix3. This is used for
22619 tsts, cmps, cmns, and teqs. */
e3cb604e
PB
22620 OT_cinfix3_legacy, /* Legacy instruction takes a conditional infix at
22621 character index 3, even in unified mode. Used for
22622 legacy instructions where suffix and infix forms
22623 may be ambiguous. */
c19d1205 22624 OT_csuf_or_in3, /* Instruction takes either a conditional
e3cb604e 22625 suffix or an infix at character index 3. */
c19d1205
ZW
22626 OT_odd_infix_unc, /* This is the unconditional variant of an
22627 instruction that takes a conditional infix
22628 at an unusual position. In unified mode,
22629 this variant will accept a suffix. */
22630 OT_odd_infix_0 /* Values greater than or equal to OT_odd_infix_0
22631 are the conditional variants of instructions that
22632 take conditional infixes in unusual positions.
22633 The infix appears at character index
22634 (tag - OT_odd_infix_0). These are not accepted
22635 in unified mode. */
22636};
b99bd4ef 22637
c19d1205
ZW
22638/* Subroutine of md_assemble, responsible for looking up the primary
22639 opcode from the mnemonic the user wrote. STR points to the
22640 beginning of the mnemonic.
22641
22642 This is not simply a hash table lookup, because of conditional
22643 variants. Most instructions have conditional variants, which are
22644 expressed with a _conditional affix_ to the mnemonic. If we were
22645 to encode each conditional variant as a literal string in the opcode
22646 table, it would have approximately 20,000 entries.
22647
22648 Most mnemonics take this affix as a suffix, and in unified syntax,
22649 'most' is upgraded to 'all'. However, in the divided syntax, some
22650 instructions take the affix as an infix, notably the s-variants of
22651 the arithmetic instructions. Of those instructions, all but six
22652 have the infix appear after the third character of the mnemonic.
22653
22654 Accordingly, the algorithm for looking up primary opcodes given
22655 an identifier is:
22656
22657 1. Look up the identifier in the opcode table.
22658 If we find a match, go to step U.
22659
22660 2. Look up the last two characters of the identifier in the
22661 conditions table. If we find a match, look up the first N-2
22662 characters of the identifier in the opcode table. If we
22663 find a match, go to step CE.
22664
22665 3. Look up the fourth and fifth characters of the identifier in
22666 the conditions table. If we find a match, extract those
22667 characters from the identifier, and look up the remaining
22668 characters in the opcode table. If we find a match, go
22669 to step CM.
22670
22671 4. Fail.
22672
22673 U. Examine the tag field of the opcode structure, in case this is
22674 one of the six instructions with its conditional infix in an
22675 unusual place. If it is, the tag tells us where to find the
22676 infix; look it up in the conditions table and set inst.cond
22677 accordingly. Otherwise, this is an unconditional instruction.
22678 Again set inst.cond accordingly. Return the opcode structure.
22679
22680 CE. Examine the tag field to make sure this is an instruction that
22681 should receive a conditional suffix. If it is not, fail.
22682 Otherwise, set inst.cond from the suffix we already looked up,
22683 and return the opcode structure.
22684
22685 CM. Examine the tag field to make sure this is an instruction that
22686 should receive a conditional infix after the third character.
22687 If it is not, fail. Otherwise, undo the edits to the current
22688 line of input and proceed as for case CE. */
22689
22690static const struct asm_opcode *
22691opcode_lookup (char **str)
22692{
22693 char *end, *base;
22694 char *affix;
22695 const struct asm_opcode *opcode;
22696 const struct asm_cond *cond;
e3cb604e 22697 char save[2];
c19d1205
ZW
22698
22699 /* Scan up to the end of the mnemonic, which must end in white space,
721a8186 22700 '.' (in unified mode, or for Neon/VFP instructions), or end of string. */
c19d1205 22701 for (base = end = *str; *end != '\0'; end++)
721a8186 22702 if (*end == ' ' || *end == '.')
c19d1205 22703 break;
b99bd4ef 22704
c19d1205 22705 if (end == base)
c921be7d 22706 return NULL;
b99bd4ef 22707
5287ad62 22708 /* Handle a possible width suffix and/or Neon type suffix. */
c19d1205 22709 if (end[0] == '.')
b99bd4ef 22710 {
5287ad62 22711 int offset = 2;
5f4273c7 22712
267d2029 22713 /* The .w and .n suffixes are only valid if the unified syntax is in
477330fc 22714 use. */
267d2029 22715 if (unified_syntax && end[1] == 'w')
c19d1205 22716 inst.size_req = 4;
267d2029 22717 else if (unified_syntax && end[1] == 'n')
c19d1205
ZW
22718 inst.size_req = 2;
22719 else
477330fc 22720 offset = 0;
5287ad62
JB
22721
22722 inst.vectype.elems = 0;
22723
22724 *str = end + offset;
b99bd4ef 22725
5f4273c7 22726 if (end[offset] == '.')
5287ad62 22727 {
267d2029 22728 /* See if we have a Neon type suffix (possible in either unified or
477330fc
RM
22729 non-unified ARM syntax mode). */
22730 if (parse_neon_type (&inst.vectype, str) == FAIL)
c921be7d 22731 return NULL;
477330fc 22732 }
5287ad62 22733 else if (end[offset] != '\0' && end[offset] != ' ')
477330fc 22734 return NULL;
b99bd4ef 22735 }
c19d1205
ZW
22736 else
22737 *str = end;
b99bd4ef 22738
c19d1205 22739 /* Look for unaffixed or special-case affixed mnemonic. */
629310ab 22740 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22741 end - base);
f3da8a96 22742 cond = NULL;
c19d1205 22743 if (opcode)
b99bd4ef 22744 {
c19d1205
ZW
22745 /* step U */
22746 if (opcode->tag < OT_odd_infix_0)
b99bd4ef 22747 {
c19d1205
ZW
22748 inst.cond = COND_ALWAYS;
22749 return opcode;
b99bd4ef 22750 }
b99bd4ef 22751
278df34e 22752 if (warn_on_deprecated && unified_syntax)
5c3696f8 22753 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205 22754 affix = base + (opcode->tag - OT_odd_infix_0);
629310ab 22755 cond = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, affix, 2);
9c2799c2 22756 gas_assert (cond);
b99bd4ef 22757
c19d1205
ZW
22758 inst.cond = cond->value;
22759 return opcode;
22760 }
5ee91343
AV
22761 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
22762 {
22763 /* Cannot have a conditional suffix on a mnemonic of less than a character.
22764 */
22765 if (end - base < 2)
22766 return NULL;
22767 affix = end - 1;
629310ab
ML
22768 cond = (const struct asm_cond *) str_hash_find_n (arm_vcond_hsh, affix, 1);
22769 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22770 affix - base);
656412a7
SMW
22771
22772 /* A known edge case is a conflict between an 'e' as a suffix for an
22773 Else of a VPT predication block and an 'ne' suffix for an IT block.
22774 If we detect that edge case here and we are not in a VPT VECTOR_PRED
22775 block, reset opcode and cond, so that the 'ne' case can be detected
22776 in the next section for 2-character conditional suffixes.
22777 An example where this is a problem is between the MVE 'vcvtn' and the
22778 non-MVE 'vcvt' instructions. */
22779 if (cond && opcode
22780 && cond->template_name[0] == 'e'
22781 && opcode->template_name[affix - base - 1] == 'n'
22782 && now_pred.type != VECTOR_PRED)
22783 {
22784 opcode = NULL;
22785 cond = NULL;
22786 }
22787
5ee91343
AV
22788 /* If this opcode can not be vector predicated then don't accept it with a
22789 vector predication code. */
22790 if (opcode && !opcode->mayBeVecPred)
22791 opcode = NULL;
22792 }
22793 if (!opcode || !cond)
22794 {
22795 /* Cannot have a conditional suffix on a mnemonic of less than two
22796 characters. */
22797 if (end - base < 3)
22798 return NULL;
b99bd4ef 22799
5ee91343
AV
22800 /* Look for suffixed mnemonic. */
22801 affix = end - 2;
629310ab
ML
22802 cond = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, affix, 2);
22803 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22804 affix - base);
5ee91343 22805 }
b99bd4ef 22806
c19d1205
ZW
22807 if (opcode && cond)
22808 {
22809 /* step CE */
22810 switch (opcode->tag)
22811 {
e3cb604e
PB
22812 case OT_cinfix3_legacy:
22813 /* Ignore conditional suffixes matched on infix only mnemonics. */
22814 break;
22815
c19d1205 22816 case OT_cinfix3:
088fa78e 22817 case OT_cinfix3_deprecated:
c19d1205
ZW
22818 case OT_odd_infix_unc:
22819 if (!unified_syntax)
0198d5e6 22820 return NULL;
1a0670f3 22821 /* Fall through. */
c19d1205
ZW
22822
22823 case OT_csuffix:
477330fc 22824 case OT_csuffixF:
c19d1205
ZW
22825 case OT_csuf_or_in3:
22826 inst.cond = cond->value;
22827 return opcode;
22828
22829 case OT_unconditional:
22830 case OT_unconditionalF:
dfa9f0d5 22831 if (thumb_mode)
c921be7d 22832 inst.cond = cond->value;
dfa9f0d5
PB
22833 else
22834 {
c921be7d 22835 /* Delayed diagnostic. */
dfa9f0d5
PB
22836 inst.error = BAD_COND;
22837 inst.cond = COND_ALWAYS;
22838 }
c19d1205 22839 return opcode;
b99bd4ef 22840
c19d1205 22841 default:
c921be7d 22842 return NULL;
c19d1205
ZW
22843 }
22844 }
b99bd4ef 22845
c19d1205
ZW
22846 /* Cannot have a usual-position infix on a mnemonic of less than
22847 six characters (five would be a suffix). */
22848 if (end - base < 6)
c921be7d 22849 return NULL;
b99bd4ef 22850
c19d1205
ZW
22851 /* Look for infixed mnemonic in the usual position. */
22852 affix = base + 3;
629310ab 22853 cond = (const struct asm_cond *) str_hash_find_n (arm_cond_hsh, affix, 2);
e3cb604e 22854 if (!cond)
c921be7d 22855 return NULL;
e3cb604e
PB
22856
22857 memcpy (save, affix, 2);
22858 memmove (affix, affix + 2, (end - affix) - 2);
629310ab 22859 opcode = (const struct asm_opcode *) str_hash_find_n (arm_ops_hsh, base,
fe0e921f 22860 (end - base) - 2);
e3cb604e
PB
22861 memmove (affix + 2, affix, (end - affix) - 2);
22862 memcpy (affix, save, 2);
22863
088fa78e
KH
22864 if (opcode
22865 && (opcode->tag == OT_cinfix3
22866 || opcode->tag == OT_cinfix3_deprecated
22867 || opcode->tag == OT_csuf_or_in3
22868 || opcode->tag == OT_cinfix3_legacy))
b99bd4ef 22869 {
c921be7d 22870 /* Step CM. */
278df34e 22871 if (warn_on_deprecated && unified_syntax
088fa78e
KH
22872 && (opcode->tag == OT_cinfix3
22873 || opcode->tag == OT_cinfix3_deprecated))
5c3696f8 22874 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205
ZW
22875
22876 inst.cond = cond->value;
22877 return opcode;
b99bd4ef
NC
22878 }
22879
c921be7d 22880 return NULL;
b99bd4ef
NC
22881}
22882
e07e6e58
NC
22883/* This function generates an initial IT instruction, leaving its block
22884 virtually open for the new instructions. Eventually,
5ee91343 22885 the mask will be updated by now_pred_add_mask () each time
e07e6e58
NC
22886 a new instruction needs to be included in the IT block.
22887 Finally, the block is closed with close_automatic_it_block ().
22888 The block closure can be requested either from md_assemble (),
22889 a tencode (), or due to a label hook. */
22890
22891static void
22892new_automatic_it_block (int cond)
22893{
5ee91343
AV
22894 now_pred.state = AUTOMATIC_PRED_BLOCK;
22895 now_pred.mask = 0x18;
22896 now_pred.cc = cond;
22897 now_pred.block_length = 1;
cd000bff 22898 mapping_state (MAP_THUMB);
5ee91343 22899 now_pred.insn = output_it_inst (cond, now_pred.mask, NULL);
5b7c81bd
AM
22900 now_pred.warn_deprecated = false;
22901 now_pred.insn_cond = true;
e07e6e58
NC
22902}
22903
22904/* Close an automatic IT block.
22905 See comments in new_automatic_it_block (). */
22906
22907static void
22908close_automatic_it_block (void)
22909{
5ee91343
AV
22910 now_pred.mask = 0x10;
22911 now_pred.block_length = 0;
e07e6e58
NC
22912}
22913
22914/* Update the mask of the current automatically-generated IT
22915 instruction. See comments in new_automatic_it_block (). */
22916
22917static void
5ee91343 22918now_pred_add_mask (int cond)
e07e6e58
NC
22919{
22920#define CLEAR_BIT(value, nbit) ((value) & ~(1 << (nbit)))
22921#define SET_BIT_VALUE(value, bitvalue, nbit) (CLEAR_BIT (value, nbit) \
477330fc 22922 | ((bitvalue) << (nbit)))
e07e6e58 22923 const int resulting_bit = (cond & 1);
c921be7d 22924
5ee91343
AV
22925 now_pred.mask &= 0xf;
22926 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 22927 resulting_bit,
5ee91343
AV
22928 (5 - now_pred.block_length));
22929 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 22930 1,
5ee91343
AV
22931 ((5 - now_pred.block_length) - 1));
22932 output_it_inst (now_pred.cc, now_pred.mask, now_pred.insn);
e07e6e58
NC
22933
22934#undef CLEAR_BIT
22935#undef SET_BIT_VALUE
e07e6e58
NC
22936}
22937
22938/* The IT blocks handling machinery is accessed through the these functions:
22939 it_fsm_pre_encode () from md_assemble ()
5ee91343
AV
22940 set_pred_insn_type () optional, from the tencode functions
22941 set_pred_insn_type_last () ditto
22942 in_pred_block () ditto
e07e6e58 22943 it_fsm_post_encode () from md_assemble ()
33eaf5de 22944 force_automatic_it_block_close () from label handling functions
e07e6e58
NC
22945
22946 Rationale:
22947 1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
477330fc
RM
22948 initializing the IT insn type with a generic initial value depending
22949 on the inst.condition.
e07e6e58 22950 2) During the tencode function, two things may happen:
477330fc 22951 a) The tencode function overrides the IT insn type by
5ee91343
AV
22952 calling either set_pred_insn_type (type) or
22953 set_pred_insn_type_last ().
477330fc 22954 b) The tencode function queries the IT block state by
5ee91343 22955 calling in_pred_block () (i.e. to determine narrow/not narrow mode).
477330fc 22956
5ee91343
AV
22957 Both set_pred_insn_type and in_pred_block run the internal FSM state
22958 handling function (handle_pred_state), because: a) setting the IT insn
477330fc
RM
22959 type may incur in an invalid state (exiting the function),
22960 and b) querying the state requires the FSM to be updated.
22961 Specifically we want to avoid creating an IT block for conditional
22962 branches, so it_fsm_pre_encode is actually a guess and we can't
22963 determine whether an IT block is required until the tencode () routine
22964 has decided what type of instruction this actually it.
5ee91343
AV
22965 Because of this, if set_pred_insn_type and in_pred_block have to be
22966 used, set_pred_insn_type has to be called first.
477330fc 22967
5ee91343
AV
22968 set_pred_insn_type_last () is a wrapper of set_pred_insn_type (type),
22969 that determines the insn IT type depending on the inst.cond code.
477330fc
RM
22970 When a tencode () routine encodes an instruction that can be
22971 either outside an IT block, or, in the case of being inside, has to be
5ee91343 22972 the last one, set_pred_insn_type_last () will determine the proper
477330fc 22973 IT instruction type based on the inst.cond code. Otherwise,
5ee91343 22974 set_pred_insn_type can be called for overriding that logic or
477330fc
RM
22975 for covering other cases.
22976
5ee91343
AV
22977 Calling handle_pred_state () may not transition the IT block state to
22978 OUTSIDE_PRED_BLOCK immediately, since the (current) state could be
477330fc 22979 still queried. Instead, if the FSM determines that the state should
5ee91343 22980 be transitioned to OUTSIDE_PRED_BLOCK, a flag is marked to be closed
477330fc
RM
22981 after the tencode () function: that's what it_fsm_post_encode () does.
22982
5ee91343 22983 Since in_pred_block () calls the state handling function to get an
477330fc
RM
22984 updated state, an error may occur (due to invalid insns combination).
22985 In that case, inst.error is set.
22986 Therefore, inst.error has to be checked after the execution of
22987 the tencode () routine.
e07e6e58
NC
22988
22989 3) Back in md_assemble(), it_fsm_post_encode () is called to commit
477330fc 22990 any pending state change (if any) that didn't take place in
5ee91343 22991 handle_pred_state () as explained above. */
e07e6e58
NC
22992
22993static void
22994it_fsm_pre_encode (void)
22995{
22996 if (inst.cond != COND_ALWAYS)
5ee91343 22997 inst.pred_insn_type = INSIDE_IT_INSN;
e07e6e58 22998 else
5ee91343 22999 inst.pred_insn_type = OUTSIDE_PRED_INSN;
e07e6e58 23000
5ee91343 23001 now_pred.state_handled = 0;
e07e6e58
NC
23002}
23003
23004/* IT state FSM handling function. */
5ee91343
AV
23005/* MVE instructions and non-MVE instructions are handled differently because of
23006 the introduction of VPT blocks.
23007 Specifications say that any non-MVE instruction inside a VPT block is
23008 UNPREDICTABLE, with the exception of the BKPT instruction. Whereas most MVE
23009 instructions are deemed to be UNPREDICTABLE if inside an IT block. For the
35c228db 23010 few exceptions we have MVE_UNPREDICABLE_INSN.
5ee91343
AV
23011 The error messages provided depending on the different combinations possible
23012 are described in the cases below:
23013 For 'most' MVE instructions:
23014 1) In an IT block, with an IT code: syntax error
23015 2) In an IT block, with a VPT code: error: must be in a VPT block
23016 3) In an IT block, with no code: warning: UNPREDICTABLE
23017 4) In a VPT block, with an IT code: syntax error
23018 5) In a VPT block, with a VPT code: OK!
23019 6) In a VPT block, with no code: error: missing code
23020 7) Outside a pred block, with an IT code: error: syntax error
23021 8) Outside a pred block, with a VPT code: error: should be in a VPT block
23022 9) Outside a pred block, with no code: OK!
23023 For non-MVE instructions:
23024 10) In an IT block, with an IT code: OK!
23025 11) In an IT block, with a VPT code: syntax error
23026 12) In an IT block, with no code: error: missing code
23027 13) In a VPT block, with an IT code: error: should be in an IT block
23028 14) In a VPT block, with a VPT code: syntax error
23029 15) In a VPT block, with no code: UNPREDICTABLE
23030 16) Outside a pred block, with an IT code: error: should be in an IT block
23031 17) Outside a pred block, with a VPT code: syntax error
23032 18) Outside a pred block, with no code: OK!
23033 */
23034
e07e6e58
NC
23035
23036static int
5ee91343 23037handle_pred_state (void)
e07e6e58 23038{
5ee91343 23039 now_pred.state_handled = 1;
5b7c81bd 23040 now_pred.insn_cond = false;
e07e6e58 23041
5ee91343 23042 switch (now_pred.state)
e07e6e58 23043 {
5ee91343
AV
23044 case OUTSIDE_PRED_BLOCK:
23045 switch (inst.pred_insn_type)
e07e6e58 23046 {
35c228db 23047 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
23048 case MVE_OUTSIDE_PRED_INSN:
23049 if (inst.cond < COND_ALWAYS)
23050 {
23051 /* Case 7: Outside a pred block, with an IT code: error: syntax
23052 error. */
23053 inst.error = BAD_SYNTAX;
23054 return FAIL;
23055 }
23056 /* Case 9: Outside a pred block, with no code: OK! */
23057 break;
23058 case OUTSIDE_PRED_INSN:
23059 if (inst.cond > COND_ALWAYS)
23060 {
23061 /* Case 17: Outside a pred block, with a VPT code: syntax error.
23062 */
23063 inst.error = BAD_SYNTAX;
23064 return FAIL;
23065 }
23066 /* Case 18: Outside a pred block, with no code: OK! */
e07e6e58
NC
23067 break;
23068
5ee91343
AV
23069 case INSIDE_VPT_INSN:
23070 /* Case 8: Outside a pred block, with a VPT code: error: should be in
23071 a VPT block. */
23072 inst.error = BAD_OUT_VPT;
23073 return FAIL;
23074
e07e6e58
NC
23075 case INSIDE_IT_INSN:
23076 case INSIDE_IT_LAST_INSN:
5ee91343 23077 if (inst.cond < COND_ALWAYS)
e07e6e58 23078 {
5ee91343
AV
23079 /* Case 16: Outside a pred block, with an IT code: error: should
23080 be in an IT block. */
23081 if (thumb_mode == 0)
e07e6e58 23082 {
5ee91343
AV
23083 if (unified_syntax
23084 && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
23085 as_tsktsk (_("Warning: conditional outside an IT block"\
23086 " for Thumb."));
e07e6e58
NC
23087 }
23088 else
23089 {
5ee91343
AV
23090 if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
23091 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
23092 {
23093 /* Automatically generate the IT instruction. */
23094 new_automatic_it_block (inst.cond);
23095 if (inst.pred_insn_type == INSIDE_IT_LAST_INSN)
23096 close_automatic_it_block ();
23097 }
23098 else
23099 {
23100 inst.error = BAD_OUT_IT;
23101 return FAIL;
23102 }
e07e6e58 23103 }
5ee91343 23104 break;
e07e6e58 23105 }
5ee91343
AV
23106 else if (inst.cond > COND_ALWAYS)
23107 {
23108 /* Case 17: Outside a pred block, with a VPT code: syntax error.
23109 */
23110 inst.error = BAD_SYNTAX;
23111 return FAIL;
23112 }
23113 else
23114 gas_assert (0);
e07e6e58
NC
23115 case IF_INSIDE_IT_LAST_INSN:
23116 case NEUTRAL_IT_INSN:
23117 break;
23118
5ee91343
AV
23119 case VPT_INSN:
23120 if (inst.cond != COND_ALWAYS)
23121 first_error (BAD_SYNTAX);
23122 now_pred.state = MANUAL_PRED_BLOCK;
23123 now_pred.block_length = 0;
23124 now_pred.type = VECTOR_PRED;
23125 now_pred.cc = 0;
23126 break;
e07e6e58 23127 case IT_INSN:
5ee91343
AV
23128 now_pred.state = MANUAL_PRED_BLOCK;
23129 now_pred.block_length = 0;
23130 now_pred.type = SCALAR_PRED;
e07e6e58
NC
23131 break;
23132 }
23133 break;
23134
5ee91343 23135 case AUTOMATIC_PRED_BLOCK:
e07e6e58
NC
23136 /* Three things may happen now:
23137 a) We should increment current it block size;
23138 b) We should close current it block (closing insn or 4 insns);
23139 c) We should close current it block and start a new one (due
23140 to incompatible conditions or
23141 4 insns-length block reached). */
23142
5ee91343 23143 switch (inst.pred_insn_type)
e07e6e58 23144 {
5ee91343
AV
23145 case INSIDE_VPT_INSN:
23146 case VPT_INSN:
35c228db 23147 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
23148 case MVE_OUTSIDE_PRED_INSN:
23149 gas_assert (0);
23150 case OUTSIDE_PRED_INSN:
2b0f3761 23151 /* The closure of the block shall happen immediately,
5ee91343 23152 so any in_pred_block () call reports the block as closed. */
e07e6e58
NC
23153 force_automatic_it_block_close ();
23154 break;
23155
23156 case INSIDE_IT_INSN:
23157 case INSIDE_IT_LAST_INSN:
23158 case IF_INSIDE_IT_LAST_INSN:
5ee91343 23159 now_pred.block_length++;
e07e6e58 23160
5ee91343
AV
23161 if (now_pred.block_length > 4
23162 || !now_pred_compatible (inst.cond))
e07e6e58
NC
23163 {
23164 force_automatic_it_block_close ();
5ee91343 23165 if (inst.pred_insn_type != IF_INSIDE_IT_LAST_INSN)
e07e6e58
NC
23166 new_automatic_it_block (inst.cond);
23167 }
23168 else
23169 {
5b7c81bd 23170 now_pred.insn_cond = true;
5ee91343 23171 now_pred_add_mask (inst.cond);
e07e6e58
NC
23172 }
23173
5ee91343
AV
23174 if (now_pred.state == AUTOMATIC_PRED_BLOCK
23175 && (inst.pred_insn_type == INSIDE_IT_LAST_INSN
23176 || inst.pred_insn_type == IF_INSIDE_IT_LAST_INSN))
e07e6e58
NC
23177 close_automatic_it_block ();
23178 break;
23179
4934a27c 23180 /* Fallthrough. */
e07e6e58 23181 case NEUTRAL_IT_INSN:
5ee91343 23182 now_pred.block_length++;
5b7c81bd 23183 now_pred.insn_cond = true;
e07e6e58 23184
5ee91343 23185 if (now_pred.block_length > 4)
e07e6e58
NC
23186 force_automatic_it_block_close ();
23187 else
5ee91343 23188 now_pred_add_mask (now_pred.cc & 1);
e07e6e58
NC
23189 break;
23190
23191 case IT_INSN:
23192 close_automatic_it_block ();
5ee91343 23193 now_pred.state = MANUAL_PRED_BLOCK;
e07e6e58
NC
23194 break;
23195 }
23196 break;
23197
5ee91343 23198 case MANUAL_PRED_BLOCK:
e07e6e58 23199 {
7af67752
AM
23200 unsigned int cond;
23201 int is_last;
5ee91343 23202 if (now_pred.type == SCALAR_PRED)
e07e6e58 23203 {
5ee91343
AV
23204 /* Check conditional suffixes. */
23205 cond = now_pred.cc ^ ((now_pred.mask >> 4) & 1) ^ 1;
23206 now_pred.mask <<= 1;
23207 now_pred.mask &= 0x1f;
23208 is_last = (now_pred.mask == 0x10);
23209 }
23210 else
23211 {
23212 now_pred.cc ^= (now_pred.mask >> 4);
23213 cond = now_pred.cc + 0xf;
23214 now_pred.mask <<= 1;
23215 now_pred.mask &= 0x1f;
23216 is_last = now_pred.mask == 0x10;
23217 }
5b7c81bd 23218 now_pred.insn_cond = true;
e07e6e58 23219
5ee91343
AV
23220 switch (inst.pred_insn_type)
23221 {
23222 case OUTSIDE_PRED_INSN:
23223 if (now_pred.type == SCALAR_PRED)
23224 {
23225 if (inst.cond == COND_ALWAYS)
23226 {
23227 /* Case 12: In an IT block, with no code: error: missing
23228 code. */
23229 inst.error = BAD_NOT_IT;
23230 return FAIL;
23231 }
23232 else if (inst.cond > COND_ALWAYS)
23233 {
23234 /* Case 11: In an IT block, with a VPT code: syntax error.
23235 */
23236 inst.error = BAD_SYNTAX;
23237 return FAIL;
23238 }
23239 else if (thumb_mode)
23240 {
23241 /* This is for some special cases where a non-MVE
23242 instruction is not allowed in an IT block, such as cbz,
23243 but are put into one with a condition code.
23244 You could argue this should be a syntax error, but we
23245 gave the 'not allowed in IT block' diagnostic in the
23246 past so we will keep doing so. */
23247 inst.error = BAD_NOT_IT;
23248 return FAIL;
23249 }
23250 break;
23251 }
23252 else
23253 {
23254 /* Case 15: In a VPT block, with no code: UNPREDICTABLE. */
23255 as_tsktsk (MVE_NOT_VPT);
23256 return SUCCESS;
23257 }
23258 case MVE_OUTSIDE_PRED_INSN:
23259 if (now_pred.type == SCALAR_PRED)
23260 {
23261 if (inst.cond == COND_ALWAYS)
23262 {
23263 /* Case 3: In an IT block, with no code: warning:
23264 UNPREDICTABLE. */
23265 as_tsktsk (MVE_NOT_IT);
23266 return SUCCESS;
23267 }
23268 else if (inst.cond < COND_ALWAYS)
23269 {
23270 /* Case 1: In an IT block, with an IT code: syntax error.
23271 */
23272 inst.error = BAD_SYNTAX;
23273 return FAIL;
23274 }
23275 else
23276 gas_assert (0);
23277 }
23278 else
23279 {
23280 if (inst.cond < COND_ALWAYS)
23281 {
23282 /* Case 4: In a VPT block, with an IT code: syntax error.
23283 */
23284 inst.error = BAD_SYNTAX;
23285 return FAIL;
23286 }
23287 else if (inst.cond == COND_ALWAYS)
23288 {
23289 /* Case 6: In a VPT block, with no code: error: missing
23290 code. */
23291 inst.error = BAD_NOT_VPT;
23292 return FAIL;
23293 }
23294 else
23295 {
23296 gas_assert (0);
23297 }
23298 }
35c228db
AV
23299 case MVE_UNPREDICABLE_INSN:
23300 as_tsktsk (now_pred.type == SCALAR_PRED ? MVE_NOT_IT : MVE_NOT_VPT);
23301 return SUCCESS;
e07e6e58 23302 case INSIDE_IT_INSN:
5ee91343 23303 if (inst.cond > COND_ALWAYS)
e07e6e58 23304 {
5ee91343
AV
23305 /* Case 11: In an IT block, with a VPT code: syntax error. */
23306 /* Case 14: In a VPT block, with a VPT code: syntax error. */
23307 inst.error = BAD_SYNTAX;
23308 return FAIL;
23309 }
23310 else if (now_pred.type == SCALAR_PRED)
23311 {
23312 /* Case 10: In an IT block, with an IT code: OK! */
23313 if (cond != inst.cond)
23314 {
23315 inst.error = now_pred.type == SCALAR_PRED ? BAD_IT_COND :
23316 BAD_VPT_COND;
23317 return FAIL;
23318 }
23319 }
23320 else
23321 {
23322 /* Case 13: In a VPT block, with an IT code: error: should be
23323 in an IT block. */
23324 inst.error = BAD_OUT_IT;
e07e6e58
NC
23325 return FAIL;
23326 }
23327 break;
23328
5ee91343
AV
23329 case INSIDE_VPT_INSN:
23330 if (now_pred.type == SCALAR_PRED)
23331 {
23332 /* Case 2: In an IT block, with a VPT code: error: must be in a
23333 VPT block. */
23334 inst.error = BAD_OUT_VPT;
23335 return FAIL;
23336 }
23337 /* Case 5: In a VPT block, with a VPT code: OK! */
23338 else if (cond != inst.cond)
23339 {
23340 inst.error = BAD_VPT_COND;
23341 return FAIL;
23342 }
23343 break;
e07e6e58
NC
23344 case INSIDE_IT_LAST_INSN:
23345 case IF_INSIDE_IT_LAST_INSN:
5ee91343
AV
23346 if (now_pred.type == VECTOR_PRED || inst.cond > COND_ALWAYS)
23347 {
23348 /* Case 4: In a VPT block, with an IT code: syntax error. */
23349 /* Case 11: In an IT block, with a VPT code: syntax error. */
23350 inst.error = BAD_SYNTAX;
23351 return FAIL;
23352 }
23353 else if (cond != inst.cond)
e07e6e58
NC
23354 {
23355 inst.error = BAD_IT_COND;
23356 return FAIL;
23357 }
23358 if (!is_last)
23359 {
23360 inst.error = BAD_BRANCH;
23361 return FAIL;
23362 }
23363 break;
23364
23365 case NEUTRAL_IT_INSN:
5ee91343
AV
23366 /* The BKPT instruction is unconditional even in a IT or VPT
23367 block. */
e07e6e58
NC
23368 break;
23369
23370 case IT_INSN:
5ee91343
AV
23371 if (now_pred.type == SCALAR_PRED)
23372 {
23373 inst.error = BAD_IT_IT;
23374 return FAIL;
23375 }
23376 /* fall through. */
23377 case VPT_INSN:
23378 if (inst.cond == COND_ALWAYS)
23379 {
23380 /* Executing a VPT/VPST instruction inside an IT block or a
23381 VPT/VPST/IT instruction inside a VPT block is UNPREDICTABLE.
23382 */
23383 if (now_pred.type == SCALAR_PRED)
23384 as_tsktsk (MVE_NOT_IT);
23385 else
23386 as_tsktsk (MVE_NOT_VPT);
23387 return SUCCESS;
23388 }
23389 else
23390 {
23391 /* VPT/VPST do not accept condition codes. */
23392 inst.error = BAD_SYNTAX;
23393 return FAIL;
23394 }
e07e6e58 23395 }
5ee91343 23396 }
e07e6e58
NC
23397 break;
23398 }
23399
23400 return SUCCESS;
23401}
23402
5a01bb1d
MGD
23403struct depr_insn_mask
23404{
23405 unsigned long pattern;
23406 unsigned long mask;
23407 const char* description;
23408};
23409
23410/* List of 16-bit instruction patterns deprecated in an IT block in
23411 ARMv8. */
23412static const struct depr_insn_mask depr_it_insns[] = {
23413 { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
23414 { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
23415 { 0xa000, 0xb800, N_("ADR") },
23416 { 0x4800, 0xf800, N_("Literal loads") },
23417 { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
23418 { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
c8de034b
JW
23419 /* NOTE: 0x00dd is not the real encoding, instead, it is the 'tvalue'
23420 field in asm_opcode. 'tvalue' is used at the stage this check happen. */
23421 { 0x00dd, 0x7fff, N_("ADD/SUB sp, sp #imm") },
5a01bb1d
MGD
23422 { 0, 0, NULL }
23423};
23424
e07e6e58
NC
23425static void
23426it_fsm_post_encode (void)
23427{
23428 int is_last;
23429
5ee91343
AV
23430 if (!now_pred.state_handled)
23431 handle_pred_state ();
e07e6e58 23432
5ee91343 23433 if (now_pred.insn_cond
24f19ccb 23434 && warn_on_restrict_it
5ee91343 23435 && !now_pred.warn_deprecated
5a01bb1d 23436 && warn_on_deprecated
164446e0
AF
23437 && (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)
23438 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8r))
df9909b8 23439 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m))
5a01bb1d
MGD
23440 {
23441 if (inst.instruction >= 0x10000)
23442 {
5c3696f8 23443 as_tsktsk (_("IT blocks containing 32-bit Thumb instructions are "
df9909b8 23444 "performance deprecated in ARMv8-A and ARMv8-R"));
5b7c81bd 23445 now_pred.warn_deprecated = true;
5a01bb1d
MGD
23446 }
23447 else
23448 {
23449 const struct depr_insn_mask *p = depr_it_insns;
23450
23451 while (p->mask != 0)
23452 {
23453 if ((inst.instruction & p->mask) == p->pattern)
23454 {
df9909b8
TP
23455 as_tsktsk (_("IT blocks containing 16-bit Thumb "
23456 "instructions of the following class are "
23457 "performance deprecated in ARMv8-A and "
23458 "ARMv8-R: %s"), p->description);
5b7c81bd 23459 now_pred.warn_deprecated = true;
5a01bb1d
MGD
23460 break;
23461 }
23462
23463 ++p;
23464 }
23465 }
23466
5ee91343 23467 if (now_pred.block_length > 1)
5a01bb1d 23468 {
5c3696f8 23469 as_tsktsk (_("IT blocks containing more than one conditional "
df9909b8
TP
23470 "instruction are performance deprecated in ARMv8-A and "
23471 "ARMv8-R"));
5b7c81bd 23472 now_pred.warn_deprecated = true;
5a01bb1d
MGD
23473 }
23474 }
23475
5ee91343
AV
23476 is_last = (now_pred.mask == 0x10);
23477 if (is_last)
23478 {
23479 now_pred.state = OUTSIDE_PRED_BLOCK;
23480 now_pred.mask = 0;
23481 }
e07e6e58
NC
23482}
23483
23484static void
23485force_automatic_it_block_close (void)
23486{
5ee91343 23487 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
e07e6e58
NC
23488 {
23489 close_automatic_it_block ();
5ee91343
AV
23490 now_pred.state = OUTSIDE_PRED_BLOCK;
23491 now_pred.mask = 0;
e07e6e58
NC
23492 }
23493}
23494
23495static int
5ee91343 23496in_pred_block (void)
e07e6e58 23497{
5ee91343
AV
23498 if (!now_pred.state_handled)
23499 handle_pred_state ();
e07e6e58 23500
5ee91343 23501 return now_pred.state != OUTSIDE_PRED_BLOCK;
e07e6e58
NC
23502}
23503
ff8646ee
TP
23504/* Whether OPCODE only has T32 encoding. Since this function is only used by
23505 t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed
23506 here, hence the "known" in the function name. */
fc289b0a 23507
5b7c81bd 23508static bool
ff8646ee 23509known_t32_only_insn (const struct asm_opcode *opcode)
fc289b0a
TP
23510{
23511 /* Original Thumb-1 wide instruction. */
23512 if (opcode->tencode == do_t_blx
23513 || opcode->tencode == do_t_branch23
23514 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
23515 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
5b7c81bd 23516 return true;
fc289b0a 23517
16a1fa25
TP
23518 /* Wide-only instruction added to ARMv8-M Baseline. */
23519 if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m_m_only)
ff8646ee
TP
23520 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics)
23521 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m)
23522 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div))
5b7c81bd 23523 return true;
ff8646ee 23524
5b7c81bd 23525 return false;
ff8646ee
TP
23526}
23527
23528/* Whether wide instruction variant can be used if available for a valid OPCODE
23529 in ARCH. */
23530
5b7c81bd 23531static bool
ff8646ee
TP
23532t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode)
23533{
23534 if (known_t32_only_insn (opcode))
5b7c81bd 23535 return true;
ff8646ee
TP
23536
23537 /* Instruction with narrow and wide encoding added to ARMv8-M. Availability
23538 of variant T3 of B.W is checked in do_t_branch. */
23539 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
23540 && opcode->tencode == do_t_branch)
5b7c81bd 23541 return true;
ff8646ee 23542
bada4342
JW
23543 /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */
23544 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
23545 && opcode->tencode == do_t_mov_cmp
23546 /* Make sure CMP instruction is not affected. */
23547 && opcode->aencode == do_mov)
5b7c81bd 23548 return true;
bada4342 23549
ff8646ee
TP
23550 /* Wide instruction variants of all instructions with narrow *and* wide
23551 variants become available with ARMv6t2. Other opcodes are either
23552 narrow-only or wide-only and are thus available if OPCODE is valid. */
23553 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2))
5b7c81bd 23554 return true;
ff8646ee
TP
23555
23556 /* OPCODE with narrow only instruction variant or wide variant not
23557 available. */
5b7c81bd 23558 return false;
fc289b0a
TP
23559}
23560
c19d1205
ZW
23561void
23562md_assemble (char *str)
b99bd4ef 23563{
c19d1205
ZW
23564 char *p = str;
23565 const struct asm_opcode * opcode;
b99bd4ef 23566
c19d1205
ZW
23567 /* Align the previous label if needed. */
23568 if (last_label_seen != NULL)
b99bd4ef 23569 {
c19d1205
ZW
23570 symbol_set_frag (last_label_seen, frag_now);
23571 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
23572 S_SET_SEGMENT (last_label_seen, now_seg);
b99bd4ef
NC
23573 }
23574
c19d1205 23575 memset (&inst, '\0', sizeof (inst));
e2b0ab59
AV
23576 int r;
23577 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
23578 inst.relocs[r].type = BFD_RELOC_UNUSED;
b99bd4ef 23579
c19d1205
ZW
23580 opcode = opcode_lookup (&p);
23581 if (!opcode)
b99bd4ef 23582 {
c19d1205 23583 /* It wasn't an instruction, but it might be a register alias of
dcbf9037 23584 the form alias .req reg, or a Neon .dn/.qn directive. */
c921be7d 23585 if (! create_register_alias (str, p)
477330fc 23586 && ! create_neon_reg_alias (str, p))
c19d1205 23587 as_bad (_("bad instruction `%s'"), str);
b99bd4ef 23588
b99bd4ef
NC
23589 return;
23590 }
23591
278df34e 23592 if (warn_on_deprecated && opcode->tag == OT_cinfix3_deprecated)
5c3696f8 23593 as_tsktsk (_("s suffix on comparison instruction is deprecated"));
088fa78e 23594
037e8744
JB
23595 /* The value which unconditional instructions should have in place of the
23596 condition field. */
7af67752 23597 inst.uncond_value = (opcode->tag == OT_csuffixF) ? 0xf : -1u;
037e8744 23598
c19d1205 23599 if (thumb_mode)
b99bd4ef 23600 {
e74cfd16 23601 arm_feature_set variant;
8f06b2d8
PB
23602
23603 variant = cpu_variant;
23604 /* Only allow coprocessor instructions on Thumb-2 capable devices. */
e74cfd16
PB
23605 if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2))
23606 ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard);
c19d1205 23607 /* Check that this instruction is supported for this CPU. */
62b3e311
PB
23608 if (!opcode->tvariant
23609 || (thumb_mode == 1
23610 && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
b99bd4ef 23611 {
173205ca
TP
23612 if (opcode->tencode == do_t_swi)
23613 as_bad (_("SVC is not permitted on this architecture"));
23614 else
23615 as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
b99bd4ef
NC
23616 return;
23617 }
c19d1205
ZW
23618 if (inst.cond != COND_ALWAYS && !unified_syntax
23619 && opcode->tencode != do_t_branch)
b99bd4ef 23620 {
c19d1205 23621 as_bad (_("Thumb does not support conditional execution"));
b99bd4ef
NC
23622 return;
23623 }
23624
fc289b0a
TP
23625 /* Two things are addressed here:
23626 1) Implicit require narrow instructions on Thumb-1.
23627 This avoids relaxation accidentally introducing Thumb-2
23628 instructions.
23629 2) Reject wide instructions in non Thumb-2 cores.
23630
23631 Only instructions with narrow and wide variants need to be handled
23632 but selecting all non wide-only instructions is easier. */
23633 if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)
ff8646ee 23634 && !t32_insn_ok (variant, opcode))
076d447c 23635 {
fc289b0a
TP
23636 if (inst.size_req == 0)
23637 inst.size_req = 2;
23638 else if (inst.size_req == 4)
752d5da4 23639 {
ff8646ee
TP
23640 if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m))
23641 as_bad (_("selected processor does not support 32bit wide "
23642 "variant of instruction `%s'"), str);
23643 else
23644 as_bad (_("selected processor does not support `%s' in "
23645 "Thumb-2 mode"), str);
fc289b0a 23646 return;
752d5da4 23647 }
076d447c
PB
23648 }
23649
c19d1205
ZW
23650 inst.instruction = opcode->tvalue;
23651
5b7c81bd 23652 if (!parse_operands (p, opcode->operands, /*thumb=*/true))
477330fc 23653 {
5ee91343 23654 /* Prepare the pred_insn_type for those encodings that don't set
477330fc
RM
23655 it. */
23656 it_fsm_pre_encode ();
c19d1205 23657
477330fc 23658 opcode->tencode ();
e07e6e58 23659
477330fc
RM
23660 it_fsm_post_encode ();
23661 }
e27ec89e 23662
0110f2b8 23663 if (!(inst.error || inst.relax))
b99bd4ef 23664 {
9c2799c2 23665 gas_assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
c19d1205
ZW
23666 inst.size = (inst.instruction > 0xffff ? 4 : 2);
23667 if (inst.size_req && inst.size_req != inst.size)
b99bd4ef 23668 {
c19d1205 23669 as_bad (_("cannot honor width suffix -- `%s'"), str);
b99bd4ef
NC
23670 return;
23671 }
23672 }
076d447c
PB
23673
23674 /* Something has gone badly wrong if we try to relax a fixed size
477330fc 23675 instruction. */
9c2799c2 23676 gas_assert (inst.size_req == 0 || !inst.relax);
076d447c 23677
e74cfd16
PB
23678 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
23679 *opcode->tvariant);
ee065d83 23680 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
fc289b0a
TP
23681 set those bits when Thumb-2 32-bit instructions are seen. The impact
23682 of relaxable instructions will be considered later after we finish all
23683 relaxation. */
ff8646ee
TP
23684 if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any))
23685 variant = arm_arch_none;
23686 else
23687 variant = cpu_variant;
23688 if (inst.size == 4 && !t32_insn_ok (variant, opcode))
e74cfd16
PB
23689 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
23690 arm_ext_v6t2);
cd000bff 23691
88714cb8
DG
23692 check_neon_suffixes;
23693
cd000bff 23694 if (!inst.error)
c877a2f2
NC
23695 {
23696 mapping_state (MAP_THUMB);
23697 }
c19d1205 23698 }
3e9e4fcf 23699 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205 23700 {
5b7c81bd 23701 bool is_bx;
845b51d6
PB
23702
23703 /* bx is allowed on v5 cores, and sometimes on v4 cores. */
23704 is_bx = (opcode->aencode == do_bx);
23705
c19d1205 23706 /* Check that this instruction is supported for this CPU. */
845b51d6
PB
23707 if (!(is_bx && fix_v4bx)
23708 && !(opcode->avariant &&
23709 ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)))
b99bd4ef 23710 {
84b52b66 23711 as_bad (_("selected processor does not support `%s' in ARM mode"), str);
c19d1205 23712 return;
b99bd4ef 23713 }
c19d1205 23714 if (inst.size_req)
b99bd4ef 23715 {
c19d1205
ZW
23716 as_bad (_("width suffixes are invalid in ARM mode -- `%s'"), str);
23717 return;
b99bd4ef
NC
23718 }
23719
c19d1205
ZW
23720 inst.instruction = opcode->avalue;
23721 if (opcode->tag == OT_unconditionalF)
eff0bc54 23722 inst.instruction |= 0xFU << 28;
c19d1205
ZW
23723 else
23724 inst.instruction |= inst.cond << 28;
23725 inst.size = INSN_SIZE;
5b7c81bd 23726 if (!parse_operands (p, opcode->operands, /*thumb=*/false))
477330fc
RM
23727 {
23728 it_fsm_pre_encode ();
23729 opcode->aencode ();
23730 it_fsm_post_encode ();
23731 }
ee065d83 23732 /* Arm mode bx is marked as both v4T and v5 because it's still required
477330fc 23733 on a hypothetical non-thumb v5 core. */
845b51d6 23734 if (is_bx)
e74cfd16 23735 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t);
ee065d83 23736 else
e74cfd16
PB
23737 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
23738 *opcode->avariant);
88714cb8
DG
23739
23740 check_neon_suffixes;
23741
cd000bff 23742 if (!inst.error)
c877a2f2
NC
23743 {
23744 mapping_state (MAP_ARM);
23745 }
b99bd4ef 23746 }
3e9e4fcf
JB
23747 else
23748 {
23749 as_bad (_("attempt to use an ARM instruction on a Thumb-only processor "
23750 "-- `%s'"), str);
23751 return;
23752 }
c19d1205
ZW
23753 output_inst (str);
23754}
b99bd4ef 23755
e07e6e58 23756static void
5ee91343 23757check_pred_blocks_finished (void)
e07e6e58
NC
23758{
23759#ifdef OBJ_ELF
23760 asection *sect;
23761
23762 for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
5ee91343
AV
23763 if (seg_info (sect)->tc_segment_info_data.current_pred.state
23764 == MANUAL_PRED_BLOCK)
e07e6e58 23765 {
5ee91343
AV
23766 if (now_pred.type == SCALAR_PRED)
23767 as_warn (_("section '%s' finished with an open IT block."),
23768 sect->name);
23769 else
23770 as_warn (_("section '%s' finished with an open VPT/VPST block."),
23771 sect->name);
e07e6e58
NC
23772 }
23773#else
5ee91343
AV
23774 if (now_pred.state == MANUAL_PRED_BLOCK)
23775 {
23776 if (now_pred.type == SCALAR_PRED)
23777 as_warn (_("file finished with an open IT block."));
23778 else
23779 as_warn (_("file finished with an open VPT/VPST block."));
23780 }
e07e6e58
NC
23781#endif
23782}
23783
c19d1205
ZW
23784/* Various frobbings of labels and their addresses. */
23785
23786void
23787arm_start_line_hook (void)
23788{
23789 last_label_seen = NULL;
b99bd4ef
NC
23790}
23791
c19d1205
ZW
23792void
23793arm_frob_label (symbolS * sym)
b99bd4ef 23794{
c19d1205 23795 last_label_seen = sym;
b99bd4ef 23796
c19d1205 23797 ARM_SET_THUMB (sym, thumb_mode);
b99bd4ef 23798
c19d1205
ZW
23799#if defined OBJ_COFF || defined OBJ_ELF
23800 ARM_SET_INTERWORK (sym, support_interwork);
23801#endif
b99bd4ef 23802
e07e6e58
NC
23803 force_automatic_it_block_close ();
23804
5f4273c7 23805 /* Note - do not allow local symbols (.Lxxx) to be labelled
c19d1205
ZW
23806 as Thumb functions. This is because these labels, whilst
23807 they exist inside Thumb code, are not the entry points for
23808 possible ARM->Thumb calls. Also, these labels can be used
23809 as part of a computed goto or switch statement. eg gcc
23810 can generate code that looks like this:
b99bd4ef 23811
c19d1205
ZW
23812 ldr r2, [pc, .Laaa]
23813 lsl r3, r3, #2
23814 ldr r2, [r3, r2]
23815 mov pc, r2
b99bd4ef 23816
c19d1205
ZW
23817 .Lbbb: .word .Lxxx
23818 .Lccc: .word .Lyyy
23819 ..etc...
23820 .Laaa: .word Lbbb
b99bd4ef 23821
c19d1205
ZW
23822 The first instruction loads the address of the jump table.
23823 The second instruction converts a table index into a byte offset.
23824 The third instruction gets the jump address out of the table.
23825 The fourth instruction performs the jump.
b99bd4ef 23826
c19d1205
ZW
23827 If the address stored at .Laaa is that of a symbol which has the
23828 Thumb_Func bit set, then the linker will arrange for this address
23829 to have the bottom bit set, which in turn would mean that the
23830 address computation performed by the third instruction would end
23831 up with the bottom bit set. Since the ARM is capable of unaligned
23832 word loads, the instruction would then load the incorrect address
23833 out of the jump table, and chaos would ensue. */
23834 if (label_is_thumb_function_name
23835 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
fd361982 23836 && (bfd_section_flags (now_seg) & SEC_CODE) != 0)
b99bd4ef 23837 {
c19d1205
ZW
23838 /* When the address of a Thumb function is taken the bottom
23839 bit of that address should be set. This will allow
23840 interworking between Arm and Thumb functions to work
23841 correctly. */
b99bd4ef 23842
c19d1205 23843 THUMB_SET_FUNC (sym, 1);
b99bd4ef 23844
5b7c81bd 23845 label_is_thumb_function_name = false;
b99bd4ef 23846 }
07a53e5c 23847
07a53e5c 23848 dwarf2_emit_label (sym);
b99bd4ef
NC
23849}
23850
5b7c81bd 23851bool
c19d1205 23852arm_data_in_code (void)
b99bd4ef 23853{
d34049e8 23854 if (thumb_mode && startswith (input_line_pointer + 1, "data:"))
b99bd4ef 23855 {
c19d1205
ZW
23856 *input_line_pointer = '/';
23857 input_line_pointer += 5;
23858 *input_line_pointer = 0;
5b7c81bd 23859 return true;
b99bd4ef
NC
23860 }
23861
5b7c81bd 23862 return false;
b99bd4ef
NC
23863}
23864
c19d1205
ZW
23865char *
23866arm_canonicalize_symbol_name (char * name)
b99bd4ef 23867{
c19d1205 23868 int len;
b99bd4ef 23869
c19d1205
ZW
23870 if (thumb_mode && (len = strlen (name)) > 5
23871 && streq (name + len - 5, "/data"))
23872 *(name + len - 5) = 0;
b99bd4ef 23873
c19d1205 23874 return name;
b99bd4ef 23875}
c19d1205
ZW
23876\f
23877/* Table of all register names defined by default. The user can
23878 define additional names with .req. Note that all register names
23879 should appear in both upper and lowercase variants. Some registers
23880 also have mixed-case names. */
b99bd4ef 23881
5b7c81bd 23882#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, true, 0 }
c19d1205 23883#define REGNUM(p,n,t) REGDEF(p##n, n, t)
5287ad62 23884#define REGNUM2(p,n,t) REGDEF(p##n, 2 * n, t)
c19d1205
ZW
23885#define REGSET(p,t) \
23886 REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
23887 REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
23888 REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
23889 REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
5287ad62
JB
23890#define REGSETH(p,t) \
23891 REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
23892 REGNUM(p,20,t), REGNUM(p,21,t), REGNUM(p,22,t), REGNUM(p,23,t), \
23893 REGNUM(p,24,t), REGNUM(p,25,t), REGNUM(p,26,t), REGNUM(p,27,t), \
23894 REGNUM(p,28,t), REGNUM(p,29,t), REGNUM(p,30,t), REGNUM(p,31,t)
23895#define REGSET2(p,t) \
23896 REGNUM2(p, 0,t), REGNUM2(p, 1,t), REGNUM2(p, 2,t), REGNUM2(p, 3,t), \
23897 REGNUM2(p, 4,t), REGNUM2(p, 5,t), REGNUM2(p, 6,t), REGNUM2(p, 7,t), \
23898 REGNUM2(p, 8,t), REGNUM2(p, 9,t), REGNUM2(p,10,t), REGNUM2(p,11,t), \
23899 REGNUM2(p,12,t), REGNUM2(p,13,t), REGNUM2(p,14,t), REGNUM2(p,15,t)
90ec0d68
MGD
23900#define SPLRBANK(base,bank,t) \
23901 REGDEF(lr_##bank, 768|((base+0)<<16), t), \
23902 REGDEF(sp_##bank, 768|((base+1)<<16), t), \
23903 REGDEF(spsr_##bank, 768|(base<<16)|SPSR_BIT, t), \
23904 REGDEF(LR_##bank, 768|((base+0)<<16), t), \
23905 REGDEF(SP_##bank, 768|((base+1)<<16), t), \
23906 REGDEF(SPSR_##bank, 768|(base<<16)|SPSR_BIT, t)
7ed4c4c5 23907
c19d1205 23908static const struct reg_entry reg_names[] =
7ed4c4c5 23909{
c19d1205
ZW
23910 /* ARM integer registers. */
23911 REGSET(r, RN), REGSET(R, RN),
7ed4c4c5 23912
c19d1205
ZW
23913 /* ATPCS synonyms. */
23914 REGDEF(a1,0,RN), REGDEF(a2,1,RN), REGDEF(a3, 2,RN), REGDEF(a4, 3,RN),
23915 REGDEF(v1,4,RN), REGDEF(v2,5,RN), REGDEF(v3, 6,RN), REGDEF(v4, 7,RN),
23916 REGDEF(v5,8,RN), REGDEF(v6,9,RN), REGDEF(v7,10,RN), REGDEF(v8,11,RN),
7ed4c4c5 23917
c19d1205
ZW
23918 REGDEF(A1,0,RN), REGDEF(A2,1,RN), REGDEF(A3, 2,RN), REGDEF(A4, 3,RN),
23919 REGDEF(V1,4,RN), REGDEF(V2,5,RN), REGDEF(V3, 6,RN), REGDEF(V4, 7,RN),
23920 REGDEF(V5,8,RN), REGDEF(V6,9,RN), REGDEF(V7,10,RN), REGDEF(V8,11,RN),
7ed4c4c5 23921
c19d1205
ZW
23922 /* Well-known aliases. */
23923 REGDEF(wr, 7,RN), REGDEF(sb, 9,RN), REGDEF(sl,10,RN), REGDEF(fp,11,RN),
23924 REGDEF(ip,12,RN), REGDEF(sp,13,RN), REGDEF(lr,14,RN), REGDEF(pc,15,RN),
23925
23926 REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
23927 REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
23928
1b883319
AV
23929 /* Defining the new Zero register from ARMv8.1-M. */
23930 REGDEF(zr,15,ZR),
23931 REGDEF(ZR,15,ZR),
23932
c19d1205
ZW
23933 /* Coprocessor numbers. */
23934 REGSET(p, CP), REGSET(P, CP),
23935
23936 /* Coprocessor register numbers. The "cr" variants are for backward
23937 compatibility. */
23938 REGSET(c, CN), REGSET(C, CN),
23939 REGSET(cr, CN), REGSET(CR, CN),
23940
90ec0d68
MGD
23941 /* ARM banked registers. */
23942 REGDEF(R8_usr,512|(0<<16),RNB), REGDEF(r8_usr,512|(0<<16),RNB),
23943 REGDEF(R9_usr,512|(1<<16),RNB), REGDEF(r9_usr,512|(1<<16),RNB),
23944 REGDEF(R10_usr,512|(2<<16),RNB), REGDEF(r10_usr,512|(2<<16),RNB),
23945 REGDEF(R11_usr,512|(3<<16),RNB), REGDEF(r11_usr,512|(3<<16),RNB),
23946 REGDEF(R12_usr,512|(4<<16),RNB), REGDEF(r12_usr,512|(4<<16),RNB),
23947 REGDEF(SP_usr,512|(5<<16),RNB), REGDEF(sp_usr,512|(5<<16),RNB),
23948 REGDEF(LR_usr,512|(6<<16),RNB), REGDEF(lr_usr,512|(6<<16),RNB),
23949
23950 REGDEF(R8_fiq,512|(8<<16),RNB), REGDEF(r8_fiq,512|(8<<16),RNB),
23951 REGDEF(R9_fiq,512|(9<<16),RNB), REGDEF(r9_fiq,512|(9<<16),RNB),
23952 REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
23953 REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
23954 REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
1472d06f 23955 REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(sp_fiq,512|(13<<16),RNB),
90ec0d68
MGD
23956 REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
23957 REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
23958
23959 SPLRBANK(0,IRQ,RNB), SPLRBANK(0,irq,RNB),
23960 SPLRBANK(2,SVC,RNB), SPLRBANK(2,svc,RNB),
23961 SPLRBANK(4,ABT,RNB), SPLRBANK(4,abt,RNB),
23962 SPLRBANK(6,UND,RNB), SPLRBANK(6,und,RNB),
23963 SPLRBANK(12,MON,RNB), SPLRBANK(12,mon,RNB),
23964 REGDEF(elr_hyp,768|(14<<16),RNB), REGDEF(ELR_hyp,768|(14<<16),RNB),
23965 REGDEF(sp_hyp,768|(15<<16),RNB), REGDEF(SP_hyp,768|(15<<16),RNB),
fa94de6b 23966 REGDEF(spsr_hyp,768|(14<<16)|SPSR_BIT,RNB),
90ec0d68
MGD
23967 REGDEF(SPSR_hyp,768|(14<<16)|SPSR_BIT,RNB),
23968
c19d1205
ZW
23969 /* FPA registers. */
23970 REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
23971 REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
23972
23973 REGNUM(F,0,FN), REGNUM(F,1,FN), REGNUM(F,2,FN), REGNUM(F,3,FN),
23974 REGNUM(F,4,FN), REGNUM(F,5,FN), REGNUM(F,6,FN), REGNUM(F,7, FN),
23975
23976 /* VFP SP registers. */
5287ad62
JB
23977 REGSET(s,VFS), REGSET(S,VFS),
23978 REGSETH(s,VFS), REGSETH(S,VFS),
c19d1205
ZW
23979
23980 /* VFP DP Registers. */
5287ad62
JB
23981 REGSET(d,VFD), REGSET(D,VFD),
23982 /* Extra Neon DP registers. */
23983 REGSETH(d,VFD), REGSETH(D,VFD),
23984
23985 /* Neon QP registers. */
23986 REGSET2(q,NQ), REGSET2(Q,NQ),
c19d1205
ZW
23987
23988 /* VFP control registers. */
23989 REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
23990 REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
cd2cf30b
PB
23991 REGDEF(fpinst,9,VFC), REGDEF(fpinst2,10,VFC),
23992 REGDEF(FPINST,9,VFC), REGDEF(FPINST2,10,VFC),
23993 REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
23994 REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
40c7d507 23995 REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
ba6cd17f
SD
23996 REGDEF(fpscr_nzcvqc,2,VFC), REGDEF(FPSCR_nzcvqc,2,VFC),
23997 REGDEF(vpr,12,VFC), REGDEF(VPR,12,VFC),
23998 REGDEF(fpcxt_ns,14,VFC), REGDEF(FPCXT_NS,14,VFC),
23999 REGDEF(fpcxt_s,15,VFC), REGDEF(FPCXT_S,15,VFC),
ee3272d4
SP
24000 REGDEF(fpcxtns,14,VFC), REGDEF(FPCXTNS,14,VFC),
24001 REGDEF(fpcxts,15,VFC), REGDEF(FPCXTS,15,VFC),
c19d1205
ZW
24002
24003 /* Maverick DSP coprocessor registers. */
24004 REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
24005 REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
24006
24007 REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
24008 REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
24009 REGDEF(dspsc,0,DSPSC),
24010
24011 REGNUM(MVAX,0,MVAX), REGNUM(MVAX,1,MVAX),
24012 REGNUM(MVAX,2,MVAX), REGNUM(MVAX,3,MVAX),
24013 REGDEF(DSPSC,0,DSPSC),
24014
24015 /* iWMMXt data registers - p0, c0-15. */
24016 REGSET(wr,MMXWR), REGSET(wR,MMXWR), REGSET(WR, MMXWR),
24017
24018 /* iWMMXt control registers - p1, c0-3. */
24019 REGDEF(wcid, 0,MMXWC), REGDEF(wCID, 0,MMXWC), REGDEF(WCID, 0,MMXWC),
24020 REGDEF(wcon, 1,MMXWC), REGDEF(wCon, 1,MMXWC), REGDEF(WCON, 1,MMXWC),
24021 REGDEF(wcssf, 2,MMXWC), REGDEF(wCSSF, 2,MMXWC), REGDEF(WCSSF, 2,MMXWC),
24022 REGDEF(wcasf, 3,MMXWC), REGDEF(wCASF, 3,MMXWC), REGDEF(WCASF, 3,MMXWC),
24023
24024 /* iWMMXt scalar (constant/offset) registers - p1, c8-11. */
24025 REGDEF(wcgr0, 8,MMXWCG), REGDEF(wCGR0, 8,MMXWCG), REGDEF(WCGR0, 8,MMXWCG),
24026 REGDEF(wcgr1, 9,MMXWCG), REGDEF(wCGR1, 9,MMXWCG), REGDEF(WCGR1, 9,MMXWCG),
24027 REGDEF(wcgr2,10,MMXWCG), REGDEF(wCGR2,10,MMXWCG), REGDEF(WCGR2,10,MMXWCG),
24028 REGDEF(wcgr3,11,MMXWCG), REGDEF(wCGR3,11,MMXWCG), REGDEF(WCGR3,11,MMXWCG),
24029
24030 /* XScale accumulator registers. */
24031 REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
0264bf6f 24032
3a368c4c
VDN
24033 /* DWARF ABI defines RA_AUTH_CODE to 143. */
24034 REGDEF(ra_auth_code,143,PSEUDO),
c19d1205
ZW
24035};
24036#undef REGDEF
24037#undef REGNUM
24038#undef REGSET
7ed4c4c5 24039
c19d1205
ZW
24040/* Table of all PSR suffixes. Bare "CPSR" and "SPSR" are handled
24041 within psr_required_here. */
24042static const struct asm_psr psrs[] =
24043{
24044 /* Backward compatibility notation. Note that "all" is no longer
24045 truly all possible PSR bits. */
24046 {"all", PSR_c | PSR_f},
24047 {"flg", PSR_f},
24048 {"ctl", PSR_c},
24049
24050 /* Individual flags. */
24051 {"f", PSR_f},
24052 {"c", PSR_c},
24053 {"x", PSR_x},
24054 {"s", PSR_s},
59b42a0d 24055
c19d1205
ZW
24056 /* Combinations of flags. */
24057 {"fs", PSR_f | PSR_s},
24058 {"fx", PSR_f | PSR_x},
24059 {"fc", PSR_f | PSR_c},
24060 {"sf", PSR_s | PSR_f},
24061 {"sx", PSR_s | PSR_x},
24062 {"sc", PSR_s | PSR_c},
24063 {"xf", PSR_x | PSR_f},
24064 {"xs", PSR_x | PSR_s},
24065 {"xc", PSR_x | PSR_c},
24066 {"cf", PSR_c | PSR_f},
24067 {"cs", PSR_c | PSR_s},
24068 {"cx", PSR_c | PSR_x},
24069 {"fsx", PSR_f | PSR_s | PSR_x},
24070 {"fsc", PSR_f | PSR_s | PSR_c},
24071 {"fxs", PSR_f | PSR_x | PSR_s},
24072 {"fxc", PSR_f | PSR_x | PSR_c},
24073 {"fcs", PSR_f | PSR_c | PSR_s},
24074 {"fcx", PSR_f | PSR_c | PSR_x},
24075 {"sfx", PSR_s | PSR_f | PSR_x},
24076 {"sfc", PSR_s | PSR_f | PSR_c},
24077 {"sxf", PSR_s | PSR_x | PSR_f},
24078 {"sxc", PSR_s | PSR_x | PSR_c},
24079 {"scf", PSR_s | PSR_c | PSR_f},
24080 {"scx", PSR_s | PSR_c | PSR_x},
24081 {"xfs", PSR_x | PSR_f | PSR_s},
24082 {"xfc", PSR_x | PSR_f | PSR_c},
24083 {"xsf", PSR_x | PSR_s | PSR_f},
24084 {"xsc", PSR_x | PSR_s | PSR_c},
24085 {"xcf", PSR_x | PSR_c | PSR_f},
24086 {"xcs", PSR_x | PSR_c | PSR_s},
24087 {"cfs", PSR_c | PSR_f | PSR_s},
24088 {"cfx", PSR_c | PSR_f | PSR_x},
24089 {"csf", PSR_c | PSR_s | PSR_f},
24090 {"csx", PSR_c | PSR_s | PSR_x},
24091 {"cxf", PSR_c | PSR_x | PSR_f},
24092 {"cxs", PSR_c | PSR_x | PSR_s},
24093 {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
24094 {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
24095 {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
24096 {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
24097 {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
24098 {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
24099 {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
24100 {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
24101 {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
24102 {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
24103 {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
24104 {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
24105 {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
24106 {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
24107 {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
24108 {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
24109 {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
24110 {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
24111 {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
24112 {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
24113 {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
24114 {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
24115 {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
24116 {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
24117};
24118
62b3e311
PB
24119/* Table of V7M psr names. */
24120static const struct asm_psr v7m_psrs[] =
24121{
1a336194
TP
24122 {"apsr", 0x0 }, {"APSR", 0x0 },
24123 {"iapsr", 0x1 }, {"IAPSR", 0x1 },
24124 {"eapsr", 0x2 }, {"EAPSR", 0x2 },
24125 {"psr", 0x3 }, {"PSR", 0x3 },
24126 {"xpsr", 0x3 }, {"XPSR", 0x3 }, {"xPSR", 3 },
24127 {"ipsr", 0x5 }, {"IPSR", 0x5 },
24128 {"epsr", 0x6 }, {"EPSR", 0x6 },
24129 {"iepsr", 0x7 }, {"IEPSR", 0x7 },
24130 {"msp", 0x8 }, {"MSP", 0x8 },
24131 {"psp", 0x9 }, {"PSP", 0x9 },
24132 {"msplim", 0xa }, {"MSPLIM", 0xa },
24133 {"psplim", 0xb }, {"PSPLIM", 0xb },
24134 {"primask", 0x10}, {"PRIMASK", 0x10},
24135 {"basepri", 0x11}, {"BASEPRI", 0x11},
24136 {"basepri_max", 0x12}, {"BASEPRI_MAX", 0x12},
1a336194
TP
24137 {"faultmask", 0x13}, {"FAULTMASK", 0x13},
24138 {"control", 0x14}, {"CONTROL", 0x14},
24139 {"msp_ns", 0x88}, {"MSP_NS", 0x88},
24140 {"psp_ns", 0x89}, {"PSP_NS", 0x89},
24141 {"msplim_ns", 0x8a}, {"MSPLIM_NS", 0x8a},
24142 {"psplim_ns", 0x8b}, {"PSPLIM_NS", 0x8b},
24143 {"primask_ns", 0x90}, {"PRIMASK_NS", 0x90},
24144 {"basepri_ns", 0x91}, {"BASEPRI_NS", 0x91},
24145 {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
24146 {"control_ns", 0x94}, {"CONTROL_NS", 0x94},
24147 {"sp_ns", 0x98}, {"SP_NS", 0x98 }
62b3e311
PB
24148};
24149
c19d1205
ZW
24150/* Table of all shift-in-operand names. */
24151static const struct asm_shift_name shift_names [] =
b99bd4ef 24152{
c19d1205
ZW
24153 { "asl", SHIFT_LSL }, { "ASL", SHIFT_LSL },
24154 { "lsl", SHIFT_LSL }, { "LSL", SHIFT_LSL },
24155 { "lsr", SHIFT_LSR }, { "LSR", SHIFT_LSR },
24156 { "asr", SHIFT_ASR }, { "ASR", SHIFT_ASR },
24157 { "ror", SHIFT_ROR }, { "ROR", SHIFT_ROR },
f5f10c66
AV
24158 { "rrx", SHIFT_RRX }, { "RRX", SHIFT_RRX },
24159 { "uxtw", SHIFT_UXTW}, { "UXTW", SHIFT_UXTW}
c19d1205 24160};
b99bd4ef 24161
c19d1205
ZW
24162/* Table of all explicit relocation names. */
24163#ifdef OBJ_ELF
24164static struct reloc_entry reloc_names[] =
24165{
24166 { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
24167 { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
24168 { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
24169 { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
24170 { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
24171 { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
24172 { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
24173 { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
24174 { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
24175 { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
b43420e6 24176 { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32},
0855e32b
NS
24177 { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL},
24178 { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC},
477330fc 24179 { "TLSDESC", BFD_RELOC_ARM_TLS_GOTDESC},
0855e32b 24180 { "tlscall", BFD_RELOC_ARM_TLS_CALL},
477330fc 24181 { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
0855e32b 24182 { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
188fd7ae
CL
24183 { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ},
24184 { "gotfuncdesc", BFD_RELOC_ARM_GOTFUNCDESC },
24185 { "GOTFUNCDESC", BFD_RELOC_ARM_GOTFUNCDESC },
24186 { "gotofffuncdesc", BFD_RELOC_ARM_GOTOFFFUNCDESC },
24187 { "GOTOFFFUNCDESC", BFD_RELOC_ARM_GOTOFFFUNCDESC },
24188 { "funcdesc", BFD_RELOC_ARM_FUNCDESC },
5c5a4843
CL
24189 { "FUNCDESC", BFD_RELOC_ARM_FUNCDESC },
24190 { "tlsgd_fdpic", BFD_RELOC_ARM_TLS_GD32_FDPIC }, { "TLSGD_FDPIC", BFD_RELOC_ARM_TLS_GD32_FDPIC },
24191 { "tlsldm_fdpic", BFD_RELOC_ARM_TLS_LDM32_FDPIC }, { "TLSLDM_FDPIC", BFD_RELOC_ARM_TLS_LDM32_FDPIC },
24192 { "gottpoff_fdpic", BFD_RELOC_ARM_TLS_IE32_FDPIC }, { "GOTTPOFF_FDIC", BFD_RELOC_ARM_TLS_IE32_FDPIC },
c19d1205
ZW
24193};
24194#endif
b99bd4ef 24195
5ee91343 24196/* Table of all conditional affixes. */
c19d1205
ZW
24197static const struct asm_cond conds[] =
24198{
24199 {"eq", 0x0},
24200 {"ne", 0x1},
24201 {"cs", 0x2}, {"hs", 0x2},
24202 {"cc", 0x3}, {"ul", 0x3}, {"lo", 0x3},
24203 {"mi", 0x4},
24204 {"pl", 0x5},
24205 {"vs", 0x6},
24206 {"vc", 0x7},
24207 {"hi", 0x8},
24208 {"ls", 0x9},
24209 {"ge", 0xa},
24210 {"lt", 0xb},
24211 {"gt", 0xc},
24212 {"le", 0xd},
24213 {"al", 0xe}
24214};
5ee91343
AV
24215static const struct asm_cond vconds[] =
24216{
24217 {"t", 0xf},
24218 {"e", 0x10}
24219};
bfae80f2 24220
e797f7e0 24221#define UL_BARRIER(L,U,CODE,FEAT) \
823d2571
TG
24222 { L, CODE, ARM_FEATURE_CORE_LOW (FEAT) }, \
24223 { U, CODE, ARM_FEATURE_CORE_LOW (FEAT) }
e797f7e0 24224
62b3e311
PB
24225static struct asm_barrier_opt barrier_opt_names[] =
24226{
e797f7e0
MGD
24227 UL_BARRIER ("sy", "SY", 0xf, ARM_EXT_BARRIER),
24228 UL_BARRIER ("st", "ST", 0xe, ARM_EXT_BARRIER),
24229 UL_BARRIER ("ld", "LD", 0xd, ARM_EXT_V8),
24230 UL_BARRIER ("ish", "ISH", 0xb, ARM_EXT_BARRIER),
24231 UL_BARRIER ("sh", "SH", 0xb, ARM_EXT_BARRIER),
24232 UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER),
24233 UL_BARRIER ("shst", "SHST", 0xa, ARM_EXT_BARRIER),
24234 UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8),
24235 UL_BARRIER ("un", "UN", 0x7, ARM_EXT_BARRIER),
24236 UL_BARRIER ("nsh", "NSH", 0x7, ARM_EXT_BARRIER),
24237 UL_BARRIER ("unst", "UNST", 0x6, ARM_EXT_BARRIER),
24238 UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER),
24239 UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8),
24240 UL_BARRIER ("osh", "OSH", 0x3, ARM_EXT_BARRIER),
24241 UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER),
24242 UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8)
62b3e311
PB
24243};
24244
e797f7e0
MGD
24245#undef UL_BARRIER
24246
c19d1205
ZW
24247/* Table of ARM-format instructions. */
24248
24249/* Macros for gluing together operand strings. N.B. In all cases
24250 other than OPS0, the trailing OP_stop comes from default
24251 zero-initialization of the unspecified elements of the array. */
24252#define OPS0() { OP_stop, }
24253#define OPS1(a) { OP_##a, }
24254#define OPS2(a,b) { OP_##a,OP_##b, }
24255#define OPS3(a,b,c) { OP_##a,OP_##b,OP_##c, }
24256#define OPS4(a,b,c,d) { OP_##a,OP_##b,OP_##c,OP_##d, }
24257#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
24258#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
24259
5be8be5d
DG
24260/* These macros are similar to the OPSn, but do not prepend the OP_ prefix.
24261 This is useful when mixing operands for ARM and THUMB, i.e. using the
24262 MIX_ARM_THUMB_OPERANDS macro.
24263 In order to use these macros, prefix the number of operands with _
24264 e.g. _3. */
24265#define OPS_1(a) { a, }
24266#define OPS_2(a,b) { a,b, }
24267#define OPS_3(a,b,c) { a,b,c, }
24268#define OPS_4(a,b,c,d) { a,b,c,d, }
24269#define OPS_5(a,b,c,d,e) { a,b,c,d,e, }
24270#define OPS_6(a,b,c,d,e,f) { a,b,c,d,e,f, }
24271
c19d1205
ZW
24272/* These macros abstract out the exact format of the mnemonic table and
24273 save some repeated characters. */
24274
24275/* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix. */
24276#define TxCE(mnem, op, top, nops, ops, ae, te) \
21d799b5 24277 { mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
5ee91343 24278 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
24279
24280/* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
24281 a T_MNEM_xyz enumerator. */
24282#define TCE(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24283 TxCE (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 24284#define tCE(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24285 TxCE (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205
ZW
24286
24287/* Second most common sort of mnemonic: has a Thumb variant, takes a conditional
24288 infix after the third character. */
24289#define TxC3(mnem, op, top, nops, ops, ae, te) \
21d799b5 24290 { mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
5ee91343 24291 THUMB_VARIANT, do_##ae, do_##te, 0 }
088fa78e 24292#define TxC3w(mnem, op, top, nops, ops, ae, te) \
21d799b5 24293 { mnem, OPS##nops ops, OT_cinfix3_deprecated, 0x##op, top, ARM_VARIANT, \
5ee91343 24294 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 24295#define TC3(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24296 TxC3 (mnem, aop, 0x##top, nops, ops, ae, te)
088fa78e 24297#define TC3w(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24298 TxC3w (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 24299#define tC3(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24300 TxC3 (mnem, aop, T_MNEM##top, nops, ops, ae, te)
088fa78e 24301#define tC3w(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24302 TxC3w (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205 24303
c19d1205 24304/* Mnemonic that cannot be conditionalized. The ARM condition-code
dfa9f0d5
PB
24305 field is still 0xE. Many of the Thumb variants can be executed
24306 conditionally, so this is checked separately. */
c19d1205 24307#define TUE(mnem, op, top, nops, ops, ae, te) \
21d799b5 24308 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24309 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 24310
dd5181d5
KT
24311/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
24312 Used by mnemonics that have very minimal differences in the encoding for
24313 ARM and Thumb variants and can be handled in a common function. */
24314#define TUEc(mnem, op, top, nops, ops, en) \
24315 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24316 THUMB_VARIANT, do_##en, do_##en, 0 }
dd5181d5 24317
c19d1205
ZW
24318/* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
24319 condition code field. */
24320#define TUF(mnem, op, top, nops, ops, ae, te) \
21d799b5 24321 { mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24322 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
24323
24324/* ARM-only variants of all the above. */
6a86118a 24325#define CE(mnem, op, nops, ops, ae) \
5ee91343 24326 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24327
24328#define C3(mnem, op, nops, ops, ae) \
5ee91343 24329 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 24330
cf3cf39d
TP
24331/* Thumb-only variants of TCE and TUE. */
24332#define ToC(mnem, top, nops, ops, te) \
24333 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
5ee91343 24334 do_##te, 0 }
cf3cf39d
TP
24335
24336#define ToU(mnem, top, nops, ops, te) \
24337 { mnem, OPS##nops ops, OT_unconditional, 0x0, 0x##top, 0, THUMB_VARIANT, \
5ee91343 24338 NULL, do_##te, 0 }
cf3cf39d 24339
4389b29a
AV
24340/* T_MNEM_xyz enumerator variants of ToC. */
24341#define toC(mnem, top, nops, ops, te) \
24342 { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \
5ee91343 24343 do_##te, 0 }
4389b29a 24344
f6b2b12d
AV
24345/* T_MNEM_xyz enumerator variants of ToU. */
24346#define toU(mnem, top, nops, ops, te) \
24347 { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \
5ee91343 24348 NULL, do_##te, 0 }
f6b2b12d 24349
e3cb604e
PB
24350/* Legacy mnemonics that always have conditional infix after the third
24351 character. */
24352#define CL(mnem, op, nops, ops, ae) \
21d799b5 24353 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 24354 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
e3cb604e 24355
8f06b2d8
PB
24356/* Coprocessor instructions. Isomorphic between Arm and Thumb-2. */
24357#define cCE(mnem, op, nops, ops, ae) \
5ee91343 24358 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 24359
57785aa2
AV
24360/* mov instructions that are shared between coprocessor and MVE. */
24361#define mcCE(mnem, op, nops, ops, ae) \
24362 { #mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##ae, 0 }
24363
e3cb604e
PB
24364/* Legacy coprocessor instructions where conditional infix and conditional
24365 suffix are ambiguous. For consistency this includes all FPA instructions,
24366 not just the potentially ambiguous ones. */
24367#define cCL(mnem, op, nops, ops, ae) \
21d799b5 24368 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 24369 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
e3cb604e
PB
24370
24371/* Coprocessor, takes either a suffix or a position-3 infix
24372 (for an FPA corner case). */
24373#define C3E(mnem, op, nops, ops, ae) \
21d799b5 24374 { mnem, OPS##nops ops, OT_csuf_or_in3, \
5ee91343 24375 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 24376
6a86118a 24377#define xCM_(m1, m2, m3, op, nops, ops, ae) \
21d799b5
NC
24378 { m1 #m2 m3, OPS##nops ops, \
24379 sizeof (#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof (m1) - 1, \
5ee91343 24380 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24381
24382#define CM(m1, m2, op, nops, ops, ae) \
e07e6e58
NC
24383 xCM_ (m1, , m2, op, nops, ops, ae), \
24384 xCM_ (m1, eq, m2, op, nops, ops, ae), \
24385 xCM_ (m1, ne, m2, op, nops, ops, ae), \
24386 xCM_ (m1, cs, m2, op, nops, ops, ae), \
24387 xCM_ (m1, hs, m2, op, nops, ops, ae), \
24388 xCM_ (m1, cc, m2, op, nops, ops, ae), \
24389 xCM_ (m1, ul, m2, op, nops, ops, ae), \
24390 xCM_ (m1, lo, m2, op, nops, ops, ae), \
24391 xCM_ (m1, mi, m2, op, nops, ops, ae), \
24392 xCM_ (m1, pl, m2, op, nops, ops, ae), \
24393 xCM_ (m1, vs, m2, op, nops, ops, ae), \
24394 xCM_ (m1, vc, m2, op, nops, ops, ae), \
24395 xCM_ (m1, hi, m2, op, nops, ops, ae), \
24396 xCM_ (m1, ls, m2, op, nops, ops, ae), \
24397 xCM_ (m1, ge, m2, op, nops, ops, ae), \
24398 xCM_ (m1, lt, m2, op, nops, ops, ae), \
24399 xCM_ (m1, gt, m2, op, nops, ops, ae), \
24400 xCM_ (m1, le, m2, op, nops, ops, ae), \
24401 xCM_ (m1, al, m2, op, nops, ops, ae)
6a86118a
NC
24402
24403#define UE(mnem, op, nops, ops, ae) \
5ee91343 24404 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24405
24406#define UF(mnem, op, nops, ops, ae) \
5ee91343 24407 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 24408
5287ad62
JB
24409/* Neon data-processing. ARM versions are unconditional with cond=0xf.
24410 The Thumb and ARM variants are mostly the same (bits 0-23 and 24/28), so we
24411 use the same encoding function for each. */
24412#define NUF(mnem, op, nops, ops, enc) \
24413 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
5ee91343 24414 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
24415
24416/* Neon data processing, version which indirects through neon_enc_tab for
24417 the various overloaded versions of opcodes. */
24418#define nUF(mnem, op, nops, ops, enc) \
21d799b5 24419 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
5ee91343 24420 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
24421
24422/* Neon insn with conditional suffix for the ARM version, non-overloaded
24423 version. */
5ee91343 24424#define NCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
037e8744 24425 { #mnem, OPS##nops ops, tag, 0x##op, 0x##op, ARM_VARIANT, \
5ee91343 24426 THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 24427
037e8744 24428#define NCE(mnem, op, nops, ops, enc) \
5ee91343 24429 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
24430
24431#define NCEF(mnem, op, nops, ops, enc) \
5ee91343 24432 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
037e8744 24433
5287ad62 24434/* Neon insn with conditional suffix for the ARM version, overloaded types. */
5ee91343 24435#define nCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
21d799b5 24436 { #mnem, OPS##nops ops, tag, N_MNEM##op, N_MNEM##op, \
5ee91343 24437 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 24438
037e8744 24439#define nCE(mnem, op, nops, ops, enc) \
5ee91343 24440 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
24441
24442#define nCEF(mnem, op, nops, ops, enc) \
5ee91343
AV
24443 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
24444
24445/* */
24446#define mCEF(mnem, op, nops, ops, enc) \
a302e574 24447 { #mnem, OPS##nops ops, OT_csuffixF, M_MNEM##op, M_MNEM##op, \
5ee91343
AV
24448 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24449
24450
24451/* nCEF but for MVE predicated instructions. */
24452#define mnCEF(mnem, op, nops, ops, enc) \
24453 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
24454
24455/* nCE but for MVE predicated instructions. */
24456#define mnCE(mnem, op, nops, ops, enc) \
24457 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
037e8744 24458
5ee91343
AV
24459/* NUF but for potentially MVE predicated instructions. */
24460#define MNUF(mnem, op, nops, ops, enc) \
24461 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
24462 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24463
24464/* nUF but for potentially MVE predicated instructions. */
24465#define mnUF(mnem, op, nops, ops, enc) \
24466 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
24467 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24468
24469/* ToC but for potentially MVE predicated instructions. */
24470#define mToC(mnem, top, nops, ops, te) \
24471 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
24472 do_##te, 1 }
24473
24474/* NCE but for MVE predicated instructions. */
24475#define MNCE(mnem, op, nops, ops, enc) \
24476 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
24477
24478/* NCEF but for MVE predicated instructions. */
24479#define MNCEF(mnem, op, nops, ops, enc) \
24480 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
c19d1205
ZW
24481#define do_0 0
24482
c19d1205 24483static const struct asm_opcode insns[] =
bfae80f2 24484{
74db7efb
NC
24485#define ARM_VARIANT & arm_ext_v1 /* Core ARM Instructions. */
24486#define THUMB_VARIANT & arm_ext_v4t
21d799b5
NC
24487 tCE("and", 0000000, _and, 3, (RR, oRR, SH), arit, t_arit3c),
24488 tC3("ands", 0100000, _ands, 3, (RR, oRR, SH), arit, t_arit3c),
24489 tCE("eor", 0200000, _eor, 3, (RR, oRR, SH), arit, t_arit3c),
24490 tC3("eors", 0300000, _eors, 3, (RR, oRR, SH), arit, t_arit3c),
24491 tCE("sub", 0400000, _sub, 3, (RR, oRR, SH), arit, t_add_sub),
24492 tC3("subs", 0500000, _subs, 3, (RR, oRR, SH), arit, t_add_sub),
24493 tCE("add", 0800000, _add, 3, (RR, oRR, SHG), arit, t_add_sub),
24494 tC3("adds", 0900000, _adds, 3, (RR, oRR, SHG), arit, t_add_sub),
24495 tCE("adc", 0a00000, _adc, 3, (RR, oRR, SH), arit, t_arit3c),
24496 tC3("adcs", 0b00000, _adcs, 3, (RR, oRR, SH), arit, t_arit3c),
24497 tCE("sbc", 0c00000, _sbc, 3, (RR, oRR, SH), arit, t_arit3),
24498 tC3("sbcs", 0d00000, _sbcs, 3, (RR, oRR, SH), arit, t_arit3),
24499 tCE("orr", 1800000, _orr, 3, (RR, oRR, SH), arit, t_arit3c),
24500 tC3("orrs", 1900000, _orrs, 3, (RR, oRR, SH), arit, t_arit3c),
24501 tCE("bic", 1c00000, _bic, 3, (RR, oRR, SH), arit, t_arit3),
24502 tC3("bics", 1d00000, _bics, 3, (RR, oRR, SH), arit, t_arit3),
c19d1205
ZW
24503
24504 /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
24505 for setting PSR flag bits. They are obsolete in V6 and do not
24506 have Thumb equivalents. */
21d799b5
NC
24507 tCE("tst", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
24508 tC3w("tsts", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
24509 CL("tstp", 110f000, 2, (RR, SH), cmp),
24510 tCE("cmp", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
24511 tC3w("cmps", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
24512 CL("cmpp", 150f000, 2, (RR, SH), cmp),
24513 tCE("cmn", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
24514 tC3w("cmns", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
24515 CL("cmnp", 170f000, 2, (RR, SH), cmp),
24516
24517 tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
72d98d16 24518 tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
21d799b5
NC
24519 tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
24520 tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
24521
24522 tCE("ldr", 4100000, _ldr, 2, (RR, ADDRGLDR),ldst, t_ldst),
5be8be5d
DG
24523 tC3("ldrb", 4500000, _ldrb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
24524 tCE("str", 4000000, _str, _2, (MIX_ARM_THUMB_OPERANDS (OP_RR,
24525 OP_RRnpc),
24526 OP_ADDRGLDR),ldst, t_ldst),
24527 tC3("strb", 4400000, _strb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
21d799b5
NC
24528
24529 tCE("stm", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24530 tC3("stmia", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24531 tC3("stmea", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24532 tCE("ldm", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24533 tC3("ldmia", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24534 tC3("ldmfd", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24535
21d799b5
NC
24536 tCE("b", a000000, _b, 1, (EXPr), branch, t_branch),
24537 TCE("bl", b000000, f000f800, 1, (EXPr), bl, t_branch23),
bfae80f2 24538
c19d1205 24539 /* Pseudo ops. */
21d799b5 24540 tCE("adr", 28f0000, _adr, 2, (RR, EXP), adr, t_adr),
2fc8bdac 24541 C3(adrl, 28f0000, 2, (RR, EXP), adrl),
21d799b5 24542 tCE("nop", 1a00000, _nop, 1, (oI255c), nop, t_nop),
74db7efb 24543 tCE("udf", 7f000f0, _udf, 1, (oIffffb), bkpt, t_udf),
c19d1205
ZW
24544
24545 /* Thumb-compatibility pseudo ops. */
21d799b5
NC
24546 tCE("lsl", 1a00000, _lsl, 3, (RR, oRR, SH), shift, t_shift),
24547 tC3("lsls", 1b00000, _lsls, 3, (RR, oRR, SH), shift, t_shift),
24548 tCE("lsr", 1a00020, _lsr, 3, (RR, oRR, SH), shift, t_shift),
24549 tC3("lsrs", 1b00020, _lsrs, 3, (RR, oRR, SH), shift, t_shift),
24550 tCE("asr", 1a00040, _asr, 3, (RR, oRR, SH), shift, t_shift),
24551 tC3("asrs", 1b00040, _asrs, 3, (RR, oRR, SH), shift, t_shift),
24552 tCE("ror", 1a00060, _ror, 3, (RR, oRR, SH), shift, t_shift),
24553 tC3("rors", 1b00060, _rors, 3, (RR, oRR, SH), shift, t_shift),
24554 tCE("neg", 2600000, _neg, 2, (RR, RR), rd_rn, t_neg),
24555 tC3("negs", 2700000, _negs, 2, (RR, RR), rd_rn, t_neg),
24556 tCE("push", 92d0000, _push, 1, (REGLST), push_pop, t_push_pop),
24557 tCE("pop", 8bd0000, _pop, 1, (REGLST), push_pop, t_push_pop),
c19d1205 24558
16a4cf17 24559 /* These may simplify to neg. */
21d799b5
NC
24560 TCE("rsb", 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
24561 TC3("rsbs", 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
16a4cf17 24562
173205ca
TP
24563#undef THUMB_VARIANT
24564#define THUMB_VARIANT & arm_ext_os
24565
24566 TCE("swi", f000000, df00, 1, (EXPi), swi, t_swi),
24567 TCE("svc", f000000, df00, 1, (EXPi), swi, t_swi),
24568
c921be7d
NC
24569#undef THUMB_VARIANT
24570#define THUMB_VARIANT & arm_ext_v6
24571
21d799b5 24572 TCE("cpy", 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
c19d1205
ZW
24573
24574 /* V1 instructions with no Thumb analogue prior to V6T2. */
c921be7d
NC
24575#undef THUMB_VARIANT
24576#define THUMB_VARIANT & arm_ext_v6t2
24577
21d799b5
NC
24578 TCE("teq", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
24579 TC3w("teqs", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
24580 CL("teqp", 130f000, 2, (RR, SH), cmp),
c19d1205 24581
5be8be5d
DG
24582 TC3("ldrt", 4300000, f8500e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
24583 TC3("ldrbt", 4700000, f8100e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
24584 TC3("strt", 4200000, f8400e00, 2, (RR_npcsp, ADDR), ldstt, t_ldstt),
24585 TC3("strbt", 4600000, f8000e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
c19d1205 24586
21d799b5
NC
24587 TC3("stmdb", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24588 TC3("stmfd", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205 24589
21d799b5
NC
24590 TC3("ldmdb", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24591 TC3("ldmea", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205
ZW
24592
24593 /* V1 instructions with no Thumb analogue at all. */
21d799b5 24594 CE("rsc", 0e00000, 3, (RR, oRR, SH), arit),
c19d1205
ZW
24595 C3(rscs, 0f00000, 3, (RR, oRR, SH), arit),
24596
24597 C3(stmib, 9800000, 2, (RRw, REGLST), ldmstm),
24598 C3(stmfa, 9800000, 2, (RRw, REGLST), ldmstm),
24599 C3(stmda, 8000000, 2, (RRw, REGLST), ldmstm),
24600 C3(stmed, 8000000, 2, (RRw, REGLST), ldmstm),
24601 C3(ldmib, 9900000, 2, (RRw, REGLST), ldmstm),
24602 C3(ldmed, 9900000, 2, (RRw, REGLST), ldmstm),
24603 C3(ldmda, 8100000, 2, (RRw, REGLST), ldmstm),
24604 C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm),
24605
c921be7d
NC
24606#undef ARM_VARIANT
24607#define ARM_VARIANT & arm_ext_v2 /* ARM 2 - multiplies. */
24608#undef THUMB_VARIANT
24609#define THUMB_VARIANT & arm_ext_v4t
24610
21d799b5
NC
24611 tCE("mul", 0000090, _mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
24612 tC3("muls", 0100090, _muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
c19d1205 24613
c921be7d
NC
24614#undef THUMB_VARIANT
24615#define THUMB_VARIANT & arm_ext_v6t2
24616
21d799b5 24617 TCE("mla", 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
c19d1205
ZW
24618 C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
24619
24620 /* Generic coprocessor instructions. */
21d799b5
NC
24621 TCE("cdp", e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
24622 TCE("ldc", c100000, ec100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24623 TC3("ldcl", c500000, ec500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24624 TCE("stc", c000000, ec000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24625 TC3("stcl", c400000, ec400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24626 TCE("mcr", e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
db472d6f 24627 TCE("mrc", e100010, ee100010, 6, (RCP, I7b, APSR_RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 24628
c921be7d
NC
24629#undef ARM_VARIANT
24630#define ARM_VARIANT & arm_ext_v2s /* ARM 3 - swp instructions. */
24631
21d799b5 24632 CE("swp", 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
c19d1205
ZW
24633 C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
24634
c921be7d
NC
24635#undef ARM_VARIANT
24636#define ARM_VARIANT & arm_ext_v3 /* ARM 6 Status register instructions. */
24637#undef THUMB_VARIANT
24638#define THUMB_VARIANT & arm_ext_msr
24639
d2cd1205
JB
24640 TCE("mrs", 1000000, f3e08000, 2, (RRnpc, rPSR), mrs, t_mrs),
24641 TCE("msr", 120f000, f3808000, 2, (wPSR, RR_EXi), msr, t_msr),
c19d1205 24642
c921be7d
NC
24643#undef ARM_VARIANT
24644#define ARM_VARIANT & arm_ext_v3m /* ARM 7M long multiplies. */
24645#undef THUMB_VARIANT
24646#define THUMB_VARIANT & arm_ext_v6t2
24647
21d799b5
NC
24648 TCE("smull", 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24649 CM("smull","s", 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24650 TCE("umull", 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24651 CM("umull","s", 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24652 TCE("smlal", 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24653 CM("smlal","s", 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24654 TCE("umlal", 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24655 CM("umlal","s", 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
c19d1205 24656
c921be7d
NC
24657#undef ARM_VARIANT
24658#define ARM_VARIANT & arm_ext_v4 /* ARM Architecture 4. */
24659#undef THUMB_VARIANT
24660#define THUMB_VARIANT & arm_ext_v4t
24661
5be8be5d
DG
24662 tC3("ldrh", 01000b0, _ldrh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24663 tC3("strh", 00000b0, _strh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24664 tC3("ldrsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24665 tC3("ldrsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
56c0a61f
RE
24666 tC3("ldsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24667 tC3("ldsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
c19d1205 24668
c921be7d
NC
24669#undef ARM_VARIANT
24670#define ARM_VARIANT & arm_ext_v4t_5
24671
c19d1205
ZW
24672 /* ARM Architecture 4T. */
24673 /* Note: bx (and blx) are required on V5, even if the processor does
24674 not support Thumb. */
21d799b5 24675 TCE("bx", 12fff10, 4700, 1, (RR), bx, t_bx),
c19d1205 24676
c921be7d
NC
24677#undef ARM_VARIANT
24678#define ARM_VARIANT & arm_ext_v5 /* ARM Architecture 5T. */
24679#undef THUMB_VARIANT
24680#define THUMB_VARIANT & arm_ext_v5t
24681
c19d1205
ZW
24682 /* Note: blx has 2 variants; the .value coded here is for
24683 BLX(2). Only this variant has conditional execution. */
21d799b5
NC
24684 TCE("blx", 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
24685 TUE("bkpt", 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
c19d1205 24686
c921be7d
NC
24687#undef THUMB_VARIANT
24688#define THUMB_VARIANT & arm_ext_v6t2
24689
21d799b5
NC
24690 TCE("clz", 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
24691 TUF("ldc2", c100000, fc100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24692 TUF("ldc2l", c500000, fc500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24693 TUF("stc2", c000000, fc000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24694 TUF("stc2l", c400000, fc400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24695 TUF("cdp2", e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
24696 TUF("mcr2", e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
24697 TUF("mrc2", e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 24698
c921be7d 24699#undef ARM_VARIANT
74db7efb
NC
24700#define ARM_VARIANT & arm_ext_v5exp /* ARM Architecture 5TExP. */
24701#undef THUMB_VARIANT
24702#define THUMB_VARIANT & arm_ext_v5exp
c921be7d 24703
21d799b5
NC
24704 TCE("smlabb", 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24705 TCE("smlatb", 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24706 TCE("smlabt", 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24707 TCE("smlatt", 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 24708
21d799b5
NC
24709 TCE("smlawb", 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24710 TCE("smlawt", 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 24711
21d799b5
NC
24712 TCE("smlalbb", 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24713 TCE("smlaltb", 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24714 TCE("smlalbt", 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24715 TCE("smlaltt", 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
c19d1205 24716
21d799b5
NC
24717 TCE("smulbb", 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24718 TCE("smultb", 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24719 TCE("smulbt", 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24720 TCE("smultt", 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 24721
21d799b5
NC
24722 TCE("smulwb", 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24723 TCE("smulwt", 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 24724
03ee1b7f
NC
24725 TCE("qadd", 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24726 TCE("qdadd", 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24727 TCE("qsub", 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24728 TCE("qdsub", 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
c19d1205 24729
c921be7d 24730#undef ARM_VARIANT
74db7efb
NC
24731#define ARM_VARIANT & arm_ext_v5e /* ARM Architecture 5TE. */
24732#undef THUMB_VARIANT
24733#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 24734
21d799b5 24735 TUF("pld", 450f000, f810f000, 1, (ADDR), pld, t_pld),
5be8be5d
DG
24736 TC3("ldrd", 00000d0, e8500000, 3, (RRnpc_npcsp, oRRnpc_npcsp, ADDRGLDRS),
24737 ldrd, t_ldstd),
24738 TC3("strd", 00000f0, e8400000, 3, (RRnpc_npcsp, oRRnpc_npcsp,
24739 ADDRGLDRS), ldrd, t_ldstd),
c19d1205 24740
21d799b5
NC
24741 TCE("mcrr", c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
24742 TCE("mrrc", c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
c19d1205 24743
c921be7d
NC
24744#undef ARM_VARIANT
24745#define ARM_VARIANT & arm_ext_v5j /* ARM Architecture 5TEJ. */
24746
21d799b5 24747 TCE("bxj", 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
c19d1205 24748
c921be7d
NC
24749#undef ARM_VARIANT
24750#define ARM_VARIANT & arm_ext_v6 /* ARM V6. */
24751#undef THUMB_VARIANT
24752#define THUMB_VARIANT & arm_ext_v6
24753
21d799b5
NC
24754 TUF("cpsie", 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
24755 TUF("cpsid", 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
24756 tCE("rev", 6bf0f30, _rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24757 tCE("rev16", 6bf0fb0, _rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24758 tCE("revsh", 6ff0fb0, _revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24759 tCE("sxth", 6bf0070, _sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24760 tCE("uxth", 6ff0070, _uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24761 tCE("sxtb", 6af0070, _sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24762 tCE("uxtb", 6ef0070, _uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24763 TUF("setend", 1010000, b650, 1, (ENDI), setend, t_setend),
c19d1205 24764
c921be7d 24765#undef THUMB_VARIANT
ff8646ee 24766#define THUMB_VARIANT & arm_ext_v6t2_v8m
c921be7d 24767
5be8be5d
DG
24768 TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
24769 TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
24770 strex, t_strex),
ff8646ee
TP
24771#undef THUMB_VARIANT
24772#define THUMB_VARIANT & arm_ext_v6t2
24773
21d799b5
NC
24774 TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
24775 TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
62b3e311 24776
21d799b5
NC
24777 TCE("ssat", 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
24778 TCE("usat", 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
62b3e311 24779
9e3c6df6 24780/* ARM V6 not included in V7M. */
c921be7d
NC
24781#undef THUMB_VARIANT
24782#define THUMB_VARIANT & arm_ext_v6_notm
9e3c6df6 24783 TUF("rfeia", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6 24784 TUF("rfe", 8900a00, e990c000, 1, (RRw), rfe, rfe),
9e3c6df6
PB
24785 UF(rfeib, 9900a00, 1, (RRw), rfe),
24786 UF(rfeda, 8100a00, 1, (RRw), rfe),
24787 TUF("rfedb", 9100a00, e810c000, 1, (RRw), rfe, rfe),
24788 TUF("rfefd", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6
RE
24789 UF(rfefa, 8100a00, 1, (RRw), rfe),
24790 TUF("rfeea", 9100a00, e810c000, 1, (RRw), rfe, rfe),
24791 UF(rfeed, 9900a00, 1, (RRw), rfe),
9e3c6df6 24792 TUF("srsia", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
d709e4e6
RE
24793 TUF("srs", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
24794 TUF("srsea", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
9e3c6df6 24795 UF(srsib, 9c00500, 2, (oRRw, I31w), srs),
d709e4e6 24796 UF(srsfa, 9c00500, 2, (oRRw, I31w), srs),
9e3c6df6 24797 UF(srsda, 8400500, 2, (oRRw, I31w), srs),
d709e4e6 24798 UF(srsed, 8400500, 2, (oRRw, I31w), srs),
9e3c6df6 24799 TUF("srsdb", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
d709e4e6 24800 TUF("srsfd", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
941c9cad 24801 TUF("cps", 1020000, f3af8100, 1, (I31b), imm0, t_cps),
c921be7d 24802
9e3c6df6
PB
24803/* ARM V6 not included in V7M (eg. integer SIMD). */
24804#undef THUMB_VARIANT
24805#define THUMB_VARIANT & arm_ext_v6_dsp
21d799b5
NC
24806 TCE("pkhbt", 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
24807 TCE("pkhtb", 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
24808 TCE("qadd16", 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24809 TCE("qadd8", 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24810 TCE("qasx", 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24811 /* Old name for QASX. */
74db7efb 24812 TCE("qaddsubx",6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 24813 TCE("qsax", 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24814 /* Old name for QSAX. */
74db7efb 24815 TCE("qsubaddx",6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24816 TCE("qsub16", 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24817 TCE("qsub8", 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24818 TCE("sadd16", 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24819 TCE("sadd8", 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24820 TCE("sasx", 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24821 /* Old name for SASX. */
74db7efb 24822 TCE("saddsubx",6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24823 TCE("shadd16", 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24824 TCE("shadd8", 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24825 TCE("shasx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24826 /* Old name for SHASX. */
21d799b5 24827 TCE("shaddsubx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24828 TCE("shsax", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24829 /* Old name for SHSAX. */
21d799b5
NC
24830 TCE("shsubaddx", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24831 TCE("shsub16", 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24832 TCE("shsub8", 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24833 TCE("ssax", 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24834 /* Old name for SSAX. */
74db7efb 24835 TCE("ssubaddx",6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24836 TCE("ssub16", 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24837 TCE("ssub8", 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24838 TCE("uadd16", 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24839 TCE("uadd8", 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24840 TCE("uasx", 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24841 /* Old name for UASX. */
74db7efb 24842 TCE("uaddsubx",6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24843 TCE("uhadd16", 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24844 TCE("uhadd8", 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24845 TCE("uhasx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24846 /* Old name for UHASX. */
21d799b5
NC
24847 TCE("uhaddsubx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24848 TCE("uhsax", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24849 /* Old name for UHSAX. */
21d799b5
NC
24850 TCE("uhsubaddx", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24851 TCE("uhsub16", 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24852 TCE("uhsub8", 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24853 TCE("uqadd16", 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24854 TCE("uqadd8", 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24855 TCE("uqasx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24856 /* Old name for UQASX. */
21d799b5
NC
24857 TCE("uqaddsubx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24858 TCE("uqsax", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24859 /* Old name for UQSAX. */
21d799b5
NC
24860 TCE("uqsubaddx", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24861 TCE("uqsub16", 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24862 TCE("uqsub8", 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24863 TCE("usub16", 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24864 TCE("usax", 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24865 /* Old name for USAX. */
74db7efb 24866 TCE("usubaddx",6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 24867 TCE("usub8", 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24868 TCE("sxtah", 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24869 TCE("sxtab16", 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24870 TCE("sxtab", 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24871 TCE("sxtb16", 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24872 TCE("uxtah", 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24873 TCE("uxtab16", 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24874 TCE("uxtab", 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24875 TCE("uxtb16", 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24876 TCE("sel", 6800fb0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24877 TCE("smlad", 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24878 TCE("smladx", 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24879 TCE("smlald", 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24880 TCE("smlaldx", 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24881 TCE("smlsd", 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24882 TCE("smlsdx", 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24883 TCE("smlsld", 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24884 TCE("smlsldx", 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24885 TCE("smmla", 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24886 TCE("smmlar", 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24887 TCE("smmls", 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24888 TCE("smmlsr", 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24889 TCE("smmul", 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24890 TCE("smmulr", 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24891 TCE("smuad", 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24892 TCE("smuadx", 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24893 TCE("smusd", 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24894 TCE("smusdx", 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
21d799b5
NC
24895 TCE("ssat16", 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
24896 TCE("umaal", 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
24897 TCE("usad8", 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24898 TCE("usada8", 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24899 TCE("usat16", 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
c19d1205 24900
c921be7d 24901#undef ARM_VARIANT
55e8aae7 24902#define ARM_VARIANT & arm_ext_v6k_v6t2
c921be7d 24903#undef THUMB_VARIANT
55e8aae7 24904#define THUMB_VARIANT & arm_ext_v6k_v6t2
c921be7d 24905
21d799b5
NC
24906 tCE("yield", 320f001, _yield, 0, (), noargs, t_hint),
24907 tCE("wfe", 320f002, _wfe, 0, (), noargs, t_hint),
24908 tCE("wfi", 320f003, _wfi, 0, (), noargs, t_hint),
24909 tCE("sev", 320f004, _sev, 0, (), noargs, t_hint),
c19d1205 24910
c921be7d
NC
24911#undef THUMB_VARIANT
24912#define THUMB_VARIANT & arm_ext_v6_notm
5be8be5d
DG
24913 TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc_npcsp, oRRnpc_npcsp, RRnpcb),
24914 ldrexd, t_ldrexd),
24915 TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc_npcsp, RRnpc_npcsp, oRRnpc_npcsp,
24916 RRnpcb), strexd, t_strexd),
ebdca51a 24917
c921be7d 24918#undef THUMB_VARIANT
ff8646ee 24919#define THUMB_VARIANT & arm_ext_v6t2_v8m
5be8be5d
DG
24920 TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
24921 rd_rn, rd_rn),
24922 TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
24923 rd_rn, rd_rn),
24924 TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 24925 strex, t_strexbh),
5be8be5d 24926 TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 24927 strex, t_strexbh),
21d799b5 24928 TUF("clrex", 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
c19d1205 24929
c921be7d 24930#undef ARM_VARIANT
f4c65163 24931#define ARM_VARIANT & arm_ext_sec
74db7efb 24932#undef THUMB_VARIANT
f4c65163 24933#define THUMB_VARIANT & arm_ext_sec
c921be7d 24934
21d799b5 24935 TCE("smc", 1600070, f7f08000, 1, (EXPi), smc, t_smc),
c19d1205 24936
90ec0d68
MGD
24937#undef ARM_VARIANT
24938#define ARM_VARIANT & arm_ext_virt
24939#undef THUMB_VARIANT
24940#define THUMB_VARIANT & arm_ext_virt
24941
24942 TCE("hvc", 1400070, f7e08000, 1, (EXPi), hvc, t_hvc),
24943 TCE("eret", 160006e, f3de8f00, 0, (), noargs, noargs),
24944
ddfded2f
MW
24945#undef ARM_VARIANT
24946#define ARM_VARIANT & arm_ext_pan
24947#undef THUMB_VARIANT
24948#define THUMB_VARIANT & arm_ext_pan
24949
24950 TUF("setpan", 1100000, b610, 1, (I7), setpan, t_setpan),
24951
c921be7d 24952#undef ARM_VARIANT
74db7efb 24953#define ARM_VARIANT & arm_ext_v6t2
f4c65163
MGD
24954#undef THUMB_VARIANT
24955#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 24956
21d799b5
NC
24957 TCE("bfc", 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
24958 TCE("bfi", 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
24959 TCE("sbfx", 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
24960 TCE("ubfx", 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
c19d1205 24961
21d799b5 24962 TCE("mls", 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
21d799b5 24963 TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
c19d1205 24964
5be8be5d
DG
24965 TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24966 TC3("ldrsht", 03000f0, f9300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24967 TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24968 TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
c19d1205 24969
91d8b670
JG
24970#undef ARM_VARIANT
24971#define ARM_VARIANT & arm_ext_v3
24972#undef THUMB_VARIANT
24973#define THUMB_VARIANT & arm_ext_v6t2
24974
24975 TUE("csdb", 320f014, f3af8014, 0, (), noargs, t_csdb),
c597cc3d
SD
24976 TUF("ssbb", 57ff040, f3bf8f40, 0, (), noargs, t_csdb),
24977 TUF("pssbb", 57ff044, f3bf8f44, 0, (), noargs, t_csdb),
91d8b670
JG
24978
24979#undef ARM_VARIANT
24980#define ARM_VARIANT & arm_ext_v6t2
ff8646ee
TP
24981#undef THUMB_VARIANT
24982#define THUMB_VARIANT & arm_ext_v6t2_v8m
24983 TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
24984 TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
24985
bf3eeda7 24986 /* Thumb-only instructions. */
74db7efb 24987#undef ARM_VARIANT
bf3eeda7
NS
24988#define ARM_VARIANT NULL
24989 TUE("cbnz", 0, b900, 2, (RR, EXP), 0, t_cbz),
24990 TUE("cbz", 0, b100, 2, (RR, EXP), 0, t_cbz),
c921be7d
NC
24991
24992 /* ARM does not really have an IT instruction, so always allow it.
24993 The opcode is copied from Thumb in order to allow warnings in
24994 -mimplicit-it=[never | arm] modes. */
24995#undef ARM_VARIANT
24996#define ARM_VARIANT & arm_ext_v1
ff8646ee
TP
24997#undef THUMB_VARIANT
24998#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 24999
21d799b5
NC
25000 TUE("it", bf08, bf08, 1, (COND), it, t_it),
25001 TUE("itt", bf0c, bf0c, 1, (COND), it, t_it),
25002 TUE("ite", bf04, bf04, 1, (COND), it, t_it),
25003 TUE("ittt", bf0e, bf0e, 1, (COND), it, t_it),
25004 TUE("itet", bf06, bf06, 1, (COND), it, t_it),
25005 TUE("itte", bf0a, bf0a, 1, (COND), it, t_it),
25006 TUE("itee", bf02, bf02, 1, (COND), it, t_it),
25007 TUE("itttt", bf0f, bf0f, 1, (COND), it, t_it),
25008 TUE("itett", bf07, bf07, 1, (COND), it, t_it),
25009 TUE("ittet", bf0b, bf0b, 1, (COND), it, t_it),
25010 TUE("iteet", bf03, bf03, 1, (COND), it, t_it),
25011 TUE("ittte", bf0d, bf0d, 1, (COND), it, t_it),
25012 TUE("itete", bf05, bf05, 1, (COND), it, t_it),
25013 TUE("ittee", bf09, bf09, 1, (COND), it, t_it),
25014 TUE("iteee", bf01, bf01, 1, (COND), it, t_it),
1c444d06 25015 /* ARM/Thumb-2 instructions with no Thumb-1 equivalent. */
21d799b5
NC
25016 TC3("rrx", 01a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rrx),
25017 TC3("rrxs", 01b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rrx),
c19d1205 25018
92e90b6e 25019 /* Thumb2 only instructions. */
c921be7d
NC
25020#undef ARM_VARIANT
25021#define ARM_VARIANT NULL
92e90b6e 25022
21d799b5
NC
25023 TCE("addw", 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
25024 TCE("subw", 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
25025 TCE("orn", 0, ea600000, 3, (RR, oRR, SH), 0, t_orn),
25026 TCE("orns", 0, ea700000, 3, (RR, oRR, SH), 0, t_orn),
25027 TCE("tbb", 0, e8d0f000, 1, (TB), 0, t_tb),
25028 TCE("tbh", 0, e8d0f010, 1, (TB), 0, t_tb),
92e90b6e 25029
eea54501
MGD
25030 /* Hardware division instructions. */
25031#undef ARM_VARIANT
25032#define ARM_VARIANT & arm_ext_adiv
c921be7d
NC
25033#undef THUMB_VARIANT
25034#define THUMB_VARIANT & arm_ext_div
25035
eea54501
MGD
25036 TCE("sdiv", 710f010, fb90f0f0, 3, (RR, oRR, RR), div, t_div),
25037 TCE("udiv", 730f010, fbb0f0f0, 3, (RR, oRR, RR), div, t_div),
62b3e311 25038
7e806470 25039 /* ARM V6M/V7 instructions. */
c921be7d
NC
25040#undef ARM_VARIANT
25041#define ARM_VARIANT & arm_ext_barrier
25042#undef THUMB_VARIANT
25043#define THUMB_VARIANT & arm_ext_barrier
25044
ccb84d65
JB
25045 TUF("dmb", 57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier, barrier),
25046 TUF("dsb", 57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier, barrier),
25047 TUF("isb", 57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier, barrier),
7e806470 25048
62b3e311 25049 /* ARM V7 instructions. */
c921be7d
NC
25050#undef ARM_VARIANT
25051#define ARM_VARIANT & arm_ext_v7
25052#undef THUMB_VARIANT
25053#define THUMB_VARIANT & arm_ext_v7
25054
21d799b5
NC
25055 TUF("pli", 450f000, f910f000, 1, (ADDR), pli, t_pld),
25056 TCE("dbg", 320f0f0, f3af80f0, 1, (I15), dbg, t_dbg),
62b3e311 25057
74db7efb 25058#undef ARM_VARIANT
60e5ef9f 25059#define ARM_VARIANT & arm_ext_mp
74db7efb 25060#undef THUMB_VARIANT
60e5ef9f
MGD
25061#define THUMB_VARIANT & arm_ext_mp
25062
25063 TUF("pldw", 410f000, f830f000, 1, (ADDR), pld, t_pld),
25064
53c4b28b
MGD
25065 /* AArchv8 instructions. */
25066#undef ARM_VARIANT
25067#define ARM_VARIANT & arm_ext_v8
4ed7ed8d
TP
25068
25069/* Instructions shared between armv8-a and armv8-m. */
53c4b28b 25070#undef THUMB_VARIANT
4ed7ed8d 25071#define THUMB_VARIANT & arm_ext_atomics
53c4b28b 25072
4ed7ed8d
TP
25073 TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25074 TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25075 TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25076 TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
25077 TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
25078 TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
4b8c8c02 25079 TCE("ldaex", 1900e9f, e8d00fef, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
4b8c8c02
RE
25080 TCE("ldaexb", 1d00e9f, e8d00fcf, 2, (RRnpc,RRnpcb), rd_rn, rd_rn),
25081 TCE("ldaexh", 1f00e9f, e8d00fdf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
25082 TCE("stlex", 1800e90, e8c00fe0, 3, (RRnpc, RRnpc, RRnpcb),
25083 stlex, t_stlex),
4b8c8c02
RE
25084 TCE("stlexb", 1c00e90, e8c00fc0, 3, (RRnpc, RRnpc, RRnpcb),
25085 stlex, t_stlex),
25086 TCE("stlexh", 1e00e90, e8c00fd0, 3, (RRnpc, RRnpc, RRnpcb),
25087 stlex, t_stlex),
4ed7ed8d
TP
25088#undef THUMB_VARIANT
25089#define THUMB_VARIANT & arm_ext_v8
53c4b28b 25090
4ed7ed8d 25091 tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
4ed7ed8d
TP
25092 TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
25093 ldrexd, t_ldrexd),
25094 TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
25095 strexd, t_strexd),
26417f19
AC
25096#undef THUMB_VARIANT
25097#define THUMB_VARIANT & arm_ext_v8r
25098#undef ARM_VARIANT
25099#define ARM_VARIANT & arm_ext_v8r
25100
25101/* ARMv8-R instructions. */
25102 TUF("dfb", 57ff04c, f3bf8f4c, 0, (), noargs, noargs),
f7dd2fb2
TC
25103
25104/* Defined in V8 but is in undefined encoding space for earlier
25105 architectures. However earlier architectures are required to treat
25106 this instuction as a semihosting trap as well. Hence while not explicitly
25107 defined as such, it is in fact correct to define the instruction for all
25108 architectures. */
25109#undef THUMB_VARIANT
25110#define THUMB_VARIANT & arm_ext_v1
25111#undef ARM_VARIANT
25112#define ARM_VARIANT & arm_ext_v1
25113 TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
25114
8884b720 25115 /* ARMv8 T32 only. */
74db7efb 25116#undef ARM_VARIANT
b79f7053
MGD
25117#define ARM_VARIANT NULL
25118 TUF("dcps1", 0, f78f8001, 0, (), noargs, noargs),
25119 TUF("dcps2", 0, f78f8002, 0, (), noargs, noargs),
25120 TUF("dcps3", 0, f78f8003, 0, (), noargs, noargs),
25121
33399f07
MGD
25122 /* FP for ARMv8. */
25123#undef ARM_VARIANT
a715796b 25124#define ARM_VARIANT & fpu_vfp_ext_armv8xd
33399f07 25125#undef THUMB_VARIANT
a715796b 25126#define THUMB_VARIANT & fpu_vfp_ext_armv8xd
33399f07
MGD
25127
25128 nUF(vseleq, _vseleq, 3, (RVSD, RVSD, RVSD), vsel),
25129 nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD), vsel),
25130 nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD), vsel),
25131 nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD), vsel),
30bdf752 25132 nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ), vrintr),
a710b305
AV
25133 mnCE(vrintz, _vrintr, 2, (RNSDQMQ, oRNSDQMQ), vrintz),
25134 mnCE(vrintx, _vrintr, 2, (RNSDQMQ, oRNSDQMQ), vrintx),
25135 mnUF(vrinta, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrinta),
25136 mnUF(vrintn, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintn),
25137 mnUF(vrintp, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintp),
25138 mnUF(vrintm, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintm),
33399f07 25139
91ff7894
MGD
25140 /* Crypto v1 extensions. */
25141#undef ARM_VARIANT
25142#define ARM_VARIANT & fpu_crypto_ext_armv8
25143#undef THUMB_VARIANT
25144#define THUMB_VARIANT & fpu_crypto_ext_armv8
25145
25146 nUF(aese, _aes, 2, (RNQ, RNQ), aese),
25147 nUF(aesd, _aes, 2, (RNQ, RNQ), aesd),
25148 nUF(aesmc, _aes, 2, (RNQ, RNQ), aesmc),
25149 nUF(aesimc, _aes, 2, (RNQ, RNQ), aesimc),
48adcd8e
MGD
25150 nUF(sha1c, _sha3op, 3, (RNQ, RNQ, RNQ), sha1c),
25151 nUF(sha1p, _sha3op, 3, (RNQ, RNQ, RNQ), sha1p),
25152 nUF(sha1m, _sha3op, 3, (RNQ, RNQ, RNQ), sha1m),
25153 nUF(sha1su0, _sha3op, 3, (RNQ, RNQ, RNQ), sha1su0),
25154 nUF(sha256h, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h),
25155 nUF(sha256h2, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h2),
25156 nUF(sha256su1, _sha3op, 3, (RNQ, RNQ, RNQ), sha256su1),
3c9017d2
MGD
25157 nUF(sha1h, _sha1h, 2, (RNQ, RNQ), sha1h),
25158 nUF(sha1su1, _sha2op, 2, (RNQ, RNQ), sha1su1),
25159 nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
91ff7894 25160
dd5181d5 25161#undef ARM_VARIANT
8b301fbb 25162#define ARM_VARIANT & arm_ext_crc
dd5181d5 25163#undef THUMB_VARIANT
8b301fbb 25164#define THUMB_VARIANT & arm_ext_crc
dd5181d5
KT
25165 TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
25166 TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
25167 TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
25168 TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
25169 TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
25170 TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
25171
105bde57
MW
25172 /* ARMv8.2 RAS extension. */
25173#undef ARM_VARIANT
4d1464f2 25174#define ARM_VARIANT & arm_ext_ras
105bde57 25175#undef THUMB_VARIANT
4d1464f2 25176#define THUMB_VARIANT & arm_ext_ras
105bde57
MW
25177 TUE ("esb", 320f010, f3af8010, 0, (), noargs, noargs),
25178
49e8a725
SN
25179#undef ARM_VARIANT
25180#define ARM_VARIANT & arm_ext_v8_3
25181#undef THUMB_VARIANT
25182#define THUMB_VARIANT & arm_ext_v8_3
25183 NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
25184
c604a79a
JW
25185#undef ARM_VARIANT
25186#define ARM_VARIANT & fpu_neon_ext_dotprod
25187#undef THUMB_VARIANT
25188#define THUMB_VARIANT & fpu_neon_ext_dotprod
25189 NUF (vsdot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_s),
25190 NUF (vudot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_u),
25191
c921be7d
NC
25192#undef ARM_VARIANT
25193#define ARM_VARIANT & fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
53c4b28b
MGD
25194#undef THUMB_VARIANT
25195#define THUMB_VARIANT NULL
c921be7d 25196
21d799b5
NC
25197 cCE("wfs", e200110, 1, (RR), rd),
25198 cCE("rfs", e300110, 1, (RR), rd),
25199 cCE("wfc", e400110, 1, (RR), rd),
25200 cCE("rfc", e500110, 1, (RR), rd),
25201
25202 cCL("ldfs", c100100, 2, (RF, ADDRGLDC), rd_cpaddr),
25203 cCL("ldfd", c108100, 2, (RF, ADDRGLDC), rd_cpaddr),
25204 cCL("ldfe", c500100, 2, (RF, ADDRGLDC), rd_cpaddr),
25205 cCL("ldfp", c508100, 2, (RF, ADDRGLDC), rd_cpaddr),
25206
25207 cCL("stfs", c000100, 2, (RF, ADDRGLDC), rd_cpaddr),
25208 cCL("stfd", c008100, 2, (RF, ADDRGLDC), rd_cpaddr),
25209 cCL("stfe", c400100, 2, (RF, ADDRGLDC), rd_cpaddr),
25210 cCL("stfp", c408100, 2, (RF, ADDRGLDC), rd_cpaddr),
25211
25212 cCL("mvfs", e008100, 2, (RF, RF_IF), rd_rm),
25213 cCL("mvfsp", e008120, 2, (RF, RF_IF), rd_rm),
25214 cCL("mvfsm", e008140, 2, (RF, RF_IF), rd_rm),
25215 cCL("mvfsz", e008160, 2, (RF, RF_IF), rd_rm),
25216 cCL("mvfd", e008180, 2, (RF, RF_IF), rd_rm),
25217 cCL("mvfdp", e0081a0, 2, (RF, RF_IF), rd_rm),
25218 cCL("mvfdm", e0081c0, 2, (RF, RF_IF), rd_rm),
25219 cCL("mvfdz", e0081e0, 2, (RF, RF_IF), rd_rm),
25220 cCL("mvfe", e088100, 2, (RF, RF_IF), rd_rm),
25221 cCL("mvfep", e088120, 2, (RF, RF_IF), rd_rm),
25222 cCL("mvfem", e088140, 2, (RF, RF_IF), rd_rm),
25223 cCL("mvfez", e088160, 2, (RF, RF_IF), rd_rm),
25224
25225 cCL("mnfs", e108100, 2, (RF, RF_IF), rd_rm),
25226 cCL("mnfsp", e108120, 2, (RF, RF_IF), rd_rm),
25227 cCL("mnfsm", e108140, 2, (RF, RF_IF), rd_rm),
25228 cCL("mnfsz", e108160, 2, (RF, RF_IF), rd_rm),
25229 cCL("mnfd", e108180, 2, (RF, RF_IF), rd_rm),
25230 cCL("mnfdp", e1081a0, 2, (RF, RF_IF), rd_rm),
25231 cCL("mnfdm", e1081c0, 2, (RF, RF_IF), rd_rm),
25232 cCL("mnfdz", e1081e0, 2, (RF, RF_IF), rd_rm),
25233 cCL("mnfe", e188100, 2, (RF, RF_IF), rd_rm),
25234 cCL("mnfep", e188120, 2, (RF, RF_IF), rd_rm),
25235 cCL("mnfem", e188140, 2, (RF, RF_IF), rd_rm),
25236 cCL("mnfez", e188160, 2, (RF, RF_IF), rd_rm),
25237
25238 cCL("abss", e208100, 2, (RF, RF_IF), rd_rm),
25239 cCL("abssp", e208120, 2, (RF, RF_IF), rd_rm),
25240 cCL("abssm", e208140, 2, (RF, RF_IF), rd_rm),
25241 cCL("abssz", e208160, 2, (RF, RF_IF), rd_rm),
25242 cCL("absd", e208180, 2, (RF, RF_IF), rd_rm),
25243 cCL("absdp", e2081a0, 2, (RF, RF_IF), rd_rm),
25244 cCL("absdm", e2081c0, 2, (RF, RF_IF), rd_rm),
25245 cCL("absdz", e2081e0, 2, (RF, RF_IF), rd_rm),
25246 cCL("abse", e288100, 2, (RF, RF_IF), rd_rm),
25247 cCL("absep", e288120, 2, (RF, RF_IF), rd_rm),
25248 cCL("absem", e288140, 2, (RF, RF_IF), rd_rm),
25249 cCL("absez", e288160, 2, (RF, RF_IF), rd_rm),
25250
25251 cCL("rnds", e308100, 2, (RF, RF_IF), rd_rm),
25252 cCL("rndsp", e308120, 2, (RF, RF_IF), rd_rm),
25253 cCL("rndsm", e308140, 2, (RF, RF_IF), rd_rm),
25254 cCL("rndsz", e308160, 2, (RF, RF_IF), rd_rm),
25255 cCL("rndd", e308180, 2, (RF, RF_IF), rd_rm),
25256 cCL("rnddp", e3081a0, 2, (RF, RF_IF), rd_rm),
25257 cCL("rnddm", e3081c0, 2, (RF, RF_IF), rd_rm),
25258 cCL("rnddz", e3081e0, 2, (RF, RF_IF), rd_rm),
25259 cCL("rnde", e388100, 2, (RF, RF_IF), rd_rm),
25260 cCL("rndep", e388120, 2, (RF, RF_IF), rd_rm),
25261 cCL("rndem", e388140, 2, (RF, RF_IF), rd_rm),
25262 cCL("rndez", e388160, 2, (RF, RF_IF), rd_rm),
25263
25264 cCL("sqts", e408100, 2, (RF, RF_IF), rd_rm),
25265 cCL("sqtsp", e408120, 2, (RF, RF_IF), rd_rm),
25266 cCL("sqtsm", e408140, 2, (RF, RF_IF), rd_rm),
25267 cCL("sqtsz", e408160, 2, (RF, RF_IF), rd_rm),
25268 cCL("sqtd", e408180, 2, (RF, RF_IF), rd_rm),
25269 cCL("sqtdp", e4081a0, 2, (RF, RF_IF), rd_rm),
25270 cCL("sqtdm", e4081c0, 2, (RF, RF_IF), rd_rm),
25271 cCL("sqtdz", e4081e0, 2, (RF, RF_IF), rd_rm),
25272 cCL("sqte", e488100, 2, (RF, RF_IF), rd_rm),
25273 cCL("sqtep", e488120, 2, (RF, RF_IF), rd_rm),
25274 cCL("sqtem", e488140, 2, (RF, RF_IF), rd_rm),
25275 cCL("sqtez", e488160, 2, (RF, RF_IF), rd_rm),
25276
25277 cCL("logs", e508100, 2, (RF, RF_IF), rd_rm),
25278 cCL("logsp", e508120, 2, (RF, RF_IF), rd_rm),
25279 cCL("logsm", e508140, 2, (RF, RF_IF), rd_rm),
25280 cCL("logsz", e508160, 2, (RF, RF_IF), rd_rm),
25281 cCL("logd", e508180, 2, (RF, RF_IF), rd_rm),
25282 cCL("logdp", e5081a0, 2, (RF, RF_IF), rd_rm),
25283 cCL("logdm", e5081c0, 2, (RF, RF_IF), rd_rm),
25284 cCL("logdz", e5081e0, 2, (RF, RF_IF), rd_rm),
25285 cCL("loge", e588100, 2, (RF, RF_IF), rd_rm),
25286 cCL("logep", e588120, 2, (RF, RF_IF), rd_rm),
25287 cCL("logem", e588140, 2, (RF, RF_IF), rd_rm),
25288 cCL("logez", e588160, 2, (RF, RF_IF), rd_rm),
25289
25290 cCL("lgns", e608100, 2, (RF, RF_IF), rd_rm),
25291 cCL("lgnsp", e608120, 2, (RF, RF_IF), rd_rm),
25292 cCL("lgnsm", e608140, 2, (RF, RF_IF), rd_rm),
25293 cCL("lgnsz", e608160, 2, (RF, RF_IF), rd_rm),
25294 cCL("lgnd", e608180, 2, (RF, RF_IF), rd_rm),
25295 cCL("lgndp", e6081a0, 2, (RF, RF_IF), rd_rm),
25296 cCL("lgndm", e6081c0, 2, (RF, RF_IF), rd_rm),
25297 cCL("lgndz", e6081e0, 2, (RF, RF_IF), rd_rm),
25298 cCL("lgne", e688100, 2, (RF, RF_IF), rd_rm),
25299 cCL("lgnep", e688120, 2, (RF, RF_IF), rd_rm),
25300 cCL("lgnem", e688140, 2, (RF, RF_IF), rd_rm),
25301 cCL("lgnez", e688160, 2, (RF, RF_IF), rd_rm),
25302
25303 cCL("exps", e708100, 2, (RF, RF_IF), rd_rm),
25304 cCL("expsp", e708120, 2, (RF, RF_IF), rd_rm),
25305 cCL("expsm", e708140, 2, (RF, RF_IF), rd_rm),
25306 cCL("expsz", e708160, 2, (RF, RF_IF), rd_rm),
25307 cCL("expd", e708180, 2, (RF, RF_IF), rd_rm),
25308 cCL("expdp", e7081a0, 2, (RF, RF_IF), rd_rm),
25309 cCL("expdm", e7081c0, 2, (RF, RF_IF), rd_rm),
25310 cCL("expdz", e7081e0, 2, (RF, RF_IF), rd_rm),
25311 cCL("expe", e788100, 2, (RF, RF_IF), rd_rm),
25312 cCL("expep", e788120, 2, (RF, RF_IF), rd_rm),
25313 cCL("expem", e788140, 2, (RF, RF_IF), rd_rm),
25314 cCL("expdz", e788160, 2, (RF, RF_IF), rd_rm),
25315
25316 cCL("sins", e808100, 2, (RF, RF_IF), rd_rm),
25317 cCL("sinsp", e808120, 2, (RF, RF_IF), rd_rm),
25318 cCL("sinsm", e808140, 2, (RF, RF_IF), rd_rm),
25319 cCL("sinsz", e808160, 2, (RF, RF_IF), rd_rm),
25320 cCL("sind", e808180, 2, (RF, RF_IF), rd_rm),
25321 cCL("sindp", e8081a0, 2, (RF, RF_IF), rd_rm),
25322 cCL("sindm", e8081c0, 2, (RF, RF_IF), rd_rm),
25323 cCL("sindz", e8081e0, 2, (RF, RF_IF), rd_rm),
25324 cCL("sine", e888100, 2, (RF, RF_IF), rd_rm),
25325 cCL("sinep", e888120, 2, (RF, RF_IF), rd_rm),
25326 cCL("sinem", e888140, 2, (RF, RF_IF), rd_rm),
25327 cCL("sinez", e888160, 2, (RF, RF_IF), rd_rm),
25328
25329 cCL("coss", e908100, 2, (RF, RF_IF), rd_rm),
25330 cCL("cossp", e908120, 2, (RF, RF_IF), rd_rm),
25331 cCL("cossm", e908140, 2, (RF, RF_IF), rd_rm),
25332 cCL("cossz", e908160, 2, (RF, RF_IF), rd_rm),
25333 cCL("cosd", e908180, 2, (RF, RF_IF), rd_rm),
25334 cCL("cosdp", e9081a0, 2, (RF, RF_IF), rd_rm),
25335 cCL("cosdm", e9081c0, 2, (RF, RF_IF), rd_rm),
25336 cCL("cosdz", e9081e0, 2, (RF, RF_IF), rd_rm),
25337 cCL("cose", e988100, 2, (RF, RF_IF), rd_rm),
25338 cCL("cosep", e988120, 2, (RF, RF_IF), rd_rm),
25339 cCL("cosem", e988140, 2, (RF, RF_IF), rd_rm),
25340 cCL("cosez", e988160, 2, (RF, RF_IF), rd_rm),
25341
25342 cCL("tans", ea08100, 2, (RF, RF_IF), rd_rm),
25343 cCL("tansp", ea08120, 2, (RF, RF_IF), rd_rm),
25344 cCL("tansm", ea08140, 2, (RF, RF_IF), rd_rm),
25345 cCL("tansz", ea08160, 2, (RF, RF_IF), rd_rm),
25346 cCL("tand", ea08180, 2, (RF, RF_IF), rd_rm),
25347 cCL("tandp", ea081a0, 2, (RF, RF_IF), rd_rm),
25348 cCL("tandm", ea081c0, 2, (RF, RF_IF), rd_rm),
25349 cCL("tandz", ea081e0, 2, (RF, RF_IF), rd_rm),
25350 cCL("tane", ea88100, 2, (RF, RF_IF), rd_rm),
25351 cCL("tanep", ea88120, 2, (RF, RF_IF), rd_rm),
25352 cCL("tanem", ea88140, 2, (RF, RF_IF), rd_rm),
25353 cCL("tanez", ea88160, 2, (RF, RF_IF), rd_rm),
25354
25355 cCL("asns", eb08100, 2, (RF, RF_IF), rd_rm),
25356 cCL("asnsp", eb08120, 2, (RF, RF_IF), rd_rm),
25357 cCL("asnsm", eb08140, 2, (RF, RF_IF), rd_rm),
25358 cCL("asnsz", eb08160, 2, (RF, RF_IF), rd_rm),
25359 cCL("asnd", eb08180, 2, (RF, RF_IF), rd_rm),
25360 cCL("asndp", eb081a0, 2, (RF, RF_IF), rd_rm),
25361 cCL("asndm", eb081c0, 2, (RF, RF_IF), rd_rm),
25362 cCL("asndz", eb081e0, 2, (RF, RF_IF), rd_rm),
25363 cCL("asne", eb88100, 2, (RF, RF_IF), rd_rm),
25364 cCL("asnep", eb88120, 2, (RF, RF_IF), rd_rm),
25365 cCL("asnem", eb88140, 2, (RF, RF_IF), rd_rm),
25366 cCL("asnez", eb88160, 2, (RF, RF_IF), rd_rm),
25367
25368 cCL("acss", ec08100, 2, (RF, RF_IF), rd_rm),
25369 cCL("acssp", ec08120, 2, (RF, RF_IF), rd_rm),
25370 cCL("acssm", ec08140, 2, (RF, RF_IF), rd_rm),
25371 cCL("acssz", ec08160, 2, (RF, RF_IF), rd_rm),
25372 cCL("acsd", ec08180, 2, (RF, RF_IF), rd_rm),
25373 cCL("acsdp", ec081a0, 2, (RF, RF_IF), rd_rm),
25374 cCL("acsdm", ec081c0, 2, (RF, RF_IF), rd_rm),
25375 cCL("acsdz", ec081e0, 2, (RF, RF_IF), rd_rm),
25376 cCL("acse", ec88100, 2, (RF, RF_IF), rd_rm),
25377 cCL("acsep", ec88120, 2, (RF, RF_IF), rd_rm),
25378 cCL("acsem", ec88140, 2, (RF, RF_IF), rd_rm),
25379 cCL("acsez", ec88160, 2, (RF, RF_IF), rd_rm),
25380
25381 cCL("atns", ed08100, 2, (RF, RF_IF), rd_rm),
25382 cCL("atnsp", ed08120, 2, (RF, RF_IF), rd_rm),
25383 cCL("atnsm", ed08140, 2, (RF, RF_IF), rd_rm),
25384 cCL("atnsz", ed08160, 2, (RF, RF_IF), rd_rm),
25385 cCL("atnd", ed08180, 2, (RF, RF_IF), rd_rm),
25386 cCL("atndp", ed081a0, 2, (RF, RF_IF), rd_rm),
25387 cCL("atndm", ed081c0, 2, (RF, RF_IF), rd_rm),
25388 cCL("atndz", ed081e0, 2, (RF, RF_IF), rd_rm),
25389 cCL("atne", ed88100, 2, (RF, RF_IF), rd_rm),
25390 cCL("atnep", ed88120, 2, (RF, RF_IF), rd_rm),
25391 cCL("atnem", ed88140, 2, (RF, RF_IF), rd_rm),
25392 cCL("atnez", ed88160, 2, (RF, RF_IF), rd_rm),
25393
25394 cCL("urds", ee08100, 2, (RF, RF_IF), rd_rm),
25395 cCL("urdsp", ee08120, 2, (RF, RF_IF), rd_rm),
25396 cCL("urdsm", ee08140, 2, (RF, RF_IF), rd_rm),
25397 cCL("urdsz", ee08160, 2, (RF, RF_IF), rd_rm),
25398 cCL("urdd", ee08180, 2, (RF, RF_IF), rd_rm),
25399 cCL("urddp", ee081a0, 2, (RF, RF_IF), rd_rm),
25400 cCL("urddm", ee081c0, 2, (RF, RF_IF), rd_rm),
25401 cCL("urddz", ee081e0, 2, (RF, RF_IF), rd_rm),
25402 cCL("urde", ee88100, 2, (RF, RF_IF), rd_rm),
25403 cCL("urdep", ee88120, 2, (RF, RF_IF), rd_rm),
25404 cCL("urdem", ee88140, 2, (RF, RF_IF), rd_rm),
25405 cCL("urdez", ee88160, 2, (RF, RF_IF), rd_rm),
25406
25407 cCL("nrms", ef08100, 2, (RF, RF_IF), rd_rm),
25408 cCL("nrmsp", ef08120, 2, (RF, RF_IF), rd_rm),
25409 cCL("nrmsm", ef08140, 2, (RF, RF_IF), rd_rm),
25410 cCL("nrmsz", ef08160, 2, (RF, RF_IF), rd_rm),
25411 cCL("nrmd", ef08180, 2, (RF, RF_IF), rd_rm),
25412 cCL("nrmdp", ef081a0, 2, (RF, RF_IF), rd_rm),
25413 cCL("nrmdm", ef081c0, 2, (RF, RF_IF), rd_rm),
25414 cCL("nrmdz", ef081e0, 2, (RF, RF_IF), rd_rm),
25415 cCL("nrme", ef88100, 2, (RF, RF_IF), rd_rm),
25416 cCL("nrmep", ef88120, 2, (RF, RF_IF), rd_rm),
25417 cCL("nrmem", ef88140, 2, (RF, RF_IF), rd_rm),
25418 cCL("nrmez", ef88160, 2, (RF, RF_IF), rd_rm),
25419
25420 cCL("adfs", e000100, 3, (RF, RF, RF_IF), rd_rn_rm),
25421 cCL("adfsp", e000120, 3, (RF, RF, RF_IF), rd_rn_rm),
25422 cCL("adfsm", e000140, 3, (RF, RF, RF_IF), rd_rn_rm),
25423 cCL("adfsz", e000160, 3, (RF, RF, RF_IF), rd_rn_rm),
25424 cCL("adfd", e000180, 3, (RF, RF, RF_IF), rd_rn_rm),
25425 cCL("adfdp", e0001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25426 cCL("adfdm", e0001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25427 cCL("adfdz", e0001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25428 cCL("adfe", e080100, 3, (RF, RF, RF_IF), rd_rn_rm),
25429 cCL("adfep", e080120, 3, (RF, RF, RF_IF), rd_rn_rm),
25430 cCL("adfem", e080140, 3, (RF, RF, RF_IF), rd_rn_rm),
25431 cCL("adfez", e080160, 3, (RF, RF, RF_IF), rd_rn_rm),
25432
25433 cCL("sufs", e200100, 3, (RF, RF, RF_IF), rd_rn_rm),
25434 cCL("sufsp", e200120, 3, (RF, RF, RF_IF), rd_rn_rm),
25435 cCL("sufsm", e200140, 3, (RF, RF, RF_IF), rd_rn_rm),
25436 cCL("sufsz", e200160, 3, (RF, RF, RF_IF), rd_rn_rm),
25437 cCL("sufd", e200180, 3, (RF, RF, RF_IF), rd_rn_rm),
25438 cCL("sufdp", e2001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25439 cCL("sufdm", e2001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25440 cCL("sufdz", e2001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25441 cCL("sufe", e280100, 3, (RF, RF, RF_IF), rd_rn_rm),
25442 cCL("sufep", e280120, 3, (RF, RF, RF_IF), rd_rn_rm),
25443 cCL("sufem", e280140, 3, (RF, RF, RF_IF), rd_rn_rm),
25444 cCL("sufez", e280160, 3, (RF, RF, RF_IF), rd_rn_rm),
25445
25446 cCL("rsfs", e300100, 3, (RF, RF, RF_IF), rd_rn_rm),
25447 cCL("rsfsp", e300120, 3, (RF, RF, RF_IF), rd_rn_rm),
25448 cCL("rsfsm", e300140, 3, (RF, RF, RF_IF), rd_rn_rm),
25449 cCL("rsfsz", e300160, 3, (RF, RF, RF_IF), rd_rn_rm),
25450 cCL("rsfd", e300180, 3, (RF, RF, RF_IF), rd_rn_rm),
25451 cCL("rsfdp", e3001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25452 cCL("rsfdm", e3001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25453 cCL("rsfdz", e3001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25454 cCL("rsfe", e380100, 3, (RF, RF, RF_IF), rd_rn_rm),
25455 cCL("rsfep", e380120, 3, (RF, RF, RF_IF), rd_rn_rm),
25456 cCL("rsfem", e380140, 3, (RF, RF, RF_IF), rd_rn_rm),
25457 cCL("rsfez", e380160, 3, (RF, RF, RF_IF), rd_rn_rm),
25458
25459 cCL("mufs", e100100, 3, (RF, RF, RF_IF), rd_rn_rm),
25460 cCL("mufsp", e100120, 3, (RF, RF, RF_IF), rd_rn_rm),
25461 cCL("mufsm", e100140, 3, (RF, RF, RF_IF), rd_rn_rm),
25462 cCL("mufsz", e100160, 3, (RF, RF, RF_IF), rd_rn_rm),
25463 cCL("mufd", e100180, 3, (RF, RF, RF_IF), rd_rn_rm),
25464 cCL("mufdp", e1001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25465 cCL("mufdm", e1001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25466 cCL("mufdz", e1001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25467 cCL("mufe", e180100, 3, (RF, RF, RF_IF), rd_rn_rm),
25468 cCL("mufep", e180120, 3, (RF, RF, RF_IF), rd_rn_rm),
25469 cCL("mufem", e180140, 3, (RF, RF, RF_IF), rd_rn_rm),
25470 cCL("mufez", e180160, 3, (RF, RF, RF_IF), rd_rn_rm),
25471
25472 cCL("dvfs", e400100, 3, (RF, RF, RF_IF), rd_rn_rm),
25473 cCL("dvfsp", e400120, 3, (RF, RF, RF_IF), rd_rn_rm),
25474 cCL("dvfsm", e400140, 3, (RF, RF, RF_IF), rd_rn_rm),
25475 cCL("dvfsz", e400160, 3, (RF, RF, RF_IF), rd_rn_rm),
25476 cCL("dvfd", e400180, 3, (RF, RF, RF_IF), rd_rn_rm),
25477 cCL("dvfdp", e4001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25478 cCL("dvfdm", e4001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25479 cCL("dvfdz", e4001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25480 cCL("dvfe", e480100, 3, (RF, RF, RF_IF), rd_rn_rm),
25481 cCL("dvfep", e480120, 3, (RF, RF, RF_IF), rd_rn_rm),
25482 cCL("dvfem", e480140, 3, (RF, RF, RF_IF), rd_rn_rm),
25483 cCL("dvfez", e480160, 3, (RF, RF, RF_IF), rd_rn_rm),
25484
25485 cCL("rdfs", e500100, 3, (RF, RF, RF_IF), rd_rn_rm),
25486 cCL("rdfsp", e500120, 3, (RF, RF, RF_IF), rd_rn_rm),
25487 cCL("rdfsm", e500140, 3, (RF, RF, RF_IF), rd_rn_rm),
25488 cCL("rdfsz", e500160, 3, (RF, RF, RF_IF), rd_rn_rm),
25489 cCL("rdfd", e500180, 3, (RF, RF, RF_IF), rd_rn_rm),
25490 cCL("rdfdp", e5001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25491 cCL("rdfdm", e5001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25492 cCL("rdfdz", e5001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25493 cCL("rdfe", e580100, 3, (RF, RF, RF_IF), rd_rn_rm),
25494 cCL("rdfep", e580120, 3, (RF, RF, RF_IF), rd_rn_rm),
25495 cCL("rdfem", e580140, 3, (RF, RF, RF_IF), rd_rn_rm),
25496 cCL("rdfez", e580160, 3, (RF, RF, RF_IF), rd_rn_rm),
25497
25498 cCL("pows", e600100, 3, (RF, RF, RF_IF), rd_rn_rm),
25499 cCL("powsp", e600120, 3, (RF, RF, RF_IF), rd_rn_rm),
25500 cCL("powsm", e600140, 3, (RF, RF, RF_IF), rd_rn_rm),
25501 cCL("powsz", e600160, 3, (RF, RF, RF_IF), rd_rn_rm),
25502 cCL("powd", e600180, 3, (RF, RF, RF_IF), rd_rn_rm),
25503 cCL("powdp", e6001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25504 cCL("powdm", e6001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25505 cCL("powdz", e6001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25506 cCL("powe", e680100, 3, (RF, RF, RF_IF), rd_rn_rm),
25507 cCL("powep", e680120, 3, (RF, RF, RF_IF), rd_rn_rm),
25508 cCL("powem", e680140, 3, (RF, RF, RF_IF), rd_rn_rm),
25509 cCL("powez", e680160, 3, (RF, RF, RF_IF), rd_rn_rm),
25510
25511 cCL("rpws", e700100, 3, (RF, RF, RF_IF), rd_rn_rm),
25512 cCL("rpwsp", e700120, 3, (RF, RF, RF_IF), rd_rn_rm),
25513 cCL("rpwsm", e700140, 3, (RF, RF, RF_IF), rd_rn_rm),
25514 cCL("rpwsz", e700160, 3, (RF, RF, RF_IF), rd_rn_rm),
25515 cCL("rpwd", e700180, 3, (RF, RF, RF_IF), rd_rn_rm),
25516 cCL("rpwdp", e7001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25517 cCL("rpwdm", e7001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25518 cCL("rpwdz", e7001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25519 cCL("rpwe", e780100, 3, (RF, RF, RF_IF), rd_rn_rm),
25520 cCL("rpwep", e780120, 3, (RF, RF, RF_IF), rd_rn_rm),
25521 cCL("rpwem", e780140, 3, (RF, RF, RF_IF), rd_rn_rm),
25522 cCL("rpwez", e780160, 3, (RF, RF, RF_IF), rd_rn_rm),
25523
25524 cCL("rmfs", e800100, 3, (RF, RF, RF_IF), rd_rn_rm),
25525 cCL("rmfsp", e800120, 3, (RF, RF, RF_IF), rd_rn_rm),
25526 cCL("rmfsm", e800140, 3, (RF, RF, RF_IF), rd_rn_rm),
25527 cCL("rmfsz", e800160, 3, (RF, RF, RF_IF), rd_rn_rm),
25528 cCL("rmfd", e800180, 3, (RF, RF, RF_IF), rd_rn_rm),
25529 cCL("rmfdp", e8001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25530 cCL("rmfdm", e8001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25531 cCL("rmfdz", e8001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25532 cCL("rmfe", e880100, 3, (RF, RF, RF_IF), rd_rn_rm),
25533 cCL("rmfep", e880120, 3, (RF, RF, RF_IF), rd_rn_rm),
25534 cCL("rmfem", e880140, 3, (RF, RF, RF_IF), rd_rn_rm),
25535 cCL("rmfez", e880160, 3, (RF, RF, RF_IF), rd_rn_rm),
25536
25537 cCL("fmls", e900100, 3, (RF, RF, RF_IF), rd_rn_rm),
25538 cCL("fmlsp", e900120, 3, (RF, RF, RF_IF), rd_rn_rm),
25539 cCL("fmlsm", e900140, 3, (RF, RF, RF_IF), rd_rn_rm),
25540 cCL("fmlsz", e900160, 3, (RF, RF, RF_IF), rd_rn_rm),
25541 cCL("fmld", e900180, 3, (RF, RF, RF_IF), rd_rn_rm),
25542 cCL("fmldp", e9001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25543 cCL("fmldm", e9001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25544 cCL("fmldz", e9001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25545 cCL("fmle", e980100, 3, (RF, RF, RF_IF), rd_rn_rm),
25546 cCL("fmlep", e980120, 3, (RF, RF, RF_IF), rd_rn_rm),
25547 cCL("fmlem", e980140, 3, (RF, RF, RF_IF), rd_rn_rm),
25548 cCL("fmlez", e980160, 3, (RF, RF, RF_IF), rd_rn_rm),
25549
25550 cCL("fdvs", ea00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25551 cCL("fdvsp", ea00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25552 cCL("fdvsm", ea00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25553 cCL("fdvsz", ea00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25554 cCL("fdvd", ea00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25555 cCL("fdvdp", ea001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25556 cCL("fdvdm", ea001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25557 cCL("fdvdz", ea001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25558 cCL("fdve", ea80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25559 cCL("fdvep", ea80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25560 cCL("fdvem", ea80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25561 cCL("fdvez", ea80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25562
25563 cCL("frds", eb00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25564 cCL("frdsp", eb00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25565 cCL("frdsm", eb00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25566 cCL("frdsz", eb00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25567 cCL("frdd", eb00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25568 cCL("frddp", eb001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25569 cCL("frddm", eb001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25570 cCL("frddz", eb001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25571 cCL("frde", eb80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25572 cCL("frdep", eb80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25573 cCL("frdem", eb80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25574 cCL("frdez", eb80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25575
25576 cCL("pols", ec00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25577 cCL("polsp", ec00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25578 cCL("polsm", ec00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25579 cCL("polsz", ec00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25580 cCL("pold", ec00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25581 cCL("poldp", ec001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25582 cCL("poldm", ec001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25583 cCL("poldz", ec001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25584 cCL("pole", ec80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25585 cCL("polep", ec80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25586 cCL("polem", ec80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25587 cCL("polez", ec80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25588
25589 cCE("cmf", e90f110, 2, (RF, RF_IF), fpa_cmp),
25590 C3E("cmfe", ed0f110, 2, (RF, RF_IF), fpa_cmp),
25591 cCE("cnf", eb0f110, 2, (RF, RF_IF), fpa_cmp),
25592 C3E("cnfe", ef0f110, 2, (RF, RF_IF), fpa_cmp),
25593
25594 cCL("flts", e000110, 2, (RF, RR), rn_rd),
25595 cCL("fltsp", e000130, 2, (RF, RR), rn_rd),
25596 cCL("fltsm", e000150, 2, (RF, RR), rn_rd),
25597 cCL("fltsz", e000170, 2, (RF, RR), rn_rd),
25598 cCL("fltd", e000190, 2, (RF, RR), rn_rd),
25599 cCL("fltdp", e0001b0, 2, (RF, RR), rn_rd),
25600 cCL("fltdm", e0001d0, 2, (RF, RR), rn_rd),
25601 cCL("fltdz", e0001f0, 2, (RF, RR), rn_rd),
25602 cCL("flte", e080110, 2, (RF, RR), rn_rd),
25603 cCL("fltep", e080130, 2, (RF, RR), rn_rd),
25604 cCL("fltem", e080150, 2, (RF, RR), rn_rd),
25605 cCL("fltez", e080170, 2, (RF, RR), rn_rd),
b99bd4ef 25606
c19d1205
ZW
25607 /* The implementation of the FIX instruction is broken on some
25608 assemblers, in that it accepts a precision specifier as well as a
25609 rounding specifier, despite the fact that this is meaningless.
25610 To be more compatible, we accept it as well, though of course it
25611 does not set any bits. */
21d799b5
NC
25612 cCE("fix", e100110, 2, (RR, RF), rd_rm),
25613 cCL("fixp", e100130, 2, (RR, RF), rd_rm),
25614 cCL("fixm", e100150, 2, (RR, RF), rd_rm),
25615 cCL("fixz", e100170, 2, (RR, RF), rd_rm),
25616 cCL("fixsp", e100130, 2, (RR, RF), rd_rm),
25617 cCL("fixsm", e100150, 2, (RR, RF), rd_rm),
25618 cCL("fixsz", e100170, 2, (RR, RF), rd_rm),
25619 cCL("fixdp", e100130, 2, (RR, RF), rd_rm),
25620 cCL("fixdm", e100150, 2, (RR, RF), rd_rm),
25621 cCL("fixdz", e100170, 2, (RR, RF), rd_rm),
25622 cCL("fixep", e100130, 2, (RR, RF), rd_rm),
25623 cCL("fixem", e100150, 2, (RR, RF), rd_rm),
25624 cCL("fixez", e100170, 2, (RR, RF), rd_rm),
bfae80f2 25625
c19d1205 25626 /* Instructions that were new with the real FPA, call them V2. */
c921be7d
NC
25627#undef ARM_VARIANT
25628#define ARM_VARIANT & fpu_fpa_ext_v2
25629
21d799b5
NC
25630 cCE("lfm", c100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25631 cCL("lfmfd", c900200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25632 cCL("lfmea", d100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25633 cCE("sfm", c000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25634 cCL("sfmfd", d000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25635 cCL("sfmea", c800200, 3, (RF, I4b, ADDR), fpa_ldmstm),
c19d1205 25636
c921be7d
NC
25637#undef ARM_VARIANT
25638#define ARM_VARIANT & fpu_vfp_ext_v1xd /* VFP V1xD (single precision). */
ba6cd17f
SD
25639#undef THUMB_VARIANT
25640#define THUMB_VARIANT & arm_ext_v6t2
25641 mcCE(vmrs, ef00a10, 2, (APSR_RR, RVC), vmrs),
25642 mcCE(vmsr, ee00a10, 2, (RVC, RR), vmsr),
ef8f595f
MI
25643 mcCE(fldd, d100b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
25644 mcCE(fstd, d000b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
25645 mcCE(flds, d100a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
25646 mcCE(fsts, d000a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
90e9955a
SP
25647
25648 /* Memory operations. */
25649 mcCE(fldmias, c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
25650 mcCE(fldmdbs, d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25651 mcCE(fstmias, c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
25652 mcCE(fstmdbs, d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
ba6cd17f 25653#undef THUMB_VARIANT
c921be7d 25654
c19d1205 25655 /* Moves and type conversions. */
21d799b5
NC
25656 cCE("fmstat", ef1fa10, 0, (), noargs),
25657 cCE("fsitos", eb80ac0, 2, (RVS, RVS), vfp_sp_monadic),
25658 cCE("fuitos", eb80a40, 2, (RVS, RVS), vfp_sp_monadic),
25659 cCE("ftosis", ebd0a40, 2, (RVS, RVS), vfp_sp_monadic),
25660 cCE("ftosizs", ebd0ac0, 2, (RVS, RVS), vfp_sp_monadic),
25661 cCE("ftouis", ebc0a40, 2, (RVS, RVS), vfp_sp_monadic),
25662 cCE("ftouizs", ebc0ac0, 2, (RVS, RVS), vfp_sp_monadic),
25663 cCE("fmrx", ef00a10, 2, (RR, RVC), rd_rn),
25664 cCE("fmxr", ee00a10, 2, (RVC, RR), rn_rd),
c19d1205
ZW
25665
25666 /* Memory operations. */
55881a11 25667 cCE("fldmfds", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
55881a11
MGD
25668 cCE("fldmeas", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25669 cCE("fldmiax", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25670 cCE("fldmfdx", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25671 cCE("fldmdbx", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
25672 cCE("fldmeax", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
55881a11 25673 cCE("fstmeas", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
55881a11
MGD
25674 cCE("fstmfds", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25675 cCE("fstmiax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25676 cCE("fstmeax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25677 cCE("fstmdbx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
25678 cCE("fstmfdx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
bfae80f2 25679
c19d1205 25680 /* Monadic operations. */
21d799b5
NC
25681 cCE("fabss", eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
25682 cCE("fnegs", eb10a40, 2, (RVS, RVS), vfp_sp_monadic),
25683 cCE("fsqrts", eb10ac0, 2, (RVS, RVS), vfp_sp_monadic),
c19d1205
ZW
25684
25685 /* Dyadic operations. */
21d799b5
NC
25686 cCE("fadds", e300a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25687 cCE("fsubs", e300a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25688 cCE("fmuls", e200a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25689 cCE("fdivs", e800a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25690 cCE("fmacs", e000a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25691 cCE("fmscs", e100a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25692 cCE("fnmuls", e200a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25693 cCE("fnmacs", e000a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25694 cCE("fnmscs", e100a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
b99bd4ef 25695
c19d1205 25696 /* Comparisons. */
21d799b5
NC
25697 cCE("fcmps", eb40a40, 2, (RVS, RVS), vfp_sp_monadic),
25698 cCE("fcmpzs", eb50a40, 1, (RVS), vfp_sp_compare_z),
25699 cCE("fcmpes", eb40ac0, 2, (RVS, RVS), vfp_sp_monadic),
25700 cCE("fcmpezs", eb50ac0, 1, (RVS), vfp_sp_compare_z),
b99bd4ef 25701
62f3b8c8
PB
25702 /* Double precision load/store are still present on single precision
25703 implementations. */
55881a11
MGD
25704 cCE("fldmiad", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25705 cCE("fldmfdd", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25706 cCE("fldmdbd", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25707 cCE("fldmead", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25708 cCE("fstmiad", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25709 cCE("fstmead", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25710 cCE("fstmdbd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25711 cCE("fstmfdd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
62f3b8c8 25712
c921be7d
NC
25713#undef ARM_VARIANT
25714#define ARM_VARIANT & fpu_vfp_ext_v1 /* VFP V1 (Double precision). */
25715
c19d1205 25716 /* Moves and type conversions. */
21d799b5
NC
25717 cCE("fcvtds", eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt),
25718 cCE("fcvtsd", eb70bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
25719 cCE("fmdhr", e200b10, 2, (RVD, RR), vfp_dp_rn_rd),
25720 cCE("fmdlr", e000b10, 2, (RVD, RR), vfp_dp_rn_rd),
25721 cCE("fmrdh", e300b10, 2, (RR, RVD), vfp_dp_rd_rn),
25722 cCE("fmrdl", e100b10, 2, (RR, RVD), vfp_dp_rd_rn),
25723 cCE("fsitod", eb80bc0, 2, (RVD, RVS), vfp_dp_sp_cvt),
25724 cCE("fuitod", eb80b40, 2, (RVD, RVS), vfp_dp_sp_cvt),
25725 cCE("ftosid", ebd0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
25726 cCE("ftosizd", ebd0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
25727 cCE("ftouid", ebc0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
25728 cCE("ftouizd", ebc0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
c19d1205 25729
c19d1205 25730 /* Monadic operations. */
21d799b5
NC
25731 cCE("fabsd", eb00bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
25732 cCE("fnegd", eb10b40, 2, (RVD, RVD), vfp_dp_rd_rm),
25733 cCE("fsqrtd", eb10bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
c19d1205
ZW
25734
25735 /* Dyadic operations. */
21d799b5
NC
25736 cCE("faddd", e300b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25737 cCE("fsubd", e300b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25738 cCE("fmuld", e200b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25739 cCE("fdivd", e800b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25740 cCE("fmacd", e000b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25741 cCE("fmscd", e100b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25742 cCE("fnmuld", e200b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25743 cCE("fnmacd", e000b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25744 cCE("fnmscd", e100b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
b99bd4ef 25745
c19d1205 25746 /* Comparisons. */
21d799b5
NC
25747 cCE("fcmpd", eb40b40, 2, (RVD, RVD), vfp_dp_rd_rm),
25748 cCE("fcmpzd", eb50b40, 1, (RVD), vfp_dp_rd),
25749 cCE("fcmped", eb40bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
25750 cCE("fcmpezd", eb50bc0, 1, (RVD), vfp_dp_rd),
c19d1205 25751
037e8744
JB
25752/* Instructions which may belong to either the Neon or VFP instruction sets.
25753 Individual encoder functions perform additional architecture checks. */
c921be7d
NC
25754#undef ARM_VARIANT
25755#define ARM_VARIANT & fpu_vfp_ext_v1xd
ef8f595f
MI
25756#undef THUMB_VARIANT
25757#define THUMB_VARIANT & arm_ext_v6t2
25758
25759 NCE(vldm, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25760 NCE(vldmia, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25761 NCE(vldmdb, d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25762 NCE(vstm, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25763 NCE(vstmia, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25764 NCE(vstmdb, d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25765
25766 NCE(vpop, 0, 1, (VRSDLST), vfp_nsyn_pop),
25767 NCE(vpush, 0, 1, (VRSDLST), vfp_nsyn_push),
25768
c921be7d
NC
25769#undef THUMB_VARIANT
25770#define THUMB_VARIANT & fpu_vfp_ext_v1xd
25771
037e8744
JB
25772 /* These mnemonics are unique to VFP. */
25773 NCE(vsqrt, 0, 2, (RVSD, RVSD), vfp_nsyn_sqrt),
25774 NCE(vdiv, 0, 3, (RVSD, RVSD, RVSD), vfp_nsyn_div),
21d799b5
NC
25775 nCE(vnmul, _vnmul, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
25776 nCE(vnmla, _vnmla, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
25777 nCE(vnmls, _vnmls, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
037e8744
JB
25778 NCE(vcvtz, 0, 2, (RVSD, RVSD), vfp_nsyn_cvtz),
25779
25780 /* Mnemonics shared by Neon and VFP. */
21d799b5 25781 nCEF(vmls, _vmls, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
037e8744 25782
dd9634d9 25783 mnCEF(vcvt, _vcvt, 3, (RNSDQMQ, RNSDQMQ, oI32z), neon_cvt),
e3e535bc 25784 nCEF(vcvtr, _vcvt, 2, (RNSDQ, RNSDQ), neon_cvtr),
dd9634d9
AV
25785 MNCEF(vcvtb, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtb),
25786 MNCEF(vcvtt, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtt),
f31fef98 25787
037e8744
JB
25788
25789 /* NOTE: All VMOV encoding is special-cased! */
037e8744
JB
25790 NCE(vmovq, 0, 1, (VMOV), neon_mov),
25791
32c36c3c
AV
25792#undef THUMB_VARIANT
25793/* Could be either VLDR/VSTR or VLDR/VSTR (system register) which are guarded
25794 by different feature bits. Since we are setting the Thumb guard, we can
25795 require Thumb-1 which makes it a nop guard and set the right feature bit in
25796 do_vldr_vstr (). */
25797#define THUMB_VARIANT & arm_ext_v4t
25798 NCE(vldr, d100b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
25799 NCE(vstr, d000b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
25800
9db2f6b4
RL
25801#undef ARM_VARIANT
25802#define ARM_VARIANT & arm_ext_fp16
25803#undef THUMB_VARIANT
25804#define THUMB_VARIANT & arm_ext_fp16
25805 /* New instructions added from v8.2, allowing the extraction and insertion of
25806 the upper 16 bits of a 32-bit vector register. */
25807 NCE (vmovx, eb00a40, 2, (RVS, RVS), neon_movhf),
25808 NCE (vins, eb00ac0, 2, (RVS, RVS), neon_movhf),
25809
dec41383 25810 /* New backported fma/fms instructions optional in v8.2. */
aab2c27d
MM
25811 NUF (vfmsl, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmsl),
25812 NUF (vfmal, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmal),
dec41383 25813
c921be7d
NC
25814#undef THUMB_VARIANT
25815#define THUMB_VARIANT & fpu_neon_ext_v1
25816#undef ARM_VARIANT
25817#define ARM_VARIANT & fpu_neon_ext_v1
25818
5287ad62
JB
25819 /* Data processing with three registers of the same length. */
25820 /* integer ops, valid types S8 S16 S32 U8 U16 U32. */
25821 NUF(vaba, 0000710, 3, (RNDQ, RNDQ, RNDQ), neon_dyadic_i_su),
25822 NUF(vabaq, 0000710, 3, (RNQ, RNQ, RNQ), neon_dyadic_i_su),
5287ad62 25823 NUF(vhaddq, 0000000, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62 25824 NUF(vrhaddq, 0000100, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62
JB
25825 NUF(vhsubq, 0000200, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
25826 /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62 25827 NUF(vqaddq, 0000010, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
5287ad62 25828 NUF(vqsubq, 0000210, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
627907b7 25829 NUF(vrshlq, 0000500, 3, (RNQ, oRNQ, RNQ), neon_rshl),
627907b7 25830 NUF(vqrshlq, 0000510, 3, (RNQ, oRNQ, RNQ), neon_rshl),
5287ad62 25831 /* If not immediate, fall back to neon_dyadic_i64_su.
5150f0d8
AV
25832 shl should accept I8 I16 I32 I64,
25833 qshl should accept S8 S16 S32 S64 U8 U16 U32 U64. */
25834 nUF(vshlq, _vshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_shl),
25835 nUF(vqshlq, _vqshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_qshl),
5287ad62 25836 /* Logic ops, types optional & ignored. */
4316f0d2 25837 nUF(vandq, _vand, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25838 nUF(vbicq, _vbic, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25839 nUF(vorrq, _vorr, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25840 nUF(vornq, _vorn, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25841 nUF(veorq, _veor, 3, (RNQ, oRNQ, RNQ), neon_logic),
5287ad62
JB
25842 /* Bitfield ops, untyped. */
25843 NUF(vbsl, 1100110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25844 NUF(vbslq, 1100110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
25845 NUF(vbit, 1200110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25846 NUF(vbitq, 1200110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
25847 NUF(vbif, 1300110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25848 NUF(vbifq, 1300110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
cc933301 25849 /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32. */
21d799b5 25850 nUF(vabdq, _vabd, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 25851 nUF(vmaxq, _vmax, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 25852 nUF(vminq, _vmin, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
5287ad62
JB
25853 /* Comparisons. Types S8 S16 S32 U8 U16 U32 F32. Non-immediate versions fall
25854 back to neon_dyadic_if_su. */
21d799b5
NC
25855 nUF(vcge, _vcge, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
25856 nUF(vcgeq, _vcge, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
25857 nUF(vcgt, _vcgt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
25858 nUF(vcgtq, _vcgt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
25859 nUF(vclt, _vclt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
25860 nUF(vcltq, _vclt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
25861 nUF(vcle, _vcle, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
25862 nUF(vcleq, _vcle, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
428e3f1f 25863 /* Comparison. Type I8 I16 I32 F32. */
21d799b5
NC
25864 nUF(vceq, _vceq, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_ceq),
25865 nUF(vceqq, _vceq, 3, (RNQ, oRNQ, RNDQ_I0), neon_ceq),
5287ad62 25866 /* As above, D registers only. */
21d799b5
NC
25867 nUF(vpmax, _vpmax, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
25868 nUF(vpmin, _vpmin, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
5287ad62 25869 /* Int and float variants, signedness unimportant. */
21d799b5
NC
25870 nUF(vmlaq, _vmla, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
25871 nUF(vmlsq, _vmls, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
25872 nUF(vpadd, _vpadd, 3, (RND, oRND, RND), neon_dyadic_if_i_d),
5287ad62 25873 /* Add/sub take types I8 I16 I32 I64 F32. */
21d799b5
NC
25874 nUF(vaddq, _vadd, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
25875 nUF(vsubq, _vsub, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
5287ad62
JB
25876 /* vtst takes sizes 8, 16, 32. */
25877 NUF(vtst, 0000810, 3, (RNDQ, oRNDQ, RNDQ), neon_tst),
25878 NUF(vtstq, 0000810, 3, (RNQ, oRNQ, RNQ), neon_tst),
25879 /* VMUL takes I8 I16 I32 F32 P8. */
21d799b5 25880 nUF(vmulq, _vmul, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mul),
5287ad62 25881 /* VQD{R}MULH takes S16 S32. */
21d799b5 25882 nUF(vqdmulhq, _vqdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
21d799b5 25883 nUF(vqrdmulhq, _vqrdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
5287ad62
JB
25884 NUF(vacge, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
25885 NUF(vacgeq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
25886 NUF(vacgt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
25887 NUF(vacgtq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
92559b5b
PB
25888 NUF(vaclt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
25889 NUF(vacltq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
25890 NUF(vacle, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
25891 NUF(vacleq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
5287ad62
JB
25892 NUF(vrecps, 0000f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
25893 NUF(vrecpsq, 0000f10, 3, (RNQ, oRNQ, RNQ), neon_step),
25894 NUF(vrsqrts, 0200f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
25895 NUF(vrsqrtsq, 0200f10, 3, (RNQ, oRNQ, RNQ), neon_step),
d6b4b13e 25896 /* ARM v8.1 extension. */
643afb90
MW
25897 nUF (vqrdmlahq, _vqrdmlah, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
25898 nUF (vqrdmlsh, _vqrdmlsh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
25899 nUF (vqrdmlshq, _vqrdmlsh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
5287ad62
JB
25900
25901 /* Two address, int/float. Types S8 S16 S32 F32. */
5287ad62 25902 NUF(vabsq, 1b10300, 2, (RNQ, RNQ), neon_abs_neg),
5287ad62
JB
25903 NUF(vnegq, 1b10380, 2, (RNQ, RNQ), neon_abs_neg),
25904
25905 /* Data processing with two registers and a shift amount. */
25906 /* Right shifts, and variants with rounding.
25907 Types accepted S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62 25908 NUF(vshrq, 0800010, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
5287ad62
JB
25909 NUF(vrshrq, 0800210, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
25910 NUF(vsra, 0800110, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
25911 NUF(vsraq, 0800110, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
25912 NUF(vrsra, 0800310, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
25913 NUF(vrsraq, 0800310, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
25914 /* Shift and insert. Sizes accepted 8 16 32 64. */
5287ad62 25915 NUF(vsliq, 1800510, 3, (RNQ, oRNQ, I63), neon_sli),
5287ad62
JB
25916 NUF(vsriq, 1800410, 3, (RNQ, oRNQ, I64), neon_sri),
25917 /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62
JB
25918 NUF(vqshluq, 1800610, 3, (RNQ, oRNQ, I63), neon_qshlu_imm),
25919 /* Right shift immediate, saturating & narrowing, with rounding variants.
25920 Types accepted S16 S32 S64 U16 U32 U64. */
25921 NUF(vqshrn, 0800910, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
25922 NUF(vqrshrn, 0800950, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
25923 /* As above, unsigned. Types accepted S16 S32 S64. */
25924 NUF(vqshrun, 0800810, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
25925 NUF(vqrshrun, 0800850, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
25926 /* Right shift narrowing. Types accepted I16 I32 I64. */
25927 NUF(vshrn, 0800810, 3, (RND, RNQ, I32z), neon_rshift_narrow),
25928 NUF(vrshrn, 0800850, 3, (RND, RNQ, I32z), neon_rshift_narrow),
25929 /* Special case. Types S8 S16 S32 U8 U16 U32. Handles max shift variant. */
21d799b5 25930 nUF(vshll, _vshll, 3, (RNQ, RND, I32), neon_shll),
5287ad62 25931 /* CVT with optional immediate for fixed-point variant. */
21d799b5 25932 nUF(vcvtq, _vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
b7fc2769 25933
4316f0d2 25934 nUF(vmvnq, _vmvn, 2, (RNQ, RNDQ_Ibig), neon_mvn),
5287ad62
JB
25935
25936 /* Data processing, three registers of different lengths. */
25937 /* Dyadic, long insns. Types S8 S16 S32 U8 U16 U32. */
25938 NUF(vabal, 0800500, 3, (RNQ, RND, RND), neon_abal),
5287ad62
JB
25939 /* If not scalar, fall back to neon_dyadic_long.
25940 Vector types as above, scalar types S16 S32 U16 U32. */
21d799b5
NC
25941 nUF(vmlal, _vmlal, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
25942 nUF(vmlsl, _vmlsl, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
5287ad62
JB
25943 /* Dyadic, widening insns. Types S8 S16 S32 U8 U16 U32. */
25944 NUF(vaddw, 0800100, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
25945 NUF(vsubw, 0800300, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
25946 /* Dyadic, narrowing insns. Types I16 I32 I64. */
25947 NUF(vaddhn, 0800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25948 NUF(vraddhn, 1800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25949 NUF(vsubhn, 0800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25950 NUF(vrsubhn, 1800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25951 /* Saturating doubling multiplies. Types S16 S32. */
21d799b5
NC
25952 nUF(vqdmlal, _vqdmlal, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
25953 nUF(vqdmlsl, _vqdmlsl, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
25954 nUF(vqdmull, _vqdmull, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
5287ad62
JB
25955 /* VMULL. Vector types S8 S16 S32 U8 U16 U32 P8, scalar types
25956 S16 S32 U16 U32. */
21d799b5 25957 nUF(vmull, _vmull, 3, (RNQ, RND, RND_RNSC), neon_vmull),
5287ad62
JB
25958
25959 /* Extract. Size 8. */
3b8d421e
PB
25960 NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I15), neon_ext),
25961 NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I15), neon_ext),
5287ad62
JB
25962
25963 /* Two registers, miscellaneous. */
25964 /* Reverse. Sizes 8 16 32 (must be < size in opcode). */
5287ad62 25965 NUF(vrev64q, 1b00000, 2, (RNQ, RNQ), neon_rev),
5287ad62 25966 NUF(vrev32q, 1b00080, 2, (RNQ, RNQ), neon_rev),
5287ad62
JB
25967 NUF(vrev16q, 1b00100, 2, (RNQ, RNQ), neon_rev),
25968 /* Vector replicate. Sizes 8 16 32. */
21d799b5 25969 nCE(vdupq, _vdup, 2, (RNQ, RR_RNSC), neon_dup),
5287ad62
JB
25970 /* VMOVL. Types S8 S16 S32 U8 U16 U32. */
25971 NUF(vmovl, 0800a10, 2, (RNQ, RND), neon_movl),
25972 /* VMOVN. Types I16 I32 I64. */
21d799b5 25973 nUF(vmovn, _vmovn, 2, (RND, RNQ), neon_movn),
5287ad62 25974 /* VQMOVN. Types S16 S32 S64 U16 U32 U64. */
21d799b5 25975 nUF(vqmovn, _vqmovn, 2, (RND, RNQ), neon_qmovn),
5287ad62 25976 /* VQMOVUN. Types S16 S32 S64. */
21d799b5 25977 nUF(vqmovun, _vqmovun, 2, (RND, RNQ), neon_qmovun),
5287ad62
JB
25978 /* VZIP / VUZP. Sizes 8 16 32. */
25979 NUF(vzip, 1b20180, 2, (RNDQ, RNDQ), neon_zip_uzp),
25980 NUF(vzipq, 1b20180, 2, (RNQ, RNQ), neon_zip_uzp),
25981 NUF(vuzp, 1b20100, 2, (RNDQ, RNDQ), neon_zip_uzp),
25982 NUF(vuzpq, 1b20100, 2, (RNQ, RNQ), neon_zip_uzp),
25983 /* VQABS / VQNEG. Types S8 S16 S32. */
5287ad62 25984 NUF(vqabsq, 1b00700, 2, (RNQ, RNQ), neon_sat_abs_neg),
5287ad62
JB
25985 NUF(vqnegq, 1b00780, 2, (RNQ, RNQ), neon_sat_abs_neg),
25986 /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32. */
25987 NUF(vpadal, 1b00600, 2, (RNDQ, RNDQ), neon_pair_long),
25988 NUF(vpadalq, 1b00600, 2, (RNQ, RNQ), neon_pair_long),
25989 NUF(vpaddl, 1b00200, 2, (RNDQ, RNDQ), neon_pair_long),
25990 NUF(vpaddlq, 1b00200, 2, (RNQ, RNQ), neon_pair_long),
cc933301 25991 /* Reciprocal estimates. Types U32 F16 F32. */
5287ad62
JB
25992 NUF(vrecpe, 1b30400, 2, (RNDQ, RNDQ), neon_recip_est),
25993 NUF(vrecpeq, 1b30400, 2, (RNQ, RNQ), neon_recip_est),
25994 NUF(vrsqrte, 1b30480, 2, (RNDQ, RNDQ), neon_recip_est),
25995 NUF(vrsqrteq, 1b30480, 2, (RNQ, RNQ), neon_recip_est),
25996 /* VCLS. Types S8 S16 S32. */
5287ad62
JB
25997 NUF(vclsq, 1b00400, 2, (RNQ, RNQ), neon_cls),
25998 /* VCLZ. Types I8 I16 I32. */
5287ad62
JB
25999 NUF(vclzq, 1b00480, 2, (RNQ, RNQ), neon_clz),
26000 /* VCNT. Size 8. */
26001 NUF(vcnt, 1b00500, 2, (RNDQ, RNDQ), neon_cnt),
26002 NUF(vcntq, 1b00500, 2, (RNQ, RNQ), neon_cnt),
26003 /* Two address, untyped. */
26004 NUF(vswp, 1b20000, 2, (RNDQ, RNDQ), neon_swp),
26005 NUF(vswpq, 1b20000, 2, (RNQ, RNQ), neon_swp),
26006 /* VTRN. Sizes 8 16 32. */
21d799b5
NC
26007 nUF(vtrn, _vtrn, 2, (RNDQ, RNDQ), neon_trn),
26008 nUF(vtrnq, _vtrn, 2, (RNQ, RNQ), neon_trn),
5287ad62
JB
26009
26010 /* Table lookup. Size 8. */
26011 NUF(vtbl, 1b00800, 3, (RND, NRDLST, RND), neon_tbl_tbx),
26012 NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
26013
c921be7d
NC
26014#undef THUMB_VARIANT
26015#define THUMB_VARIANT & fpu_vfp_v3_or_neon_ext
26016#undef ARM_VARIANT
26017#define ARM_VARIANT & fpu_vfp_v3_or_neon_ext
26018
5287ad62 26019 /* Neon element/structure load/store. */
21d799b5
NC
26020 nUF(vld1, _vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
26021 nUF(vst1, _vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
26022 nUF(vld2, _vld2, 2, (NSTRLST, ADDR), neon_ldx_stx),
26023 nUF(vst2, _vst2, 2, (NSTRLST, ADDR), neon_ldx_stx),
26024 nUF(vld3, _vld3, 2, (NSTRLST, ADDR), neon_ldx_stx),
26025 nUF(vst3, _vst3, 2, (NSTRLST, ADDR), neon_ldx_stx),
26026 nUF(vld4, _vld4, 2, (NSTRLST, ADDR), neon_ldx_stx),
26027 nUF(vst4, _vst4, 2, (NSTRLST, ADDR), neon_ldx_stx),
5287ad62 26028
c921be7d 26029#undef THUMB_VARIANT
74db7efb
NC
26030#define THUMB_VARIANT & fpu_vfp_ext_v3xd
26031#undef ARM_VARIANT
26032#define ARM_VARIANT & fpu_vfp_ext_v3xd
62f3b8c8
PB
26033 cCE("fconsts", eb00a00, 2, (RVS, I255), vfp_sp_const),
26034 cCE("fshtos", eba0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26035 cCE("fsltos", eba0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26036 cCE("fuhtos", ebb0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26037 cCE("fultos", ebb0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26038 cCE("ftoshs", ebe0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26039 cCE("ftosls", ebe0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26040 cCE("ftouhs", ebf0a40, 2, (RVS, I16z), vfp_sp_conv_16),
26041 cCE("ftouls", ebf0ac0, 2, (RVS, I32), vfp_sp_conv_32),
26042
74db7efb 26043#undef THUMB_VARIANT
c921be7d
NC
26044#define THUMB_VARIANT & fpu_vfp_ext_v3
26045#undef ARM_VARIANT
26046#define ARM_VARIANT & fpu_vfp_ext_v3
26047
21d799b5 26048 cCE("fconstd", eb00b00, 2, (RVD, I255), vfp_dp_const),
21d799b5 26049 cCE("fshtod", eba0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26050 cCE("fsltod", eba0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 26051 cCE("fuhtod", ebb0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26052 cCE("fultod", ebb0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 26053 cCE("ftoshd", ebe0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26054 cCE("ftosld", ebe0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 26055 cCE("ftouhd", ebf0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 26056 cCE("ftould", ebf0bc0, 2, (RVD, I32), vfp_dp_conv_32),
c19d1205 26057
74db7efb
NC
26058#undef ARM_VARIANT
26059#define ARM_VARIANT & fpu_vfp_ext_fma
26060#undef THUMB_VARIANT
26061#define THUMB_VARIANT & fpu_vfp_ext_fma
aab2c27d 26062 /* Mnemonics shared by Neon, VFP, MVE and BF16. These are included in the
62f3b8c8
PB
26063 VFP FMA variant; NEON and VFP FMA always includes the NEON
26064 FMA instructions. */
d58196e0 26065 mnCEF(vfma, _vfma, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_fmac),
aab2c27d 26066 TUF ("vfmat", c300850, fc300850, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), mve_vfma, mve_vfma),
d58196e0
AV
26067 mnCEF(vfms, _vfms, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), neon_fmac),
26068
62f3b8c8
PB
26069 /* ffmas/ffmad/ffmss/ffmsd are dummy mnemonics to satisfy gas;
26070 the v form should always be used. */
26071 cCE("ffmas", ea00a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
26072 cCE("ffnmas", ea00a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
26073 cCE("ffmad", ea00b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
26074 cCE("ffnmad", ea00b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
26075 nCE(vfnma, _vfnma, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
26076 nCE(vfnms, _vfnms, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
26077
5287ad62 26078#undef THUMB_VARIANT
c921be7d
NC
26079#undef ARM_VARIANT
26080#define ARM_VARIANT & arm_cext_xscale /* Intel XScale extensions. */
26081
21d799b5
NC
26082 cCE("mia", e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26083 cCE("miaph", e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26084 cCE("miabb", e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26085 cCE("miabt", e2d0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26086 cCE("miatb", e2e0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26087 cCE("miatt", e2f0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
26088 cCE("mar", c400000, 3, (RXA, RRnpc, RRnpc), xsc_mar),
26089 cCE("mra", c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra),
c19d1205 26090
c921be7d
NC
26091#undef ARM_VARIANT
26092#define ARM_VARIANT & arm_cext_iwmmxt /* Intel Wireless MMX technology. */
26093
21d799b5
NC
26094 cCE("tandcb", e13f130, 1, (RR), iwmmxt_tandorc),
26095 cCE("tandch", e53f130, 1, (RR), iwmmxt_tandorc),
26096 cCE("tandcw", e93f130, 1, (RR), iwmmxt_tandorc),
26097 cCE("tbcstb", e400010, 2, (RIWR, RR), rn_rd),
26098 cCE("tbcsth", e400050, 2, (RIWR, RR), rn_rd),
26099 cCE("tbcstw", e400090, 2, (RIWR, RR), rn_rd),
26100 cCE("textrcb", e130170, 2, (RR, I7), iwmmxt_textrc),
26101 cCE("textrch", e530170, 2, (RR, I7), iwmmxt_textrc),
26102 cCE("textrcw", e930170, 2, (RR, I7), iwmmxt_textrc),
74db7efb
NC
26103 cCE("textrmub",e100070, 3, (RR, RIWR, I7), iwmmxt_textrm),
26104 cCE("textrmuh",e500070, 3, (RR, RIWR, I7), iwmmxt_textrm),
26105 cCE("textrmuw",e900070, 3, (RR, RIWR, I7), iwmmxt_textrm),
26106 cCE("textrmsb",e100078, 3, (RR, RIWR, I7), iwmmxt_textrm),
26107 cCE("textrmsh",e500078, 3, (RR, RIWR, I7), iwmmxt_textrm),
26108 cCE("textrmsw",e900078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21d799b5
NC
26109 cCE("tinsrb", e600010, 3, (RIWR, RR, I7), iwmmxt_tinsr),
26110 cCE("tinsrh", e600050, 3, (RIWR, RR, I7), iwmmxt_tinsr),
26111 cCE("tinsrw", e600090, 3, (RIWR, RR, I7), iwmmxt_tinsr),
26112 cCE("tmcr", e000110, 2, (RIWC_RIWG, RR), rn_rd),
26113 cCE("tmcrr", c400000, 3, (RIWR, RR, RR), rm_rd_rn),
26114 cCE("tmia", e200010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26115 cCE("tmiaph", e280010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26116 cCE("tmiabb", e2c0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26117 cCE("tmiabt", e2d0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26118 cCE("tmiatb", e2e0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
26119 cCE("tmiatt", e2f0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
74db7efb
NC
26120 cCE("tmovmskb",e100030, 2, (RR, RIWR), rd_rn),
26121 cCE("tmovmskh",e500030, 2, (RR, RIWR), rd_rn),
26122 cCE("tmovmskw",e900030, 2, (RR, RIWR), rd_rn),
21d799b5
NC
26123 cCE("tmrc", e100110, 2, (RR, RIWC_RIWG), rd_rn),
26124 cCE("tmrrc", c500000, 3, (RR, RR, RIWR), rd_rn_rm),
26125 cCE("torcb", e13f150, 1, (RR), iwmmxt_tandorc),
26126 cCE("torch", e53f150, 1, (RR), iwmmxt_tandorc),
26127 cCE("torcw", e93f150, 1, (RR), iwmmxt_tandorc),
26128 cCE("waccb", e0001c0, 2, (RIWR, RIWR), rd_rn),
26129 cCE("wacch", e4001c0, 2, (RIWR, RIWR), rd_rn),
26130 cCE("waccw", e8001c0, 2, (RIWR, RIWR), rd_rn),
26131 cCE("waddbss", e300180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26132 cCE("waddb", e000180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26133 cCE("waddbus", e100180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26134 cCE("waddhss", e700180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26135 cCE("waddh", e400180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26136 cCE("waddhus", e500180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26137 cCE("waddwss", eb00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26138 cCE("waddw", e800180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26139 cCE("waddwus", e900180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26140 cCE("waligni", e000020, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_waligni),
74db7efb
NC
26141 cCE("walignr0",e800020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26142 cCE("walignr1",e900020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26143 cCE("walignr2",ea00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26144 cCE("walignr3",eb00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
26145 cCE("wand", e200000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26146 cCE("wandn", e300000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26147 cCE("wavg2b", e800000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26148 cCE("wavg2br", e900000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26149 cCE("wavg2h", ec00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26150 cCE("wavg2hr", ed00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26151 cCE("wcmpeqb", e000060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26152 cCE("wcmpeqh", e400060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26153 cCE("wcmpeqw", e800060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
26154 cCE("wcmpgtub",e100060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26155 cCE("wcmpgtuh",e500060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26156 cCE("wcmpgtuw",e900060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26157 cCE("wcmpgtsb",e300060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26158 cCE("wcmpgtsh",e700060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26159 cCE("wcmpgtsw",eb00060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
26160 cCE("wldrb", c100000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26161 cCE("wldrh", c500000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26162 cCE("wldrw", c100100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
26163 cCE("wldrd", c500100, 2, (RIWR, ADDR), iwmmxt_wldstd),
26164 cCE("wmacs", e600100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26165 cCE("wmacsz", e700100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26166 cCE("wmacu", e400100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26167 cCE("wmacuz", e500100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26168 cCE("wmadds", ea00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26169 cCE("wmaddu", e800100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26170 cCE("wmaxsb", e200160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26171 cCE("wmaxsh", e600160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26172 cCE("wmaxsw", ea00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26173 cCE("wmaxub", e000160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26174 cCE("wmaxuh", e400160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26175 cCE("wmaxuw", e800160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26176 cCE("wminsb", e300160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26177 cCE("wminsh", e700160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26178 cCE("wminsw", eb00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26179 cCE("wminub", e100160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26180 cCE("wminuh", e500160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26181 cCE("wminuw", e900160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26182 cCE("wmov", e000000, 2, (RIWR, RIWR), iwmmxt_wmov),
26183 cCE("wmulsm", e300100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26184 cCE("wmulsl", e200100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26185 cCE("wmulum", e100100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26186 cCE("wmulul", e000100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26187 cCE("wor", e000000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
26188 cCE("wpackhss",e700080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26189 cCE("wpackhus",e500080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26190 cCE("wpackwss",eb00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26191 cCE("wpackwus",e900080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26192 cCE("wpackdss",ef00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26193 cCE("wpackdus",ed00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
26194 cCE("wrorh", e700040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26195 cCE("wrorhg", e700148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26196 cCE("wrorw", eb00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26197 cCE("wrorwg", eb00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26198 cCE("wrord", ef00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26199 cCE("wrordg", ef00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26200 cCE("wsadb", e000120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26201 cCE("wsadbz", e100120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26202 cCE("wsadh", e400120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26203 cCE("wsadhz", e500120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26204 cCE("wshufh", e0001e0, 3, (RIWR, RIWR, I255), iwmmxt_wshufh),
26205 cCE("wsllh", e500040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26206 cCE("wsllhg", e500148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26207 cCE("wsllw", e900040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26208 cCE("wsllwg", e900148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26209 cCE("wslld", ed00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26210 cCE("wslldg", ed00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26211 cCE("wsrah", e400040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26212 cCE("wsrahg", e400148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26213 cCE("wsraw", e800040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26214 cCE("wsrawg", e800148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26215 cCE("wsrad", ec00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26216 cCE("wsradg", ec00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26217 cCE("wsrlh", e600040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26218 cCE("wsrlhg", e600148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26219 cCE("wsrlw", ea00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26220 cCE("wsrlwg", ea00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26221 cCE("wsrld", ee00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26222 cCE("wsrldg", ee00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26223 cCE("wstrb", c000000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26224 cCE("wstrh", c400000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26225 cCE("wstrw", c000100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
26226 cCE("wstrd", c400100, 2, (RIWR, ADDR), iwmmxt_wldstd),
26227 cCE("wsubbss", e3001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26228 cCE("wsubb", e0001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26229 cCE("wsubbus", e1001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26230 cCE("wsubhss", e7001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26231 cCE("wsubh", e4001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26232 cCE("wsubhus", e5001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26233 cCE("wsubwss", eb001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26234 cCE("wsubw", e8001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26235 cCE("wsubwus", e9001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26236 cCE("wunpckehub",e0000c0, 2, (RIWR, RIWR), rd_rn),
26237 cCE("wunpckehuh",e4000c0, 2, (RIWR, RIWR), rd_rn),
26238 cCE("wunpckehuw",e8000c0, 2, (RIWR, RIWR), rd_rn),
26239 cCE("wunpckehsb",e2000c0, 2, (RIWR, RIWR), rd_rn),
26240 cCE("wunpckehsh",e6000c0, 2, (RIWR, RIWR), rd_rn),
26241 cCE("wunpckehsw",ea000c0, 2, (RIWR, RIWR), rd_rn),
26242 cCE("wunpckihb", e1000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26243 cCE("wunpckihh", e5000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26244 cCE("wunpckihw", e9000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26245 cCE("wunpckelub",e0000e0, 2, (RIWR, RIWR), rd_rn),
26246 cCE("wunpckeluh",e4000e0, 2, (RIWR, RIWR), rd_rn),
26247 cCE("wunpckeluw",e8000e0, 2, (RIWR, RIWR), rd_rn),
26248 cCE("wunpckelsb",e2000e0, 2, (RIWR, RIWR), rd_rn),
26249 cCE("wunpckelsh",e6000e0, 2, (RIWR, RIWR), rd_rn),
26250 cCE("wunpckelsw",ea000e0, 2, (RIWR, RIWR), rd_rn),
26251 cCE("wunpckilb", e1000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26252 cCE("wunpckilh", e5000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26253 cCE("wunpckilw", e9000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26254 cCE("wxor", e100000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26255 cCE("wzero", e300000, 1, (RIWR), iwmmxt_wzero),
c19d1205 26256
c921be7d
NC
26257#undef ARM_VARIANT
26258#define ARM_VARIANT & arm_cext_iwmmxt2 /* Intel Wireless MMX technology, version 2. */
26259
21d799b5
NC
26260 cCE("torvscb", e12f190, 1, (RR), iwmmxt_tandorc),
26261 cCE("torvsch", e52f190, 1, (RR), iwmmxt_tandorc),
26262 cCE("torvscw", e92f190, 1, (RR), iwmmxt_tandorc),
26263 cCE("wabsb", e2001c0, 2, (RIWR, RIWR), rd_rn),
26264 cCE("wabsh", e6001c0, 2, (RIWR, RIWR), rd_rn),
26265 cCE("wabsw", ea001c0, 2, (RIWR, RIWR), rd_rn),
26266 cCE("wabsdiffb", e1001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26267 cCE("wabsdiffh", e5001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26268 cCE("wabsdiffw", e9001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26269 cCE("waddbhusl", e2001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26270 cCE("waddbhusm", e6001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26271 cCE("waddhc", e600180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26272 cCE("waddwc", ea00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26273 cCE("waddsubhx", ea001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26274 cCE("wavg4", e400000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26275 cCE("wavg4r", e500000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26276 cCE("wmaddsn", ee00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26277 cCE("wmaddsx", eb00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26278 cCE("wmaddun", ec00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26279 cCE("wmaddux", e900100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26280 cCE("wmerge", e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
26281 cCE("wmiabb", e0000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26282 cCE("wmiabt", e1000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26283 cCE("wmiatb", e2000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26284 cCE("wmiatt", e3000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26285 cCE("wmiabbn", e4000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26286 cCE("wmiabtn", e5000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26287 cCE("wmiatbn", e6000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26288 cCE("wmiattn", e7000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26289 cCE("wmiawbb", e800120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26290 cCE("wmiawbt", e900120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26291 cCE("wmiawtb", ea00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26292 cCE("wmiawtt", eb00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26293 cCE("wmiawbbn", ec00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26294 cCE("wmiawbtn", ed00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26295 cCE("wmiawtbn", ee00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26296 cCE("wmiawttn", ef00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26297 cCE("wmulsmr", ef00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26298 cCE("wmulumr", ed00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26299 cCE("wmulwumr", ec000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26300 cCE("wmulwsmr", ee000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26301 cCE("wmulwum", ed000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26302 cCE("wmulwsm", ef000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26303 cCE("wmulwl", eb000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26304 cCE("wqmiabb", e8000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26305 cCE("wqmiabt", e9000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26306 cCE("wqmiatb", ea000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26307 cCE("wqmiatt", eb000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26308 cCE("wqmiabbn", ec000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26309 cCE("wqmiabtn", ed000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26310 cCE("wqmiatbn", ee000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26311 cCE("wqmiattn", ef000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26312 cCE("wqmulm", e100080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26313 cCE("wqmulmr", e300080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26314 cCE("wqmulwm", ec000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26315 cCE("wqmulwmr", ee000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26316 cCE("wsubaddhx", ed001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
2d447fca 26317
c921be7d
NC
26318#undef ARM_VARIANT
26319#define ARM_VARIANT & arm_cext_maverick /* Cirrus Maverick instructions. */
26320
21d799b5
NC
26321 cCE("cfldrs", c100400, 2, (RMF, ADDRGLDC), rd_cpaddr),
26322 cCE("cfldrd", c500400, 2, (RMD, ADDRGLDC), rd_cpaddr),
26323 cCE("cfldr32", c100500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
26324 cCE("cfldr64", c500500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
26325 cCE("cfstrs", c000400, 2, (RMF, ADDRGLDC), rd_cpaddr),
26326 cCE("cfstrd", c400400, 2, (RMD, ADDRGLDC), rd_cpaddr),
26327 cCE("cfstr32", c000500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
26328 cCE("cfstr64", c400500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
26329 cCE("cfmvsr", e000450, 2, (RMF, RR), rn_rd),
26330 cCE("cfmvrs", e100450, 2, (RR, RMF), rd_rn),
26331 cCE("cfmvdlr", e000410, 2, (RMD, RR), rn_rd),
26332 cCE("cfmvrdl", e100410, 2, (RR, RMD), rd_rn),
26333 cCE("cfmvdhr", e000430, 2, (RMD, RR), rn_rd),
26334 cCE("cfmvrdh", e100430, 2, (RR, RMD), rd_rn),
74db7efb
NC
26335 cCE("cfmv64lr",e000510, 2, (RMDX, RR), rn_rd),
26336 cCE("cfmvr64l",e100510, 2, (RR, RMDX), rd_rn),
26337 cCE("cfmv64hr",e000530, 2, (RMDX, RR), rn_rd),
26338 cCE("cfmvr64h",e100530, 2, (RR, RMDX), rd_rn),
26339 cCE("cfmval32",e200440, 2, (RMAX, RMFX), rd_rn),
26340 cCE("cfmv32al",e100440, 2, (RMFX, RMAX), rd_rn),
26341 cCE("cfmvam32",e200460, 2, (RMAX, RMFX), rd_rn),
26342 cCE("cfmv32am",e100460, 2, (RMFX, RMAX), rd_rn),
26343 cCE("cfmvah32",e200480, 2, (RMAX, RMFX), rd_rn),
26344 cCE("cfmv32ah",e100480, 2, (RMFX, RMAX), rd_rn),
21d799b5
NC
26345 cCE("cfmva32", e2004a0, 2, (RMAX, RMFX), rd_rn),
26346 cCE("cfmv32a", e1004a0, 2, (RMFX, RMAX), rd_rn),
26347 cCE("cfmva64", e2004c0, 2, (RMAX, RMDX), rd_rn),
26348 cCE("cfmv64a", e1004c0, 2, (RMDX, RMAX), rd_rn),
74db7efb
NC
26349 cCE("cfmvsc32",e2004e0, 2, (RMDS, RMDX), mav_dspsc),
26350 cCE("cfmv32sc",e1004e0, 2, (RMDX, RMDS), rd),
21d799b5
NC
26351 cCE("cfcpys", e000400, 2, (RMF, RMF), rd_rn),
26352 cCE("cfcpyd", e000420, 2, (RMD, RMD), rd_rn),
26353 cCE("cfcvtsd", e000460, 2, (RMD, RMF), rd_rn),
26354 cCE("cfcvtds", e000440, 2, (RMF, RMD), rd_rn),
74db7efb
NC
26355 cCE("cfcvt32s",e000480, 2, (RMF, RMFX), rd_rn),
26356 cCE("cfcvt32d",e0004a0, 2, (RMD, RMFX), rd_rn),
26357 cCE("cfcvt64s",e0004c0, 2, (RMF, RMDX), rd_rn),
26358 cCE("cfcvt64d",e0004e0, 2, (RMD, RMDX), rd_rn),
26359 cCE("cfcvts32",e100580, 2, (RMFX, RMF), rd_rn),
26360 cCE("cfcvtd32",e1005a0, 2, (RMFX, RMD), rd_rn),
21d799b5
NC
26361 cCE("cftruncs32",e1005c0, 2, (RMFX, RMF), rd_rn),
26362 cCE("cftruncd32",e1005e0, 2, (RMFX, RMD), rd_rn),
74db7efb
NC
26363 cCE("cfrshl32",e000550, 3, (RMFX, RMFX, RR), mav_triple),
26364 cCE("cfrshl64",e000570, 3, (RMDX, RMDX, RR), mav_triple),
21d799b5
NC
26365 cCE("cfsh32", e000500, 3, (RMFX, RMFX, I63s), mav_shift),
26366 cCE("cfsh64", e200500, 3, (RMDX, RMDX, I63s), mav_shift),
26367 cCE("cfcmps", e100490, 3, (RR, RMF, RMF), rd_rn_rm),
26368 cCE("cfcmpd", e1004b0, 3, (RR, RMD, RMD), rd_rn_rm),
26369 cCE("cfcmp32", e100590, 3, (RR, RMFX, RMFX), rd_rn_rm),
26370 cCE("cfcmp64", e1005b0, 3, (RR, RMDX, RMDX), rd_rn_rm),
26371 cCE("cfabss", e300400, 2, (RMF, RMF), rd_rn),
26372 cCE("cfabsd", e300420, 2, (RMD, RMD), rd_rn),
26373 cCE("cfnegs", e300440, 2, (RMF, RMF), rd_rn),
26374 cCE("cfnegd", e300460, 2, (RMD, RMD), rd_rn),
26375 cCE("cfadds", e300480, 3, (RMF, RMF, RMF), rd_rn_rm),
26376 cCE("cfaddd", e3004a0, 3, (RMD, RMD, RMD), rd_rn_rm),
26377 cCE("cfsubs", e3004c0, 3, (RMF, RMF, RMF), rd_rn_rm),
26378 cCE("cfsubd", e3004e0, 3, (RMD, RMD, RMD), rd_rn_rm),
26379 cCE("cfmuls", e100400, 3, (RMF, RMF, RMF), rd_rn_rm),
26380 cCE("cfmuld", e100420, 3, (RMD, RMD, RMD), rd_rn_rm),
26381 cCE("cfabs32", e300500, 2, (RMFX, RMFX), rd_rn),
26382 cCE("cfabs64", e300520, 2, (RMDX, RMDX), rd_rn),
26383 cCE("cfneg32", e300540, 2, (RMFX, RMFX), rd_rn),
26384 cCE("cfneg64", e300560, 2, (RMDX, RMDX), rd_rn),
26385 cCE("cfadd32", e300580, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26386 cCE("cfadd64", e3005a0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26387 cCE("cfsub32", e3005c0, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26388 cCE("cfsub64", e3005e0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26389 cCE("cfmul32", e100500, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26390 cCE("cfmul64", e100520, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26391 cCE("cfmac32", e100540, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26392 cCE("cfmsc32", e100560, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
74db7efb
NC
26393 cCE("cfmadd32",e000600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
26394 cCE("cfmsub32",e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21d799b5
NC
26395 cCE("cfmadda32", e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
26396 cCE("cfmsuba32", e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
4ed7ed8d 26397
7fadb25d
SD
26398 /* ARMv8.5-A instructions. */
26399#undef ARM_VARIANT
26400#define ARM_VARIANT & arm_ext_sb
26401#undef THUMB_VARIANT
26402#define THUMB_VARIANT & arm_ext_sb
26403 TUF("sb", 57ff070, f3bf8f70, 0, (), noargs, noargs),
26404
dad0c3bf
SD
26405#undef ARM_VARIANT
26406#define ARM_VARIANT & arm_ext_predres
26407#undef THUMB_VARIANT
26408#define THUMB_VARIANT & arm_ext_predres
26409 CE("cfprctx", e070f93, 1, (RRnpc), rd),
26410 CE("dvprctx", e070fb3, 1, (RRnpc), rd),
26411 CE("cpprctx", e070ff3, 1, (RRnpc), rd),
26412
16a1fa25 26413 /* ARMv8-M instructions. */
4ed7ed8d
TP
26414#undef ARM_VARIANT
26415#define ARM_VARIANT NULL
26416#undef THUMB_VARIANT
26417#define THUMB_VARIANT & arm_ext_v8m
cf3cf39d
TP
26418 ToU("sg", e97fe97f, 0, (), noargs),
26419 ToC("blxns", 4784, 1, (RRnpc), t_blx),
26420 ToC("bxns", 4704, 1, (RRnpc), t_bx),
26421 ToC("tt", e840f000, 2, (RRnpc, RRnpc), tt),
26422 ToC("ttt", e840f040, 2, (RRnpc, RRnpc), tt),
26423 ToC("tta", e840f080, 2, (RRnpc, RRnpc), tt),
26424 ToC("ttat", e840f0c0, 2, (RRnpc, RRnpc), tt),
16a1fa25
TP
26425
26426 /* FP for ARMv8-M Mainline. Enabled for ARMv8-M Mainline because the
26427 instructions behave as nop if no VFP is present. */
26428#undef THUMB_VARIANT
26429#define THUMB_VARIANT & arm_ext_v8m_main
cf3cf39d
TP
26430 ToC("vlldm", ec300a00, 1, (RRnpc), rn),
26431 ToC("vlstm", ec200a00, 1, (RRnpc), rn),
4389b29a
AV
26432
26433 /* Armv8.1-M Mainline instructions. */
26434#undef THUMB_VARIANT
26435#define THUMB_VARIANT & arm_ext_v8_1m_main
e43ca2cb 26436 toU("aut", _aut, 3, (R12, LR, SP), t_pacbti),
be05908c 26437 toU("autg", _autg, 3, (RR, RR, RR), t_pacbti_nonop),
3751264c 26438 ToU("bti", f3af800f, 0, (), noargs),
e07352fa 26439 toU("bxaut", _bxaut, 3, (RR, RR, RR), t_pacbti_nonop),
ce537a7d 26440 toU("pac", _pac, 3, (R12, LR, SP), t_pacbti),
f1e1d7f3 26441 toU("pacbti", _pacbti, 3, (R12, LR, SP), t_pacbti),
5c43020d 26442 toU("pacg", _pacg, 3, (RR, RR, RR), t_pacbti_pacg),
e39c1607
SD
26443 toU("cinc", _cinc, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26444 toU("cinv", _cinv, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26445 toU("cneg", _cneg, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26446 toU("csel", _csel, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26447 toU("csetm", _csetm, 2, (RRnpcsp, COND), t_cond),
26448 toU("cset", _cset, 2, (RRnpcsp, COND), t_cond),
26449 toU("csinc", _csinc, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26450 toU("csinv", _csinv, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26451 toU("csneg", _csneg, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26452
4389b29a 26453 toC("bf", _bf, 2, (EXPs, EXPs), t_branch_future),
f6b2b12d 26454 toU("bfcsel", _bfcsel, 4, (EXPs, EXPs, EXPs, COND), t_branch_future),
f1c7f421 26455 toC("bfx", _bfx, 2, (EXPs, RRnpcsp), t_branch_future),
65d1bc05 26456 toC("bfl", _bfl, 2, (EXPs, EXPs), t_branch_future),
f1c7f421 26457 toC("bflx", _bflx, 2, (EXPs, RRnpcsp), t_branch_future),
60f993ce
AV
26458
26459 toU("dls", _dls, 2, (LR, RRnpcsp), t_loloop),
26460 toU("wls", _wls, 3, (LR, RRnpcsp, EXP), t_loloop),
26461 toU("le", _le, 2, (oLR, EXP), t_loloop),
4b5a202f 26462
efd6b359 26463 ToC("clrm", e89f0000, 1, (CLRMLST), t_clrm),
5ee91343
AV
26464 ToC("vscclrm", ec9f0a00, 1, (VRSDVLST), t_vscclrm),
26465
26466#undef THUMB_VARIANT
26467#define THUMB_VARIANT & mve_ext
23d00a41
SD
26468 ToC("lsll", ea50010d, 3, (RRe, RRo, RRnpcsp_I32), mve_scalar_shift),
26469 ToC("lsrl", ea50011f, 3, (RRe, RRo, I32), mve_scalar_shift),
26470 ToC("asrl", ea50012d, 3, (RRe, RRo, RRnpcsp_I32), mve_scalar_shift),
08132bdd
SP
26471 ToC("uqrshll", ea51010d, 4, (RRe, RRo, I48_I64, RRnpcsp), mve_scalar_shift1),
26472 ToC("sqrshrl", ea51012d, 4, (RRe, RRo, I48_I64, RRnpcsp), mve_scalar_shift1),
23d00a41
SD
26473 ToC("uqshll", ea51010f, 3, (RRe, RRo, I32), mve_scalar_shift),
26474 ToC("urshrl", ea51011f, 3, (RRe, RRo, I32), mve_scalar_shift),
26475 ToC("srshrl", ea51012f, 3, (RRe, RRo, I32), mve_scalar_shift),
26476 ToC("sqshll", ea51013f, 3, (RRe, RRo, I32), mve_scalar_shift),
26477 ToC("uqrshl", ea500f0d, 2, (RRnpcsp, RRnpcsp), mve_scalar_shift),
26478 ToC("sqrshr", ea500f2d, 2, (RRnpcsp, RRnpcsp), mve_scalar_shift),
26479 ToC("uqshl", ea500f0f, 2, (RRnpcsp, I32), mve_scalar_shift),
26480 ToC("urshr", ea500f1f, 2, (RRnpcsp, I32), mve_scalar_shift),
26481 ToC("srshr", ea500f2f, 2, (RRnpcsp, I32), mve_scalar_shift),
26482 ToC("sqshl", ea500f3f, 2, (RRnpcsp, I32), mve_scalar_shift),
1b883319
AV
26483
26484 ToC("vpt", ee410f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26485 ToC("vptt", ee018f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26486 ToC("vpte", ee418f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26487 ToC("vpttt", ee014f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26488 ToC("vptte", ee01cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26489 ToC("vptet", ee41cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26490 ToC("vptee", ee414f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26491 ToC("vptttt", ee012f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26492 ToC("vpttte", ee016f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26493 ToC("vpttet", ee01ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26494 ToC("vpttee", ee01af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26495 ToC("vptett", ee41af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26496 ToC("vptete", ee41ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26497 ToC("vpteet", ee416f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26498 ToC("vpteee", ee412f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26499
5ee91343
AV
26500 ToC("vpst", fe710f4d, 0, (), mve_vpt),
26501 ToC("vpstt", fe318f4d, 0, (), mve_vpt),
26502 ToC("vpste", fe718f4d, 0, (), mve_vpt),
26503 ToC("vpsttt", fe314f4d, 0, (), mve_vpt),
26504 ToC("vpstte", fe31cf4d, 0, (), mve_vpt),
26505 ToC("vpstet", fe71cf4d, 0, (), mve_vpt),
26506 ToC("vpstee", fe714f4d, 0, (), mve_vpt),
26507 ToC("vpstttt", fe312f4d, 0, (), mve_vpt),
26508 ToC("vpsttte", fe316f4d, 0, (), mve_vpt),
26509 ToC("vpsttet", fe31ef4d, 0, (), mve_vpt),
26510 ToC("vpsttee", fe31af4d, 0, (), mve_vpt),
26511 ToC("vpstett", fe71af4d, 0, (), mve_vpt),
26512 ToC("vpstete", fe71ef4d, 0, (), mve_vpt),
26513 ToC("vpsteet", fe716f4d, 0, (), mve_vpt),
26514 ToC("vpsteee", fe712f4d, 0, (), mve_vpt),
26515
a302e574 26516 /* MVE and MVE FP only. */
7df54120 26517 mToC("vhcadd", ee000f00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vhcadd),
efd0b310 26518 mCEF(vctp, _vctp, 1, (RRnpc), mve_vctp),
c2dafc2a
AV
26519 mCEF(vadc, _vadc, 3, (RMQ, RMQ, RMQ), mve_vadc),
26520 mCEF(vadci, _vadci, 3, (RMQ, RMQ, RMQ), mve_vadc),
26521 mToC("vsbc", fe300f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
26522 mToC("vsbci", fe301f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
886e1c73 26523 mCEF(vmullb, _vmullb, 3, (RMQ, RMQ, RMQ), mve_vmull),
a302e574
AV
26524 mCEF(vabav, _vabav, 3, (RRnpcsp, RMQ, RMQ), mve_vabav),
26525 mCEF(vmladav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26526 mCEF(vmladava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26527 mCEF(vmladavx, _vmladavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
26528 mCEF(vmladavax, _vmladavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
26529 mCEF(vmlav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26530 mCEF(vmlava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26531 mCEF(vmlsdav, _vmlsdav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26532 mCEF(vmlsdava, _vmlsdava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26533 mCEF(vmlsdavx, _vmlsdavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
26534 mCEF(vmlsdavax, _vmlsdavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
26535
35c228db
AV
26536 mCEF(vst20, _vst20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26537 mCEF(vst21, _vst21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26538 mCEF(vst40, _vst40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26539 mCEF(vst41, _vst41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26540 mCEF(vst42, _vst42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26541 mCEF(vst43, _vst43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26542 mCEF(vld20, _vld20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26543 mCEF(vld21, _vld21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26544 mCEF(vld40, _vld40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26545 mCEF(vld41, _vld41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26546 mCEF(vld42, _vld42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26547 mCEF(vld43, _vld43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
f5f10c66
AV
26548 mCEF(vstrb, _vstrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26549 mCEF(vstrh, _vstrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26550 mCEF(vstrw, _vstrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26551 mCEF(vstrd, _vstrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26552 mCEF(vldrb, _vldrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26553 mCEF(vldrh, _vldrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26554 mCEF(vldrw, _vldrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26555 mCEF(vldrd, _vldrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
35c228db 26556
57785aa2
AV
26557 mCEF(vmovnt, _vmovnt, 2, (RMQ, RMQ), mve_movn),
26558 mCEF(vmovnb, _vmovnb, 2, (RMQ, RMQ), mve_movn),
c2dafc2a 26559 mCEF(vbrsr, _vbrsr, 3, (RMQ, RMQ, RR), mve_vbrsr),
26c1e780
AV
26560 mCEF(vaddlv, _vaddlv, 3, (RRe, RRo, RMQ), mve_vaddlv),
26561 mCEF(vaddlva, _vaddlva, 3, (RRe, RRo, RMQ), mve_vaddlv),
26562 mCEF(vaddv, _vaddv, 2, (RRe, RMQ), mve_vaddv),
26563 mCEF(vaddva, _vaddva, 2, (RRe, RMQ), mve_vaddv),
b409bdb6
AV
26564 mCEF(vddup, _vddup, 3, (RMQ, RRe, EXPi), mve_viddup),
26565 mCEF(vdwdup, _vdwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
26566 mCEF(vidup, _vidup, 3, (RMQ, RRe, EXPi), mve_viddup),
26567 mCEF(viwdup, _viwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
935295b5
AV
26568 mToC("vmaxa", ee330e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
26569 mToC("vmina", ee331e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
13ccd4c0
AV
26570 mCEF(vmaxv, _vmaxv, 2, (RR, RMQ), mve_vmaxv),
26571 mCEF(vmaxav, _vmaxav, 2, (RR, RMQ), mve_vmaxv),
26572 mCEF(vminv, _vminv, 2, (RR, RMQ), mve_vmaxv),
26573 mCEF(vminav, _vminav, 2, (RR, RMQ), mve_vmaxv),
57785aa2 26574
93925576
AV
26575 mCEF(vmlaldav, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26576 mCEF(vmlaldava, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26577 mCEF(vmlaldavx, _vmlaldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26578 mCEF(vmlaldavax, _vmlaldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26579 mCEF(vmlalv, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26580 mCEF(vmlalva, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26581 mCEF(vmlsldav, _vmlsldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26582 mCEF(vmlsldava, _vmlsldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26583 mCEF(vmlsldavx, _vmlsldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26584 mCEF(vmlsldavax, _vmlsldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26585 mToC("vrmlaldavh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26586 mToC("vrmlaldavha",ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26587 mCEF(vrmlaldavhx, _vrmlaldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26588 mCEF(vrmlaldavhax, _vrmlaldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26589 mToC("vrmlalvh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26590 mToC("vrmlalvha", ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26591 mCEF(vrmlsldavh, _vrmlsldavh, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26592 mCEF(vrmlsldavha, _vrmlsldavha, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26593 mCEF(vrmlsldavhx, _vrmlsldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26594 mCEF(vrmlsldavhax, _vrmlsldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26595
2d78f95b
AV
26596 mToC("vmlas", ee011e40, 3, (RMQ, RMQ, RR), mve_vmlas),
26597 mToC("vmulh", ee010e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
26598 mToC("vrmulh", ee011e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
3063888e
AV
26599 mToC("vpnot", fe310f4d, 0, (), mve_vpnot),
26600 mToC("vpsel", fe310f01, 3, (RMQ, RMQ, RMQ), mve_vpsel),
2d78f95b 26601
8b8b22a4
AV
26602 mToC("vqdmladh", ee000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26603 mToC("vqdmladhx", ee001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26604 mToC("vqrdmladh", ee000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26605 mToC("vqrdmladhx",ee001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26606 mToC("vqdmlsdh", fe000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26607 mToC("vqdmlsdhx", fe001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26608 mToC("vqrdmlsdh", fe000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26609 mToC("vqrdmlsdhx",fe001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
42b16635
AV
26610 mToC("vqdmlah", ee000e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
26611 mToC("vqdmlash", ee001e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
26612 mToC("vqrdmlash", ee001e40, 3, (RMQ, RMQ, RR), mve_vqdmlah),
35d1cfc2
AV
26613 mToC("vqdmullt", ee301f00, 3, (RMQ, RMQ, RMQRR), mve_vqdmull),
26614 mToC("vqdmullb", ee300f00, 3, (RMQ, RMQ, RMQRR), mve_vqdmull),
1be7aba3
AV
26615 mCEF(vqmovnt, _vqmovnt, 2, (RMQ, RMQ), mve_vqmovn),
26616 mCEF(vqmovnb, _vqmovnb, 2, (RMQ, RMQ), mve_vqmovn),
26617 mCEF(vqmovunt, _vqmovunt, 2, (RMQ, RMQ), mve_vqmovn),
26618 mCEF(vqmovunb, _vqmovunb, 2, (RMQ, RMQ), mve_vqmovn),
8b8b22a4 26619
4aa88b50
AV
26620 mCEF(vshrnt, _vshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26621 mCEF(vshrnb, _vshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26622 mCEF(vrshrnt, _vrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26623 mCEF(vrshrnb, _vrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
b3a561ab
AC
26624 mCEF(vqshrnt, _vqshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26625 mCEF(vqshrnb, _vqshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26626 mCEF(vqshrunt, _vqshrunt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26627 mCEF(vqshrunb, _vqshrunb, 3, (RMQ, RMQ, I32z), mve_vshrn),
4aa88b50
AV
26628 mCEF(vqrshrnt, _vqrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26629 mCEF(vqrshrnb, _vqrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26630 mCEF(vqrshrunt, _vqrshrunt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26631 mCEF(vqrshrunb, _vqrshrunb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26632
acca5630
AV
26633 mToC("vshlc", eea00fc0, 3, (RMQ, RR, I32z), mve_vshlc),
26634 mToC("vshllt", ee201e00, 3, (RMQ, RMQ, I32), mve_vshll),
26635 mToC("vshllb", ee200e00, 3, (RMQ, RMQ, I32), mve_vshll),
26636
1f6234a3
AV
26637 toU("dlstp", _dlstp, 2, (LR, RR), t_loloop),
26638 toU("wlstp", _wlstp, 3, (LR, RR, EXP), t_loloop),
26639 toU("letp", _letp, 2, (LR, EXP), t_loloop),
26640 toU("lctp", _lctp, 0, (), t_loloop),
26641
5d281bf0
AV
26642#undef THUMB_VARIANT
26643#define THUMB_VARIANT & mve_fp_ext
26644 mToC("vcmul", ee300e00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vcmul),
f30ee27c 26645 mToC("vfmas", ee311e40, 3, (RMQ, RMQ, RR), mve_vfmas),
935295b5
AV
26646 mToC("vmaxnma", ee3f0e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
26647 mToC("vminnma", ee3f1e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
8cd78170
AV
26648 mToC("vmaxnmv", eeee0f00, 2, (RR, RMQ), mve_vmaxnmv),
26649 mToC("vmaxnmav",eeec0f00, 2, (RR, RMQ), mve_vmaxnmv),
26650 mToC("vminnmv", eeee0f80, 2, (RR, RMQ), mve_vmaxnmv),
26651 mToC("vminnmav",eeec0f80, 2, (RR, RMQ), mve_vmaxnmv),
5d281bf0 26652
5ee91343 26653#undef ARM_VARIANT
57785aa2 26654#define ARM_VARIANT & fpu_vfp_ext_v1
5ee91343
AV
26655#undef THUMB_VARIANT
26656#define THUMB_VARIANT & arm_ext_v6t2
26657
57785aa2
AV
26658 mcCE(fcpyd, eb00b40, 2, (RVD, RVD), vfp_dp_rd_rm),
26659
26660#undef ARM_VARIANT
26661#define ARM_VARIANT & fpu_vfp_ext_v1xd
26662
48f4d8ce
AV
26663 mnCEF(vmla, _vmla, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mac_maybe_scalar),
26664 mnCEF(vmul, _vmul, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mul),
57785aa2
AV
26665 MNCE(vmov, 0, 1, (VMOV), neon_mov),
26666 mcCE(fmrs, e100a10, 2, (RR, RVS), vfp_reg_from_sp),
26667 mcCE(fmsr, e000a10, 2, (RVS, RR), vfp_sp_from_reg),
26668 mcCE(fcpys, eb00a40, 2, (RVS, RVS), vfp_sp_monadic),
26669
886e1c73
AV
26670 mCEF(vmullt, _vmullt, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ), mve_vmull),
26671 mnCEF(vadd, _vadd, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
26672 mnCEF(vsub, _vsub, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
5ee91343 26673
485dee97
AV
26674 MNCEF(vabs, 1b10300, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
26675 MNCEF(vneg, 1b10380, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
26676
57785aa2
AV
26677 mCEF(vmovlt, _vmovlt, 1, (VMOV), mve_movl),
26678 mCEF(vmovlb, _vmovlb, 1, (VMOV), mve_movl),
26679
1b883319
AV
26680 mnCE(vcmp, _vcmp, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
26681 mnCE(vcmpe, _vcmpe, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
26682
57785aa2
AV
26683#undef ARM_VARIANT
26684#define ARM_VARIANT & fpu_vfp_ext_v2
26685
26686 mcCE(fmsrr, c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
26687 mcCE(fmrrs, c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
26688 mcCE(fmdrr, c400b10, 3, (RVD, RR, RR), vfp_dp_rm_rd_rn),
26689 mcCE(fmrrd, c500b10, 3, (RR, RR, RVD), vfp_dp_rd_rn_rm),
26690
dd9634d9
AV
26691#undef ARM_VARIANT
26692#define ARM_VARIANT & fpu_vfp_ext_armv8xd
26693 mnUF(vcvta, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvta),
26694 mnUF(vcvtp, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtp),
26695 mnUF(vcvtn, _vcvta, 3, (RNSDQMQ, oRNSDQMQ, oI32z), neon_cvtn),
26696 mnUF(vcvtm, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtm),
935295b5
AV
26697 mnUF(vmaxnm, _vmaxnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
26698 mnUF(vminnm, _vminnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
dd9634d9
AV
26699
26700#undef ARM_VARIANT
5ee91343 26701#define ARM_VARIANT & fpu_neon_ext_v1
f601a00c 26702 mnUF(vabd, _vabd, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
5ee91343 26703 mnUF(vabdl, _vabdl, 3, (RNQMQ, RNDMQ, RNDMQ), neon_dyadic_long),
66d1f7cc
AV
26704 mnUF(vaddl, _vaddl, 3, (RNSDQMQ, oRNSDMQ, RNSDMQR), neon_dyadic_long),
26705 mnUF(vsubl, _vsubl, 3, (RNSDQMQ, oRNSDMQ, RNSDMQR), neon_dyadic_long),
f601a00c
AV
26706 mnUF(vand, _vand, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26707 mnUF(vbic, _vbic, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26708 mnUF(vorr, _vorr, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26709 mnUF(vorn, _vorn, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26710 mnUF(veor, _veor, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_logic),
f30ee27c
AV
26711 MNUF(vcls, 1b00400, 2, (RNDQMQ, RNDQMQ), neon_cls),
26712 MNUF(vclz, 1b00480, 2, (RNDQMQ, RNDQMQ), neon_clz),
b409bdb6 26713 mnCE(vdup, _vdup, 2, (RNDQMQ, RR_RNSC), neon_dup),
7df54120
AV
26714 MNUF(vhadd, 00000000, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
26715 MNUF(vrhadd, 00000100, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_i_su),
26716 MNUF(vhsub, 00000200, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
935295b5
AV
26717 mnUF(vmin, _vmin, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
26718 mnUF(vmax, _vmax, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
a8465a06
AV
26719 MNUF(vqadd, 0000010, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
26720 MNUF(vqsub, 0000210, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
1a186d29
AV
26721 mnUF(vmvn, _vmvn, 2, (RNDQMQ, RNDQMQ_Ibig), neon_mvn),
26722 MNUF(vqabs, 1b00700, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
26723 MNUF(vqneg, 1b00780, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
42b16635
AV
26724 mnUF(vqrdmlah, _vqrdmlah,3, (RNDQMQ, oRNDQMQ, RNDQ_RNSC_RR), neon_qrdmlah),
26725 mnUF(vqdmulh, _vqdmulh, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
26726 mnUF(vqrdmulh, _vqrdmulh,3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
1be7aba3
AV
26727 MNUF(vqrshl, 0000510, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
26728 MNUF(vrshl, 0000500, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
4401c241
AV
26729 MNUF(vshr, 0800010, 3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
26730 MNUF(vrshr, 0800210, 3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
26731 MNUF(vsli, 1800510, 3, (RNDQMQ, oRNDQMQ, I63), neon_sli),
26732 MNUF(vsri, 1800410, 3, (RNDQMQ, oRNDQMQ, I64z), neon_sri),
26733 MNUF(vrev64, 1b00000, 2, (RNDQMQ, RNDQMQ), neon_rev),
26734 MNUF(vrev32, 1b00080, 2, (RNDQMQ, RNDQMQ), neon_rev),
26735 MNUF(vrev16, 1b00100, 2, (RNDQMQ, RNDQMQ), neon_rev),
5150f0d8
AV
26736 mnUF(vshl, _vshl, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_shl),
26737 mnUF(vqshl, _vqshl, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_qshl),
26738 MNUF(vqshlu, 1800610, 3, (RNDQMQ, oRNDQMQ, I63), neon_qshlu_imm),
5d281bf0
AV
26739
26740#undef ARM_VARIANT
26741#define ARM_VARIANT & arm_ext_v8_3
26742#undef THUMB_VARIANT
26743#define THUMB_VARIANT & arm_ext_v6t2_v8m
26744 MNUF (vcadd, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ, EXPi), vcadd),
26745 MNUF (vcmla, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ_RNSC, EXPi), vcmla),
aab2c27d
MM
26746
26747#undef ARM_VARIANT
26748#define ARM_VARIANT &arm_ext_bf16
26749#undef THUMB_VARIANT
26750#define THUMB_VARIANT &arm_ext_bf16
26751 TUF ("vdot", c000d00, fc000d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), vdot, vdot),
26752 TUF ("vmmla", c000c40, fc000c40, 3, (RNQ, RNQ, RNQ), vmmla, vmmla),
26753 TUF ("vfmab", c300810, fc300810, 3, (RNDQ, RNDQ, RNDQ_RNSC), bfloat_vfma, bfloat_vfma),
26754
26755#undef ARM_VARIANT
26756#define ARM_VARIANT &arm_ext_i8mm
26757#undef THUMB_VARIANT
26758#define THUMB_VARIANT &arm_ext_i8mm
26759 TUF ("vsmmla", c200c40, fc200c40, 3, (RNQ, RNQ, RNQ), vsmmla, vsmmla),
26760 TUF ("vummla", c200c50, fc200c50, 3, (RNQ, RNQ, RNQ), vummla, vummla),
616ce08e 26761 TUF ("vusmmla", ca00c40, fca00c40, 3, (RNQ, RNQ, RNQ), vsmmla, vsmmla),
aab2c27d
MM
26762 TUF ("vusdot", c800d00, fc800d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), vusdot, vusdot),
26763 TUF ("vsudot", c800d10, fc800d10, 3, (RNDQ, RNDQ, RNSC), vsudot, vsudot),
4934a27c
MM
26764
26765#undef ARM_VARIANT
26766#undef THUMB_VARIANT
26767#define THUMB_VARIANT &arm_ext_cde
26768 ToC ("cx1", ee000000, 3, (RCP, APSR_RR, I8191), cx1),
26769 ToC ("cx1a", fe000000, 3, (RCP, APSR_RR, I8191), cx1a),
26770 ToC ("cx1d", ee000040, 4, (RCP, RR, APSR_RR, I8191), cx1d),
26771 ToC ("cx1da", fe000040, 4, (RCP, RR, APSR_RR, I8191), cx1da),
26772
26773 ToC ("cx2", ee400000, 4, (RCP, APSR_RR, APSR_RR, I511), cx2),
26774 ToC ("cx2a", fe400000, 4, (RCP, APSR_RR, APSR_RR, I511), cx2a),
26775 ToC ("cx2d", ee400040, 5, (RCP, RR, APSR_RR, APSR_RR, I511), cx2d),
26776 ToC ("cx2da", fe400040, 5, (RCP, RR, APSR_RR, APSR_RR, I511), cx2da),
26777
26778 ToC ("cx3", ee800000, 5, (RCP, APSR_RR, APSR_RR, APSR_RR, I63), cx3),
26779 ToC ("cx3a", fe800000, 5, (RCP, APSR_RR, APSR_RR, APSR_RR, I63), cx3a),
26780 ToC ("cx3d", ee800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3d),
26781 ToC ("cx3da", fe800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3da),
5aae9ae9
MM
26782
26783 mToC ("vcx1", ec200000, 3, (RCP, RNSDMQ, I4095), vcx1),
26784 mToC ("vcx1a", fc200000, 3, (RCP, RNSDMQ, I4095), vcx1),
26785
26786 mToC ("vcx2", ec300000, 4, (RCP, RNSDMQ, RNSDMQ, I127), vcx2),
26787 mToC ("vcx2a", fc300000, 4, (RCP, RNSDMQ, RNSDMQ, I127), vcx2),
26788
26789 mToC ("vcx3", ec800000, 5, (RCP, RNSDMQ, RNSDMQ, RNSDMQ, I15), vcx3),
26790 mToC ("vcx3a", fc800000, 5, (RCP, RNSDMQ, RNSDMQ, RNSDMQ, I15), vcx3),
c19d1205 26791};
5aae9ae9 26792
c19d1205
ZW
26793#undef ARM_VARIANT
26794#undef THUMB_VARIANT
26795#undef TCE
c19d1205
ZW
26796#undef TUE
26797#undef TUF
26798#undef TCC
8f06b2d8 26799#undef cCE
e3cb604e
PB
26800#undef cCL
26801#undef C3E
4389b29a 26802#undef C3
c19d1205
ZW
26803#undef CE
26804#undef CM
4389b29a 26805#undef CL
c19d1205
ZW
26806#undef UE
26807#undef UF
26808#undef UT
5287ad62
JB
26809#undef NUF
26810#undef nUF
26811#undef NCE
26812#undef nCE
c19d1205
ZW
26813#undef OPS0
26814#undef OPS1
26815#undef OPS2
26816#undef OPS3
26817#undef OPS4
26818#undef OPS5
26819#undef OPS6
26820#undef do_0
4389b29a
AV
26821#undef ToC
26822#undef toC
26823#undef ToU
f6b2b12d 26824#undef toU
c19d1205
ZW
26825\f
26826/* MD interface: bits in the object file. */
bfae80f2 26827
c19d1205
ZW
26828/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
26829 for use in the a.out file, and stores them in the array pointed to by buf.
26830 This knows about the endian-ness of the target machine and does
26831 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
26832 2 (short) and 4 (long) Floating numbers are put out as a series of
26833 LITTLENUMS (shorts, here at least). */
b99bd4ef 26834
c19d1205
ZW
26835void
26836md_number_to_chars (char * buf, valueT val, int n)
26837{
26838 if (target_big_endian)
26839 number_to_chars_bigendian (buf, val, n);
26840 else
26841 number_to_chars_littleendian (buf, val, n);
bfae80f2
RE
26842}
26843
c19d1205
ZW
26844static valueT
26845md_chars_to_number (char * buf, int n)
bfae80f2 26846{
c19d1205
ZW
26847 valueT result = 0;
26848 unsigned char * where = (unsigned char *) buf;
bfae80f2 26849
c19d1205 26850 if (target_big_endian)
b99bd4ef 26851 {
c19d1205
ZW
26852 while (n--)
26853 {
26854 result <<= 8;
26855 result |= (*where++ & 255);
26856 }
b99bd4ef 26857 }
c19d1205 26858 else
b99bd4ef 26859 {
c19d1205
ZW
26860 while (n--)
26861 {
26862 result <<= 8;
26863 result |= (where[n] & 255);
26864 }
bfae80f2 26865 }
b99bd4ef 26866
c19d1205 26867 return result;
bfae80f2 26868}
b99bd4ef 26869
c19d1205 26870/* MD interface: Sections. */
b99bd4ef 26871
fa94de6b
RM
26872/* Calculate the maximum variable size (i.e., excluding fr_fix)
26873 that an rs_machine_dependent frag may reach. */
26874
26875unsigned int
26876arm_frag_max_var (fragS *fragp)
26877{
26878 /* We only use rs_machine_dependent for variable-size Thumb instructions,
26879 which are either THUMB_SIZE (2) or INSN_SIZE (4).
26880
26881 Note that we generate relaxable instructions even for cases that don't
26882 really need it, like an immediate that's a trivial constant. So we're
26883 overestimating the instruction size for some of those cases. Rather
26884 than putting more intelligence here, it would probably be better to
26885 avoid generating a relaxation frag in the first place when it can be
26886 determined up front that a short instruction will suffice. */
26887
26888 gas_assert (fragp->fr_type == rs_machine_dependent);
26889 return INSN_SIZE;
26890}
26891
0110f2b8
PB
26892/* Estimate the size of a frag before relaxing. Assume everything fits in
26893 2 bytes. */
26894
c19d1205 26895int
0110f2b8 26896md_estimate_size_before_relax (fragS * fragp,
c19d1205
ZW
26897 segT segtype ATTRIBUTE_UNUSED)
26898{
0110f2b8
PB
26899 fragp->fr_var = 2;
26900 return 2;
26901}
26902
26903/* Convert a machine dependent frag. */
26904
26905void
26906md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
26907{
26908 unsigned long insn;
26909 unsigned long old_op;
26910 char *buf;
26911 expressionS exp;
26912 fixS *fixp;
26913 int reloc_type;
26914 int pc_rel;
26915 int opcode;
26916
26917 buf = fragp->fr_literal + fragp->fr_fix;
26918
26919 old_op = bfd_get_16(abfd, buf);
5f4273c7
NC
26920 if (fragp->fr_symbol)
26921 {
0110f2b8
PB
26922 exp.X_op = O_symbol;
26923 exp.X_add_symbol = fragp->fr_symbol;
5f4273c7
NC
26924 }
26925 else
26926 {
0110f2b8 26927 exp.X_op = O_constant;
5f4273c7 26928 }
0110f2b8
PB
26929 exp.X_add_number = fragp->fr_offset;
26930 opcode = fragp->fr_subtype;
26931 switch (opcode)
26932 {
26933 case T_MNEM_ldr_pc:
26934 case T_MNEM_ldr_pc2:
26935 case T_MNEM_ldr_sp:
26936 case T_MNEM_str_sp:
26937 case T_MNEM_ldr:
26938 case T_MNEM_ldrb:
26939 case T_MNEM_ldrh:
26940 case T_MNEM_str:
26941 case T_MNEM_strb:
26942 case T_MNEM_strh:
26943 if (fragp->fr_var == 4)
26944 {
5f4273c7 26945 insn = THUMB_OP32 (opcode);
0110f2b8
PB
26946 if ((old_op >> 12) == 4 || (old_op >> 12) == 9)
26947 {
26948 insn |= (old_op & 0x700) << 4;
26949 }
26950 else
26951 {
26952 insn |= (old_op & 7) << 12;
26953 insn |= (old_op & 0x38) << 13;
26954 }
26955 insn |= 0x00000c00;
26956 put_thumb32_insn (buf, insn);
26957 reloc_type = BFD_RELOC_ARM_T32_OFFSET_IMM;
26958 }
26959 else
26960 {
26961 reloc_type = BFD_RELOC_ARM_THUMB_OFFSET;
26962 }
26963 pc_rel = (opcode == T_MNEM_ldr_pc2);
26964 break;
26965 case T_MNEM_adr:
d3e52e12
TC
26966 /* Thumb bits should be set in the frag handling so we process them
26967 after all symbols have been seen. PR gas/25235. */
26968 if (exp.X_op == O_symbol
26969 && exp.X_add_symbol != NULL
26970 && S_IS_DEFINED (exp.X_add_symbol)
26971 && THUMB_IS_FUNC (exp.X_add_symbol))
26972 exp.X_add_number |= 1;
26973
0110f2b8
PB
26974 if (fragp->fr_var == 4)
26975 {
26976 insn = THUMB_OP32 (opcode);
26977 insn |= (old_op & 0xf0) << 4;
26978 put_thumb32_insn (buf, insn);
26979 reloc_type = BFD_RELOC_ARM_T32_ADD_PC12;
26980 }
26981 else
26982 {
26983 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
26984 exp.X_add_number -= 4;
26985 }
26986 pc_rel = 1;
26987 break;
26988 case T_MNEM_mov:
26989 case T_MNEM_movs:
26990 case T_MNEM_cmp:
26991 case T_MNEM_cmn:
26992 if (fragp->fr_var == 4)
26993 {
26994 int r0off = (opcode == T_MNEM_mov
26995 || opcode == T_MNEM_movs) ? 0 : 8;
26996 insn = THUMB_OP32 (opcode);
26997 insn = (insn & 0xe1ffffff) | 0x10000000;
26998 insn |= (old_op & 0x700) << r0off;
26999 put_thumb32_insn (buf, insn);
27000 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
27001 }
27002 else
27003 {
27004 reloc_type = BFD_RELOC_ARM_THUMB_IMM;
27005 }
27006 pc_rel = 0;
27007 break;
27008 case T_MNEM_b:
27009 if (fragp->fr_var == 4)
27010 {
27011 insn = THUMB_OP32(opcode);
27012 put_thumb32_insn (buf, insn);
27013 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH25;
27014 }
27015 else
27016 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH12;
27017 pc_rel = 1;
27018 break;
27019 case T_MNEM_bcond:
27020 if (fragp->fr_var == 4)
27021 {
27022 insn = THUMB_OP32(opcode);
27023 insn |= (old_op & 0xf00) << 14;
27024 put_thumb32_insn (buf, insn);
27025 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH20;
27026 }
27027 else
27028 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH9;
27029 pc_rel = 1;
27030 break;
27031 case T_MNEM_add_sp:
27032 case T_MNEM_add_pc:
27033 case T_MNEM_inc_sp:
27034 case T_MNEM_dec_sp:
27035 if (fragp->fr_var == 4)
27036 {
27037 /* ??? Choose between add and addw. */
27038 insn = THUMB_OP32 (opcode);
27039 insn |= (old_op & 0xf0) << 4;
27040 put_thumb32_insn (buf, insn);
16805f35
PB
27041 if (opcode == T_MNEM_add_pc)
27042 reloc_type = BFD_RELOC_ARM_T32_IMM12;
27043 else
27044 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
0110f2b8
PB
27045 }
27046 else
27047 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
27048 pc_rel = 0;
27049 break;
27050
27051 case T_MNEM_addi:
27052 case T_MNEM_addis:
27053 case T_MNEM_subi:
27054 case T_MNEM_subis:
27055 if (fragp->fr_var == 4)
27056 {
27057 insn = THUMB_OP32 (opcode);
27058 insn |= (old_op & 0xf0) << 4;
27059 insn |= (old_op & 0xf) << 16;
27060 put_thumb32_insn (buf, insn);
16805f35
PB
27061 if (insn & (1 << 20))
27062 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
27063 else
27064 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8
PB
27065 }
27066 else
27067 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
27068 pc_rel = 0;
27069 break;
27070 default:
5f4273c7 27071 abort ();
0110f2b8
PB
27072 }
27073 fixp = fix_new_exp (fragp, fragp->fr_fix, fragp->fr_var, &exp, pc_rel,
21d799b5 27074 (enum bfd_reloc_code_real) reloc_type);
0110f2b8
PB
27075 fixp->fx_file = fragp->fr_file;
27076 fixp->fx_line = fragp->fr_line;
27077 fragp->fr_fix += fragp->fr_var;
3cfdb781
TG
27078
27079 /* Set whether we use thumb-2 ISA based on final relaxation results. */
27080 if (thumb_mode && fragp->fr_var == 4 && no_cpu_selected ()
27081 && !ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2))
27082 ARM_MERGE_FEATURE_SETS (arm_arch_used, thumb_arch_used, arm_ext_v6t2);
0110f2b8
PB
27083}
27084
27085/* Return the size of a relaxable immediate operand instruction.
27086 SHIFT and SIZE specify the form of the allowable immediate. */
27087static int
27088relax_immediate (fragS *fragp, int size, int shift)
27089{
27090 offsetT offset;
27091 offsetT mask;
27092 offsetT low;
27093
27094 /* ??? Should be able to do better than this. */
27095 if (fragp->fr_symbol)
27096 return 4;
27097
27098 low = (1 << shift) - 1;
27099 mask = (1 << (shift + size)) - (1 << shift);
27100 offset = fragp->fr_offset;
27101 /* Force misaligned offsets to 32-bit variant. */
27102 if (offset & low)
5e77afaa 27103 return 4;
0110f2b8
PB
27104 if (offset & ~mask)
27105 return 4;
27106 return 2;
27107}
27108
5e77afaa
PB
27109/* Get the address of a symbol during relaxation. */
27110static addressT
5f4273c7 27111relaxed_symbol_addr (fragS *fragp, long stretch)
5e77afaa
PB
27112{
27113 fragS *sym_frag;
27114 addressT addr;
27115 symbolS *sym;
27116
27117 sym = fragp->fr_symbol;
27118 sym_frag = symbol_get_frag (sym);
27119 know (S_GET_SEGMENT (sym) != absolute_section
27120 || sym_frag == &zero_address_frag);
27121 addr = S_GET_VALUE (sym) + fragp->fr_offset;
27122
27123 /* If frag has yet to be reached on this pass, assume it will
27124 move by STRETCH just as we did. If this is not so, it will
27125 be because some frag between grows, and that will force
27126 another pass. */
27127
27128 if (stretch != 0
27129 && sym_frag->relax_marker != fragp->relax_marker)
4396b686
PB
27130 {
27131 fragS *f;
27132
27133 /* Adjust stretch for any alignment frag. Note that if have
27134 been expanding the earlier code, the symbol may be
27135 defined in what appears to be an earlier frag. FIXME:
27136 This doesn't handle the fr_subtype field, which specifies
27137 a maximum number of bytes to skip when doing an
27138 alignment. */
27139 for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
27140 {
27141 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
27142 {
27143 if (stretch < 0)
27144 stretch = - ((- stretch)
27145 & ~ ((1 << (int) f->fr_offset) - 1));
27146 else
27147 stretch &= ~ ((1 << (int) f->fr_offset) - 1);
27148 if (stretch == 0)
27149 break;
27150 }
27151 }
27152 if (f != NULL)
27153 addr += stretch;
27154 }
5e77afaa
PB
27155
27156 return addr;
27157}
27158
0110f2b8
PB
27159/* Return the size of a relaxable adr pseudo-instruction or PC-relative
27160 load. */
27161static int
5e77afaa 27162relax_adr (fragS *fragp, asection *sec, long stretch)
0110f2b8
PB
27163{
27164 addressT addr;
27165 offsetT val;
27166
27167 /* Assume worst case for symbols not known to be in the same section. */
974da60d
NC
27168 if (fragp->fr_symbol == NULL
27169 || !S_IS_DEFINED (fragp->fr_symbol)
77db8e2e 27170 || sec != S_GET_SEGMENT (fragp->fr_symbol)
d3e52e12
TC
27171 || S_IS_WEAK (fragp->fr_symbol)
27172 || THUMB_IS_FUNC (fragp->fr_symbol))
0110f2b8
PB
27173 return 4;
27174
5f4273c7 27175 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
27176 addr = fragp->fr_address + fragp->fr_fix;
27177 addr = (addr + 4) & ~3;
5e77afaa 27178 /* Force misaligned targets to 32-bit variant. */
0110f2b8 27179 if (val & 3)
5e77afaa 27180 return 4;
0110f2b8
PB
27181 val -= addr;
27182 if (val < 0 || val > 1020)
27183 return 4;
27184 return 2;
27185}
27186
27187/* Return the size of a relaxable add/sub immediate instruction. */
27188static int
27189relax_addsub (fragS *fragp, asection *sec)
27190{
27191 char *buf;
27192 int op;
27193
27194 buf = fragp->fr_literal + fragp->fr_fix;
27195 op = bfd_get_16(sec->owner, buf);
27196 if ((op & 0xf) == ((op >> 4) & 0xf))
27197 return relax_immediate (fragp, 8, 0);
27198 else
27199 return relax_immediate (fragp, 3, 0);
27200}
27201
e83a675f
RE
27202/* Return TRUE iff the definition of symbol S could be pre-empted
27203 (overridden) at link or load time. */
5b7c81bd 27204static bool
e83a675f
RE
27205symbol_preemptible (symbolS *s)
27206{
27207 /* Weak symbols can always be pre-empted. */
27208 if (S_IS_WEAK (s))
5b7c81bd 27209 return true;
e83a675f
RE
27210
27211 /* Non-global symbols cannot be pre-empted. */
27212 if (! S_IS_EXTERNAL (s))
5b7c81bd 27213 return false;
e83a675f
RE
27214
27215#ifdef OBJ_ELF
27216 /* In ELF, a global symbol can be marked protected, or private. In that
27217 case it can't be pre-empted (other definitions in the same link unit
27218 would violate the ODR). */
27219 if (ELF_ST_VISIBILITY (S_GET_OTHER (s)) > STV_DEFAULT)
5b7c81bd 27220 return false;
e83a675f
RE
27221#endif
27222
27223 /* Other global symbols might be pre-empted. */
5b7c81bd 27224 return true;
e83a675f 27225}
0110f2b8
PB
27226
27227/* Return the size of a relaxable branch instruction. BITS is the
27228 size of the offset field in the narrow instruction. */
27229
27230static int
5e77afaa 27231relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
0110f2b8
PB
27232{
27233 addressT addr;
27234 offsetT val;
27235 offsetT limit;
27236
27237 /* Assume worst case for symbols not known to be in the same section. */
5f4273c7 27238 if (!S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
27239 || sec != S_GET_SEGMENT (fragp->fr_symbol)
27240 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
27241 return 4;
27242
267bf995 27243#ifdef OBJ_ELF
e83a675f 27244 /* A branch to a function in ARM state will require interworking. */
267bf995
RR
27245 if (S_IS_DEFINED (fragp->fr_symbol)
27246 && ARM_IS_FUNC (fragp->fr_symbol))
27247 return 4;
e83a675f 27248#endif
0d9b4b55 27249
e83a675f 27250 if (symbol_preemptible (fragp->fr_symbol))
0d9b4b55 27251 return 4;
267bf995 27252
5f4273c7 27253 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
27254 addr = fragp->fr_address + fragp->fr_fix + 4;
27255 val -= addr;
27256
27257 /* Offset is a signed value *2 */
27258 limit = 1 << bits;
27259 if (val >= limit || val < -limit)
27260 return 4;
27261 return 2;
27262}
27263
27264
27265/* Relax a machine dependent frag. This returns the amount by which
27266 the current size of the frag should change. */
27267
27268int
5e77afaa 27269arm_relax_frag (asection *sec, fragS *fragp, long stretch)
0110f2b8
PB
27270{
27271 int oldsize;
27272 int newsize;
27273
27274 oldsize = fragp->fr_var;
27275 switch (fragp->fr_subtype)
27276 {
27277 case T_MNEM_ldr_pc2:
5f4273c7 27278 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
27279 break;
27280 case T_MNEM_ldr_pc:
27281 case T_MNEM_ldr_sp:
27282 case T_MNEM_str_sp:
5f4273c7 27283 newsize = relax_immediate (fragp, 8, 2);
0110f2b8
PB
27284 break;
27285 case T_MNEM_ldr:
27286 case T_MNEM_str:
5f4273c7 27287 newsize = relax_immediate (fragp, 5, 2);
0110f2b8
PB
27288 break;
27289 case T_MNEM_ldrh:
27290 case T_MNEM_strh:
5f4273c7 27291 newsize = relax_immediate (fragp, 5, 1);
0110f2b8
PB
27292 break;
27293 case T_MNEM_ldrb:
27294 case T_MNEM_strb:
5f4273c7 27295 newsize = relax_immediate (fragp, 5, 0);
0110f2b8
PB
27296 break;
27297 case T_MNEM_adr:
5f4273c7 27298 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
27299 break;
27300 case T_MNEM_mov:
27301 case T_MNEM_movs:
27302 case T_MNEM_cmp:
27303 case T_MNEM_cmn:
5f4273c7 27304 newsize = relax_immediate (fragp, 8, 0);
0110f2b8
PB
27305 break;
27306 case T_MNEM_b:
5f4273c7 27307 newsize = relax_branch (fragp, sec, 11, stretch);
0110f2b8
PB
27308 break;
27309 case T_MNEM_bcond:
5f4273c7 27310 newsize = relax_branch (fragp, sec, 8, stretch);
0110f2b8
PB
27311 break;
27312 case T_MNEM_add_sp:
27313 case T_MNEM_add_pc:
27314 newsize = relax_immediate (fragp, 8, 2);
27315 break;
27316 case T_MNEM_inc_sp:
27317 case T_MNEM_dec_sp:
27318 newsize = relax_immediate (fragp, 7, 2);
27319 break;
27320 case T_MNEM_addi:
27321 case T_MNEM_addis:
27322 case T_MNEM_subi:
27323 case T_MNEM_subis:
27324 newsize = relax_addsub (fragp, sec);
27325 break;
27326 default:
5f4273c7 27327 abort ();
0110f2b8 27328 }
5e77afaa
PB
27329
27330 fragp->fr_var = newsize;
27331 /* Freeze wide instructions that are at or before the same location as
27332 in the previous pass. This avoids infinite loops.
5f4273c7
NC
27333 Don't freeze them unconditionally because targets may be artificially
27334 misaligned by the expansion of preceding frags. */
5e77afaa 27335 if (stretch <= 0 && newsize > 2)
0110f2b8 27336 {
0110f2b8 27337 md_convert_frag (sec->owner, sec, fragp);
5f4273c7 27338 frag_wane (fragp);
0110f2b8 27339 }
5e77afaa 27340
0110f2b8 27341 return newsize - oldsize;
c19d1205 27342}
b99bd4ef 27343
c19d1205 27344/* Round up a section size to the appropriate boundary. */
b99bd4ef 27345
c19d1205
ZW
27346valueT
27347md_section_align (segT segment ATTRIBUTE_UNUSED,
27348 valueT size)
27349{
6844c0cc 27350 return size;
bfae80f2 27351}
b99bd4ef 27352
c19d1205
ZW
27353/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
27354 of an rs_align_code fragment. */
27355
27356void
27357arm_handle_align (fragS * fragP)
bfae80f2 27358{
d9235011 27359 static unsigned char const arm_noop[2][2][4] =
e7495e45
NS
27360 {
27361 { /* ARMv1 */
27362 {0x00, 0x00, 0xa0, 0xe1}, /* LE */
27363 {0xe1, 0xa0, 0x00, 0x00}, /* BE */
27364 },
27365 { /* ARMv6k */
27366 {0x00, 0xf0, 0x20, 0xe3}, /* LE */
27367 {0xe3, 0x20, 0xf0, 0x00}, /* BE */
27368 },
27369 };
d9235011 27370 static unsigned char const thumb_noop[2][2][2] =
e7495e45
NS
27371 {
27372 { /* Thumb-1 */
27373 {0xc0, 0x46}, /* LE */
27374 {0x46, 0xc0}, /* BE */
27375 },
27376 { /* Thumb-2 */
27377 {0x00, 0xbf}, /* LE */
27378 {0xbf, 0x00} /* BE */
27379 }
27380 };
d9235011 27381 static unsigned char const wide_thumb_noop[2][4] =
e7495e45
NS
27382 { /* Wide Thumb-2 */
27383 {0xaf, 0xf3, 0x00, 0x80}, /* LE */
27384 {0xf3, 0xaf, 0x80, 0x00}, /* BE */
27385 };
c921be7d 27386
e7495e45 27387 unsigned bytes, fix, noop_size;
c19d1205 27388 char * p;
d9235011
TS
27389 const unsigned char * noop;
27390 const unsigned char *narrow_noop = NULL;
cd000bff
DJ
27391#ifdef OBJ_ELF
27392 enum mstate state;
27393#endif
bfae80f2 27394
c19d1205 27395 if (fragP->fr_type != rs_align_code)
bfae80f2
RE
27396 return;
27397
c19d1205
ZW
27398 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
27399 p = fragP->fr_literal + fragP->fr_fix;
27400 fix = 0;
bfae80f2 27401
c19d1205
ZW
27402 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
27403 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
bfae80f2 27404
cd000bff 27405 gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
8dc2430f 27406
cd000bff 27407 if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
a737bd4d 27408 {
7f78eb34
JW
27409 if (ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
27410 ? selected_cpu : arm_arch_none, arm_ext_v6t2))
e7495e45
NS
27411 {
27412 narrow_noop = thumb_noop[1][target_big_endian];
27413 noop = wide_thumb_noop[target_big_endian];
27414 }
c19d1205 27415 else
e7495e45
NS
27416 noop = thumb_noop[0][target_big_endian];
27417 noop_size = 2;
cd000bff
DJ
27418#ifdef OBJ_ELF
27419 state = MAP_THUMB;
27420#endif
7ed4c4c5
NC
27421 }
27422 else
27423 {
7f78eb34
JW
27424 noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
27425 ? selected_cpu : arm_arch_none,
27426 arm_ext_v6k) != 0]
e7495e45
NS
27427 [target_big_endian];
27428 noop_size = 4;
cd000bff
DJ
27429#ifdef OBJ_ELF
27430 state = MAP_ARM;
27431#endif
7ed4c4c5 27432 }
c921be7d 27433
e7495e45 27434 fragP->fr_var = noop_size;
c921be7d 27435
c19d1205 27436 if (bytes & (noop_size - 1))
7ed4c4c5 27437 {
c19d1205 27438 fix = bytes & (noop_size - 1);
cd000bff
DJ
27439#ifdef OBJ_ELF
27440 insert_data_mapping_symbol (state, fragP->fr_fix, fragP, fix);
27441#endif
c19d1205
ZW
27442 memset (p, 0, fix);
27443 p += fix;
27444 bytes -= fix;
a737bd4d 27445 }
a737bd4d 27446
e7495e45
NS
27447 if (narrow_noop)
27448 {
27449 if (bytes & noop_size)
27450 {
27451 /* Insert a narrow noop. */
27452 memcpy (p, narrow_noop, noop_size);
27453 p += noop_size;
27454 bytes -= noop_size;
27455 fix += noop_size;
27456 }
27457
27458 /* Use wide noops for the remainder */
27459 noop_size = 4;
27460 }
27461
c19d1205 27462 while (bytes >= noop_size)
a737bd4d 27463 {
c19d1205
ZW
27464 memcpy (p, noop, noop_size);
27465 p += noop_size;
27466 bytes -= noop_size;
27467 fix += noop_size;
a737bd4d
NC
27468 }
27469
c19d1205 27470 fragP->fr_fix += fix;
a737bd4d
NC
27471}
27472
c19d1205
ZW
27473/* Called from md_do_align. Used to create an alignment
27474 frag in a code section. */
27475
27476void
27477arm_frag_align_code (int n, int max)
bfae80f2 27478{
c19d1205 27479 char * p;
7ed4c4c5 27480
c19d1205 27481 /* We assume that there will never be a requirement
6ec8e702 27482 to support alignments greater than MAX_MEM_FOR_RS_ALIGN_CODE bytes. */
c19d1205 27483 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
6ec8e702
NC
27484 {
27485 char err_msg[128];
27486
fa94de6b 27487 sprintf (err_msg,
477330fc
RM
27488 _("alignments greater than %d bytes not supported in .text sections."),
27489 MAX_MEM_FOR_RS_ALIGN_CODE + 1);
20203fb9 27490 as_fatal ("%s", err_msg);
6ec8e702 27491 }
bfae80f2 27492
c19d1205
ZW
27493 p = frag_var (rs_align_code,
27494 MAX_MEM_FOR_RS_ALIGN_CODE,
27495 1,
27496 (relax_substateT) max,
27497 (symbolS *) NULL,
27498 (offsetT) n,
27499 (char *) NULL);
27500 *p = 0;
27501}
bfae80f2 27502
8dc2430f
NC
27503/* Perform target specific initialisation of a frag.
27504 Note - despite the name this initialisation is not done when the frag
27505 is created, but only when its type is assigned. A frag can be created
27506 and used a long time before its type is set, so beware of assuming that
33eaf5de 27507 this initialisation is performed first. */
bfae80f2 27508
cd000bff
DJ
27509#ifndef OBJ_ELF
27510void
27511arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
27512{
27513 /* Record whether this frag is in an ARM or a THUMB area. */
2e98972e 27514 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
cd000bff
DJ
27515}
27516
27517#else /* OBJ_ELF is defined. */
c19d1205 27518void
cd000bff 27519arm_init_frag (fragS * fragP, int max_chars)
c19d1205 27520{
5b7c81bd 27521 bool frag_thumb_mode;
b968d18a 27522
8dc2430f
NC
27523 /* If the current ARM vs THUMB mode has not already
27524 been recorded into this frag then do so now. */
cd000bff 27525 if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
b968d18a
JW
27526 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
27527
e8d84ca1
NC
27528 /* PR 21809: Do not set a mapping state for debug sections
27529 - it just confuses other tools. */
fd361982 27530 if (bfd_section_flags (now_seg) & SEC_DEBUGGING)
e8d84ca1
NC
27531 return;
27532
b968d18a 27533 frag_thumb_mode = fragP->tc_frag_data.thumb_mode ^ MODE_RECORDED;
cd000bff 27534
f9c1b181
RL
27535 /* Record a mapping symbol for alignment frags. We will delete this
27536 later if the alignment ends up empty. */
27537 switch (fragP->fr_type)
27538 {
27539 case rs_align:
27540 case rs_align_test:
27541 case rs_fill:
27542 mapping_state_2 (MAP_DATA, max_chars);
27543 break;
27544 case rs_align_code:
b968d18a 27545 mapping_state_2 (frag_thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
f9c1b181
RL
27546 break;
27547 default:
27548 break;
cd000bff 27549 }
bfae80f2
RE
27550}
27551
c19d1205
ZW
27552/* When we change sections we need to issue a new mapping symbol. */
27553
27554void
27555arm_elf_change_section (void)
bfae80f2 27556{
c19d1205
ZW
27557 /* Link an unlinked unwind index table section to the .text section. */
27558 if (elf_section_type (now_seg) == SHT_ARM_EXIDX
27559 && elf_linked_to_section (now_seg) == NULL)
27560 elf_linked_to_section (now_seg) = text_section;
bfae80f2
RE
27561}
27562
c19d1205
ZW
27563int
27564arm_elf_section_type (const char * str, size_t len)
e45d0630 27565{
d34049e8 27566 if (len == 5 && startswith (str, "exidx"))
c19d1205 27567 return SHT_ARM_EXIDX;
e45d0630 27568
c19d1205
ZW
27569 return -1;
27570}
27571\f
27572/* Code to deal with unwinding tables. */
e45d0630 27573
c19d1205 27574static void add_unwind_adjustsp (offsetT);
e45d0630 27575
5f4273c7 27576/* Generate any deferred unwind frame offset. */
e45d0630 27577
bfae80f2 27578static void
c19d1205 27579flush_pending_unwind (void)
bfae80f2 27580{
c19d1205 27581 offsetT offset;
bfae80f2 27582
c19d1205
ZW
27583 offset = unwind.pending_offset;
27584 unwind.pending_offset = 0;
27585 if (offset != 0)
27586 add_unwind_adjustsp (offset);
bfae80f2
RE
27587}
27588
c19d1205
ZW
27589/* Add an opcode to this list for this function. Two-byte opcodes should
27590 be passed as op[0] << 8 | op[1]. The list of opcodes is built in reverse
27591 order. */
27592
bfae80f2 27593static void
c19d1205 27594add_unwind_opcode (valueT op, int length)
bfae80f2 27595{
c19d1205
ZW
27596 /* Add any deferred stack adjustment. */
27597 if (unwind.pending_offset)
27598 flush_pending_unwind ();
bfae80f2 27599
c19d1205 27600 unwind.sp_restored = 0;
bfae80f2 27601
c19d1205 27602 if (unwind.opcode_count + length > unwind.opcode_alloc)
bfae80f2 27603 {
c19d1205
ZW
27604 unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
27605 if (unwind.opcodes)
325801bd
TS
27606 unwind.opcodes = XRESIZEVEC (unsigned char, unwind.opcodes,
27607 unwind.opcode_alloc);
c19d1205 27608 else
325801bd 27609 unwind.opcodes = XNEWVEC (unsigned char, unwind.opcode_alloc);
bfae80f2 27610 }
c19d1205 27611 while (length > 0)
bfae80f2 27612 {
c19d1205
ZW
27613 length--;
27614 unwind.opcodes[unwind.opcode_count] = op & 0xff;
27615 op >>= 8;
27616 unwind.opcode_count++;
bfae80f2 27617 }
bfae80f2
RE
27618}
27619
c19d1205
ZW
27620/* Add unwind opcodes to adjust the stack pointer. */
27621
bfae80f2 27622static void
c19d1205 27623add_unwind_adjustsp (offsetT offset)
bfae80f2 27624{
c19d1205 27625 valueT op;
bfae80f2 27626
c19d1205 27627 if (offset > 0x200)
bfae80f2 27628 {
c19d1205
ZW
27629 /* We need at most 5 bytes to hold a 32-bit value in a uleb128. */
27630 char bytes[5];
27631 int n;
27632 valueT o;
bfae80f2 27633
c19d1205
ZW
27634 /* Long form: 0xb2, uleb128. */
27635 /* This might not fit in a word so add the individual bytes,
27636 remembering the list is built in reverse order. */
27637 o = (valueT) ((offset - 0x204) >> 2);
27638 if (o == 0)
27639 add_unwind_opcode (0, 1);
bfae80f2 27640
c19d1205
ZW
27641 /* Calculate the uleb128 encoding of the offset. */
27642 n = 0;
27643 while (o)
27644 {
27645 bytes[n] = o & 0x7f;
27646 o >>= 7;
27647 if (o)
27648 bytes[n] |= 0x80;
27649 n++;
27650 }
27651 /* Add the insn. */
27652 for (; n; n--)
27653 add_unwind_opcode (bytes[n - 1], 1);
27654 add_unwind_opcode (0xb2, 1);
27655 }
27656 else if (offset > 0x100)
bfae80f2 27657 {
c19d1205
ZW
27658 /* Two short opcodes. */
27659 add_unwind_opcode (0x3f, 1);
27660 op = (offset - 0x104) >> 2;
27661 add_unwind_opcode (op, 1);
bfae80f2 27662 }
c19d1205
ZW
27663 else if (offset > 0)
27664 {
27665 /* Short opcode. */
27666 op = (offset - 4) >> 2;
27667 add_unwind_opcode (op, 1);
27668 }
27669 else if (offset < 0)
bfae80f2 27670 {
c19d1205
ZW
27671 offset = -offset;
27672 while (offset > 0x100)
bfae80f2 27673 {
c19d1205
ZW
27674 add_unwind_opcode (0x7f, 1);
27675 offset -= 0x100;
bfae80f2 27676 }
c19d1205
ZW
27677 op = ((offset - 4) >> 2) | 0x40;
27678 add_unwind_opcode (op, 1);
bfae80f2 27679 }
bfae80f2
RE
27680}
27681
c19d1205 27682/* Finish the list of unwind opcodes for this function. */
0198d5e6 27683
c19d1205
ZW
27684static void
27685finish_unwind_opcodes (void)
bfae80f2 27686{
c19d1205 27687 valueT op;
bfae80f2 27688
c19d1205 27689 if (unwind.fp_used)
bfae80f2 27690 {
708587a4 27691 /* Adjust sp as necessary. */
c19d1205
ZW
27692 unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
27693 flush_pending_unwind ();
bfae80f2 27694
c19d1205
ZW
27695 /* After restoring sp from the frame pointer. */
27696 op = 0x90 | unwind.fp_reg;
27697 add_unwind_opcode (op, 1);
27698 }
27699 else
27700 flush_pending_unwind ();
bfae80f2
RE
27701}
27702
bfae80f2 27703
c19d1205
ZW
27704/* Start an exception table entry. If idx is nonzero this is an index table
27705 entry. */
bfae80f2
RE
27706
27707static void
c19d1205 27708start_unwind_section (const segT text_seg, int idx)
bfae80f2 27709{
c19d1205
ZW
27710 const char * text_name;
27711 const char * prefix;
27712 const char * prefix_once;
a8c4d40b 27713 struct elf_section_match match;
c19d1205 27714 char * sec_name;
c19d1205
ZW
27715 int type;
27716 int flags;
27717 int linkonce;
bfae80f2 27718
c19d1205 27719 if (idx)
bfae80f2 27720 {
c19d1205
ZW
27721 prefix = ELF_STRING_ARM_unwind;
27722 prefix_once = ELF_STRING_ARM_unwind_once;
27723 type = SHT_ARM_EXIDX;
bfae80f2 27724 }
c19d1205 27725 else
bfae80f2 27726 {
c19d1205
ZW
27727 prefix = ELF_STRING_ARM_unwind_info;
27728 prefix_once = ELF_STRING_ARM_unwind_info_once;
27729 type = SHT_PROGBITS;
bfae80f2
RE
27730 }
27731
c19d1205
ZW
27732 text_name = segment_name (text_seg);
27733 if (streq (text_name, ".text"))
27734 text_name = "";
27735
d34049e8 27736 if (startswith (text_name, ".gnu.linkonce.t."))
bfae80f2 27737 {
c19d1205
ZW
27738 prefix = prefix_once;
27739 text_name += strlen (".gnu.linkonce.t.");
bfae80f2
RE
27740 }
27741
29a2809e 27742 sec_name = concat (prefix, text_name, (char *) NULL);
bfae80f2 27743
c19d1205
ZW
27744 flags = SHF_ALLOC;
27745 linkonce = 0;
a8c4d40b 27746 memset (&match, 0, sizeof (match));
bfae80f2 27747
c19d1205
ZW
27748 /* Handle COMDAT group. */
27749 if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
bfae80f2 27750 {
a8c4d40b
L
27751 match.group_name = elf_group_name (text_seg);
27752 if (match.group_name == NULL)
c19d1205 27753 {
bd3ba5d1 27754 as_bad (_("Group section `%s' has no group signature"),
c19d1205
ZW
27755 segment_name (text_seg));
27756 ignore_rest_of_line ();
27757 return;
27758 }
27759 flags |= SHF_GROUP;
27760 linkonce = 1;
bfae80f2
RE
27761 }
27762
a8c4d40b 27763 obj_elf_change_section (sec_name, type, flags, 0, &match,
f2711095 27764 linkonce);
bfae80f2 27765
5f4273c7 27766 /* Set the section link for index tables. */
c19d1205
ZW
27767 if (idx)
27768 elf_linked_to_section (now_seg) = text_seg;
bfae80f2
RE
27769}
27770
bfae80f2 27771
c19d1205
ZW
27772/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
27773 personality routine data. Returns zero, or the index table value for
cad0da33 27774 an inline entry. */
c19d1205
ZW
27775
27776static valueT
27777create_unwind_entry (int have_data)
bfae80f2 27778{
c19d1205
ZW
27779 int size;
27780 addressT where;
27781 char *ptr;
27782 /* The current word of data. */
27783 valueT data;
27784 /* The number of bytes left in this word. */
27785 int n;
bfae80f2 27786
c19d1205 27787 finish_unwind_opcodes ();
bfae80f2 27788
c19d1205
ZW
27789 /* Remember the current text section. */
27790 unwind.saved_seg = now_seg;
27791 unwind.saved_subseg = now_subseg;
bfae80f2 27792
c19d1205 27793 start_unwind_section (now_seg, 0);
bfae80f2 27794
c19d1205 27795 if (unwind.personality_routine == NULL)
bfae80f2 27796 {
c19d1205
ZW
27797 if (unwind.personality_index == -2)
27798 {
27799 if (have_data)
5f4273c7 27800 as_bad (_("handlerdata in cantunwind frame"));
c19d1205
ZW
27801 return 1; /* EXIDX_CANTUNWIND. */
27802 }
bfae80f2 27803
c19d1205
ZW
27804 /* Use a default personality routine if none is specified. */
27805 if (unwind.personality_index == -1)
27806 {
27807 if (unwind.opcode_count > 3)
27808 unwind.personality_index = 1;
27809 else
27810 unwind.personality_index = 0;
27811 }
bfae80f2 27812
c19d1205
ZW
27813 /* Space for the personality routine entry. */
27814 if (unwind.personality_index == 0)
27815 {
27816 if (unwind.opcode_count > 3)
b43e801e
AM
27817 {
27818 as_bad (_("too many unwind opcodes for personality routine 0"));
27819 return 1;
27820 }
bfae80f2 27821
c19d1205
ZW
27822 if (!have_data)
27823 {
27824 /* All the data is inline in the index table. */
27825 data = 0x80;
27826 n = 3;
27827 while (unwind.opcode_count > 0)
27828 {
27829 unwind.opcode_count--;
27830 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
27831 n--;
27832 }
bfae80f2 27833
c19d1205
ZW
27834 /* Pad with "finish" opcodes. */
27835 while (n--)
27836 data = (data << 8) | 0xb0;
bfae80f2 27837
c19d1205
ZW
27838 return data;
27839 }
27840 size = 0;
27841 }
27842 else
27843 /* We get two opcodes "free" in the first word. */
27844 size = unwind.opcode_count - 2;
27845 }
27846 else
5011093d 27847 {
cad0da33
NC
27848 /* PR 16765: Missing or misplaced unwind directives can trigger this. */
27849 if (unwind.personality_index != -1)
27850 {
27851 as_bad (_("attempt to recreate an unwind entry"));
27852 return 1;
27853 }
5011093d
NC
27854
27855 /* An extra byte is required for the opcode count. */
27856 size = unwind.opcode_count + 1;
27857 }
bfae80f2 27858
c19d1205
ZW
27859 size = (size + 3) >> 2;
27860 if (size > 0xff)
b43e801e
AM
27861 {
27862 as_bad (_("too many unwind opcodes"));
27863 return 1;
27864 }
bfae80f2 27865
c19d1205
ZW
27866 frag_align (2, 0, 0);
27867 record_alignment (now_seg, 2);
27868 unwind.table_entry = expr_build_dot ();
27869
27870 /* Allocate the table entry. */
27871 ptr = frag_more ((size << 2) + 4);
74929e7b
NC
27872 /* PR 13449: Zero the table entries in case some of them are not used. */
27873 memset (ptr, 0, (size << 2) + 4);
c19d1205 27874 where = frag_now_fix () - ((size << 2) + 4);
bfae80f2 27875
c19d1205 27876 switch (unwind.personality_index)
bfae80f2 27877 {
c19d1205
ZW
27878 case -1:
27879 /* ??? Should this be a PLT generating relocation? */
27880 /* Custom personality routine. */
27881 fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
27882 BFD_RELOC_ARM_PREL31);
bfae80f2 27883
c19d1205
ZW
27884 where += 4;
27885 ptr += 4;
bfae80f2 27886
c19d1205 27887 /* Set the first byte to the number of additional words. */
5011093d 27888 data = size > 0 ? size - 1 : 0;
c19d1205
ZW
27889 n = 3;
27890 break;
bfae80f2 27891
c19d1205
ZW
27892 /* ABI defined personality routines. */
27893 case 0:
27894 /* Three opcodes bytes are packed into the first word. */
27895 data = 0x80;
27896 n = 3;
27897 break;
bfae80f2 27898
c19d1205
ZW
27899 case 1:
27900 case 2:
27901 /* The size and first two opcode bytes go in the first word. */
27902 data = ((0x80 + unwind.personality_index) << 8) | size;
27903 n = 2;
27904 break;
bfae80f2 27905
c19d1205
ZW
27906 default:
27907 /* Should never happen. */
27908 abort ();
27909 }
bfae80f2 27910
c19d1205
ZW
27911 /* Pack the opcodes into words (MSB first), reversing the list at the same
27912 time. */
27913 while (unwind.opcode_count > 0)
27914 {
27915 if (n == 0)
27916 {
27917 md_number_to_chars (ptr, data, 4);
27918 ptr += 4;
27919 n = 4;
27920 data = 0;
27921 }
27922 unwind.opcode_count--;
27923 n--;
27924 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
27925 }
27926
27927 /* Finish off the last word. */
27928 if (n < 4)
27929 {
27930 /* Pad with "finish" opcodes. */
27931 while (n--)
27932 data = (data << 8) | 0xb0;
27933
27934 md_number_to_chars (ptr, data, 4);
27935 }
27936
27937 if (!have_data)
27938 {
27939 /* Add an empty descriptor if there is no user-specified data. */
27940 ptr = frag_more (4);
27941 md_number_to_chars (ptr, 0, 4);
27942 }
27943
27944 return 0;
bfae80f2
RE
27945}
27946
f0927246
NC
27947/* Initialize the DWARF-2 unwind information for this procedure. */
27948
27949void
27950tc_arm_frame_initial_instructions (void)
27951{
27952 cfi_add_CFA_def_cfa (REG_SP, 0);
27953}
27954#endif /* OBJ_ELF */
27955
c19d1205
ZW
27956/* Convert REGNAME to a DWARF-2 register number. */
27957
27958int
1df69f4f 27959tc_arm_regname_to_dw2regnum (char *regname)
bfae80f2 27960{
1df69f4f 27961 int reg = arm_reg_parse (&regname, REG_TYPE_RN);
1f5afe1c
NC
27962 if (reg != FAIL)
27963 return reg;
c19d1205 27964
1f5afe1c
NC
27965 /* PR 16694: Allow VFP registers as well. */
27966 reg = arm_reg_parse (&regname, REG_TYPE_VFS);
27967 if (reg != FAIL)
27968 return 64 + reg;
c19d1205 27969
1f5afe1c
NC
27970 reg = arm_reg_parse (&regname, REG_TYPE_VFD);
27971 if (reg != FAIL)
27972 return reg + 256;
27973
e90f28a7
VDN
27974 reg = arm_reg_parse (&regname, REG_TYPE_PSEUDO);
27975 if (reg != FAIL)
27976 return reg;
27977
0198d5e6 27978 return FAIL;
bfae80f2
RE
27979}
27980
f0927246 27981#ifdef TE_PE
c19d1205 27982void
f0927246 27983tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
bfae80f2 27984{
91d6fa6a 27985 expressionS exp;
bfae80f2 27986
91d6fa6a
NC
27987 exp.X_op = O_secrel;
27988 exp.X_add_symbol = symbol;
27989 exp.X_add_number = 0;
27990 emit_expr (&exp, size);
f0927246
NC
27991}
27992#endif
bfae80f2 27993
c19d1205 27994/* MD interface: Symbol and relocation handling. */
bfae80f2 27995
2fc8bdac
ZW
27996/* Return the address within the segment that a PC-relative fixup is
27997 relative to. For ARM, PC-relative fixups applied to instructions
27998 are generally relative to the location of the fixup plus 8 bytes.
27999 Thumb branches are offset by 4, and Thumb loads relative to PC
28000 require special handling. */
bfae80f2 28001
c19d1205 28002long
2fc8bdac 28003md_pcrel_from_section (fixS * fixP, segT seg)
bfae80f2 28004{
2fc8bdac
ZW
28005 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
28006
28007 /* If this is pc-relative and we are going to emit a relocation
28008 then we just want to put out any pipeline compensation that the linker
53baae48
NC
28009 will need. Otherwise we want to use the calculated base.
28010 For WinCE we skip the bias for externals as well, since this
28011 is how the MS ARM-CE assembler behaves and we want to be compatible. */
5f4273c7 28012 if (fixP->fx_pcrel
2fc8bdac 28013 && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
53baae48
NC
28014 || (arm_force_relocation (fixP)
28015#ifdef TE_WINCE
28016 && !S_IS_EXTERNAL (fixP->fx_addsy)
28017#endif
28018 )))
2fc8bdac 28019 base = 0;
bfae80f2 28020
267bf995 28021
c19d1205 28022 switch (fixP->fx_r_type)
bfae80f2 28023 {
2fc8bdac
ZW
28024 /* PC relative addressing on the Thumb is slightly odd as the
28025 bottom two bits of the PC are forced to zero for the
28026 calculation. This happens *after* application of the
28027 pipeline offset. However, Thumb adrl already adjusts for
28028 this, so we need not do it again. */
c19d1205 28029 case BFD_RELOC_ARM_THUMB_ADD:
2fc8bdac 28030 return base & ~3;
c19d1205
ZW
28031
28032 case BFD_RELOC_ARM_THUMB_OFFSET:
28033 case BFD_RELOC_ARM_T32_OFFSET_IMM:
e9f89963 28034 case BFD_RELOC_ARM_T32_ADD_PC12:
8f06b2d8 28035 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
2fc8bdac 28036 return (base + 4) & ~3;
c19d1205 28037
2fc8bdac 28038 /* Thumb branches are simply offset by +4. */
e12437dc 28039 case BFD_RELOC_THUMB_PCREL_BRANCH5:
2fc8bdac
ZW
28040 case BFD_RELOC_THUMB_PCREL_BRANCH7:
28041 case BFD_RELOC_THUMB_PCREL_BRANCH9:
28042 case BFD_RELOC_THUMB_PCREL_BRANCH12:
28043 case BFD_RELOC_THUMB_PCREL_BRANCH20:
2fc8bdac 28044 case BFD_RELOC_THUMB_PCREL_BRANCH25:
f6b2b12d 28045 case BFD_RELOC_THUMB_PCREL_BFCSEL:
e5d6e09e 28046 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 28047 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 28048 case BFD_RELOC_ARM_THUMB_BF13:
60f993ce 28049 case BFD_RELOC_ARM_THUMB_LOOP12:
2fc8bdac 28050 return base + 4;
bfae80f2 28051
267bf995 28052 case BFD_RELOC_THUMB_PCREL_BRANCH23:
486499d0
CL
28053 if (fixP->fx_addsy
28054 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28055 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995 28056 && ARM_IS_FUNC (fixP->fx_addsy)
477330fc
RM
28057 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28058 base = fixP->fx_where + fixP->fx_frag->fr_address;
267bf995
RR
28059 return base + 4;
28060
00adf2d4
JB
28061 /* BLX is like branches above, but forces the low two bits of PC to
28062 zero. */
486499d0
CL
28063 case BFD_RELOC_THUMB_PCREL_BLX:
28064 if (fixP->fx_addsy
28065 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28066 && !S_FORCE_RELOC (fixP->fx_addsy, true)
477330fc
RM
28067 && THUMB_IS_FUNC (fixP->fx_addsy)
28068 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28069 base = fixP->fx_where + fixP->fx_frag->fr_address;
00adf2d4
JB
28070 return (base + 4) & ~3;
28071
2fc8bdac
ZW
28072 /* ARM mode branches are offset by +8. However, the Windows CE
28073 loader expects the relocation not to take this into account. */
267bf995 28074 case BFD_RELOC_ARM_PCREL_BLX:
486499d0
CL
28075 if (fixP->fx_addsy
28076 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28077 && !S_FORCE_RELOC (fixP->fx_addsy, true)
477330fc
RM
28078 && ARM_IS_FUNC (fixP->fx_addsy)
28079 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28080 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 28081 return base + 8;
267bf995 28082
486499d0
CL
28083 case BFD_RELOC_ARM_PCREL_CALL:
28084 if (fixP->fx_addsy
28085 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 28086 && !S_FORCE_RELOC (fixP->fx_addsy, true)
477330fc
RM
28087 && THUMB_IS_FUNC (fixP->fx_addsy)
28088 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28089 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 28090 return base + 8;
267bf995 28091
2fc8bdac 28092 case BFD_RELOC_ARM_PCREL_BRANCH:
39b41c9c 28093 case BFD_RELOC_ARM_PCREL_JUMP:
2fc8bdac 28094 case BFD_RELOC_ARM_PLT32:
c19d1205 28095#ifdef TE_WINCE
5f4273c7 28096 /* When handling fixups immediately, because we have already
477330fc 28097 discovered the value of a symbol, or the address of the frag involved
53baae48 28098 we must account for the offset by +8, as the OS loader will never see the reloc.
477330fc
RM
28099 see fixup_segment() in write.c
28100 The S_IS_EXTERNAL test handles the case of global symbols.
28101 Those need the calculated base, not just the pipe compensation the linker will need. */
53baae48
NC
28102 if (fixP->fx_pcrel
28103 && fixP->fx_addsy != NULL
28104 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28105 && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP)))
28106 return base + 8;
2fc8bdac 28107 return base;
c19d1205 28108#else
2fc8bdac 28109 return base + 8;
c19d1205 28110#endif
2fc8bdac 28111
267bf995 28112
2fc8bdac
ZW
28113 /* ARM mode loads relative to PC are also offset by +8. Unlike
28114 branches, the Windows CE loader *does* expect the relocation
28115 to take this into account. */
28116 case BFD_RELOC_ARM_OFFSET_IMM:
28117 case BFD_RELOC_ARM_OFFSET_IMM8:
28118 case BFD_RELOC_ARM_HWLITERAL:
28119 case BFD_RELOC_ARM_LITERAL:
28120 case BFD_RELOC_ARM_CP_OFF_IMM:
28121 return base + 8;
28122
28123
28124 /* Other PC-relative relocations are un-offset. */
28125 default:
28126 return base;
28127 }
bfae80f2
RE
28128}
28129
5b7c81bd 28130static bool flag_warn_syms = true;
8b2d793c 28131
5b7c81bd 28132bool
ae8714c2 28133arm_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char * name)
bfae80f2 28134{
8b2d793c
NC
28135 /* PR 18347 - Warn if the user attempts to create a symbol with the same
28136 name as an ARM instruction. Whilst strictly speaking it is allowed, it
28137 does mean that the resulting code might be very confusing to the reader.
28138 Also this warning can be triggered if the user omits an operand before
28139 an immediate address, eg:
28140
28141 LDR =foo
28142
28143 GAS treats this as an assignment of the value of the symbol foo to a
28144 symbol LDR, and so (without this code) it will not issue any kind of
28145 warning or error message.
28146
28147 Note - ARM instructions are case-insensitive but the strings in the hash
28148 table are all stored in lower case, so we must first ensure that name is
ae8714c2
NC
28149 lower case too. */
28150 if (flag_warn_syms && arm_ops_hsh)
8b2d793c
NC
28151 {
28152 char * nbuf = strdup (name);
28153 char * p;
28154
28155 for (p = nbuf; *p; p++)
28156 *p = TOLOWER (*p);
629310ab 28157 if (str_hash_find (arm_ops_hsh, nbuf) != NULL)
8b2d793c 28158 {
629310ab 28159 static htab_t already_warned = NULL;
8b2d793c
NC
28160
28161 if (already_warned == NULL)
629310ab 28162 already_warned = str_htab_create ();
8b2d793c 28163 /* Only warn about the symbol once. To keep the code
629310ab 28164 simple we let str_hash_insert do the lookup for us. */
d3be5dab
AM
28165 if (str_hash_insert (already_warned, nbuf, NULL, 0) == NULL)
28166 as_warn (_("[-mwarn-syms]: Assignment makes a symbol match an ARM instruction: %s"), name);
8b2d793c
NC
28167 }
28168 else
28169 free (nbuf);
28170 }
3739860c 28171
5b7c81bd 28172 return false;
ae8714c2
NC
28173}
28174
28175/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
28176 Otherwise we have no need to default values of symbols. */
28177
28178symbolS *
28179md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
28180{
28181#ifdef OBJ_ELF
28182 if (name[0] == '_' && name[1] == 'G'
28183 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
28184 {
28185 if (!GOT_symbol)
28186 {
28187 if (symbol_find (name))
28188 as_bad (_("GOT already in the symbol table"));
28189
28190 GOT_symbol = symbol_new (name, undefined_section,
e01e1cee 28191 &zero_address_frag, 0);
ae8714c2
NC
28192 }
28193
28194 return GOT_symbol;
28195 }
28196#endif
28197
c921be7d 28198 return NULL;
bfae80f2
RE
28199}
28200
55cf6793 28201/* Subroutine of md_apply_fix. Check to see if an immediate can be
c19d1205
ZW
28202 computed as two separate immediate values, added together. We
28203 already know that this value cannot be computed by just one ARM
28204 instruction. */
28205
28206static unsigned int
28207validate_immediate_twopart (unsigned int val,
28208 unsigned int * highpart)
bfae80f2 28209{
c19d1205
ZW
28210 unsigned int a;
28211 unsigned int i;
bfae80f2 28212
c19d1205
ZW
28213 for (i = 0; i < 32; i += 2)
28214 if (((a = rotate_left (val, i)) & 0xff) != 0)
28215 {
28216 if (a & 0xff00)
28217 {
28218 if (a & ~ 0xffff)
28219 continue;
28220 * highpart = (a >> 8) | ((i + 24) << 7);
28221 }
28222 else if (a & 0xff0000)
28223 {
28224 if (a & 0xff000000)
28225 continue;
28226 * highpart = (a >> 16) | ((i + 16) << 7);
28227 }
28228 else
28229 {
9c2799c2 28230 gas_assert (a & 0xff000000);
c19d1205
ZW
28231 * highpart = (a >> 24) | ((i + 8) << 7);
28232 }
bfae80f2 28233
c19d1205
ZW
28234 return (a & 0xff) | (i << 7);
28235 }
bfae80f2 28236
c19d1205 28237 return FAIL;
bfae80f2
RE
28238}
28239
c19d1205
ZW
28240static int
28241validate_offset_imm (unsigned int val, int hwse)
28242{
28243 if ((hwse && val > 255) || val > 4095)
28244 return FAIL;
28245 return val;
28246}
bfae80f2 28247
55cf6793 28248/* Subroutine of md_apply_fix. Do those data_ops which can take a
c19d1205
ZW
28249 negative immediate constant by altering the instruction. A bit of
28250 a hack really.
28251 MOV <-> MVN
28252 AND <-> BIC
28253 ADC <-> SBC
28254 by inverting the second operand, and
28255 ADD <-> SUB
28256 CMP <-> CMN
28257 by negating the second operand. */
bfae80f2 28258
c19d1205
ZW
28259static int
28260negate_data_op (unsigned long * instruction,
28261 unsigned long value)
bfae80f2 28262{
c19d1205
ZW
28263 int op, new_inst;
28264 unsigned long negated, inverted;
bfae80f2 28265
c19d1205
ZW
28266 negated = encode_arm_immediate (-value);
28267 inverted = encode_arm_immediate (~value);
bfae80f2 28268
c19d1205
ZW
28269 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
28270 switch (op)
bfae80f2 28271 {
c19d1205
ZW
28272 /* First negates. */
28273 case OPCODE_SUB: /* ADD <-> SUB */
28274 new_inst = OPCODE_ADD;
28275 value = negated;
28276 break;
bfae80f2 28277
c19d1205
ZW
28278 case OPCODE_ADD:
28279 new_inst = OPCODE_SUB;
28280 value = negated;
28281 break;
bfae80f2 28282
c19d1205
ZW
28283 case OPCODE_CMP: /* CMP <-> CMN */
28284 new_inst = OPCODE_CMN;
28285 value = negated;
28286 break;
bfae80f2 28287
c19d1205
ZW
28288 case OPCODE_CMN:
28289 new_inst = OPCODE_CMP;
28290 value = negated;
28291 break;
bfae80f2 28292
c19d1205
ZW
28293 /* Now Inverted ops. */
28294 case OPCODE_MOV: /* MOV <-> MVN */
28295 new_inst = OPCODE_MVN;
28296 value = inverted;
28297 break;
bfae80f2 28298
c19d1205
ZW
28299 case OPCODE_MVN:
28300 new_inst = OPCODE_MOV;
28301 value = inverted;
28302 break;
bfae80f2 28303
c19d1205
ZW
28304 case OPCODE_AND: /* AND <-> BIC */
28305 new_inst = OPCODE_BIC;
28306 value = inverted;
28307 break;
bfae80f2 28308
c19d1205
ZW
28309 case OPCODE_BIC:
28310 new_inst = OPCODE_AND;
28311 value = inverted;
28312 break;
bfae80f2 28313
c19d1205
ZW
28314 case OPCODE_ADC: /* ADC <-> SBC */
28315 new_inst = OPCODE_SBC;
28316 value = inverted;
28317 break;
bfae80f2 28318
c19d1205
ZW
28319 case OPCODE_SBC:
28320 new_inst = OPCODE_ADC;
28321 value = inverted;
28322 break;
bfae80f2 28323
c19d1205
ZW
28324 /* We cannot do anything. */
28325 default:
28326 return FAIL;
b99bd4ef
NC
28327 }
28328
c19d1205
ZW
28329 if (value == (unsigned) FAIL)
28330 return FAIL;
28331
28332 *instruction &= OPCODE_MASK;
28333 *instruction |= new_inst << DATA_OP_SHIFT;
28334 return value;
b99bd4ef
NC
28335}
28336
ef8d22e6
PB
28337/* Like negate_data_op, but for Thumb-2. */
28338
28339static unsigned int
7af67752 28340thumb32_negate_data_op (valueT *instruction, unsigned int value)
ef8d22e6 28341{
7af67752
AM
28342 unsigned int op, new_inst;
28343 unsigned int rd;
16dd5e42 28344 unsigned int negated, inverted;
ef8d22e6
PB
28345
28346 negated = encode_thumb32_immediate (-value);
28347 inverted = encode_thumb32_immediate (~value);
28348
28349 rd = (*instruction >> 8) & 0xf;
28350 op = (*instruction >> T2_DATA_OP_SHIFT) & 0xf;
28351 switch (op)
28352 {
28353 /* ADD <-> SUB. Includes CMP <-> CMN. */
28354 case T2_OPCODE_SUB:
28355 new_inst = T2_OPCODE_ADD;
28356 value = negated;
28357 break;
28358
28359 case T2_OPCODE_ADD:
28360 new_inst = T2_OPCODE_SUB;
28361 value = negated;
28362 break;
28363
28364 /* ORR <-> ORN. Includes MOV <-> MVN. */
28365 case T2_OPCODE_ORR:
28366 new_inst = T2_OPCODE_ORN;
28367 value = inverted;
28368 break;
28369
28370 case T2_OPCODE_ORN:
28371 new_inst = T2_OPCODE_ORR;
28372 value = inverted;
28373 break;
28374
28375 /* AND <-> BIC. TST has no inverted equivalent. */
28376 case T2_OPCODE_AND:
28377 new_inst = T2_OPCODE_BIC;
28378 if (rd == 15)
28379 value = FAIL;
28380 else
28381 value = inverted;
28382 break;
28383
28384 case T2_OPCODE_BIC:
28385 new_inst = T2_OPCODE_AND;
28386 value = inverted;
28387 break;
28388
28389 /* ADC <-> SBC */
28390 case T2_OPCODE_ADC:
28391 new_inst = T2_OPCODE_SBC;
28392 value = inverted;
28393 break;
28394
28395 case T2_OPCODE_SBC:
28396 new_inst = T2_OPCODE_ADC;
28397 value = inverted;
28398 break;
28399
28400 /* We cannot do anything. */
28401 default:
28402 return FAIL;
28403 }
28404
16dd5e42 28405 if (value == (unsigned int)FAIL)
ef8d22e6
PB
28406 return FAIL;
28407
28408 *instruction &= T2_OPCODE_MASK;
28409 *instruction |= new_inst << T2_DATA_OP_SHIFT;
28410 return value;
28411}
28412
8f06b2d8 28413/* Read a 32-bit thumb instruction from buf. */
0198d5e6 28414
8f06b2d8
PB
28415static unsigned long
28416get_thumb32_insn (char * buf)
28417{
28418 unsigned long insn;
28419 insn = md_chars_to_number (buf, THUMB_SIZE) << 16;
28420 insn |= md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28421
28422 return insn;
28423}
28424
a8bc6c78
PB
28425/* We usually want to set the low bit on the address of thumb function
28426 symbols. In particular .word foo - . should have the low bit set.
28427 Generic code tries to fold the difference of two symbols to
28428 a constant. Prevent this and force a relocation when the first symbols
28429 is a thumb function. */
c921be7d 28430
5b7c81bd 28431bool
a8bc6c78
PB
28432arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
28433{
28434 if (op == O_subtract
28435 && l->X_op == O_symbol
28436 && r->X_op == O_symbol
28437 && THUMB_IS_FUNC (l->X_add_symbol))
28438 {
28439 l->X_op = O_subtract;
28440 l->X_op_symbol = r->X_add_symbol;
28441 l->X_add_number -= r->X_add_number;
5b7c81bd 28442 return true;
a8bc6c78 28443 }
c921be7d 28444
a8bc6c78 28445 /* Process as normal. */
5b7c81bd 28446 return false;
a8bc6c78
PB
28447}
28448
4a42ebbc
RR
28449/* Encode Thumb2 unconditional branches and calls. The encoding
28450 for the 2 are identical for the immediate values. */
28451
28452static void
28453encode_thumb2_b_bl_offset (char * buf, offsetT value)
28454{
28455#define T2I1I2MASK ((1 << 13) | (1 << 11))
28456 offsetT newval;
28457 offsetT newval2;
28458 addressT S, I1, I2, lo, hi;
28459
28460 S = (value >> 24) & 0x01;
28461 I1 = (value >> 23) & 0x01;
28462 I2 = (value >> 22) & 0x01;
28463 hi = (value >> 12) & 0x3ff;
fa94de6b 28464 lo = (value >> 1) & 0x7ff;
4a42ebbc
RR
28465 newval = md_chars_to_number (buf, THUMB_SIZE);
28466 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28467 newval |= (S << 10) | hi;
28468 newval2 &= ~T2I1I2MASK;
28469 newval2 |= (((I1 ^ S) << 13) | ((I2 ^ S) << 11) | lo) ^ T2I1I2MASK;
28470 md_number_to_chars (buf, newval, THUMB_SIZE);
28471 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
28472}
28473
c19d1205 28474void
55cf6793 28475md_apply_fix (fixS * fixP,
c19d1205
ZW
28476 valueT * valP,
28477 segT seg)
28478{
7af67752
AM
28479 valueT value = * valP;
28480 valueT newval;
c19d1205
ZW
28481 unsigned int newimm;
28482 unsigned long temp;
28483 int sign;
28484 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
b99bd4ef 28485
9c2799c2 28486 gas_assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
b99bd4ef 28487
c19d1205 28488 /* Note whether this will delete the relocation. */
4962c51a 28489
c19d1205
ZW
28490 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
28491 fixP->fx_done = 1;
b99bd4ef 28492
adbaf948 28493 /* On a 64-bit host, silently truncate 'value' to 32 bits for
5f4273c7 28494 consistency with the behaviour on 32-bit hosts. Remember value
adbaf948
ZW
28495 for emit_reloc. */
28496 value &= 0xffffffff;
28497 value ^= 0x80000000;
5f4273c7 28498 value -= 0x80000000;
adbaf948
ZW
28499
28500 *valP = value;
c19d1205 28501 fixP->fx_addnumber = value;
b99bd4ef 28502
adbaf948
ZW
28503 /* Same treatment for fixP->fx_offset. */
28504 fixP->fx_offset &= 0xffffffff;
28505 fixP->fx_offset ^= 0x80000000;
28506 fixP->fx_offset -= 0x80000000;
28507
c19d1205 28508 switch (fixP->fx_r_type)
b99bd4ef 28509 {
c19d1205
ZW
28510 case BFD_RELOC_NONE:
28511 /* This will need to go in the object file. */
28512 fixP->fx_done = 0;
28513 break;
b99bd4ef 28514
c19d1205
ZW
28515 case BFD_RELOC_ARM_IMMEDIATE:
28516 /* We claim that this fixup has been processed here,
28517 even if in fact we generate an error because we do
28518 not have a reloc for it, so tc_gen_reloc will reject it. */
28519 fixP->fx_done = 1;
b99bd4ef 28520
77db8e2e 28521 if (fixP->fx_addsy)
b99bd4ef 28522 {
77db8e2e 28523 const char *msg = 0;
b99bd4ef 28524
77db8e2e
NC
28525 if (! S_IS_DEFINED (fixP->fx_addsy))
28526 msg = _("undefined symbol %s used as an immediate value");
28527 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
28528 msg = _("symbol %s is in a different section");
28529 else if (S_IS_WEAK (fixP->fx_addsy))
28530 msg = _("symbol %s is weak and may be overridden later");
28531
28532 if (msg)
28533 {
28534 as_bad_where (fixP->fx_file, fixP->fx_line,
28535 msg, S_GET_NAME (fixP->fx_addsy));
28536 break;
28537 }
42e5fcbf
AS
28538 }
28539
c19d1205
ZW
28540 temp = md_chars_to_number (buf, INSN_SIZE);
28541
5e73442d 28542 /* If the offset is negative, we should use encoding A2 for ADR. */
7af67752 28543 if ((temp & 0xfff0000) == 0x28f0000 && (offsetT) value < 0)
5e73442d
SL
28544 newimm = negate_data_op (&temp, value);
28545 else
28546 {
28547 newimm = encode_arm_immediate (value);
28548
28549 /* If the instruction will fail, see if we can fix things up by
28550 changing the opcode. */
28551 if (newimm == (unsigned int) FAIL)
28552 newimm = negate_data_op (&temp, value);
bada4342
JW
28553 /* MOV accepts both ARM modified immediate (A1 encoding) and
28554 UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
28555 When disassembling, MOV is preferred when there is no encoding
28556 overlap. */
28557 if (newimm == (unsigned int) FAIL
28558 && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
28559 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
28560 && !((temp >> SBIT_SHIFT) & 0x1)
7af67752 28561 && value <= 0xffff)
bada4342
JW
28562 {
28563 /* Clear bits[23:20] to change encoding from A1 to A2. */
28564 temp &= 0xff0fffff;
28565 /* Encoding high 4bits imm. Code below will encode the remaining
28566 low 12bits. */
28567 temp |= (value & 0x0000f000) << 4;
28568 newimm = value & 0x00000fff;
28569 }
5e73442d
SL
28570 }
28571
28572 if (newimm == (unsigned int) FAIL)
b99bd4ef 28573 {
c19d1205
ZW
28574 as_bad_where (fixP->fx_file, fixP->fx_line,
28575 _("invalid constant (%lx) after fixup"),
28576 (unsigned long) value);
28577 break;
b99bd4ef 28578 }
b99bd4ef 28579
c19d1205
ZW
28580 newimm |= (temp & 0xfffff000);
28581 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
28582 break;
b99bd4ef 28583
c19d1205
ZW
28584 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
28585 {
28586 unsigned int highpart = 0;
28587 unsigned int newinsn = 0xe1a00000; /* nop. */
b99bd4ef 28588
77db8e2e 28589 if (fixP->fx_addsy)
42e5fcbf 28590 {
77db8e2e 28591 const char *msg = 0;
42e5fcbf 28592
77db8e2e
NC
28593 if (! S_IS_DEFINED (fixP->fx_addsy))
28594 msg = _("undefined symbol %s used as an immediate value");
28595 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
28596 msg = _("symbol %s is in a different section");
28597 else if (S_IS_WEAK (fixP->fx_addsy))
28598 msg = _("symbol %s is weak and may be overridden later");
42e5fcbf 28599
77db8e2e
NC
28600 if (msg)
28601 {
28602 as_bad_where (fixP->fx_file, fixP->fx_line,
28603 msg, S_GET_NAME (fixP->fx_addsy));
28604 break;
28605 }
28606 }
fa94de6b 28607
c19d1205
ZW
28608 newimm = encode_arm_immediate (value);
28609 temp = md_chars_to_number (buf, INSN_SIZE);
b99bd4ef 28610
c19d1205
ZW
28611 /* If the instruction will fail, see if we can fix things up by
28612 changing the opcode. */
28613 if (newimm == (unsigned int) FAIL
28614 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
28615 {
28616 /* No ? OK - try using two ADD instructions to generate
28617 the value. */
28618 newimm = validate_immediate_twopart (value, & highpart);
b99bd4ef 28619
c19d1205
ZW
28620 /* Yes - then make sure that the second instruction is
28621 also an add. */
28622 if (newimm != (unsigned int) FAIL)
28623 newinsn = temp;
28624 /* Still No ? Try using a negated value. */
28625 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
28626 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
28627 /* Otherwise - give up. */
28628 else
28629 {
28630 as_bad_where (fixP->fx_file, fixP->fx_line,
28631 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
28632 (long) value);
28633 break;
28634 }
b99bd4ef 28635
c19d1205
ZW
28636 /* Replace the first operand in the 2nd instruction (which
28637 is the PC) with the destination register. We have
28638 already added in the PC in the first instruction and we
28639 do not want to do it again. */
28640 newinsn &= ~ 0xf0000;
28641 newinsn |= ((newinsn & 0x0f000) << 4);
28642 }
b99bd4ef 28643
c19d1205
ZW
28644 newimm |= (temp & 0xfffff000);
28645 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
b99bd4ef 28646
c19d1205
ZW
28647 highpart |= (newinsn & 0xfffff000);
28648 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
28649 }
28650 break;
b99bd4ef 28651
c19d1205 28652 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
28653 if (!fixP->fx_done && seg->use_rela_p)
28654 value = 0;
1a0670f3 28655 /* Fall through. */
00a97672 28656
c19d1205 28657 case BFD_RELOC_ARM_LITERAL:
7af67752 28658 sign = (offsetT) value > 0;
b99bd4ef 28659
7af67752 28660 if ((offsetT) value < 0)
c19d1205 28661 value = - value;
b99bd4ef 28662
c19d1205 28663 if (validate_offset_imm (value, 0) == FAIL)
f03698e6 28664 {
c19d1205
ZW
28665 if (fixP->fx_r_type == BFD_RELOC_ARM_LITERAL)
28666 as_bad_where (fixP->fx_file, fixP->fx_line,
28667 _("invalid literal constant: pool needs to be closer"));
28668 else
28669 as_bad_where (fixP->fx_file, fixP->fx_line,
28670 _("bad immediate value for offset (%ld)"),
28671 (long) value);
28672 break;
f03698e6
RE
28673 }
28674
c19d1205 28675 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
28676 if (value == 0)
28677 newval &= 0xfffff000;
28678 else
28679 {
28680 newval &= 0xff7ff000;
28681 newval |= value | (sign ? INDEX_UP : 0);
28682 }
c19d1205
ZW
28683 md_number_to_chars (buf, newval, INSN_SIZE);
28684 break;
b99bd4ef 28685
c19d1205
ZW
28686 case BFD_RELOC_ARM_OFFSET_IMM8:
28687 case BFD_RELOC_ARM_HWLITERAL:
7af67752 28688 sign = (offsetT) value > 0;
b99bd4ef 28689
7af67752 28690 if ((offsetT) value < 0)
c19d1205 28691 value = - value;
b99bd4ef 28692
c19d1205 28693 if (validate_offset_imm (value, 1) == FAIL)
b99bd4ef 28694 {
c19d1205
ZW
28695 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
28696 as_bad_where (fixP->fx_file, fixP->fx_line,
28697 _("invalid literal constant: pool needs to be closer"));
28698 else
427d0db6
RM
28699 as_bad_where (fixP->fx_file, fixP->fx_line,
28700 _("bad immediate value for 8-bit offset (%ld)"),
28701 (long) value);
c19d1205 28702 break;
b99bd4ef
NC
28703 }
28704
c19d1205 28705 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
28706 if (value == 0)
28707 newval &= 0xfffff0f0;
28708 else
28709 {
28710 newval &= 0xff7ff0f0;
28711 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
28712 }
c19d1205
ZW
28713 md_number_to_chars (buf, newval, INSN_SIZE);
28714 break;
b99bd4ef 28715
c19d1205 28716 case BFD_RELOC_ARM_T32_OFFSET_U8:
7af67752 28717 if (value > 1020 || value % 4 != 0)
c19d1205
ZW
28718 as_bad_where (fixP->fx_file, fixP->fx_line,
28719 _("bad immediate value for offset (%ld)"), (long) value);
28720 value /= 4;
b99bd4ef 28721
c19d1205 28722 newval = md_chars_to_number (buf+2, THUMB_SIZE);
c19d1205
ZW
28723 newval |= value;
28724 md_number_to_chars (buf+2, newval, THUMB_SIZE);
28725 break;
b99bd4ef 28726
c19d1205
ZW
28727 case BFD_RELOC_ARM_T32_OFFSET_IMM:
28728 /* This is a complicated relocation used for all varieties of Thumb32
28729 load/store instruction with immediate offset:
28730
28731 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
477330fc 28732 *4, optional writeback(W)
c19d1205
ZW
28733 (doubleword load/store)
28734
28735 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
28736 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
28737 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
28738 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
28739 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
28740
28741 Uppercase letters indicate bits that are already encoded at
28742 this point. Lowercase letters are our problem. For the
28743 second block of instructions, the secondary opcode nybble
28744 (bits 8..11) is present, and bit 23 is zero, even if this is
28745 a PC-relative operation. */
28746 newval = md_chars_to_number (buf, THUMB_SIZE);
28747 newval <<= 16;
28748 newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
b99bd4ef 28749
c19d1205 28750 if ((newval & 0xf0000000) == 0xe0000000)
b99bd4ef 28751 {
c19d1205 28752 /* Doubleword load/store: 8-bit offset, scaled by 4. */
7af67752 28753 if ((offsetT) value >= 0)
c19d1205
ZW
28754 newval |= (1 << 23);
28755 else
28756 value = -value;
28757 if (value % 4 != 0)
28758 {
28759 as_bad_where (fixP->fx_file, fixP->fx_line,
28760 _("offset not a multiple of 4"));
28761 break;
28762 }
28763 value /= 4;
216d22bc 28764 if (value > 0xff)
c19d1205
ZW
28765 {
28766 as_bad_where (fixP->fx_file, fixP->fx_line,
28767 _("offset out of range"));
28768 break;
28769 }
28770 newval &= ~0xff;
b99bd4ef 28771 }
c19d1205 28772 else if ((newval & 0x000f0000) == 0x000f0000)
b99bd4ef 28773 {
c19d1205 28774 /* PC-relative, 12-bit offset. */
7af67752 28775 if ((offsetT) value >= 0)
c19d1205
ZW
28776 newval |= (1 << 23);
28777 else
28778 value = -value;
216d22bc 28779 if (value > 0xfff)
c19d1205
ZW
28780 {
28781 as_bad_where (fixP->fx_file, fixP->fx_line,
28782 _("offset out of range"));
28783 break;
28784 }
28785 newval &= ~0xfff;
b99bd4ef 28786 }
c19d1205 28787 else if ((newval & 0x00000100) == 0x00000100)
b99bd4ef 28788 {
c19d1205 28789 /* Writeback: 8-bit, +/- offset. */
7af67752 28790 if ((offsetT) value >= 0)
c19d1205
ZW
28791 newval |= (1 << 9);
28792 else
28793 value = -value;
216d22bc 28794 if (value > 0xff)
c19d1205
ZW
28795 {
28796 as_bad_where (fixP->fx_file, fixP->fx_line,
28797 _("offset out of range"));
28798 break;
28799 }
28800 newval &= ~0xff;
b99bd4ef 28801 }
c19d1205 28802 else if ((newval & 0x00000f00) == 0x00000e00)
b99bd4ef 28803 {
c19d1205 28804 /* T-instruction: positive 8-bit offset. */
7af67752 28805 if (value > 0xff)
b99bd4ef 28806 {
c19d1205
ZW
28807 as_bad_where (fixP->fx_file, fixP->fx_line,
28808 _("offset out of range"));
28809 break;
b99bd4ef 28810 }
c19d1205
ZW
28811 newval &= ~0xff;
28812 newval |= value;
b99bd4ef
NC
28813 }
28814 else
b99bd4ef 28815 {
c19d1205 28816 /* Positive 12-bit or negative 8-bit offset. */
7af67752
AM
28817 unsigned int limit;
28818 if ((offsetT) value >= 0)
b99bd4ef 28819 {
c19d1205
ZW
28820 newval |= (1 << 23);
28821 limit = 0xfff;
28822 }
28823 else
28824 {
28825 value = -value;
28826 limit = 0xff;
28827 }
28828 if (value > limit)
28829 {
28830 as_bad_where (fixP->fx_file, fixP->fx_line,
28831 _("offset out of range"));
28832 break;
b99bd4ef 28833 }
c19d1205 28834 newval &= ~limit;
b99bd4ef 28835 }
b99bd4ef 28836
c19d1205
ZW
28837 newval |= value;
28838 md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
28839 md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
28840 break;
404ff6b5 28841
c19d1205
ZW
28842 case BFD_RELOC_ARM_SHIFT_IMM:
28843 newval = md_chars_to_number (buf, INSN_SIZE);
7af67752 28844 if (value > 32
c19d1205
ZW
28845 || (value == 32
28846 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
28847 {
28848 as_bad_where (fixP->fx_file, fixP->fx_line,
28849 _("shift expression is too large"));
28850 break;
28851 }
404ff6b5 28852
c19d1205
ZW
28853 if (value == 0)
28854 /* Shifts of zero must be done as lsl. */
28855 newval &= ~0x60;
28856 else if (value == 32)
28857 value = 0;
28858 newval &= 0xfffff07f;
28859 newval |= (value & 0x1f) << 7;
28860 md_number_to_chars (buf, newval, INSN_SIZE);
28861 break;
404ff6b5 28862
c19d1205 28863 case BFD_RELOC_ARM_T32_IMMEDIATE:
16805f35 28864 case BFD_RELOC_ARM_T32_ADD_IMM:
92e90b6e 28865 case BFD_RELOC_ARM_T32_IMM12:
e9f89963 28866 case BFD_RELOC_ARM_T32_ADD_PC12:
c19d1205
ZW
28867 /* We claim that this fixup has been processed here,
28868 even if in fact we generate an error because we do
28869 not have a reloc for it, so tc_gen_reloc will reject it. */
28870 fixP->fx_done = 1;
404ff6b5 28871
c19d1205
ZW
28872 if (fixP->fx_addsy
28873 && ! S_IS_DEFINED (fixP->fx_addsy))
28874 {
28875 as_bad_where (fixP->fx_file, fixP->fx_line,
28876 _("undefined symbol %s used as an immediate value"),
28877 S_GET_NAME (fixP->fx_addsy));
28878 break;
28879 }
404ff6b5 28880
c19d1205
ZW
28881 newval = md_chars_to_number (buf, THUMB_SIZE);
28882 newval <<= 16;
28883 newval |= md_chars_to_number (buf+2, THUMB_SIZE);
404ff6b5 28884
16805f35 28885 newimm = FAIL;
bada4342
JW
28886 if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
28887 /* ARMv8-M Baseline MOV will reach here, but it doesn't support
28888 Thumb2 modified immediate encoding (T2). */
28889 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
16805f35 28890 || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
ef8d22e6
PB
28891 {
28892 newimm = encode_thumb32_immediate (value);
28893 if (newimm == (unsigned int) FAIL)
28894 newimm = thumb32_negate_data_op (&newval, value);
28895 }
bada4342 28896 if (newimm == (unsigned int) FAIL)
92e90b6e 28897 {
bada4342 28898 if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
e9f89963 28899 {
bada4342
JW
28900 /* Turn add/sum into addw/subw. */
28901 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
28902 newval = (newval & 0xfeffffff) | 0x02000000;
28903 /* No flat 12-bit imm encoding for addsw/subsw. */
28904 if ((newval & 0x00100000) == 0)
40f246e3 28905 {
bada4342 28906 /* 12 bit immediate for addw/subw. */
7af67752 28907 if ((offsetT) value < 0)
bada4342
JW
28908 {
28909 value = -value;
28910 newval ^= 0x00a00000;
28911 }
28912 if (value > 0xfff)
28913 newimm = (unsigned int) FAIL;
28914 else
28915 newimm = value;
28916 }
28917 }
28918 else
28919 {
28920 /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
28921 UINT16 (T3 encoding), MOVW only accepts UINT16. When
28922 disassembling, MOV is preferred when there is no encoding
db7bf105 28923 overlap. */
bada4342 28924 if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
db7bf105
NC
28925 /* NOTE: MOV uses the ORR opcode in Thumb 2 mode
28926 but with the Rn field [19:16] set to 1111. */
28927 && (((newval >> 16) & 0xf) == 0xf)
bada4342
JW
28928 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
28929 && !((newval >> T2_SBIT_SHIFT) & 0x1)
7af67752 28930 && value <= 0xffff)
bada4342
JW
28931 {
28932 /* Toggle bit[25] to change encoding from T2 to T3. */
28933 newval ^= 1 << 25;
28934 /* Clear bits[19:16]. */
28935 newval &= 0xfff0ffff;
28936 /* Encoding high 4bits imm. Code below will encode the
28937 remaining low 12bits. */
28938 newval |= (value & 0x0000f000) << 4;
28939 newimm = value & 0x00000fff;
40f246e3 28940 }
e9f89963 28941 }
92e90b6e 28942 }
cc8a6dd0 28943
c19d1205 28944 if (newimm == (unsigned int)FAIL)
3631a3c8 28945 {
c19d1205
ZW
28946 as_bad_where (fixP->fx_file, fixP->fx_line,
28947 _("invalid constant (%lx) after fixup"),
28948 (unsigned long) value);
28949 break;
3631a3c8
NC
28950 }
28951
c19d1205
ZW
28952 newval |= (newimm & 0x800) << 15;
28953 newval |= (newimm & 0x700) << 4;
28954 newval |= (newimm & 0x0ff);
cc8a6dd0 28955
c19d1205
ZW
28956 md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
28957 md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
28958 break;
a737bd4d 28959
3eb17e6b 28960 case BFD_RELOC_ARM_SMC:
7af67752 28961 if (value > 0xf)
c19d1205 28962 as_bad_where (fixP->fx_file, fixP->fx_line,
3eb17e6b 28963 _("invalid smc expression"));
ba85f98c 28964
2fc8bdac 28965 newval = md_chars_to_number (buf, INSN_SIZE);
ba85f98c 28966 newval |= (value & 0xf);
c19d1205
ZW
28967 md_number_to_chars (buf, newval, INSN_SIZE);
28968 break;
a737bd4d 28969
90ec0d68 28970 case BFD_RELOC_ARM_HVC:
7af67752 28971 if (value > 0xffff)
90ec0d68
MGD
28972 as_bad_where (fixP->fx_file, fixP->fx_line,
28973 _("invalid hvc expression"));
28974 newval = md_chars_to_number (buf, INSN_SIZE);
28975 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
28976 md_number_to_chars (buf, newval, INSN_SIZE);
28977 break;
28978
c19d1205 28979 case BFD_RELOC_ARM_SWI:
adbaf948 28980 if (fixP->tc_fix_data != 0)
c19d1205 28981 {
7af67752 28982 if (value > 0xff)
c19d1205
ZW
28983 as_bad_where (fixP->fx_file, fixP->fx_line,
28984 _("invalid swi expression"));
2fc8bdac 28985 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205
ZW
28986 newval |= value;
28987 md_number_to_chars (buf, newval, THUMB_SIZE);
28988 }
28989 else
28990 {
7af67752 28991 if (value > 0x00ffffff)
c19d1205
ZW
28992 as_bad_where (fixP->fx_file, fixP->fx_line,
28993 _("invalid swi expression"));
2fc8bdac 28994 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
28995 newval |= value;
28996 md_number_to_chars (buf, newval, INSN_SIZE);
28997 }
28998 break;
a737bd4d 28999
c19d1205 29000 case BFD_RELOC_ARM_MULTI:
7af67752 29001 if (value > 0xffff)
c19d1205
ZW
29002 as_bad_where (fixP->fx_file, fixP->fx_line,
29003 _("invalid expression in load/store multiple"));
29004 newval = value | md_chars_to_number (buf, INSN_SIZE);
29005 md_number_to_chars (buf, newval, INSN_SIZE);
29006 break;
a737bd4d 29007
c19d1205 29008#ifdef OBJ_ELF
39b41c9c 29009 case BFD_RELOC_ARM_PCREL_CALL:
267bf995
RR
29010
29011 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
29012 && fixP->fx_addsy
5b7c81bd 29013 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29014 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29015 && THUMB_IS_FUNC (fixP->fx_addsy))
29016 /* Flip the bl to blx. This is a simple flip
29017 bit here because we generate PCREL_CALL for
29018 unconditional bls. */
29019 {
29020 newval = md_chars_to_number (buf, INSN_SIZE);
29021 newval = newval | 0x10000000;
29022 md_number_to_chars (buf, newval, INSN_SIZE);
29023 temp = 1;
29024 fixP->fx_done = 1;
29025 }
39b41c9c
PB
29026 else
29027 temp = 3;
29028 goto arm_branch_common;
29029
29030 case BFD_RELOC_ARM_PCREL_JUMP:
267bf995
RR
29031 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
29032 && fixP->fx_addsy
5b7c81bd 29033 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29034 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29035 && THUMB_IS_FUNC (fixP->fx_addsy))
29036 {
29037 /* This would map to a bl<cond>, b<cond>,
29038 b<always> to a Thumb function. We
29039 need to force a relocation for this particular
29040 case. */
29041 newval = md_chars_to_number (buf, INSN_SIZE);
29042 fixP->fx_done = 0;
29043 }
1a0670f3 29044 /* Fall through. */
267bf995 29045
2fc8bdac 29046 case BFD_RELOC_ARM_PLT32:
c19d1205 29047#endif
39b41c9c
PB
29048 case BFD_RELOC_ARM_PCREL_BRANCH:
29049 temp = 3;
29050 goto arm_branch_common;
a737bd4d 29051
39b41c9c 29052 case BFD_RELOC_ARM_PCREL_BLX:
267bf995 29053
39b41c9c 29054 temp = 1;
267bf995
RR
29055 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
29056 && fixP->fx_addsy
5b7c81bd 29057 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29058 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29059 && ARM_IS_FUNC (fixP->fx_addsy))
29060 {
29061 /* Flip the blx to a bl and warn. */
29062 const char *name = S_GET_NAME (fixP->fx_addsy);
29063 newval = 0xeb000000;
29064 as_warn_where (fixP->fx_file, fixP->fx_line,
29065 _("blx to '%s' an ARM ISA state function changed to bl"),
29066 name);
29067 md_number_to_chars (buf, newval, INSN_SIZE);
29068 temp = 3;
29069 fixP->fx_done = 1;
29070 }
29071
29072#ifdef OBJ_ELF
29073 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
477330fc 29074 fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
267bf995
RR
29075#endif
29076
39b41c9c 29077 arm_branch_common:
c19d1205 29078 /* We are going to store value (shifted right by two) in the
39b41c9c
PB
29079 instruction, in a 24 bit, signed field. Bits 26 through 32 either
29080 all clear or all set and bit 0 must be clear. For B/BL bit 1 must
de194d85 29081 also be clear. */
39b41c9c 29082 if (value & temp)
c19d1205 29083 as_bad_where (fixP->fx_file, fixP->fx_line,
2fc8bdac 29084 _("misaligned branch destination"));
7af67752
AM
29085 if ((value & 0xfe000000) != 0
29086 && (value & 0xfe000000) != 0xfe000000)
08f10d51 29087 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 29088
2fc8bdac 29089 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 29090 {
2fc8bdac
ZW
29091 newval = md_chars_to_number (buf, INSN_SIZE);
29092 newval |= (value >> 2) & 0x00ffffff;
7ae2971b
PB
29093 /* Set the H bit on BLX instructions. */
29094 if (temp == 1)
29095 {
29096 if (value & 2)
29097 newval |= 0x01000000;
29098 else
29099 newval &= ~0x01000000;
29100 }
2fc8bdac 29101 md_number_to_chars (buf, newval, INSN_SIZE);
c19d1205 29102 }
c19d1205 29103 break;
a737bd4d 29104
25fe350b
MS
29105 case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CBZ */
29106 /* CBZ can only branch forward. */
a737bd4d 29107
738755b0 29108 /* Attempts to use CBZ to branch to the next instruction
477330fc
RM
29109 (which, strictly speaking, are prohibited) will be turned into
29110 no-ops.
738755b0
MS
29111
29112 FIXME: It may be better to remove the instruction completely and
29113 perform relaxation. */
7af67752 29114 if ((offsetT) value == -2)
2fc8bdac
ZW
29115 {
29116 newval = md_chars_to_number (buf, THUMB_SIZE);
738755b0 29117 newval = 0xbf00; /* NOP encoding T1 */
2fc8bdac
ZW
29118 md_number_to_chars (buf, newval, THUMB_SIZE);
29119 }
738755b0
MS
29120 else
29121 {
29122 if (value & ~0x7e)
08f10d51 29123 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
738755b0 29124
477330fc 29125 if (fixP->fx_done || !seg->use_rela_p)
738755b0
MS
29126 {
29127 newval = md_chars_to_number (buf, THUMB_SIZE);
29128 newval |= ((value & 0x3e) << 2) | ((value & 0x40) << 3);
29129 md_number_to_chars (buf, newval, THUMB_SIZE);
29130 }
29131 }
c19d1205 29132 break;
a737bd4d 29133
c19d1205 29134 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
e8f8842d 29135 if (out_of_range_p (value, 8))
08f10d51 29136 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 29137
2fc8bdac
ZW
29138 if (fixP->fx_done || !seg->use_rela_p)
29139 {
29140 newval = md_chars_to_number (buf, THUMB_SIZE);
29141 newval |= (value & 0x1ff) >> 1;
29142 md_number_to_chars (buf, newval, THUMB_SIZE);
29143 }
c19d1205 29144 break;
a737bd4d 29145
c19d1205 29146 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
e8f8842d 29147 if (out_of_range_p (value, 11))
08f10d51 29148 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 29149
2fc8bdac
ZW
29150 if (fixP->fx_done || !seg->use_rela_p)
29151 {
29152 newval = md_chars_to_number (buf, THUMB_SIZE);
29153 newval |= (value & 0xfff) >> 1;
29154 md_number_to_chars (buf, newval, THUMB_SIZE);
29155 }
c19d1205 29156 break;
a737bd4d 29157
e8f8842d 29158 /* This relocation is misnamed, it should be BRANCH21. */
c19d1205 29159 case BFD_RELOC_THUMB_PCREL_BRANCH20:
267bf995
RR
29160 if (fixP->fx_addsy
29161 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29162 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29163 && ARM_IS_FUNC (fixP->fx_addsy)
29164 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
29165 {
29166 /* Force a relocation for a branch 20 bits wide. */
29167 fixP->fx_done = 0;
29168 }
e8f8842d 29169 if (out_of_range_p (value, 20))
2fc8bdac
ZW
29170 as_bad_where (fixP->fx_file, fixP->fx_line,
29171 _("conditional branch out of range"));
404ff6b5 29172
2fc8bdac
ZW
29173 if (fixP->fx_done || !seg->use_rela_p)
29174 {
29175 offsetT newval2;
29176 addressT S, J1, J2, lo, hi;
404ff6b5 29177
2fc8bdac
ZW
29178 S = (value & 0x00100000) >> 20;
29179 J2 = (value & 0x00080000) >> 19;
29180 J1 = (value & 0x00040000) >> 18;
29181 hi = (value & 0x0003f000) >> 12;
29182 lo = (value & 0x00000ffe) >> 1;
6c43fab6 29183
2fc8bdac
ZW
29184 newval = md_chars_to_number (buf, THUMB_SIZE);
29185 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29186 newval |= (S << 10) | hi;
29187 newval2 |= (J1 << 13) | (J2 << 11) | lo;
29188 md_number_to_chars (buf, newval, THUMB_SIZE);
29189 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
29190 }
c19d1205 29191 break;
6c43fab6 29192
c19d1205 29193 case BFD_RELOC_THUMB_PCREL_BLX:
267bf995
RR
29194 /* If there is a blx from a thumb state function to
29195 another thumb function flip this to a bl and warn
29196 about it. */
29197
29198 if (fixP->fx_addsy
5b7c81bd 29199 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29200 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29201 && THUMB_IS_FUNC (fixP->fx_addsy))
29202 {
29203 const char *name = S_GET_NAME (fixP->fx_addsy);
29204 as_warn_where (fixP->fx_file, fixP->fx_line,
29205 _("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
29206 name);
29207 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29208 newval = newval | 0x1000;
29209 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
29210 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
29211 fixP->fx_done = 1;
29212 }
29213
29214
29215 goto thumb_bl_common;
29216
c19d1205 29217 case BFD_RELOC_THUMB_PCREL_BRANCH23:
267bf995
RR
29218 /* A bl from Thumb state ISA to an internal ARM state function
29219 is converted to a blx. */
29220 if (fixP->fx_addsy
29221 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29222 && !S_FORCE_RELOC (fixP->fx_addsy, true)
267bf995
RR
29223 && ARM_IS_FUNC (fixP->fx_addsy)
29224 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
29225 {
29226 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29227 newval = newval & ~0x1000;
29228 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
29229 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
29230 fixP->fx_done = 1;
29231 }
29232
29233 thumb_bl_common:
29234
2fc8bdac
ZW
29235 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
29236 /* For a BLX instruction, make sure that the relocation is rounded up
29237 to a word boundary. This follows the semantics of the instruction
29238 which specifies that bit 1 of the target address will come from bit
29239 1 of the base address. */
d406f3e4
JB
29240 value = (value + 3) & ~ 3;
29241
29242#ifdef OBJ_ELF
29243 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
29244 && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
29245 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
29246#endif
404ff6b5 29247
e8f8842d 29248 if (out_of_range_p (value, 22))
2b2f5df9 29249 {
fc289b0a 29250 if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)))
2b2f5df9 29251 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
e8f8842d 29252 else if (out_of_range_p (value, 24))
2b2f5df9
NC
29253 as_bad_where (fixP->fx_file, fixP->fx_line,
29254 _("Thumb2 branch out of range"));
29255 }
4a42ebbc
RR
29256
29257 if (fixP->fx_done || !seg->use_rela_p)
29258 encode_thumb2_b_bl_offset (buf, value);
29259
c19d1205 29260 break;
404ff6b5 29261
c19d1205 29262 case BFD_RELOC_THUMB_PCREL_BRANCH25:
e8f8842d 29263 if (out_of_range_p (value, 24))
08f10d51 29264 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
6c43fab6 29265
2fc8bdac 29266 if (fixP->fx_done || !seg->use_rela_p)
4a42ebbc 29267 encode_thumb2_b_bl_offset (buf, value);
6c43fab6 29268
2fc8bdac 29269 break;
a737bd4d 29270
2fc8bdac
ZW
29271 case BFD_RELOC_8:
29272 if (fixP->fx_done || !seg->use_rela_p)
4b1a927e 29273 *buf = value;
c19d1205 29274 break;
a737bd4d 29275
c19d1205 29276 case BFD_RELOC_16:
2fc8bdac 29277 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 29278 md_number_to_chars (buf, value, 2);
c19d1205 29279 break;
a737bd4d 29280
c19d1205 29281#ifdef OBJ_ELF
0855e32b
NS
29282 case BFD_RELOC_ARM_TLS_CALL:
29283 case BFD_RELOC_ARM_THM_TLS_CALL:
29284 case BFD_RELOC_ARM_TLS_DESCSEQ:
29285 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
0855e32b 29286 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205
ZW
29287 case BFD_RELOC_ARM_TLS_GD32:
29288 case BFD_RELOC_ARM_TLS_LE32:
29289 case BFD_RELOC_ARM_TLS_IE32:
29290 case BFD_RELOC_ARM_TLS_LDM32:
29291 case BFD_RELOC_ARM_TLS_LDO32:
29292 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4b1a927e 29293 break;
6c43fab6 29294
5c5a4843
CL
29295 /* Same handling as above, but with the arm_fdpic guard. */
29296 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
29297 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
29298 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
29299 if (arm_fdpic)
29300 {
29301 S_SET_THREAD_LOCAL (fixP->fx_addsy);
29302 }
29303 else
29304 {
29305 as_bad_where (fixP->fx_file, fixP->fx_line,
29306 _("Relocation supported only in FDPIC mode"));
29307 }
29308 break;
29309
c19d1205
ZW
29310 case BFD_RELOC_ARM_GOT32:
29311 case BFD_RELOC_ARM_GOTOFF:
c19d1205 29312 break;
b43420e6
NC
29313
29314 case BFD_RELOC_ARM_GOT_PREL:
29315 if (fixP->fx_done || !seg->use_rela_p)
477330fc 29316 md_number_to_chars (buf, value, 4);
b43420e6
NC
29317 break;
29318
9a6f4e97
NS
29319 case BFD_RELOC_ARM_TARGET2:
29320 /* TARGET2 is not partial-inplace, so we need to write the
477330fc
RM
29321 addend here for REL targets, because it won't be written out
29322 during reloc processing later. */
9a6f4e97
NS
29323 if (fixP->fx_done || !seg->use_rela_p)
29324 md_number_to_chars (buf, fixP->fx_offset, 4);
29325 break;
188fd7ae
CL
29326
29327 /* Relocations for FDPIC. */
29328 case BFD_RELOC_ARM_GOTFUNCDESC:
29329 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
29330 case BFD_RELOC_ARM_FUNCDESC:
29331 if (arm_fdpic)
29332 {
29333 if (fixP->fx_done || !seg->use_rela_p)
29334 md_number_to_chars (buf, 0, 4);
29335 }
29336 else
29337 {
29338 as_bad_where (fixP->fx_file, fixP->fx_line,
29339 _("Relocation supported only in FDPIC mode"));
29340 }
29341 break;
c19d1205 29342#endif
6c43fab6 29343
c19d1205
ZW
29344 case BFD_RELOC_RVA:
29345 case BFD_RELOC_32:
29346 case BFD_RELOC_ARM_TARGET1:
29347 case BFD_RELOC_ARM_ROSEGREL32:
29348 case BFD_RELOC_ARM_SBREL32:
29349 case BFD_RELOC_32_PCREL:
f0927246
NC
29350#ifdef TE_PE
29351 case BFD_RELOC_32_SECREL:
29352#endif
2fc8bdac 29353 if (fixP->fx_done || !seg->use_rela_p)
53baae48
NC
29354#ifdef TE_WINCE
29355 /* For WinCE we only do this for pcrel fixups. */
29356 if (fixP->fx_done || fixP->fx_pcrel)
29357#endif
29358 md_number_to_chars (buf, value, 4);
c19d1205 29359 break;
6c43fab6 29360
c19d1205
ZW
29361#ifdef OBJ_ELF
29362 case BFD_RELOC_ARM_PREL31:
2fc8bdac 29363 if (fixP->fx_done || !seg->use_rela_p)
c19d1205
ZW
29364 {
29365 newval = md_chars_to_number (buf, 4) & 0x80000000;
29366 if ((value ^ (value >> 1)) & 0x40000000)
29367 {
29368 as_bad_where (fixP->fx_file, fixP->fx_line,
29369 _("rel31 relocation overflow"));
29370 }
29371 newval |= value & 0x7fffffff;
29372 md_number_to_chars (buf, newval, 4);
29373 }
29374 break;
c19d1205 29375#endif
a737bd4d 29376
c19d1205 29377 case BFD_RELOC_ARM_CP_OFF_IMM:
8f06b2d8 29378 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
32c36c3c 29379 case BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM:
9db2f6b4
RL
29380 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
29381 newval = md_chars_to_number (buf, INSN_SIZE);
29382 else
29383 newval = get_thumb32_insn (buf);
29384 if ((newval & 0x0f200f00) == 0x0d000900)
29385 {
29386 /* This is a fp16 vstr/vldr. The immediate offset in the mnemonic
7af67752 29387 has permitted values that are multiples of 2, in the range -510
9db2f6b4 29388 to 510. */
7af67752 29389 if (value + 510 > 510 + 510 || (value & 1))
9db2f6b4
RL
29390 as_bad_where (fixP->fx_file, fixP->fx_line,
29391 _("co-processor offset out of range"));
29392 }
32c36c3c
AV
29393 else if ((newval & 0xfe001f80) == 0xec000f80)
29394 {
7af67752 29395 if (value + 511 > 512 + 511 || (value & 3))
32c36c3c
AV
29396 as_bad_where (fixP->fx_file, fixP->fx_line,
29397 _("co-processor offset out of range"));
29398 }
7af67752 29399 else if (value + 1023 > 1023 + 1023 || (value & 3))
c19d1205
ZW
29400 as_bad_where (fixP->fx_file, fixP->fx_line,
29401 _("co-processor offset out of range"));
29402 cp_off_common:
7af67752
AM
29403 sign = (offsetT) value > 0;
29404 if ((offsetT) value < 0)
c19d1205 29405 value = -value;
8f06b2d8
PB
29406 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
29407 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
29408 newval = md_chars_to_number (buf, INSN_SIZE);
29409 else
29410 newval = get_thumb32_insn (buf);
26d97720 29411 if (value == 0)
32c36c3c
AV
29412 {
29413 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
29414 newval &= 0xffffff80;
29415 else
29416 newval &= 0xffffff00;
29417 }
26d97720
NS
29418 else
29419 {
32c36c3c
AV
29420 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
29421 newval &= 0xff7fff80;
29422 else
29423 newval &= 0xff7fff00;
9db2f6b4
RL
29424 if ((newval & 0x0f200f00) == 0x0d000900)
29425 {
29426 /* This is a fp16 vstr/vldr.
29427
29428 It requires the immediate offset in the instruction is shifted
29429 left by 1 to be a half-word offset.
29430
29431 Here, left shift by 1 first, and later right shift by 2
29432 should get the right offset. */
29433 value <<= 1;
29434 }
26d97720
NS
29435 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
29436 }
8f06b2d8
PB
29437 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
29438 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
29439 md_number_to_chars (buf, newval, INSN_SIZE);
29440 else
29441 put_thumb32_insn (buf, newval);
c19d1205 29442 break;
a737bd4d 29443
c19d1205 29444 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
8f06b2d8 29445 case BFD_RELOC_ARM_T32_CP_OFF_IMM_S2:
7af67752 29446 if (value + 255 > 255 + 255)
c19d1205
ZW
29447 as_bad_where (fixP->fx_file, fixP->fx_line,
29448 _("co-processor offset out of range"));
df7849c5 29449 value *= 4;
c19d1205 29450 goto cp_off_common;
6c43fab6 29451
c19d1205
ZW
29452 case BFD_RELOC_ARM_THUMB_OFFSET:
29453 newval = md_chars_to_number (buf, THUMB_SIZE);
29454 /* Exactly what ranges, and where the offset is inserted depends
29455 on the type of instruction, we can establish this from the
29456 top 4 bits. */
29457 switch (newval >> 12)
29458 {
29459 case 4: /* PC load. */
29460 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
29461 forced to zero for these loads; md_pcrel_from has already
29462 compensated for this. */
29463 if (value & 3)
29464 as_bad_where (fixP->fx_file, fixP->fx_line,
29465 _("invalid offset, target not word aligned (0x%08lX)"),
0359e808
NC
29466 (((unsigned long) fixP->fx_frag->fr_address
29467 + (unsigned long) fixP->fx_where) & ~3)
29468 + (unsigned long) value);
749479c8
AO
29469 else if (get_recorded_alignment (seg) < 2)
29470 as_warn_where (fixP->fx_file, fixP->fx_line,
29471 _("section does not have enough alignment to ensure safe PC-relative loads"));
a737bd4d 29472
c19d1205
ZW
29473 if (value & ~0x3fc)
29474 as_bad_where (fixP->fx_file, fixP->fx_line,
29475 _("invalid offset, value too big (0x%08lX)"),
29476 (long) value);
a737bd4d 29477
c19d1205
ZW
29478 newval |= value >> 2;
29479 break;
a737bd4d 29480
c19d1205
ZW
29481 case 9: /* SP load/store. */
29482 if (value & ~0x3fc)
29483 as_bad_where (fixP->fx_file, fixP->fx_line,
29484 _("invalid offset, value too big (0x%08lX)"),
29485 (long) value);
29486 newval |= value >> 2;
29487 break;
6c43fab6 29488
c19d1205
ZW
29489 case 6: /* Word load/store. */
29490 if (value & ~0x7c)
29491 as_bad_where (fixP->fx_file, fixP->fx_line,
29492 _("invalid offset, value too big (0x%08lX)"),
29493 (long) value);
29494 newval |= value << 4; /* 6 - 2. */
29495 break;
a737bd4d 29496
c19d1205
ZW
29497 case 7: /* Byte load/store. */
29498 if (value & ~0x1f)
29499 as_bad_where (fixP->fx_file, fixP->fx_line,
29500 _("invalid offset, value too big (0x%08lX)"),
29501 (long) value);
29502 newval |= value << 6;
29503 break;
a737bd4d 29504
c19d1205
ZW
29505 case 8: /* Halfword load/store. */
29506 if (value & ~0x3e)
29507 as_bad_where (fixP->fx_file, fixP->fx_line,
29508 _("invalid offset, value too big (0x%08lX)"),
29509 (long) value);
29510 newval |= value << 5; /* 6 - 1. */
29511 break;
a737bd4d 29512
c19d1205
ZW
29513 default:
29514 as_bad_where (fixP->fx_file, fixP->fx_line,
29515 "Unable to process relocation for thumb opcode: %lx",
29516 (unsigned long) newval);
29517 break;
29518 }
29519 md_number_to_chars (buf, newval, THUMB_SIZE);
29520 break;
a737bd4d 29521
c19d1205
ZW
29522 case BFD_RELOC_ARM_THUMB_ADD:
29523 /* This is a complicated relocation, since we use it for all of
29524 the following immediate relocations:
a737bd4d 29525
c19d1205
ZW
29526 3bit ADD/SUB
29527 8bit ADD/SUB
29528 9bit ADD/SUB SP word-aligned
29529 10bit ADD PC/SP word-aligned
a737bd4d 29530
c19d1205
ZW
29531 The type of instruction being processed is encoded in the
29532 instruction field:
a737bd4d 29533
c19d1205
ZW
29534 0x8000 SUB
29535 0x00F0 Rd
29536 0x000F Rs
29537 */
29538 newval = md_chars_to_number (buf, THUMB_SIZE);
29539 {
29540 int rd = (newval >> 4) & 0xf;
29541 int rs = newval & 0xf;
29542 int subtract = !!(newval & 0x8000);
a737bd4d 29543
c19d1205
ZW
29544 /* Check for HI regs, only very restricted cases allowed:
29545 Adjusting SP, and using PC or SP to get an address. */
29546 if ((rd > 7 && (rd != REG_SP || rs != REG_SP))
29547 || (rs > 7 && rs != REG_SP && rs != REG_PC))
29548 as_bad_where (fixP->fx_file, fixP->fx_line,
29549 _("invalid Hi register with immediate"));
a737bd4d 29550
c19d1205 29551 /* If value is negative, choose the opposite instruction. */
7af67752 29552 if ((offsetT) value < 0)
c19d1205
ZW
29553 {
29554 value = -value;
29555 subtract = !subtract;
7af67752 29556 if ((offsetT) value < 0)
c19d1205
ZW
29557 as_bad_where (fixP->fx_file, fixP->fx_line,
29558 _("immediate value out of range"));
29559 }
a737bd4d 29560
c19d1205
ZW
29561 if (rd == REG_SP)
29562 {
75c11999 29563 if (value & ~0x1fc)
c19d1205
ZW
29564 as_bad_where (fixP->fx_file, fixP->fx_line,
29565 _("invalid immediate for stack address calculation"));
29566 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
29567 newval |= value >> 2;
29568 }
29569 else if (rs == REG_PC || rs == REG_SP)
29570 {
c12d2c9d
NC
29571 /* PR gas/18541. If the addition is for a defined symbol
29572 within range of an ADR instruction then accept it. */
29573 if (subtract
29574 && value == 4
29575 && fixP->fx_addsy != NULL)
29576 {
29577 subtract = 0;
29578
29579 if (! S_IS_DEFINED (fixP->fx_addsy)
29580 || S_GET_SEGMENT (fixP->fx_addsy) != seg
29581 || S_IS_WEAK (fixP->fx_addsy))
29582 {
29583 as_bad_where (fixP->fx_file, fixP->fx_line,
29584 _("address calculation needs a strongly defined nearby symbol"));
29585 }
29586 else
29587 {
29588 offsetT v = fixP->fx_where + fixP->fx_frag->fr_address;
29589
29590 /* Round up to the next 4-byte boundary. */
29591 if (v & 3)
29592 v = (v + 3) & ~ 3;
29593 else
29594 v += 4;
29595 v = S_GET_VALUE (fixP->fx_addsy) - v;
29596
29597 if (v & ~0x3fc)
29598 {
29599 as_bad_where (fixP->fx_file, fixP->fx_line,
29600 _("symbol too far away"));
29601 }
29602 else
29603 {
29604 fixP->fx_done = 1;
29605 value = v;
29606 }
29607 }
29608 }
29609
c19d1205
ZW
29610 if (subtract || value & ~0x3fc)
29611 as_bad_where (fixP->fx_file, fixP->fx_line,
29612 _("invalid immediate for address calculation (value = 0x%08lX)"),
5fc177c8 29613 (unsigned long) (subtract ? - value : value));
c19d1205
ZW
29614 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
29615 newval |= rd << 8;
29616 newval |= value >> 2;
29617 }
29618 else if (rs == rd)
29619 {
29620 if (value & ~0xff)
29621 as_bad_where (fixP->fx_file, fixP->fx_line,
29622 _("immediate value out of range"));
29623 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
29624 newval |= (rd << 8) | value;
29625 }
29626 else
29627 {
29628 if (value & ~0x7)
29629 as_bad_where (fixP->fx_file, fixP->fx_line,
29630 _("immediate value out of range"));
29631 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
29632 newval |= rd | (rs << 3) | (value << 6);
29633 }
29634 }
29635 md_number_to_chars (buf, newval, THUMB_SIZE);
29636 break;
a737bd4d 29637
c19d1205
ZW
29638 case BFD_RELOC_ARM_THUMB_IMM:
29639 newval = md_chars_to_number (buf, THUMB_SIZE);
7af67752 29640 if (value > 255)
c19d1205 29641 as_bad_where (fixP->fx_file, fixP->fx_line,
4e6e072b 29642 _("invalid immediate: %ld is out of range"),
c19d1205
ZW
29643 (long) value);
29644 newval |= value;
29645 md_number_to_chars (buf, newval, THUMB_SIZE);
29646 break;
a737bd4d 29647
c19d1205
ZW
29648 case BFD_RELOC_ARM_THUMB_SHIFT:
29649 /* 5bit shift value (0..32). LSL cannot take 32. */
29650 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf83f;
29651 temp = newval & 0xf800;
7af67752 29652 if (value > 32 || (value == 32 && temp == T_OPCODE_LSL_I))
c19d1205
ZW
29653 as_bad_where (fixP->fx_file, fixP->fx_line,
29654 _("invalid shift value: %ld"), (long) value);
29655 /* Shifts of zero must be encoded as LSL. */
29656 if (value == 0)
29657 newval = (newval & 0x003f) | T_OPCODE_LSL_I;
29658 /* Shifts of 32 are encoded as zero. */
29659 else if (value == 32)
29660 value = 0;
29661 newval |= value << 6;
29662 md_number_to_chars (buf, newval, THUMB_SIZE);
29663 break;
a737bd4d 29664
c19d1205
ZW
29665 case BFD_RELOC_VTABLE_INHERIT:
29666 case BFD_RELOC_VTABLE_ENTRY:
29667 fixP->fx_done = 0;
29668 return;
6c43fab6 29669
b6895b4f
PB
29670 case BFD_RELOC_ARM_MOVW:
29671 case BFD_RELOC_ARM_MOVT:
29672 case BFD_RELOC_ARM_THUMB_MOVW:
29673 case BFD_RELOC_ARM_THUMB_MOVT:
29674 if (fixP->fx_done || !seg->use_rela_p)
29675 {
29676 /* REL format relocations are limited to a 16-bit addend. */
29677 if (!fixP->fx_done)
29678 {
7af67752 29679 if (value + 0x8000 > 0x7fff + 0x8000)
b6895b4f 29680 as_bad_where (fixP->fx_file, fixP->fx_line,
ff5075ca 29681 _("offset out of range"));
b6895b4f
PB
29682 }
29683 else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT
29684 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
29685 {
29686 value >>= 16;
29687 }
29688
29689 if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
29690 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
29691 {
29692 newval = get_thumb32_insn (buf);
29693 newval &= 0xfbf08f00;
29694 newval |= (value & 0xf000) << 4;
29695 newval |= (value & 0x0800) << 15;
29696 newval |= (value & 0x0700) << 4;
29697 newval |= (value & 0x00ff);
29698 put_thumb32_insn (buf, newval);
29699 }
29700 else
29701 {
29702 newval = md_chars_to_number (buf, 4);
29703 newval &= 0xfff0f000;
29704 newval |= value & 0x0fff;
29705 newval |= (value & 0xf000) << 4;
29706 md_number_to_chars (buf, newval, 4);
29707 }
29708 }
29709 return;
29710
72d98d16
MG
29711 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
29712 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
29713 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
29714 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
29715 gas_assert (!fixP->fx_done);
29716 {
29717 bfd_vma insn;
5b7c81bd 29718 bool is_mov;
72d98d16
MG
29719 bfd_vma encoded_addend = value;
29720
29721 /* Check that addend can be encoded in instruction. */
7af67752 29722 if (!seg->use_rela_p && value > 255)
72d98d16
MG
29723 as_bad_where (fixP->fx_file, fixP->fx_line,
29724 _("the offset 0x%08lX is not representable"),
29725 (unsigned long) encoded_addend);
29726
29727 /* Extract the instruction. */
29728 insn = md_chars_to_number (buf, THUMB_SIZE);
29729 is_mov = (insn & 0xf800) == 0x2000;
29730
29731 /* Encode insn. */
29732 if (is_mov)
29733 {
29734 if (!seg->use_rela_p)
29735 insn |= encoded_addend;
29736 }
29737 else
29738 {
29739 int rd, rs;
29740
29741 /* Extract the instruction. */
29742 /* Encoding is the following
29743 0x8000 SUB
29744 0x00F0 Rd
29745 0x000F Rs
29746 */
29747 /* The following conditions must be true :
29748 - ADD
29749 - Rd == Rs
29750 - Rd <= 7
29751 */
29752 rd = (insn >> 4) & 0xf;
29753 rs = insn & 0xf;
29754 if ((insn & 0x8000) || (rd != rs) || rd > 7)
29755 as_bad_where (fixP->fx_file, fixP->fx_line,
29756 _("Unable to process relocation for thumb opcode: %lx"),
29757 (unsigned long) insn);
29758
29759 /* Encode as ADD immediate8 thumb 1 code. */
29760 insn = 0x3000 | (rd << 8);
29761
29762 /* Place the encoded addend into the first 8 bits of the
29763 instruction. */
29764 if (!seg->use_rela_p)
29765 insn |= encoded_addend;
29766 }
29767
29768 /* Update the instruction. */
29769 md_number_to_chars (buf, insn, THUMB_SIZE);
29770 }
29771 break;
29772
4962c51a
MS
29773 case BFD_RELOC_ARM_ALU_PC_G0_NC:
29774 case BFD_RELOC_ARM_ALU_PC_G0:
29775 case BFD_RELOC_ARM_ALU_PC_G1_NC:
29776 case BFD_RELOC_ARM_ALU_PC_G1:
29777 case BFD_RELOC_ARM_ALU_PC_G2:
29778 case BFD_RELOC_ARM_ALU_SB_G0_NC:
29779 case BFD_RELOC_ARM_ALU_SB_G0:
29780 case BFD_RELOC_ARM_ALU_SB_G1_NC:
29781 case BFD_RELOC_ARM_ALU_SB_G1:
29782 case BFD_RELOC_ARM_ALU_SB_G2:
9c2799c2 29783 gas_assert (!fixP->fx_done);
4962c51a
MS
29784 if (!seg->use_rela_p)
29785 {
477330fc
RM
29786 bfd_vma insn;
29787 bfd_vma encoded_addend;
7af67752 29788 bfd_vma addend_abs = llabs ((offsetT) value);
477330fc
RM
29789
29790 /* Check that the absolute value of the addend can be
29791 expressed as an 8-bit constant plus a rotation. */
29792 encoded_addend = encode_arm_immediate (addend_abs);
29793 if (encoded_addend == (unsigned int) FAIL)
4962c51a 29794 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29795 _("the offset 0x%08lX is not representable"),
29796 (unsigned long) addend_abs);
29797
29798 /* Extract the instruction. */
29799 insn = md_chars_to_number (buf, INSN_SIZE);
29800
29801 /* If the addend is positive, use an ADD instruction.
29802 Otherwise use a SUB. Take care not to destroy the S bit. */
29803 insn &= 0xff1fffff;
7af67752 29804 if ((offsetT) value < 0)
477330fc
RM
29805 insn |= 1 << 22;
29806 else
29807 insn |= 1 << 23;
29808
29809 /* Place the encoded addend into the first 12 bits of the
29810 instruction. */
29811 insn &= 0xfffff000;
29812 insn |= encoded_addend;
29813
29814 /* Update the instruction. */
29815 md_number_to_chars (buf, insn, INSN_SIZE);
4962c51a
MS
29816 }
29817 break;
29818
29819 case BFD_RELOC_ARM_LDR_PC_G0:
29820 case BFD_RELOC_ARM_LDR_PC_G1:
29821 case BFD_RELOC_ARM_LDR_PC_G2:
29822 case BFD_RELOC_ARM_LDR_SB_G0:
29823 case BFD_RELOC_ARM_LDR_SB_G1:
29824 case BFD_RELOC_ARM_LDR_SB_G2:
9c2799c2 29825 gas_assert (!fixP->fx_done);
4962c51a 29826 if (!seg->use_rela_p)
477330fc
RM
29827 {
29828 bfd_vma insn;
7af67752 29829 bfd_vma addend_abs = llabs ((offsetT) value);
4962c51a 29830
477330fc
RM
29831 /* Check that the absolute value of the addend can be
29832 encoded in 12 bits. */
29833 if (addend_abs >= 0x1000)
4962c51a 29834 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29835 _("bad offset 0x%08lX (only 12 bits available for the magnitude)"),
29836 (unsigned long) addend_abs);
29837
29838 /* Extract the instruction. */
29839 insn = md_chars_to_number (buf, INSN_SIZE);
29840
29841 /* If the addend is negative, clear bit 23 of the instruction.
29842 Otherwise set it. */
7af67752 29843 if ((offsetT) value < 0)
477330fc
RM
29844 insn &= ~(1 << 23);
29845 else
29846 insn |= 1 << 23;
29847
29848 /* Place the absolute value of the addend into the first 12 bits
29849 of the instruction. */
29850 insn &= 0xfffff000;
29851 insn |= addend_abs;
29852
29853 /* Update the instruction. */
29854 md_number_to_chars (buf, insn, INSN_SIZE);
29855 }
4962c51a
MS
29856 break;
29857
29858 case BFD_RELOC_ARM_LDRS_PC_G0:
29859 case BFD_RELOC_ARM_LDRS_PC_G1:
29860 case BFD_RELOC_ARM_LDRS_PC_G2:
29861 case BFD_RELOC_ARM_LDRS_SB_G0:
29862 case BFD_RELOC_ARM_LDRS_SB_G1:
29863 case BFD_RELOC_ARM_LDRS_SB_G2:
9c2799c2 29864 gas_assert (!fixP->fx_done);
4962c51a 29865 if (!seg->use_rela_p)
477330fc
RM
29866 {
29867 bfd_vma insn;
7af67752 29868 bfd_vma addend_abs = llabs ((offsetT) value);
4962c51a 29869
477330fc
RM
29870 /* Check that the absolute value of the addend can be
29871 encoded in 8 bits. */
29872 if (addend_abs >= 0x100)
4962c51a 29873 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29874 _("bad offset 0x%08lX (only 8 bits available for the magnitude)"),
29875 (unsigned long) addend_abs);
29876
29877 /* Extract the instruction. */
29878 insn = md_chars_to_number (buf, INSN_SIZE);
29879
29880 /* If the addend is negative, clear bit 23 of the instruction.
29881 Otherwise set it. */
7af67752 29882 if ((offsetT) value < 0)
477330fc
RM
29883 insn &= ~(1 << 23);
29884 else
29885 insn |= 1 << 23;
29886
29887 /* Place the first four bits of the absolute value of the addend
29888 into the first 4 bits of the instruction, and the remaining
29889 four into bits 8 .. 11. */
29890 insn &= 0xfffff0f0;
29891 insn |= (addend_abs & 0xf) | ((addend_abs & 0xf0) << 4);
29892
29893 /* Update the instruction. */
29894 md_number_to_chars (buf, insn, INSN_SIZE);
29895 }
4962c51a
MS
29896 break;
29897
29898 case BFD_RELOC_ARM_LDC_PC_G0:
29899 case BFD_RELOC_ARM_LDC_PC_G1:
29900 case BFD_RELOC_ARM_LDC_PC_G2:
29901 case BFD_RELOC_ARM_LDC_SB_G0:
29902 case BFD_RELOC_ARM_LDC_SB_G1:
29903 case BFD_RELOC_ARM_LDC_SB_G2:
9c2799c2 29904 gas_assert (!fixP->fx_done);
4962c51a 29905 if (!seg->use_rela_p)
477330fc
RM
29906 {
29907 bfd_vma insn;
7af67752 29908 bfd_vma addend_abs = llabs ((offsetT) value);
4962c51a 29909
477330fc
RM
29910 /* Check that the absolute value of the addend is a multiple of
29911 four and, when divided by four, fits in 8 bits. */
29912 if (addend_abs & 0x3)
4962c51a 29913 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29914 _("bad offset 0x%08lX (must be word-aligned)"),
29915 (unsigned long) addend_abs);
4962c51a 29916
477330fc 29917 if ((addend_abs >> 2) > 0xff)
4962c51a 29918 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29919 _("bad offset 0x%08lX (must be an 8-bit number of words)"),
29920 (unsigned long) addend_abs);
29921
29922 /* Extract the instruction. */
29923 insn = md_chars_to_number (buf, INSN_SIZE);
29924
29925 /* If the addend is negative, clear bit 23 of the instruction.
29926 Otherwise set it. */
7af67752 29927 if ((offsetT) value < 0)
477330fc
RM
29928 insn &= ~(1 << 23);
29929 else
29930 insn |= 1 << 23;
29931
29932 /* Place the addend (divided by four) into the first eight
29933 bits of the instruction. */
29934 insn &= 0xfffffff0;
29935 insn |= addend_abs >> 2;
29936
29937 /* Update the instruction. */
29938 md_number_to_chars (buf, insn, INSN_SIZE);
29939 }
4962c51a
MS
29940 break;
29941
e12437dc
AV
29942 case BFD_RELOC_THUMB_PCREL_BRANCH5:
29943 if (fixP->fx_addsy
29944 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29945 && !S_FORCE_RELOC (fixP->fx_addsy, true)
e12437dc
AV
29946 && ARM_IS_FUNC (fixP->fx_addsy)
29947 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29948 {
29949 /* Force a relocation for a branch 5 bits wide. */
29950 fixP->fx_done = 0;
29951 }
5b7c81bd 29952 if (v8_1_branch_value_check (value, 5, false) == FAIL)
e12437dc
AV
29953 as_bad_where (fixP->fx_file, fixP->fx_line,
29954 BAD_BRANCH_OFF);
29955
29956 if (fixP->fx_done || !seg->use_rela_p)
29957 {
29958 addressT boff = value >> 1;
29959
29960 newval = md_chars_to_number (buf, THUMB_SIZE);
29961 newval |= (boff << 7);
29962 md_number_to_chars (buf, newval, THUMB_SIZE);
29963 }
29964 break;
29965
f6b2b12d
AV
29966 case BFD_RELOC_THUMB_PCREL_BFCSEL:
29967 if (fixP->fx_addsy
29968 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 29969 && !S_FORCE_RELOC (fixP->fx_addsy, true)
f6b2b12d
AV
29970 && ARM_IS_FUNC (fixP->fx_addsy)
29971 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29972 {
29973 fixP->fx_done = 0;
29974 }
7af67752 29975 if ((value & ~0x7f) && ((value & ~0x3f) != (valueT) ~0x3f))
f6b2b12d
AV
29976 as_bad_where (fixP->fx_file, fixP->fx_line,
29977 _("branch out of range"));
29978
29979 if (fixP->fx_done || !seg->use_rela_p)
29980 {
29981 newval = md_chars_to_number (buf, THUMB_SIZE);
29982
29983 addressT boff = ((newval & 0x0780) >> 7) << 1;
29984 addressT diff = value - boff;
29985
29986 if (diff == 4)
29987 {
29988 newval |= 1 << 1; /* T bit. */
29989 }
29990 else if (diff != 2)
29991 {
29992 as_bad_where (fixP->fx_file, fixP->fx_line,
29993 _("out of range label-relative fixup value"));
29994 }
29995 md_number_to_chars (buf, newval, THUMB_SIZE);
29996 }
29997 break;
29998
e5d6e09e
AV
29999 case BFD_RELOC_ARM_THUMB_BF17:
30000 if (fixP->fx_addsy
30001 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 30002 && !S_FORCE_RELOC (fixP->fx_addsy, true)
e5d6e09e
AV
30003 && ARM_IS_FUNC (fixP->fx_addsy)
30004 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
30005 {
30006 /* Force a relocation for a branch 17 bits wide. */
30007 fixP->fx_done = 0;
30008 }
30009
5b7c81bd 30010 if (v8_1_branch_value_check (value, 17, true) == FAIL)
e5d6e09e
AV
30011 as_bad_where (fixP->fx_file, fixP->fx_line,
30012 BAD_BRANCH_OFF);
30013
30014 if (fixP->fx_done || !seg->use_rela_p)
30015 {
30016 offsetT newval2;
30017 addressT immA, immB, immC;
30018
30019 immA = (value & 0x0001f000) >> 12;
30020 immB = (value & 0x00000ffc) >> 2;
30021 immC = (value & 0x00000002) >> 1;
30022
30023 newval = md_chars_to_number (buf, THUMB_SIZE);
30024 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30025 newval |= immA;
30026 newval2 |= (immC << 11) | (immB << 1);
30027 md_number_to_chars (buf, newval, THUMB_SIZE);
30028 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
30029 }
30030 break;
30031
1caf72a5
AV
30032 case BFD_RELOC_ARM_THUMB_BF19:
30033 if (fixP->fx_addsy
30034 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 30035 && !S_FORCE_RELOC (fixP->fx_addsy, true)
1caf72a5
AV
30036 && ARM_IS_FUNC (fixP->fx_addsy)
30037 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
30038 {
30039 /* Force a relocation for a branch 19 bits wide. */
30040 fixP->fx_done = 0;
30041 }
30042
5b7c81bd 30043 if (v8_1_branch_value_check (value, 19, true) == FAIL)
1caf72a5
AV
30044 as_bad_where (fixP->fx_file, fixP->fx_line,
30045 BAD_BRANCH_OFF);
30046
30047 if (fixP->fx_done || !seg->use_rela_p)
30048 {
30049 offsetT newval2;
30050 addressT immA, immB, immC;
30051
30052 immA = (value & 0x0007f000) >> 12;
30053 immB = (value & 0x00000ffc) >> 2;
30054 immC = (value & 0x00000002) >> 1;
30055
30056 newval = md_chars_to_number (buf, THUMB_SIZE);
30057 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30058 newval |= immA;
30059 newval2 |= (immC << 11) | (immB << 1);
30060 md_number_to_chars (buf, newval, THUMB_SIZE);
30061 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
30062 }
30063 break;
30064
1889da70
AV
30065 case BFD_RELOC_ARM_THUMB_BF13:
30066 if (fixP->fx_addsy
30067 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 30068 && !S_FORCE_RELOC (fixP->fx_addsy, true)
1889da70
AV
30069 && ARM_IS_FUNC (fixP->fx_addsy)
30070 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
30071 {
30072 /* Force a relocation for a branch 13 bits wide. */
30073 fixP->fx_done = 0;
30074 }
30075
5b7c81bd 30076 if (v8_1_branch_value_check (value, 13, true) == FAIL)
1889da70
AV
30077 as_bad_where (fixP->fx_file, fixP->fx_line,
30078 BAD_BRANCH_OFF);
30079
30080 if (fixP->fx_done || !seg->use_rela_p)
30081 {
30082 offsetT newval2;
30083 addressT immA, immB, immC;
30084
30085 immA = (value & 0x00001000) >> 12;
30086 immB = (value & 0x00000ffc) >> 2;
30087 immC = (value & 0x00000002) >> 1;
30088
30089 newval = md_chars_to_number (buf, THUMB_SIZE);
30090 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30091 newval |= immA;
30092 newval2 |= (immC << 11) | (immB << 1);
30093 md_number_to_chars (buf, newval, THUMB_SIZE);
30094 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
30095 }
30096 break;
30097
60f993ce
AV
30098 case BFD_RELOC_ARM_THUMB_LOOP12:
30099 if (fixP->fx_addsy
30100 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
5b7c81bd 30101 && !S_FORCE_RELOC (fixP->fx_addsy, true)
60f993ce
AV
30102 && ARM_IS_FUNC (fixP->fx_addsy)
30103 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
30104 {
30105 /* Force a relocation for a branch 12 bits wide. */
30106 fixP->fx_done = 0;
30107 }
30108
30109 bfd_vma insn = get_thumb32_insn (buf);
1f6234a3 30110 /* le lr, <label>, le <label> or letp lr, <label> */
60f993ce 30111 if (((insn & 0xffffffff) == 0xf00fc001)
1f6234a3
AV
30112 || ((insn & 0xffffffff) == 0xf02fc001)
30113 || ((insn & 0xffffffff) == 0xf01fc001))
60f993ce
AV
30114 value = -value;
30115
5b7c81bd 30116 if (v8_1_branch_value_check (value, 12, false) == FAIL)
60f993ce
AV
30117 as_bad_where (fixP->fx_file, fixP->fx_line,
30118 BAD_BRANCH_OFF);
30119 if (fixP->fx_done || !seg->use_rela_p)
30120 {
30121 addressT imml, immh;
30122
30123 immh = (value & 0x00000ffc) >> 2;
30124 imml = (value & 0x00000002) >> 1;
30125
30126 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
30127 newval |= (imml << 11) | (immh << 1);
30128 md_number_to_chars (buf + THUMB_SIZE, newval, THUMB_SIZE);
30129 }
30130 break;
30131
845b51d6
PB
30132 case BFD_RELOC_ARM_V4BX:
30133 /* This will need to go in the object file. */
30134 fixP->fx_done = 0;
30135 break;
30136
c19d1205
ZW
30137 case BFD_RELOC_UNUSED:
30138 default:
30139 as_bad_where (fixP->fx_file, fixP->fx_line,
30140 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
30141 }
6c43fab6
RE
30142}
30143
c19d1205
ZW
30144/* Translate internal representation of relocation info to BFD target
30145 format. */
a737bd4d 30146
c19d1205 30147arelent *
00a97672 30148tc_gen_reloc (asection *section, fixS *fixp)
a737bd4d 30149{
c19d1205
ZW
30150 arelent * reloc;
30151 bfd_reloc_code_real_type code;
a737bd4d 30152
325801bd 30153 reloc = XNEW (arelent);
a737bd4d 30154
325801bd 30155 reloc->sym_ptr_ptr = XNEW (asymbol *);
c19d1205
ZW
30156 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
30157 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
a737bd4d 30158
2fc8bdac 30159 if (fixp->fx_pcrel)
00a97672
RS
30160 {
30161 if (section->use_rela_p)
30162 fixp->fx_offset -= md_pcrel_from_section (fixp, section);
30163 else
30164 fixp->fx_offset = reloc->address;
30165 }
c19d1205 30166 reloc->addend = fixp->fx_offset;
a737bd4d 30167
c19d1205 30168 switch (fixp->fx_r_type)
a737bd4d 30169 {
c19d1205
ZW
30170 case BFD_RELOC_8:
30171 if (fixp->fx_pcrel)
30172 {
30173 code = BFD_RELOC_8_PCREL;
30174 break;
30175 }
1a0670f3 30176 /* Fall through. */
a737bd4d 30177
c19d1205
ZW
30178 case BFD_RELOC_16:
30179 if (fixp->fx_pcrel)
30180 {
30181 code = BFD_RELOC_16_PCREL;
30182 break;
30183 }
1a0670f3 30184 /* Fall through. */
6c43fab6 30185
c19d1205
ZW
30186 case BFD_RELOC_32:
30187 if (fixp->fx_pcrel)
30188 {
30189 code = BFD_RELOC_32_PCREL;
30190 break;
30191 }
1a0670f3 30192 /* Fall through. */
a737bd4d 30193
b6895b4f
PB
30194 case BFD_RELOC_ARM_MOVW:
30195 if (fixp->fx_pcrel)
30196 {
30197 code = BFD_RELOC_ARM_MOVW_PCREL;
30198 break;
30199 }
1a0670f3 30200 /* Fall through. */
b6895b4f
PB
30201
30202 case BFD_RELOC_ARM_MOVT:
30203 if (fixp->fx_pcrel)
30204 {
30205 code = BFD_RELOC_ARM_MOVT_PCREL;
30206 break;
30207 }
1a0670f3 30208 /* Fall through. */
b6895b4f
PB
30209
30210 case BFD_RELOC_ARM_THUMB_MOVW:
30211 if (fixp->fx_pcrel)
30212 {
30213 code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
30214 break;
30215 }
1a0670f3 30216 /* Fall through. */
b6895b4f
PB
30217
30218 case BFD_RELOC_ARM_THUMB_MOVT:
30219 if (fixp->fx_pcrel)
30220 {
30221 code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
30222 break;
30223 }
1a0670f3 30224 /* Fall through. */
b6895b4f 30225
c19d1205
ZW
30226 case BFD_RELOC_NONE:
30227 case BFD_RELOC_ARM_PCREL_BRANCH:
30228 case BFD_RELOC_ARM_PCREL_BLX:
30229 case BFD_RELOC_RVA:
30230 case BFD_RELOC_THUMB_PCREL_BRANCH7:
30231 case BFD_RELOC_THUMB_PCREL_BRANCH9:
30232 case BFD_RELOC_THUMB_PCREL_BRANCH12:
30233 case BFD_RELOC_THUMB_PCREL_BRANCH20:
30234 case BFD_RELOC_THUMB_PCREL_BRANCH23:
30235 case BFD_RELOC_THUMB_PCREL_BRANCH25:
c19d1205
ZW
30236 case BFD_RELOC_VTABLE_ENTRY:
30237 case BFD_RELOC_VTABLE_INHERIT:
f0927246
NC
30238#ifdef TE_PE
30239 case BFD_RELOC_32_SECREL:
30240#endif
c19d1205
ZW
30241 code = fixp->fx_r_type;
30242 break;
a737bd4d 30243
00adf2d4
JB
30244 case BFD_RELOC_THUMB_PCREL_BLX:
30245#ifdef OBJ_ELF
30246 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
30247 code = BFD_RELOC_THUMB_PCREL_BRANCH23;
30248 else
30249#endif
30250 code = BFD_RELOC_THUMB_PCREL_BLX;
30251 break;
30252
c19d1205
ZW
30253 case BFD_RELOC_ARM_LITERAL:
30254 case BFD_RELOC_ARM_HWLITERAL:
30255 /* If this is called then the a literal has
30256 been referenced across a section boundary. */
30257 as_bad_where (fixp->fx_file, fixp->fx_line,
30258 _("literal referenced across section boundary"));
30259 return NULL;
a737bd4d 30260
c19d1205 30261#ifdef OBJ_ELF
0855e32b
NS
30262 case BFD_RELOC_ARM_TLS_CALL:
30263 case BFD_RELOC_ARM_THM_TLS_CALL:
30264 case BFD_RELOC_ARM_TLS_DESCSEQ:
30265 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
c19d1205
ZW
30266 case BFD_RELOC_ARM_GOT32:
30267 case BFD_RELOC_ARM_GOTOFF:
b43420e6 30268 case BFD_RELOC_ARM_GOT_PREL:
c19d1205
ZW
30269 case BFD_RELOC_ARM_PLT32:
30270 case BFD_RELOC_ARM_TARGET1:
30271 case BFD_RELOC_ARM_ROSEGREL32:
30272 case BFD_RELOC_ARM_SBREL32:
30273 case BFD_RELOC_ARM_PREL31:
30274 case BFD_RELOC_ARM_TARGET2:
c19d1205 30275 case BFD_RELOC_ARM_TLS_LDO32:
39b41c9c
PB
30276 case BFD_RELOC_ARM_PCREL_CALL:
30277 case BFD_RELOC_ARM_PCREL_JUMP:
4962c51a
MS
30278 case BFD_RELOC_ARM_ALU_PC_G0_NC:
30279 case BFD_RELOC_ARM_ALU_PC_G0:
30280 case BFD_RELOC_ARM_ALU_PC_G1_NC:
30281 case BFD_RELOC_ARM_ALU_PC_G1:
30282 case BFD_RELOC_ARM_ALU_PC_G2:
30283 case BFD_RELOC_ARM_LDR_PC_G0:
30284 case BFD_RELOC_ARM_LDR_PC_G1:
30285 case BFD_RELOC_ARM_LDR_PC_G2:
30286 case BFD_RELOC_ARM_LDRS_PC_G0:
30287 case BFD_RELOC_ARM_LDRS_PC_G1:
30288 case BFD_RELOC_ARM_LDRS_PC_G2:
30289 case BFD_RELOC_ARM_LDC_PC_G0:
30290 case BFD_RELOC_ARM_LDC_PC_G1:
30291 case BFD_RELOC_ARM_LDC_PC_G2:
30292 case BFD_RELOC_ARM_ALU_SB_G0_NC:
30293 case BFD_RELOC_ARM_ALU_SB_G0:
30294 case BFD_RELOC_ARM_ALU_SB_G1_NC:
30295 case BFD_RELOC_ARM_ALU_SB_G1:
30296 case BFD_RELOC_ARM_ALU_SB_G2:
30297 case BFD_RELOC_ARM_LDR_SB_G0:
30298 case BFD_RELOC_ARM_LDR_SB_G1:
30299 case BFD_RELOC_ARM_LDR_SB_G2:
30300 case BFD_RELOC_ARM_LDRS_SB_G0:
30301 case BFD_RELOC_ARM_LDRS_SB_G1:
30302 case BFD_RELOC_ARM_LDRS_SB_G2:
30303 case BFD_RELOC_ARM_LDC_SB_G0:
30304 case BFD_RELOC_ARM_LDC_SB_G1:
30305 case BFD_RELOC_ARM_LDC_SB_G2:
845b51d6 30306 case BFD_RELOC_ARM_V4BX:
72d98d16
MG
30307 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
30308 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
30309 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
30310 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
188fd7ae
CL
30311 case BFD_RELOC_ARM_GOTFUNCDESC:
30312 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
30313 case BFD_RELOC_ARM_FUNCDESC:
e5d6e09e 30314 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 30315 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 30316 case BFD_RELOC_ARM_THUMB_BF13:
c19d1205
ZW
30317 code = fixp->fx_r_type;
30318 break;
a737bd4d 30319
0855e32b 30320 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205 30321 case BFD_RELOC_ARM_TLS_GD32:
5c5a4843 30322 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
75c11999 30323 case BFD_RELOC_ARM_TLS_LE32:
c19d1205 30324 case BFD_RELOC_ARM_TLS_IE32:
5c5a4843 30325 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
c19d1205 30326 case BFD_RELOC_ARM_TLS_LDM32:
5c5a4843 30327 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
c19d1205
ZW
30328 /* BFD will include the symbol's address in the addend.
30329 But we don't want that, so subtract it out again here. */
30330 if (!S_IS_COMMON (fixp->fx_addsy))
30331 reloc->addend -= (*reloc->sym_ptr_ptr)->value;
30332 code = fixp->fx_r_type;
30333 break;
30334#endif
a737bd4d 30335
c19d1205
ZW
30336 case BFD_RELOC_ARM_IMMEDIATE:
30337 as_bad_where (fixp->fx_file, fixp->fx_line,
30338 _("internal relocation (type: IMMEDIATE) not fixed up"));
30339 return NULL;
a737bd4d 30340
c19d1205
ZW
30341 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
30342 as_bad_where (fixp->fx_file, fixp->fx_line,
30343 _("ADRL used for a symbol not defined in the same file"));
30344 return NULL;
a737bd4d 30345
e12437dc 30346 case BFD_RELOC_THUMB_PCREL_BRANCH5:
f6b2b12d 30347 case BFD_RELOC_THUMB_PCREL_BFCSEL:
60f993ce 30348 case BFD_RELOC_ARM_THUMB_LOOP12:
e12437dc
AV
30349 as_bad_where (fixp->fx_file, fixp->fx_line,
30350 _("%s used for a symbol not defined in the same file"),
30351 bfd_get_reloc_code_name (fixp->fx_r_type));
30352 return NULL;
30353
c19d1205 30354 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
30355 if (section->use_rela_p)
30356 {
30357 code = fixp->fx_r_type;
30358 break;
30359 }
30360
c19d1205
ZW
30361 if (fixp->fx_addsy != NULL
30362 && !S_IS_DEFINED (fixp->fx_addsy)
30363 && S_IS_LOCAL (fixp->fx_addsy))
a737bd4d 30364 {
c19d1205
ZW
30365 as_bad_where (fixp->fx_file, fixp->fx_line,
30366 _("undefined local label `%s'"),
30367 S_GET_NAME (fixp->fx_addsy));
30368 return NULL;
a737bd4d
NC
30369 }
30370
c19d1205
ZW
30371 as_bad_where (fixp->fx_file, fixp->fx_line,
30372 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
30373 return NULL;
a737bd4d 30374
c19d1205
ZW
30375 default:
30376 {
e0471c16 30377 const char * type;
6c43fab6 30378
c19d1205
ZW
30379 switch (fixp->fx_r_type)
30380 {
30381 case BFD_RELOC_NONE: type = "NONE"; break;
30382 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
30383 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
3eb17e6b 30384 case BFD_RELOC_ARM_SMC: type = "SMC"; break;
c19d1205
ZW
30385 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
30386 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
30387 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
db187cb9 30388 case BFD_RELOC_ARM_T32_OFFSET_IMM: type = "T32_OFFSET_IMM"; break;
8f06b2d8 30389 case BFD_RELOC_ARM_T32_CP_OFF_IMM: type = "T32_CP_OFF_IMM"; break;
c19d1205
ZW
30390 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
30391 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
30392 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
30393 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
30394 default: type = _("<unknown>"); break;
30395 }
30396 as_bad_where (fixp->fx_file, fixp->fx_line,
30397 _("cannot represent %s relocation in this object file format"),
30398 type);
30399 return NULL;
30400 }
a737bd4d 30401 }
6c43fab6 30402
c19d1205
ZW
30403#ifdef OBJ_ELF
30404 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
30405 && GOT_symbol
30406 && fixp->fx_addsy == GOT_symbol)
30407 {
30408 code = BFD_RELOC_ARM_GOTPC;
30409 reloc->addend = fixp->fx_offset = reloc->address;
30410 }
30411#endif
6c43fab6 30412
c19d1205 30413 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6c43fab6 30414
c19d1205
ZW
30415 if (reloc->howto == NULL)
30416 {
30417 as_bad_where (fixp->fx_file, fixp->fx_line,
30418 _("cannot represent %s relocation in this object file format"),
30419 bfd_get_reloc_code_name (code));
30420 return NULL;
30421 }
6c43fab6 30422
c19d1205
ZW
30423 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
30424 vtable entry to be used in the relocation's section offset. */
30425 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
30426 reloc->address = fixp->fx_offset;
6c43fab6 30427
c19d1205 30428 return reloc;
6c43fab6
RE
30429}
30430
c19d1205 30431/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6c43fab6 30432
c19d1205
ZW
30433void
30434cons_fix_new_arm (fragS * frag,
30435 int where,
30436 int size,
62ebcb5c
AM
30437 expressionS * exp,
30438 bfd_reloc_code_real_type reloc)
6c43fab6 30439{
c19d1205 30440 int pcrel = 0;
6c43fab6 30441
c19d1205
ZW
30442 /* Pick a reloc.
30443 FIXME: @@ Should look at CPU word size. */
30444 switch (size)
30445 {
30446 case 1:
62ebcb5c 30447 reloc = BFD_RELOC_8;
c19d1205
ZW
30448 break;
30449 case 2:
62ebcb5c 30450 reloc = BFD_RELOC_16;
c19d1205
ZW
30451 break;
30452 case 4:
30453 default:
62ebcb5c 30454 reloc = BFD_RELOC_32;
c19d1205
ZW
30455 break;
30456 case 8:
62ebcb5c 30457 reloc = BFD_RELOC_64;
c19d1205
ZW
30458 break;
30459 }
6c43fab6 30460
f0927246
NC
30461#ifdef TE_PE
30462 if (exp->X_op == O_secrel)
30463 {
30464 exp->X_op = O_symbol;
62ebcb5c 30465 reloc = BFD_RELOC_32_SECREL;
f0927246
NC
30466 }
30467#endif
30468
62ebcb5c 30469 fix_new_exp (frag, where, size, exp, pcrel, reloc);
c19d1205 30470}
6c43fab6 30471
4343666d 30472#if defined (OBJ_COFF)
c19d1205
ZW
30473void
30474arm_validate_fix (fixS * fixP)
6c43fab6 30475{
c19d1205
ZW
30476 /* If the destination of the branch is a defined symbol which does not have
30477 the THUMB_FUNC attribute, then we must be calling a function which has
30478 the (interfacearm) attribute. We look for the Thumb entry point to that
30479 function and change the branch to refer to that function instead. */
30480 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
30481 && fixP->fx_addsy != NULL
30482 && S_IS_DEFINED (fixP->fx_addsy)
30483 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6c43fab6 30484 {
c19d1205 30485 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6c43fab6 30486 }
c19d1205
ZW
30487}
30488#endif
6c43fab6 30489
267bf995 30490
c19d1205
ZW
30491int
30492arm_force_relocation (struct fix * fixp)
30493{
30494#if defined (OBJ_COFF) && defined (TE_PE)
30495 if (fixp->fx_r_type == BFD_RELOC_RVA)
30496 return 1;
30497#endif
6c43fab6 30498
267bf995
RR
30499 /* In case we have a call or a branch to a function in ARM ISA mode from
30500 a thumb function or vice-versa force the relocation. These relocations
30501 are cleared off for some cores that might have blx and simple transformations
30502 are possible. */
30503
30504#ifdef OBJ_ELF
30505 switch (fixp->fx_r_type)
30506 {
30507 case BFD_RELOC_ARM_PCREL_JUMP:
30508 case BFD_RELOC_ARM_PCREL_CALL:
30509 case BFD_RELOC_THUMB_PCREL_BLX:
30510 if (THUMB_IS_FUNC (fixp->fx_addsy))
30511 return 1;
30512 break;
30513
30514 case BFD_RELOC_ARM_PCREL_BLX:
30515 case BFD_RELOC_THUMB_PCREL_BRANCH25:
30516 case BFD_RELOC_THUMB_PCREL_BRANCH20:
30517 case BFD_RELOC_THUMB_PCREL_BRANCH23:
30518 if (ARM_IS_FUNC (fixp->fx_addsy))
30519 return 1;
30520 break;
30521
30522 default:
30523 break;
30524 }
30525#endif
30526
b5884301
PB
30527 /* Resolve these relocations even if the symbol is extern or weak.
30528 Technically this is probably wrong due to symbol preemption.
30529 In practice these relocations do not have enough range to be useful
30530 at dynamic link time, and some code (e.g. in the Linux kernel)
30531 expects these references to be resolved. */
c19d1205
ZW
30532 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
30533 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
b5884301 30534 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM8
0110f2b8 30535 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
b5884301
PB
30536 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
30537 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2
30538 || fixp->fx_r_type == BFD_RELOC_ARM_THUMB_OFFSET
b59d128a 30539 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH12
16805f35 30540 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
0110f2b8
PB
30541 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
30542 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
b5884301
PB
30543 || fixp->fx_r_type == BFD_RELOC_ARM_T32_OFFSET_IMM
30544 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12
30545 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM
30546 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM_S2)
c19d1205 30547 return 0;
a737bd4d 30548
4962c51a
MS
30549 /* Always leave these relocations for the linker. */
30550 if ((fixp->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
30551 && fixp->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
30552 || fixp->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
30553 return 1;
30554
f0291e4c
PB
30555 /* Always generate relocations against function symbols. */
30556 if (fixp->fx_r_type == BFD_RELOC_32
30557 && fixp->fx_addsy
30558 && (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION))
30559 return 1;
30560
c19d1205 30561 return generic_force_reloc (fixp);
404ff6b5
AH
30562}
30563
0ffdc86c 30564#if defined (OBJ_ELF) || defined (OBJ_COFF)
e28387c3
PB
30565/* Relocations against function names must be left unadjusted,
30566 so that the linker can use this information to generate interworking
30567 stubs. The MIPS version of this function
c19d1205
ZW
30568 also prevents relocations that are mips-16 specific, but I do not
30569 know why it does this.
404ff6b5 30570
c19d1205
ZW
30571 FIXME:
30572 There is one other problem that ought to be addressed here, but
30573 which currently is not: Taking the address of a label (rather
30574 than a function) and then later jumping to that address. Such
30575 addresses also ought to have their bottom bit set (assuming that
30576 they reside in Thumb code), but at the moment they will not. */
404ff6b5 30577
5b7c81bd 30578bool
c19d1205 30579arm_fix_adjustable (fixS * fixP)
404ff6b5 30580{
c19d1205
ZW
30581 if (fixP->fx_addsy == NULL)
30582 return 1;
404ff6b5 30583
e28387c3
PB
30584 /* Preserve relocations against symbols with function type. */
30585 if (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION)
5b7c81bd 30586 return false;
e28387c3 30587
c19d1205
ZW
30588 if (THUMB_IS_FUNC (fixP->fx_addsy)
30589 && fixP->fx_subsy == NULL)
5b7c81bd 30590 return false;
a737bd4d 30591
c19d1205
ZW
30592 /* We need the symbol name for the VTABLE entries. */
30593 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
30594 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5b7c81bd 30595 return false;
404ff6b5 30596
c19d1205
ZW
30597 /* Don't allow symbols to be discarded on GOT related relocs. */
30598 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
30599 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
30600 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
30601 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
5c5a4843 30602 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32_FDPIC
c19d1205
ZW
30603 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
30604 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
5c5a4843 30605 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32_FDPIC
c19d1205 30606 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
5c5a4843 30607 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32_FDPIC
c19d1205 30608 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
0855e32b
NS
30609 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GOTDESC
30610 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
30611 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_CALL
30612 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
30613 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_DESCSEQ
c19d1205 30614 || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
5b7c81bd 30615 return false;
a737bd4d 30616
4962c51a
MS
30617 /* Similarly for group relocations. */
30618 if ((fixP->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
30619 && fixP->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
30620 || fixP->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
5b7c81bd 30621 return false;
4962c51a 30622
79947c54
CD
30623 /* MOVW/MOVT REL relocations have limited offsets, so keep the symbols. */
30624 if (fixP->fx_r_type == BFD_RELOC_ARM_MOVW
30625 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT
30626 || fixP->fx_r_type == BFD_RELOC_ARM_MOVW_PCREL
30627 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT_PCREL
30628 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
30629 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT
30630 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW_PCREL
30631 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
5b7c81bd 30632 return false;
79947c54 30633
72d98d16
MG
30634 /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
30635 offsets, so keep these symbols. */
30636 if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
30637 && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
5b7c81bd 30638 return false;
72d98d16 30639
5b7c81bd 30640 return true;
a737bd4d 30641}
0ffdc86c
NC
30642#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
30643
30644#ifdef OBJ_ELF
c19d1205
ZW
30645const char *
30646elf32_arm_target_format (void)
404ff6b5 30647{
a57d1773 30648#if defined (TE_VXWORKS)
c19d1205
ZW
30649 return (target_big_endian
30650 ? "elf32-bigarm-vxworks"
30651 : "elf32-littlearm-vxworks");
b38cadfb
NC
30652#elif defined (TE_NACL)
30653 return (target_big_endian
30654 ? "elf32-bigarm-nacl"
30655 : "elf32-littlearm-nacl");
c19d1205 30656#else
18a20338
CL
30657 if (arm_fdpic)
30658 {
30659 if (target_big_endian)
30660 return "elf32-bigarm-fdpic";
30661 else
30662 return "elf32-littlearm-fdpic";
30663 }
c19d1205 30664 else
18a20338
CL
30665 {
30666 if (target_big_endian)
30667 return "elf32-bigarm";
30668 else
30669 return "elf32-littlearm";
30670 }
c19d1205 30671#endif
404ff6b5
AH
30672}
30673
c19d1205
ZW
30674void
30675armelf_frob_symbol (symbolS * symp,
30676 int * puntp)
404ff6b5 30677{
c19d1205
ZW
30678 elf_frob_symbol (symp, puntp);
30679}
30680#endif
404ff6b5 30681
c19d1205 30682/* MD interface: Finalization. */
a737bd4d 30683
c19d1205
ZW
30684void
30685arm_cleanup (void)
30686{
30687 literal_pool * pool;
a737bd4d 30688
5ee91343
AV
30689 /* Ensure that all the predication blocks are properly closed. */
30690 check_pred_blocks_finished ();
e07e6e58 30691
c19d1205
ZW
30692 for (pool = list_of_pools; pool; pool = pool->next)
30693 {
5f4273c7 30694 /* Put it at the end of the relevant section. */
c19d1205
ZW
30695 subseg_set (pool->section, pool->sub_section);
30696#ifdef OBJ_ELF
30697 arm_elf_change_section ();
30698#endif
30699 s_ltorg (0);
30700 }
404ff6b5
AH
30701}
30702
cd000bff
DJ
30703#ifdef OBJ_ELF
30704/* Remove any excess mapping symbols generated for alignment frags in
30705 SEC. We may have created a mapping symbol before a zero byte
30706 alignment; remove it if there's a mapping symbol after the
30707 alignment. */
30708static void
30709check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
30710 void *dummy ATTRIBUTE_UNUSED)
30711{
30712 segment_info_type *seginfo = seg_info (sec);
30713 fragS *fragp;
30714
30715 if (seginfo == NULL || seginfo->frchainP == NULL)
30716 return;
30717
30718 for (fragp = seginfo->frchainP->frch_root;
30719 fragp != NULL;
30720 fragp = fragp->fr_next)
30721 {
30722 symbolS *sym = fragp->tc_frag_data.last_map;
30723 fragS *next = fragp->fr_next;
30724
30725 /* Variable-sized frags have been converted to fixed size by
30726 this point. But if this was variable-sized to start with,
30727 there will be a fixed-size frag after it. So don't handle
30728 next == NULL. */
30729 if (sym == NULL || next == NULL)
30730 continue;
30731
30732 if (S_GET_VALUE (sym) < next->fr_address)
30733 /* Not at the end of this frag. */
30734 continue;
30735 know (S_GET_VALUE (sym) == next->fr_address);
30736
30737 do
30738 {
30739 if (next->tc_frag_data.first_map != NULL)
30740 {
30741 /* Next frag starts with a mapping symbol. Discard this
30742 one. */
30743 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
30744 break;
30745 }
30746
30747 if (next->fr_next == NULL)
30748 {
30749 /* This mapping symbol is at the end of the section. Discard
30750 it. */
30751 know (next->fr_fix == 0 && next->fr_var == 0);
30752 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
30753 break;
30754 }
30755
30756 /* As long as we have empty frags without any mapping symbols,
30757 keep looking. */
30758 /* If the next frag is non-empty and does not start with a
30759 mapping symbol, then this mapping symbol is required. */
30760 if (next->fr_address != next->fr_next->fr_address)
30761 break;
30762
30763 next = next->fr_next;
30764 }
30765 while (next != NULL);
30766 }
30767}
30768#endif
30769
c19d1205
ZW
30770/* Adjust the symbol table. This marks Thumb symbols as distinct from
30771 ARM ones. */
404ff6b5 30772
c19d1205
ZW
30773void
30774arm_adjust_symtab (void)
404ff6b5 30775{
c19d1205
ZW
30776#ifdef OBJ_COFF
30777 symbolS * sym;
404ff6b5 30778
c19d1205
ZW
30779 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
30780 {
30781 if (ARM_IS_THUMB (sym))
30782 {
30783 if (THUMB_IS_FUNC (sym))
30784 {
30785 /* Mark the symbol as a Thumb function. */
30786 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
30787 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
30788 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
404ff6b5 30789
c19d1205
ZW
30790 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
30791 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
30792 else
30793 as_bad (_("%s: unexpected function type: %d"),
30794 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
30795 }
30796 else switch (S_GET_STORAGE_CLASS (sym))
30797 {
30798 case C_EXT:
30799 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
30800 break;
30801 case C_STAT:
30802 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
30803 break;
30804 case C_LABEL:
30805 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
30806 break;
30807 default:
30808 /* Do nothing. */
30809 break;
30810 }
30811 }
a737bd4d 30812
c19d1205
ZW
30813 if (ARM_IS_INTERWORK (sym))
30814 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
404ff6b5 30815 }
c19d1205
ZW
30816#endif
30817#ifdef OBJ_ELF
30818 symbolS * sym;
30819 char bind;
404ff6b5 30820
c19d1205 30821 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
404ff6b5 30822 {
c19d1205
ZW
30823 if (ARM_IS_THUMB (sym))
30824 {
30825 elf_symbol_type * elf_sym;
404ff6b5 30826
c19d1205
ZW
30827 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
30828 bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
404ff6b5 30829
b0796911
PB
30830 if (! bfd_is_arm_special_symbol_name (elf_sym->symbol.name,
30831 BFD_ARM_SPECIAL_SYM_TYPE_ANY))
c19d1205
ZW
30832 {
30833 /* If it's a .thumb_func, declare it as so,
30834 otherwise tag label as .code 16. */
30835 if (THUMB_IS_FUNC (sym))
39d911fc
TP
30836 ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
30837 ST_BRANCH_TO_THUMB);
3ba67470 30838 else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
c19d1205
ZW
30839 elf_sym->internal_elf_sym.st_info =
30840 ELF_ST_INFO (bind, STT_ARM_16BIT);
30841 }
30842 }
30843 }
cd000bff
DJ
30844
30845 /* Remove any overlapping mapping symbols generated by alignment frags. */
30846 bfd_map_over_sections (stdoutput, check_mapping_symbols, (char *) 0);
709001e9
MM
30847 /* Now do generic ELF adjustments. */
30848 elf_adjust_symtab ();
c19d1205 30849#endif
404ff6b5
AH
30850}
30851
c19d1205 30852/* MD interface: Initialization. */
404ff6b5 30853
a737bd4d 30854static void
c19d1205 30855set_constant_flonums (void)
a737bd4d 30856{
c19d1205 30857 int i;
404ff6b5 30858
c19d1205
ZW
30859 for (i = 0; i < NUM_FLOAT_VALS; i++)
30860 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
30861 abort ();
a737bd4d 30862}
404ff6b5 30863
3e9e4fcf
JB
30864/* Auto-select Thumb mode if it's the only available instruction set for the
30865 given architecture. */
30866
30867static void
30868autoselect_thumb_from_cpu_variant (void)
30869{
30870 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
30871 opcode_select (16);
30872}
30873
c19d1205
ZW
30874void
30875md_begin (void)
a737bd4d 30876{
c19d1205
ZW
30877 unsigned mach;
30878 unsigned int i;
404ff6b5 30879
f16c3d4f
AM
30880 arm_ops_hsh = str_htab_create ();
30881 arm_cond_hsh = str_htab_create ();
30882 arm_vcond_hsh = str_htab_create ();
30883 arm_shift_hsh = str_htab_create ();
30884 arm_psr_hsh = str_htab_create ();
30885 arm_v7m_psr_hsh = str_htab_create ();
30886 arm_reg_hsh = str_htab_create ();
30887 arm_reloc_hsh = str_htab_create ();
30888 arm_barrier_opt_hsh = str_htab_create ();
c19d1205
ZW
30889
30890 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
629310ab 30891 if (str_hash_find (arm_ops_hsh, insns[i].template_name) == NULL)
fe0e921f 30892 str_hash_insert (arm_ops_hsh, insns[i].template_name, insns + i, 0);
c19d1205 30893 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
fe0e921f 30894 str_hash_insert (arm_cond_hsh, conds[i].template_name, conds + i, 0);
5ee91343 30895 for (i = 0; i < sizeof (vconds) / sizeof (struct asm_cond); i++)
fe0e921f 30896 str_hash_insert (arm_vcond_hsh, vconds[i].template_name, vconds + i, 0);
c19d1205 30897 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
fe0e921f 30898 str_hash_insert (arm_shift_hsh, shift_names[i].name, shift_names + i, 0);
c19d1205 30899 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
fe0e921f 30900 str_hash_insert (arm_psr_hsh, psrs[i].template_name, psrs + i, 0);
62b3e311 30901 for (i = 0; i < sizeof (v7m_psrs) / sizeof (struct asm_psr); i++)
629310ab 30902 str_hash_insert (arm_v7m_psr_hsh, v7m_psrs[i].template_name,
fe0e921f 30903 v7m_psrs + i, 0);
c19d1205 30904 for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
fe0e921f 30905 str_hash_insert (arm_reg_hsh, reg_names[i].name, reg_names + i, 0);
62b3e311
PB
30906 for (i = 0;
30907 i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
30908 i++)
629310ab 30909 str_hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
fe0e921f 30910 barrier_opt_names + i, 0);
c19d1205 30911#ifdef OBJ_ELF
3da1d841
NC
30912 for (i = 0; i < ARRAY_SIZE (reloc_names); i++)
30913 {
30914 struct reloc_entry * entry = reloc_names + i;
30915
30916 if (arm_is_eabi() && entry->reloc == BFD_RELOC_ARM_PLT32)
30917 /* This makes encode_branch() use the EABI versions of this relocation. */
30918 entry->reloc = BFD_RELOC_UNUSED;
30919
fe0e921f 30920 str_hash_insert (arm_reloc_hsh, entry->name, entry, 0);
3da1d841 30921 }
c19d1205
ZW
30922#endif
30923
30924 set_constant_flonums ();
404ff6b5 30925
c19d1205
ZW
30926 /* Set the cpu variant based on the command-line options. We prefer
30927 -mcpu= over -march= if both are set (as for GCC); and we prefer
30928 -mfpu= over any other way of setting the floating point unit.
30929 Use of legacy options with new options are faulted. */
e74cfd16 30930 if (legacy_cpu)
404ff6b5 30931 {
e74cfd16 30932 if (mcpu_cpu_opt || march_cpu_opt)
c19d1205
ZW
30933 as_bad (_("use of old and new-style options to set CPU type"));
30934
4d354d8b 30935 selected_arch = *legacy_cpu;
404ff6b5 30936 }
4d354d8b
TP
30937 else if (mcpu_cpu_opt)
30938 {
30939 selected_arch = *mcpu_cpu_opt;
30940 selected_ext = *mcpu_ext_opt;
30941 }
30942 else if (march_cpu_opt)
c168ce07 30943 {
4d354d8b
TP
30944 selected_arch = *march_cpu_opt;
30945 selected_ext = *march_ext_opt;
c168ce07 30946 }
4d354d8b 30947 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
404ff6b5 30948
e74cfd16 30949 if (legacy_fpu)
c19d1205 30950 {
e74cfd16 30951 if (mfpu_opt)
c19d1205 30952 as_bad (_("use of old and new-style options to set FPU type"));
03b1477f 30953
4d354d8b 30954 selected_fpu = *legacy_fpu;
03b1477f 30955 }
4d354d8b
TP
30956 else if (mfpu_opt)
30957 selected_fpu = *mfpu_opt;
30958 else
03b1477f 30959 {
45eb4c1b
NS
30960#if !(defined (EABI_DEFAULT) || defined (TE_LINUX) \
30961 || defined (TE_NetBSD) || defined (TE_VXWORKS))
39c2da32
RE
30962 /* Some environments specify a default FPU. If they don't, infer it
30963 from the processor. */
e74cfd16 30964 if (mcpu_fpu_opt)
4d354d8b 30965 selected_fpu = *mcpu_fpu_opt;
e7da50fa 30966 else if (march_fpu_opt)
4d354d8b 30967 selected_fpu = *march_fpu_opt;
39c2da32 30968#else
4d354d8b 30969 selected_fpu = fpu_default;
39c2da32 30970#endif
03b1477f
RE
30971 }
30972
4d354d8b 30973 if (ARM_FEATURE_ZERO (selected_fpu))
03b1477f 30974 {
4d354d8b
TP
30975 if (!no_cpu_selected ())
30976 selected_fpu = fpu_default;
03b1477f 30977 else
4d354d8b 30978 selected_fpu = fpu_arch_fpa;
03b1477f
RE
30979 }
30980
ee065d83 30981#ifdef CPU_DEFAULT
4d354d8b 30982 if (ARM_FEATURE_ZERO (selected_arch))
ee065d83 30983 {
4d354d8b
TP
30984 selected_arch = cpu_default;
30985 selected_cpu = selected_arch;
ee065d83 30986 }
4d354d8b 30987 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
e74cfd16 30988#else
4d354d8b
TP
30989 /* Autodection of feature mode: allow all features in cpu_variant but leave
30990 selected_cpu unset. It will be set in aeabi_set_public_attributes ()
30991 after all instruction have been processed and we can decide what CPU
30992 should be selected. */
30993 if (ARM_FEATURE_ZERO (selected_arch))
30994 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
ee065d83 30995 else
4d354d8b 30996 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 30997#endif
03b1477f 30998
3e9e4fcf
JB
30999 autoselect_thumb_from_cpu_variant ();
31000
e74cfd16 31001 arm_arch_used = thumb_arch_used = arm_arch_none;
ee065d83 31002
f17c130b 31003#if defined OBJ_COFF || defined OBJ_ELF
b99bd4ef 31004 {
7cc69913
NC
31005 unsigned int flags = 0;
31006
31007#if defined OBJ_ELF
31008 flags = meabi_flags;
d507cf36
PB
31009
31010 switch (meabi_flags)
33a392fb 31011 {
d507cf36 31012 case EF_ARM_EABI_UNKNOWN:
7cc69913 31013#endif
d507cf36
PB
31014 /* Set the flags in the private structure. */
31015 if (uses_apcs_26) flags |= F_APCS26;
31016 if (support_interwork) flags |= F_INTERWORK;
31017 if (uses_apcs_float) flags |= F_APCS_FLOAT;
c19d1205 31018 if (pic_code) flags |= F_PIC;
e74cfd16 31019 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_any_hard))
7cc69913
NC
31020 flags |= F_SOFT_FLOAT;
31021
d507cf36
PB
31022 switch (mfloat_abi_opt)
31023 {
31024 case ARM_FLOAT_ABI_SOFT:
31025 case ARM_FLOAT_ABI_SOFTFP:
31026 flags |= F_SOFT_FLOAT;
31027 break;
33a392fb 31028
d507cf36
PB
31029 case ARM_FLOAT_ABI_HARD:
31030 if (flags & F_SOFT_FLOAT)
31031 as_bad (_("hard-float conflicts with specified fpu"));
31032 break;
31033 }
03b1477f 31034
e74cfd16
PB
31035 /* Using pure-endian doubles (even if soft-float). */
31036 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
7cc69913 31037 flags |= F_VFP_FLOAT;
f17c130b 31038
fde78edd 31039#if defined OBJ_ELF
e74cfd16 31040 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_maverick))
d507cf36 31041 flags |= EF_ARM_MAVERICK_FLOAT;
d507cf36
PB
31042 break;
31043
8cb51566 31044 case EF_ARM_EABI_VER4:
3a4a14e9 31045 case EF_ARM_EABI_VER5:
c19d1205 31046 /* No additional flags to set. */
d507cf36
PB
31047 break;
31048
31049 default:
31050 abort ();
31051 }
7cc69913 31052#endif
b99bd4ef
NC
31053 bfd_set_private_flags (stdoutput, flags);
31054
31055 /* We have run out flags in the COFF header to encode the
31056 status of ATPCS support, so instead we create a dummy,
c19d1205 31057 empty, debug section called .arm.atpcs. */
b99bd4ef
NC
31058 if (atpcs)
31059 {
31060 asection * sec;
31061
31062 sec = bfd_make_section (stdoutput, ".arm.atpcs");
31063
31064 if (sec != NULL)
31065 {
fd361982
AM
31066 bfd_set_section_flags (sec, SEC_READONLY | SEC_DEBUGGING);
31067 bfd_set_section_size (sec, 0);
b99bd4ef
NC
31068 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
31069 }
31070 }
7cc69913 31071 }
f17c130b 31072#endif
b99bd4ef
NC
31073
31074 /* Record the CPU type as well. */
2d447fca
JM
31075 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
31076 mach = bfd_mach_arm_iWMMXt2;
31077 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
e16bb312 31078 mach = bfd_mach_arm_iWMMXt;
e74cfd16 31079 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
b99bd4ef 31080 mach = bfd_mach_arm_XScale;
e74cfd16 31081 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick))
fde78edd 31082 mach = bfd_mach_arm_ep9312;
e74cfd16 31083 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5e))
b99bd4ef 31084 mach = bfd_mach_arm_5TE;
e74cfd16 31085 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5))
b99bd4ef 31086 {
e74cfd16 31087 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
31088 mach = bfd_mach_arm_5T;
31089 else
31090 mach = bfd_mach_arm_5;
31091 }
e74cfd16 31092 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4))
b99bd4ef 31093 {
e74cfd16 31094 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
31095 mach = bfd_mach_arm_4T;
31096 else
31097 mach = bfd_mach_arm_4;
31098 }
e74cfd16 31099 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3m))
b99bd4ef 31100 mach = bfd_mach_arm_3M;
e74cfd16
PB
31101 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3))
31102 mach = bfd_mach_arm_3;
31103 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2s))
31104 mach = bfd_mach_arm_2a;
31105 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2))
31106 mach = bfd_mach_arm_2;
31107 else
31108 mach = bfd_mach_arm_unknown;
b99bd4ef
NC
31109
31110 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
31111}
31112
c19d1205 31113/* Command line processing. */
b99bd4ef 31114
c19d1205
ZW
31115/* md_parse_option
31116 Invocation line includes a switch not recognized by the base assembler.
31117 See if it's a processor-specific option.
b99bd4ef 31118
c19d1205
ZW
31119 This routine is somewhat complicated by the need for backwards
31120 compatibility (since older releases of gcc can't be changed).
31121 The new options try to make the interface as compatible as
31122 possible with GCC.
b99bd4ef 31123
c19d1205 31124 New options (supported) are:
b99bd4ef 31125
c19d1205
ZW
31126 -mcpu=<cpu name> Assemble for selected processor
31127 -march=<architecture name> Assemble for selected architecture
31128 -mfpu=<fpu architecture> Assemble for selected FPU.
31129 -EB/-mbig-endian Big-endian
31130 -EL/-mlittle-endian Little-endian
31131 -k Generate PIC code
31132 -mthumb Start in Thumb mode
31133 -mthumb-interwork Code supports ARM/Thumb interworking
b99bd4ef 31134
278df34e 31135 -m[no-]warn-deprecated Warn about deprecated features
8b2d793c 31136 -m[no-]warn-syms Warn when symbols match instructions
267bf995 31137
c19d1205 31138 For now we will also provide support for:
b99bd4ef 31139
c19d1205
ZW
31140 -mapcs-32 32-bit Program counter
31141 -mapcs-26 26-bit Program counter
31142 -macps-float Floats passed in FP registers
31143 -mapcs-reentrant Reentrant code
31144 -matpcs
31145 (sometime these will probably be replaced with -mapcs=<list of options>
31146 and -matpcs=<list of options>)
b99bd4ef 31147
c19d1205
ZW
31148 The remaining options are only supported for back-wards compatibility.
31149 Cpu variants, the arm part is optional:
31150 -m[arm]1 Currently not supported.
31151 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
31152 -m[arm]3 Arm 3 processor
31153 -m[arm]6[xx], Arm 6 processors
31154 -m[arm]7[xx][t][[d]m] Arm 7 processors
31155 -m[arm]8[10] Arm 8 processors
31156 -m[arm]9[20][tdmi] Arm 9 processors
31157 -mstrongarm[110[0]] StrongARM processors
31158 -mxscale XScale processors
31159 -m[arm]v[2345[t[e]]] Arm architectures
31160 -mall All (except the ARM1)
31161 FP variants:
31162 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
31163 -mfpe-old (No float load/store multiples)
31164 -mvfpxd VFP Single precision
31165 -mvfp All VFP
31166 -mno-fpu Disable all floating point instructions
b99bd4ef 31167
c19d1205
ZW
31168 The following CPU names are recognized:
31169 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
31170 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
31171 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
31172 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
31173 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
31174 arm10t arm10e, arm1020t, arm1020e, arm10200e,
31175 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
b99bd4ef 31176
c19d1205 31177 */
b99bd4ef 31178
c19d1205 31179const char * md_shortopts = "m:k";
b99bd4ef 31180
c19d1205
ZW
31181#ifdef ARM_BI_ENDIAN
31182#define OPTION_EB (OPTION_MD_BASE + 0)
31183#define OPTION_EL (OPTION_MD_BASE + 1)
b99bd4ef 31184#else
c19d1205
ZW
31185#if TARGET_BYTES_BIG_ENDIAN
31186#define OPTION_EB (OPTION_MD_BASE + 0)
b99bd4ef 31187#else
c19d1205
ZW
31188#define OPTION_EL (OPTION_MD_BASE + 1)
31189#endif
b99bd4ef 31190#endif
845b51d6 31191#define OPTION_FIX_V4BX (OPTION_MD_BASE + 2)
18a20338 31192#define OPTION_FDPIC (OPTION_MD_BASE + 3)
b99bd4ef 31193
c19d1205 31194struct option md_longopts[] =
b99bd4ef 31195{
c19d1205
ZW
31196#ifdef OPTION_EB
31197 {"EB", no_argument, NULL, OPTION_EB},
31198#endif
31199#ifdef OPTION_EL
31200 {"EL", no_argument, NULL, OPTION_EL},
b99bd4ef 31201#endif
845b51d6 31202 {"fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
18a20338
CL
31203#ifdef OBJ_ELF
31204 {"fdpic", no_argument, NULL, OPTION_FDPIC},
31205#endif
c19d1205
ZW
31206 {NULL, no_argument, NULL, 0}
31207};
b99bd4ef 31208
c19d1205 31209size_t md_longopts_size = sizeof (md_longopts);
b99bd4ef 31210
c19d1205 31211struct arm_option_table
b99bd4ef 31212{
0198d5e6
TC
31213 const char * option; /* Option name to match. */
31214 const char * help; /* Help information. */
31215 int * var; /* Variable to change. */
31216 int value; /* What to change it to. */
31217 const char * deprecated; /* If non-null, print this message. */
c19d1205 31218};
b99bd4ef 31219
c19d1205
ZW
31220struct arm_option_table arm_opts[] =
31221{
31222 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
31223 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
31224 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
31225 &support_interwork, 1, NULL},
31226 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
31227 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
31228 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
31229 1, NULL},
31230 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
31231 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
31232 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
31233 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
31234 NULL},
b99bd4ef 31235
c19d1205
ZW
31236 /* These are recognized by the assembler, but have no affect on code. */
31237 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
31238 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
278df34e
NS
31239
31240 {"mwarn-deprecated", NULL, &warn_on_deprecated, 1, NULL},
31241 {"mno-warn-deprecated", N_("do not warn on use of deprecated feature"),
31242 &warn_on_deprecated, 0, NULL},
24f19ccb
AV
31243
31244 {"mwarn-restrict-it", N_("warn about performance deprecated IT instructions"
31245 " in ARMv8-A and ARMv8-R"), &warn_on_restrict_it, 1, NULL},
31246 {"mno-warn-restrict-it", NULL, &warn_on_restrict_it, 0, NULL},
31247
5b7c81bd
AM
31248 {"mwarn-syms", N_("warn about symbols that match instruction names [default]"), (int *) (& flag_warn_syms), true, NULL},
31249 {"mno-warn-syms", N_("disable warnings about symobls that match instructions"), (int *) (& flag_warn_syms), false, NULL},
e74cfd16
PB
31250 {NULL, NULL, NULL, 0, NULL}
31251};
31252
31253struct arm_legacy_option_table
31254{
0198d5e6
TC
31255 const char * option; /* Option name to match. */
31256 const arm_feature_set ** var; /* Variable to change. */
31257 const arm_feature_set value; /* What to change it to. */
31258 const char * deprecated; /* If non-null, print this message. */
e74cfd16 31259};
b99bd4ef 31260
e74cfd16
PB
31261const struct arm_legacy_option_table arm_legacy_opts[] =
31262{
c19d1205
ZW
31263 /* DON'T add any new processors to this list -- we want the whole list
31264 to go away... Add them to the processors table instead. */
e74cfd16
PB
31265 {"marm1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
31266 {"m1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
31267 {"marm2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
31268 {"m2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
31269 {"marm250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
31270 {"m250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
31271 {"marm3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
31272 {"m3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
31273 {"marm6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
31274 {"m6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
31275 {"marm600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
31276 {"m600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
31277 {"marm610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
31278 {"m610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
31279 {"marm620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
31280 {"m620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
31281 {"marm7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
31282 {"m7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
31283 {"marm70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
31284 {"m70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
31285 {"marm700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
31286 {"m700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
31287 {"marm700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
31288 {"m700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
31289 {"marm710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
31290 {"m710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
31291 {"marm710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
31292 {"m710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
31293 {"marm720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
31294 {"m720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
31295 {"marm7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
31296 {"m7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
31297 {"marm7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
31298 {"m7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
31299 {"marm7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
31300 {"m7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
31301 {"marm7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
31302 {"m7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
31303 {"marm7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
31304 {"m7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
31305 {"marm7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
31306 {"m7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
31307 {"marm7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
31308 {"m7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
31309 {"marm7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
31310 {"m7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
31311 {"marm7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31312 {"m7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31313 {"marm7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31314 {"m7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31315 {"marm710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
31316 {"m710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
31317 {"marm720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
31318 {"m720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
31319 {"marm740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
31320 {"m740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
31321 {"marm8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
31322 {"m8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
31323 {"marm810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
31324 {"m810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
31325 {"marm9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
31326 {"m9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
31327 {"marm9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
31328 {"m9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
31329 {"marm920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
31330 {"m920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
31331 {"marm940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
31332 {"m940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
31333 {"mstrongarm", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
31334 {"mstrongarm110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31335 N_("use -mcpu=strongarm110")},
e74cfd16 31336 {"mstrongarm1100", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31337 N_("use -mcpu=strongarm1100")},
e74cfd16 31338 {"mstrongarm1110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31339 N_("use -mcpu=strongarm1110")},
e74cfd16
PB
31340 {"mxscale", &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
31341 {"miwmmxt", &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
31342 {"mall", &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
7ed4c4c5 31343
c19d1205 31344 /* Architecture variants -- don't add any more to this list either. */
e74cfd16
PB
31345 {"mv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
31346 {"marmv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
31347 {"mv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
31348 {"marmv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
31349 {"mv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
31350 {"marmv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
31351 {"mv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
31352 {"marmv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
31353 {"mv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
31354 {"marmv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
31355 {"mv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
31356 {"marmv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
31357 {"mv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
31358 {"marmv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
31359 {"mv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
31360 {"marmv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
31361 {"mv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
31362 {"marmv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
7ed4c4c5 31363
c19d1205 31364 /* Floating point variants -- don't add any more to this list either. */
0198d5e6
TC
31365 {"mfpe-old", &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
31366 {"mfpa10", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
31367 {"mfpa11", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
31368 {"mno-fpu", &legacy_fpu, ARM_ARCH_NONE,
c19d1205 31369 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
7ed4c4c5 31370
e74cfd16 31371 {NULL, NULL, ARM_ARCH_NONE, NULL}
c19d1205 31372};
7ed4c4c5 31373
c19d1205 31374struct arm_cpu_option_table
7ed4c4c5 31375{
0198d5e6
TC
31376 const char * name;
31377 size_t name_len;
31378 const arm_feature_set value;
31379 const arm_feature_set ext;
c19d1205
ZW
31380 /* For some CPUs we assume an FPU unless the user explicitly sets
31381 -mfpu=... */
0198d5e6 31382 const arm_feature_set default_fpu;
ee065d83
PB
31383 /* The canonical name of the CPU, or NULL to use NAME converted to upper
31384 case. */
0198d5e6 31385 const char * canonical_name;
c19d1205 31386};
7ed4c4c5 31387
c19d1205
ZW
31388/* This list should, at a minimum, contain all the cpu names
31389 recognized by GCC. */
996b5569 31390#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
0198d5e6 31391
e74cfd16 31392static const struct arm_cpu_option_table arm_cpus[] =
c19d1205 31393{
996b5569
TP
31394 ARM_CPU_OPT ("all", NULL, ARM_ANY,
31395 ARM_ARCH_NONE,
31396 FPU_ARCH_FPA),
31397 ARM_CPU_OPT ("arm1", NULL, ARM_ARCH_V1,
31398 ARM_ARCH_NONE,
31399 FPU_ARCH_FPA),
31400 ARM_CPU_OPT ("arm2", NULL, ARM_ARCH_V2,
31401 ARM_ARCH_NONE,
31402 FPU_ARCH_FPA),
31403 ARM_CPU_OPT ("arm250", NULL, ARM_ARCH_V2S,
31404 ARM_ARCH_NONE,
31405 FPU_ARCH_FPA),
31406 ARM_CPU_OPT ("arm3", NULL, ARM_ARCH_V2S,
31407 ARM_ARCH_NONE,
31408 FPU_ARCH_FPA),
31409 ARM_CPU_OPT ("arm6", NULL, ARM_ARCH_V3,
31410 ARM_ARCH_NONE,
31411 FPU_ARCH_FPA),
31412 ARM_CPU_OPT ("arm60", NULL, ARM_ARCH_V3,
31413 ARM_ARCH_NONE,
31414 FPU_ARCH_FPA),
31415 ARM_CPU_OPT ("arm600", NULL, ARM_ARCH_V3,
31416 ARM_ARCH_NONE,
31417 FPU_ARCH_FPA),
31418 ARM_CPU_OPT ("arm610", NULL, ARM_ARCH_V3,
31419 ARM_ARCH_NONE,
31420 FPU_ARCH_FPA),
31421 ARM_CPU_OPT ("arm620", NULL, ARM_ARCH_V3,
31422 ARM_ARCH_NONE,
31423 FPU_ARCH_FPA),
31424 ARM_CPU_OPT ("arm7", NULL, ARM_ARCH_V3,
31425 ARM_ARCH_NONE,
31426 FPU_ARCH_FPA),
31427 ARM_CPU_OPT ("arm7m", NULL, ARM_ARCH_V3M,
31428 ARM_ARCH_NONE,
31429 FPU_ARCH_FPA),
31430 ARM_CPU_OPT ("arm7d", NULL, ARM_ARCH_V3,
31431 ARM_ARCH_NONE,
31432 FPU_ARCH_FPA),
31433 ARM_CPU_OPT ("arm7dm", NULL, ARM_ARCH_V3M,
31434 ARM_ARCH_NONE,
31435 FPU_ARCH_FPA),
31436 ARM_CPU_OPT ("arm7di", NULL, ARM_ARCH_V3,
31437 ARM_ARCH_NONE,
31438 FPU_ARCH_FPA),
31439 ARM_CPU_OPT ("arm7dmi", NULL, ARM_ARCH_V3M,
31440 ARM_ARCH_NONE,
31441 FPU_ARCH_FPA),
31442 ARM_CPU_OPT ("arm70", NULL, ARM_ARCH_V3,
31443 ARM_ARCH_NONE,
31444 FPU_ARCH_FPA),
31445 ARM_CPU_OPT ("arm700", NULL, ARM_ARCH_V3,
31446 ARM_ARCH_NONE,
31447 FPU_ARCH_FPA),
31448 ARM_CPU_OPT ("arm700i", NULL, ARM_ARCH_V3,
31449 ARM_ARCH_NONE,
31450 FPU_ARCH_FPA),
31451 ARM_CPU_OPT ("arm710", NULL, ARM_ARCH_V3,
31452 ARM_ARCH_NONE,
31453 FPU_ARCH_FPA),
31454 ARM_CPU_OPT ("arm710t", NULL, ARM_ARCH_V4T,
31455 ARM_ARCH_NONE,
31456 FPU_ARCH_FPA),
31457 ARM_CPU_OPT ("arm720", NULL, ARM_ARCH_V3,
31458 ARM_ARCH_NONE,
31459 FPU_ARCH_FPA),
31460 ARM_CPU_OPT ("arm720t", NULL, ARM_ARCH_V4T,
31461 ARM_ARCH_NONE,
31462 FPU_ARCH_FPA),
31463 ARM_CPU_OPT ("arm740t", NULL, ARM_ARCH_V4T,
31464 ARM_ARCH_NONE,
31465 FPU_ARCH_FPA),
31466 ARM_CPU_OPT ("arm710c", NULL, ARM_ARCH_V3,
31467 ARM_ARCH_NONE,
31468 FPU_ARCH_FPA),
31469 ARM_CPU_OPT ("arm7100", NULL, ARM_ARCH_V3,
31470 ARM_ARCH_NONE,
31471 FPU_ARCH_FPA),
31472 ARM_CPU_OPT ("arm7500", NULL, ARM_ARCH_V3,
31473 ARM_ARCH_NONE,
31474 FPU_ARCH_FPA),
31475 ARM_CPU_OPT ("arm7500fe", NULL, ARM_ARCH_V3,
31476 ARM_ARCH_NONE,
31477 FPU_ARCH_FPA),
31478 ARM_CPU_OPT ("arm7t", NULL, ARM_ARCH_V4T,
31479 ARM_ARCH_NONE,
31480 FPU_ARCH_FPA),
31481 ARM_CPU_OPT ("arm7tdmi", NULL, ARM_ARCH_V4T,
31482 ARM_ARCH_NONE,
31483 FPU_ARCH_FPA),
31484 ARM_CPU_OPT ("arm7tdmi-s", NULL, ARM_ARCH_V4T,
31485 ARM_ARCH_NONE,
31486 FPU_ARCH_FPA),
31487 ARM_CPU_OPT ("arm8", NULL, ARM_ARCH_V4,
31488 ARM_ARCH_NONE,
31489 FPU_ARCH_FPA),
31490 ARM_CPU_OPT ("arm810", NULL, ARM_ARCH_V4,
31491 ARM_ARCH_NONE,
31492 FPU_ARCH_FPA),
31493 ARM_CPU_OPT ("strongarm", NULL, ARM_ARCH_V4,
31494 ARM_ARCH_NONE,
31495 FPU_ARCH_FPA),
31496 ARM_CPU_OPT ("strongarm1", NULL, ARM_ARCH_V4,
31497 ARM_ARCH_NONE,
31498 FPU_ARCH_FPA),
31499 ARM_CPU_OPT ("strongarm110", NULL, ARM_ARCH_V4,
31500 ARM_ARCH_NONE,
31501 FPU_ARCH_FPA),
31502 ARM_CPU_OPT ("strongarm1100", NULL, ARM_ARCH_V4,
31503 ARM_ARCH_NONE,
31504 FPU_ARCH_FPA),
31505 ARM_CPU_OPT ("strongarm1110", NULL, ARM_ARCH_V4,
31506 ARM_ARCH_NONE,
31507 FPU_ARCH_FPA),
31508 ARM_CPU_OPT ("arm9", NULL, ARM_ARCH_V4T,
31509 ARM_ARCH_NONE,
31510 FPU_ARCH_FPA),
31511 ARM_CPU_OPT ("arm920", "ARM920T", ARM_ARCH_V4T,
31512 ARM_ARCH_NONE,
31513 FPU_ARCH_FPA),
31514 ARM_CPU_OPT ("arm920t", NULL, ARM_ARCH_V4T,
31515 ARM_ARCH_NONE,
31516 FPU_ARCH_FPA),
31517 ARM_CPU_OPT ("arm922t", NULL, ARM_ARCH_V4T,
31518 ARM_ARCH_NONE,
31519 FPU_ARCH_FPA),
31520 ARM_CPU_OPT ("arm940t", NULL, ARM_ARCH_V4T,
31521 ARM_ARCH_NONE,
31522 FPU_ARCH_FPA),
31523 ARM_CPU_OPT ("arm9tdmi", NULL, ARM_ARCH_V4T,
31524 ARM_ARCH_NONE,
31525 FPU_ARCH_FPA),
31526 ARM_CPU_OPT ("fa526", NULL, ARM_ARCH_V4,
31527 ARM_ARCH_NONE,
31528 FPU_ARCH_FPA),
31529 ARM_CPU_OPT ("fa626", NULL, ARM_ARCH_V4,
31530 ARM_ARCH_NONE,
31531 FPU_ARCH_FPA),
31532
c19d1205
ZW
31533 /* For V5 or later processors we default to using VFP; but the user
31534 should really set the FPU type explicitly. */
996b5569
TP
31535 ARM_CPU_OPT ("arm9e-r0", NULL, ARM_ARCH_V5TExP,
31536 ARM_ARCH_NONE,
31537 FPU_ARCH_VFP_V2),
31538 ARM_CPU_OPT ("arm9e", NULL, ARM_ARCH_V5TE,
31539 ARM_ARCH_NONE,
31540 FPU_ARCH_VFP_V2),
31541 ARM_CPU_OPT ("arm926ej", "ARM926EJ-S", ARM_ARCH_V5TEJ,
31542 ARM_ARCH_NONE,
31543 FPU_ARCH_VFP_V2),
31544 ARM_CPU_OPT ("arm926ejs", "ARM926EJ-S", ARM_ARCH_V5TEJ,
31545 ARM_ARCH_NONE,
31546 FPU_ARCH_VFP_V2),
31547 ARM_CPU_OPT ("arm926ej-s", NULL, ARM_ARCH_V5TEJ,
31548 ARM_ARCH_NONE,
31549 FPU_ARCH_VFP_V2),
31550 ARM_CPU_OPT ("arm946e-r0", NULL, ARM_ARCH_V5TExP,
31551 ARM_ARCH_NONE,
31552 FPU_ARCH_VFP_V2),
31553 ARM_CPU_OPT ("arm946e", "ARM946E-S", ARM_ARCH_V5TE,
31554 ARM_ARCH_NONE,
31555 FPU_ARCH_VFP_V2),
31556 ARM_CPU_OPT ("arm946e-s", NULL, ARM_ARCH_V5TE,
31557 ARM_ARCH_NONE,
31558 FPU_ARCH_VFP_V2),
31559 ARM_CPU_OPT ("arm966e-r0", NULL, ARM_ARCH_V5TExP,
31560 ARM_ARCH_NONE,
31561 FPU_ARCH_VFP_V2),
31562 ARM_CPU_OPT ("arm966e", "ARM966E-S", ARM_ARCH_V5TE,
31563 ARM_ARCH_NONE,
31564 FPU_ARCH_VFP_V2),
31565 ARM_CPU_OPT ("arm966e-s", NULL, ARM_ARCH_V5TE,
31566 ARM_ARCH_NONE,
31567 FPU_ARCH_VFP_V2),
31568 ARM_CPU_OPT ("arm968e-s", NULL, ARM_ARCH_V5TE,
31569 ARM_ARCH_NONE,
31570 FPU_ARCH_VFP_V2),
31571 ARM_CPU_OPT ("arm10t", NULL, ARM_ARCH_V5T,
31572 ARM_ARCH_NONE,
31573 FPU_ARCH_VFP_V1),
31574 ARM_CPU_OPT ("arm10tdmi", NULL, ARM_ARCH_V5T,
31575 ARM_ARCH_NONE,
31576 FPU_ARCH_VFP_V1),
31577 ARM_CPU_OPT ("arm10e", NULL, ARM_ARCH_V5TE,
31578 ARM_ARCH_NONE,
31579 FPU_ARCH_VFP_V2),
31580 ARM_CPU_OPT ("arm1020", "ARM1020E", ARM_ARCH_V5TE,
31581 ARM_ARCH_NONE,
31582 FPU_ARCH_VFP_V2),
31583 ARM_CPU_OPT ("arm1020t", NULL, ARM_ARCH_V5T,
31584 ARM_ARCH_NONE,
31585 FPU_ARCH_VFP_V1),
31586 ARM_CPU_OPT ("arm1020e", NULL, ARM_ARCH_V5TE,
31587 ARM_ARCH_NONE,
31588 FPU_ARCH_VFP_V2),
31589 ARM_CPU_OPT ("arm1022e", NULL, ARM_ARCH_V5TE,
31590 ARM_ARCH_NONE,
31591 FPU_ARCH_VFP_V2),
31592 ARM_CPU_OPT ("arm1026ejs", "ARM1026EJ-S", ARM_ARCH_V5TEJ,
31593 ARM_ARCH_NONE,
31594 FPU_ARCH_VFP_V2),
31595 ARM_CPU_OPT ("arm1026ej-s", NULL, ARM_ARCH_V5TEJ,
31596 ARM_ARCH_NONE,
31597 FPU_ARCH_VFP_V2),
31598 ARM_CPU_OPT ("fa606te", NULL, ARM_ARCH_V5TE,
31599 ARM_ARCH_NONE,
31600 FPU_ARCH_VFP_V2),
31601 ARM_CPU_OPT ("fa616te", NULL, ARM_ARCH_V5TE,
31602 ARM_ARCH_NONE,
31603 FPU_ARCH_VFP_V2),
31604 ARM_CPU_OPT ("fa626te", NULL, ARM_ARCH_V5TE,
31605 ARM_ARCH_NONE,
31606 FPU_ARCH_VFP_V2),
31607 ARM_CPU_OPT ("fmp626", NULL, ARM_ARCH_V5TE,
31608 ARM_ARCH_NONE,
31609 FPU_ARCH_VFP_V2),
31610 ARM_CPU_OPT ("fa726te", NULL, ARM_ARCH_V5TE,
31611 ARM_ARCH_NONE,
31612 FPU_ARCH_VFP_V2),
31613 ARM_CPU_OPT ("arm1136js", "ARM1136J-S", ARM_ARCH_V6,
31614 ARM_ARCH_NONE,
31615 FPU_NONE),
31616 ARM_CPU_OPT ("arm1136j-s", NULL, ARM_ARCH_V6,
31617 ARM_ARCH_NONE,
31618 FPU_NONE),
31619 ARM_CPU_OPT ("arm1136jfs", "ARM1136JF-S", ARM_ARCH_V6,
31620 ARM_ARCH_NONE,
31621 FPU_ARCH_VFP_V2),
31622 ARM_CPU_OPT ("arm1136jf-s", NULL, ARM_ARCH_V6,
31623 ARM_ARCH_NONE,
31624 FPU_ARCH_VFP_V2),
31625 ARM_CPU_OPT ("mpcore", "MPCore", ARM_ARCH_V6K,
31626 ARM_ARCH_NONE,
31627 FPU_ARCH_VFP_V2),
31628 ARM_CPU_OPT ("mpcorenovfp", "MPCore", ARM_ARCH_V6K,
31629 ARM_ARCH_NONE,
31630 FPU_NONE),
31631 ARM_CPU_OPT ("arm1156t2-s", NULL, ARM_ARCH_V6T2,
31632 ARM_ARCH_NONE,
31633 FPU_NONE),
31634 ARM_CPU_OPT ("arm1156t2f-s", NULL, ARM_ARCH_V6T2,
31635 ARM_ARCH_NONE,
31636 FPU_ARCH_VFP_V2),
31637 ARM_CPU_OPT ("arm1176jz-s", NULL, ARM_ARCH_V6KZ,
31638 ARM_ARCH_NONE,
31639 FPU_NONE),
31640 ARM_CPU_OPT ("arm1176jzf-s", NULL, ARM_ARCH_V6KZ,
31641 ARM_ARCH_NONE,
31642 FPU_ARCH_VFP_V2),
31643 ARM_CPU_OPT ("cortex-a5", "Cortex-A5", ARM_ARCH_V7A,
31644 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31645 FPU_NONE),
31646 ARM_CPU_OPT ("cortex-a7", "Cortex-A7", ARM_ARCH_V7VE,
31647 ARM_ARCH_NONE,
31648 FPU_ARCH_NEON_VFP_V4),
31649 ARM_CPU_OPT ("cortex-a8", "Cortex-A8", ARM_ARCH_V7A,
31650 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
31651 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
31652 ARM_CPU_OPT ("cortex-a9", "Cortex-A9", ARM_ARCH_V7A,
31653 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31654 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
31655 ARM_CPU_OPT ("cortex-a12", "Cortex-A12", ARM_ARCH_V7VE,
31656 ARM_ARCH_NONE,
31657 FPU_ARCH_NEON_VFP_V4),
31658 ARM_CPU_OPT ("cortex-a15", "Cortex-A15", ARM_ARCH_V7VE,
31659 ARM_ARCH_NONE,
31660 FPU_ARCH_NEON_VFP_V4),
31661 ARM_CPU_OPT ("cortex-a17", "Cortex-A17", ARM_ARCH_V7VE,
31662 ARM_ARCH_NONE,
31663 FPU_ARCH_NEON_VFP_V4),
31664 ARM_CPU_OPT ("cortex-a32", "Cortex-A32", ARM_ARCH_V8A,
8b301fbb 31665 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31666 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31667 ARM_CPU_OPT ("cortex-a35", "Cortex-A35", ARM_ARCH_V8A,
8b301fbb 31668 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31669 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31670 ARM_CPU_OPT ("cortex-a53", "Cortex-A53", ARM_ARCH_V8A,
8b301fbb 31671 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31672 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
31673 ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A,
31674 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 31675 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569 31676 ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A,
8b301fbb 31677 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31678 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31679 ARM_CPU_OPT ("cortex-a72", "Cortex-A72", ARM_ARCH_V8A,
8b301fbb 31680 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31681 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31682 ARM_CPU_OPT ("cortex-a73", "Cortex-A73", ARM_ARCH_V8A,
8b301fbb 31683 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31684 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
31685 ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A,
31686 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 31687 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
7ebd1359 31688 ARM_CPU_OPT ("cortex-a76", "Cortex-A76", ARM_ARCH_V8_2A,
31689 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31690 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
0535e5d7
DZ
31691 ARM_CPU_OPT ("cortex-a76ae", "Cortex-A76AE", ARM_ARCH_V8_2A,
31692 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31693 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
31694 ARM_CPU_OPT ("cortex-a77", "Cortex-A77", ARM_ARCH_V8_2A,
31695 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31696 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
42c36b73
PW
31697 ARM_CPU_OPT ("cortex-a78", "Cortex-A78", ARM_ARCH_V8_2A,
31698 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
31699 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31700 ARM_CPU_OPT ("cortex-a78ae", "Cortex-A78AE", ARM_ARCH_V8_2A,
31701 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
31702 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
1bbda94f
PW
31703 ARM_CPU_OPT ("cortex-a78c", "Cortex-A78C", ARM_ARCH_V8_2A,
31704 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
31705 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
14f45859
PW
31706 ARM_CPU_OPT ("cortex-a710", "Cortex-A710", ARM_ARCH_V9A,
31707 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
31708 | ARM_EXT2_BF16
31709 | ARM_EXT2_I8MM),
31710 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
ef8df4ca
KT
31711 ARM_CPU_OPT ("ares", "Ares", ARM_ARCH_V8_2A,
31712 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31713 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
31714 ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R,
31715 ARM_ARCH_NONE,
31716 FPU_NONE),
31717 ARM_CPU_OPT ("cortex-r4f", "Cortex-R4F", ARM_ARCH_V7R,
31718 ARM_ARCH_NONE,
31719 FPU_ARCH_VFP_V3D16),
31720 ARM_CPU_OPT ("cortex-r5", "Cortex-R5", ARM_ARCH_V7R,
31721 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31722 FPU_NONE),
31723 ARM_CPU_OPT ("cortex-r7", "Cortex-R7", ARM_ARCH_V7R,
31724 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31725 FPU_ARCH_VFP_V3D16),
31726 ARM_CPU_OPT ("cortex-r8", "Cortex-R8", ARM_ARCH_V7R,
31727 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31728 FPU_ARCH_VFP_V3D16),
0cda1e19 31729 ARM_CPU_OPT ("cortex-r52", "Cortex-R52", ARM_ARCH_V8R,
8b301fbb 31730 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
0cda1e19 31731 FPU_ARCH_NEON_VFP_ARMV8),
80cfde76
PW
31732 ARM_CPU_OPT ("cortex-r52plus", "Cortex-R52+", ARM_ARCH_V8R,
31733 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
31734 FPU_ARCH_NEON_VFP_ARMV8),
0535e5d7
DZ
31735 ARM_CPU_OPT ("cortex-m35p", "Cortex-M35P", ARM_ARCH_V8M_MAIN,
31736 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
31737 FPU_NONE),
996b5569
TP
31738 ARM_CPU_OPT ("cortex-m33", "Cortex-M33", ARM_ARCH_V8M_MAIN,
31739 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
31740 FPU_NONE),
31741 ARM_CPU_OPT ("cortex-m23", "Cortex-M23", ARM_ARCH_V8M_BASE,
31742 ARM_ARCH_NONE,
31743 FPU_NONE),
31744 ARM_CPU_OPT ("cortex-m7", "Cortex-M7", ARM_ARCH_V7EM,
31745 ARM_ARCH_NONE,
31746 FPU_NONE),
31747 ARM_CPU_OPT ("cortex-m4", "Cortex-M4", ARM_ARCH_V7EM,
31748 ARM_ARCH_NONE,
31749 FPU_NONE),
31750 ARM_CPU_OPT ("cortex-m3", "Cortex-M3", ARM_ARCH_V7M,
31751 ARM_ARCH_NONE,
31752 FPU_NONE),
31753 ARM_CPU_OPT ("cortex-m1", "Cortex-M1", ARM_ARCH_V6SM,
31754 ARM_ARCH_NONE,
31755 FPU_NONE),
31756 ARM_CPU_OPT ("cortex-m0", "Cortex-M0", ARM_ARCH_V6SM,
31757 ARM_ARCH_NONE,
31758 FPU_NONE),
31759 ARM_CPU_OPT ("cortex-m0plus", "Cortex-M0+", ARM_ARCH_V6SM,
31760 ARM_ARCH_NONE,
31761 FPU_NONE),
394e9bf6 31762 ARM_CPU_OPT ("cortex-x1", "Cortex-X1", ARM_ARCH_V8_2A,
a417e439 31763 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
394e9bf6 31764 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
cafdb713
SP
31765 ARM_CPU_OPT ("cortex-x1c", "Cortex-X1C", ARM_ARCH_V8_2A,
31766 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_SB),
31767 FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
996b5569 31768 ARM_CPU_OPT ("exynos-m1", "Samsung Exynos M1", ARM_ARCH_V8A,
8b301fbb 31769 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31770 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
83f43c83
KT
31771 ARM_CPU_OPT ("neoverse-n1", "Neoverse N1", ARM_ARCH_V8_2A,
31772 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31773 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
f3034e25
AC
31774 ARM_CPU_OPT ("neoverse-n2", "Neoverse N2", ARM_ARCH_V8_5A,
31775 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
31776 | ARM_EXT2_BF16
31777 | ARM_EXT2_I8MM),
31778 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4),
6eee0315 31779 ARM_CPU_OPT ("neoverse-v1", "Neoverse V1", ARM_ARCH_V8_4A,
9bede61c
AC
31780 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
31781 | ARM_EXT2_BF16
31782 | ARM_EXT2_I8MM),
6eee0315 31783 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4),
c19d1205 31784 /* ??? XSCALE is really an architecture. */
996b5569
TP
31785 ARM_CPU_OPT ("xscale", NULL, ARM_ARCH_XSCALE,
31786 ARM_ARCH_NONE,
31787 FPU_ARCH_VFP_V2),
31788
c19d1205 31789 /* ??? iwmmxt is not a processor. */
996b5569
TP
31790 ARM_CPU_OPT ("iwmmxt", NULL, ARM_ARCH_IWMMXT,
31791 ARM_ARCH_NONE,
31792 FPU_ARCH_VFP_V2),
31793 ARM_CPU_OPT ("iwmmxt2", NULL, ARM_ARCH_IWMMXT2,
31794 ARM_ARCH_NONE,
31795 FPU_ARCH_VFP_V2),
31796 ARM_CPU_OPT ("i80200", NULL, ARM_ARCH_XSCALE,
31797 ARM_ARCH_NONE,
31798 FPU_ARCH_VFP_V2),
31799
0198d5e6 31800 /* Maverick. */
996b5569
TP
31801 ARM_CPU_OPT ("ep9312", "ARM920T",
31802 ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
31803 ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
31804
da4339ed 31805 /* Marvell processors. */
996b5569
TP
31806 ARM_CPU_OPT ("marvell-pj4", NULL, ARM_ARCH_V7A,
31807 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31808 FPU_ARCH_VFP_V3D16),
31809 ARM_CPU_OPT ("marvell-whitney", NULL, ARM_ARCH_V7A,
31810 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31811 FPU_ARCH_NEON_VFP_V4),
da4339ed 31812
996b5569
TP
31813 /* APM X-Gene family. */
31814 ARM_CPU_OPT ("xgene1", "APM X-Gene 1", ARM_ARCH_V8A,
31815 ARM_ARCH_NONE,
31816 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31817 ARM_CPU_OPT ("xgene2", "APM X-Gene 2", ARM_ARCH_V8A,
8b301fbb 31818 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31819 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31820
31821 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 31822};
f3bad469 31823#undef ARM_CPU_OPT
7ed4c4c5 31824
34ef62f4
AV
31825struct arm_ext_table
31826{
31827 const char * name;
31828 size_t name_len;
31829 const arm_feature_set merge;
31830 const arm_feature_set clear;
31831};
31832
c19d1205 31833struct arm_arch_option_table
7ed4c4c5 31834{
34ef62f4
AV
31835 const char * name;
31836 size_t name_len;
31837 const arm_feature_set value;
31838 const arm_feature_set default_fpu;
31839 const struct arm_ext_table * ext_table;
31840};
31841
31842/* Used to add support for +E and +noE extension. */
31843#define ARM_EXT(E, M, C) { E, sizeof (E) - 1, M, C }
31844/* Used to add support for a +E extension. */
31845#define ARM_ADD(E, M) { E, sizeof(E) - 1, M, ARM_ARCH_NONE }
31846/* Used to add support for a +noE extension. */
31847#define ARM_REMOVE(E, C) { E, sizeof(E) -1, ARM_ARCH_NONE, C }
31848
31849#define ALL_FP ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_FP16_FML, \
31850 ~0 & ~FPU_ENDIAN_PURE)
31851
31852static const struct arm_ext_table armv5te_ext_table[] =
31853{
31854 ARM_EXT ("fp", FPU_ARCH_VFP_V2, ALL_FP),
31855 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31856};
31857
31858static const struct arm_ext_table armv7_ext_table[] =
31859{
31860 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31861 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31862};
31863
31864static const struct arm_ext_table armv7ve_ext_table[] =
31865{
31866 ARM_EXT ("fp", FPU_ARCH_VFP_V4D16, ALL_FP),
31867 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16),
31868 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
31869 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31870 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
31871 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), /* Alias for +fp. */
31872 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
31873
31874 ARM_EXT ("simd", FPU_ARCH_NEON_VFP_V4,
31875 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
31876
31877 /* Aliases for +simd. */
31878 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
31879
31880 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31881 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31882 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
31883
31884 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31885};
31886
31887static const struct arm_ext_table armv7a_ext_table[] =
31888{
31889 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31890 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
31891 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
31892 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31893 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
31894 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16),
31895 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
31896
31897 ARM_EXT ("simd", FPU_ARCH_VFP_V3_PLUS_NEON_V1,
31898 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
31899
31900 /* Aliases for +simd. */
31901 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31902 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31903
31904 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
31905 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
31906
31907 ARM_ADD ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP)),
31908 ARM_ADD ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC)),
31909 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31910};
31911
31912static const struct arm_ext_table armv7r_ext_table[] =
31913{
31914 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V3xD),
31915 ARM_ADD ("vfpv3xd", FPU_ARCH_VFP_V3xD), /* Alias for +fp.sp. */
31916 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31917 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
31918 ARM_ADD ("vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16),
31919 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31920 ARM_EXT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
31921 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV)),
31922 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31923};
31924
31925static const struct arm_ext_table armv7em_ext_table[] =
31926{
31927 ARM_EXT ("fp", FPU_ARCH_VFP_V4_SP_D16, ALL_FP),
31928 /* Alias for +fp, used to be known as fpv4-sp-d16. */
31929 ARM_ADD ("vfpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16),
31930 ARM_ADD ("fpv5", FPU_ARCH_VFP_V5_SP_D16),
31931 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
31932 ARM_ADD ("fpv5-d16", FPU_ARCH_VFP_V5D16),
31933 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31934};
31935
31936static const struct arm_ext_table armv8a_ext_table[] =
31937{
8b301fbb 31938 ARM_ADD ("crc", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC)),
34ef62f4
AV
31939 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
31940 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
31941 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31942
31943 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31944 should use the +simd option to turn on FP. */
31945 ARM_REMOVE ("fp", ALL_FP),
31946 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31947 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31948 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31949};
31950
31951
31952static const struct arm_ext_table armv81a_ext_table[] =
31953{
31954 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
31955 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
31956 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31957
31958 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31959 should use the +simd option to turn on FP. */
31960 ARM_REMOVE ("fp", ALL_FP),
31961 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31962 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31963 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31964};
31965
31966static const struct arm_ext_table armv82a_ext_table[] =
31967{
31968 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
31969 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_2_FP16),
31970 ARM_ADD ("fp16fml", FPU_ARCH_NEON_VFP_ARMV8_2_FP16FML),
616ce08e
MM
31971 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
31972 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
31973 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
31974 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31975 ARM_ADD ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31976
31977 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31978 should use the +simd option to turn on FP. */
31979 ARM_REMOVE ("fp", ALL_FP),
31980 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31981 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31982 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31983};
31984
31985static const struct arm_ext_table armv84a_ext_table[] =
31986{
31987 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31988 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
616ce08e
MM
31989 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
31990 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
31991 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
31992 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31993
31994 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31995 should use the +simd option to turn on FP. */
31996 ARM_REMOVE ("fp", ALL_FP),
31997 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31998 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31999 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32000};
32001
32002static const struct arm_ext_table armv85a_ext_table[] =
32003{
32004 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
32005 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
616ce08e
MM
32006 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
32007 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
32008 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
32009 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
32010
32011 /* Armv8-a does not allow an FP implementation without SIMD, so the user
32012 should use the +simd option to turn on FP. */
32013 ARM_REMOVE ("fp", ALL_FP),
32014 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32015};
32016
aab2c27d
MM
32017static const struct arm_ext_table armv86a_ext_table[] =
32018{
616ce08e 32019 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
aab2c27d
MM
32020 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32021};
32022
b3e4d932
RS
32023#define armv87a_ext_table armv86a_ext_table
32024#define armv88a_ext_table armv87a_ext_table
b3b647dc 32025#define armv89a_ext_table armv88a_ext_table
b3e4d932 32026
3197e593
PW
32027static const struct arm_ext_table armv9a_ext_table[] =
32028{
32029 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
32030 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
32031 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
32032 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
32033 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
32034 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
32035
32036 /* Armv9-a does not allow an FP implementation without SIMD, so the user
32037 should use the +simd option to turn on FP. */
32038 ARM_REMOVE ("fp", ALL_FP),
32039 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32040};
32041
a2b1ea81
RS
32042#define armv91a_ext_table armv86a_ext_table
32043#define armv92a_ext_table armv91a_ext_table
32044#define armv93a_ext_table armv92a_ext_table
b3b647dc 32045#define armv94a_ext_table armv93a_ext_table
b47cef7c 32046#define armv95a_ext_table armv94a_ext_table
a2b1ea81 32047
4934a27c
MM
32048#define CDE_EXTENSIONS \
32049 ARM_ADD ("cdecp0", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE0)), \
32050 ARM_ADD ("cdecp1", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE1)), \
32051 ARM_ADD ("cdecp2", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE2)), \
32052 ARM_ADD ("cdecp3", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE3)), \
32053 ARM_ADD ("cdecp4", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE4)), \
32054 ARM_ADD ("cdecp5", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE5)), \
32055 ARM_ADD ("cdecp6", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE6)), \
32056 ARM_ADD ("cdecp7", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE7))
32057
34ef62f4
AV
32058static const struct arm_ext_table armv8m_main_ext_table[] =
32059{
92169145
AV
32060 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP),
32061 ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP)),
34ef62f4
AV
32062 ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP),
32063 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
4934a27c 32064 CDE_EXTENSIONS,
34ef62f4
AV
32065 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32066};
32067
92169145 32068
e0991585
AV
32069static const struct arm_ext_table armv8_1m_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)),
e0991585
AV
32073 ARM_EXT ("fp",
32074 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
32075 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA),
32076 ALL_FP),
32077 ARM_ADD ("fp.dp",
32078 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
32079 FPU_VFP_V5D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
92169145 32080 ARM_EXT ("mve", ARM_FEATURE (ARM_AEXT_V8M_MAIN_DSP, ARM_EXT2_MVE, 0),
2da2eaf4 32081 ARM_FEATURE_CORE_HIGH (ARM_EXT2_MVE | ARM_EXT2_MVE_FP)),
a7ad558c 32082 ARM_ADD ("mve.fp",
92169145
AV
32083 ARM_FEATURE (ARM_AEXT_V8M_MAIN_DSP,
32084 ARM_EXT2_FP16_INST | ARM_EXT2_MVE | ARM_EXT2_MVE_FP,
2da2eaf4 32085 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
4934a27c 32086 CDE_EXTENSIONS,
5a0c7a81 32087 ARM_ADD ("pacbti", ARM_FEATURE_CORE_HIGH_HIGH (ARM_AEXT3_V8_1M_MAIN_PACBTI)),
e0991585
AV
32088 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
32089};
32090
4934a27c
MM
32091#undef CDE_EXTENSIONS
32092
34ef62f4
AV
32093static const struct arm_ext_table armv8r_ext_table[] =
32094{
8b301fbb 32095 ARM_ADD ("crc", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC)),
34ef62f4
AV
32096 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
32097 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
32098 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
32099 ARM_REMOVE ("fp", ALL_FP),
32100 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V5_SP_D16),
32101 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
c19d1205 32102};
7ed4c4c5 32103
c19d1205
ZW
32104/* This list should, at a minimum, contain all the architecture names
32105 recognized by GCC. */
34ef62f4
AV
32106#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF, NULL }
32107#define ARM_ARCH_OPT2(N, V, DF, ext) \
32108 { N, sizeof (N) - 1, V, DF, ext##_ext_table }
0198d5e6 32109
e74cfd16 32110static const struct arm_arch_option_table arm_archs[] =
c19d1205 32111{
497d849d
TP
32112 ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
32113 ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
32114 ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
32115 ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
32116 ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
32117 ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
32118 ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
32119 ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
32120 ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
32121 ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
32122 ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
32123 ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
32124 ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
32125 ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
34ef62f4
AV
32126 ARM_ARCH_OPT2 ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP, armv5te),
32127 ARM_ARCH_OPT2 ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP, armv5te),
32128 ARM_ARCH_OPT2 ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP, armv5te),
32129 ARM_ARCH_OPT2 ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
32130 ARM_ARCH_OPT2 ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
32131 ARM_ARCH_OPT2 ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP, armv5te),
32132 ARM_ARCH_OPT2 ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP, armv5te),
f33026a9
MW
32133 /* The official spelling of this variant is ARMv6KZ, the name "armv6zk" is
32134 kept to preserve existing behaviour. */
34ef62f4
AV
32135 ARM_ARCH_OPT2 ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
32136 ARM_ARCH_OPT2 ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
32137 ARM_ARCH_OPT2 ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP, armv5te),
32138 ARM_ARCH_OPT2 ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP, armv5te),
32139 ARM_ARCH_OPT2 ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP, armv5te),
f33026a9
MW
32140 /* The official spelling of this variant is ARMv6KZ, the name "armv6zkt2" is
32141 kept to preserve existing behaviour. */
34ef62f4
AV
32142 ARM_ARCH_OPT2 ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
32143 ARM_ARCH_OPT2 ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
497d849d
TP
32144 ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
32145 ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
34ef62f4 32146 ARM_ARCH_OPT2 ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP, armv7),
c450d570
PB
32147 /* The official spelling of the ARMv7 profile variants is the dashed form.
32148 Accept the non-dashed form for compatibility with old toolchains. */
34ef62f4
AV
32149 ARM_ARCH_OPT2 ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
32150 ARM_ARCH_OPT2 ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP, armv7ve),
32151 ARM_ARCH_OPT2 ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 32152 ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4
AV
32153 ARM_ARCH_OPT2 ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
32154 ARM_ARCH_OPT2 ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 32155 ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4 32156 ARM_ARCH_OPT2 ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP, armv7em),
497d849d 32157 ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP),
34ef62f4
AV
32158 ARM_ARCH_OPT2 ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP,
32159 armv8m_main),
e0991585
AV
32160 ARM_ARCH_OPT2 ("armv8.1-m.main", ARM_ARCH_V8_1M_MAIN, FPU_ARCH_VFP,
32161 armv8_1m_main),
34ef62f4
AV
32162 ARM_ARCH_OPT2 ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP, armv8a),
32163 ARM_ARCH_OPT2 ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP, armv81a),
32164 ARM_ARCH_OPT2 ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP, armv82a),
32165 ARM_ARCH_OPT2 ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP, armv82a),
32166 ARM_ARCH_OPT2 ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP, armv8r),
32167 ARM_ARCH_OPT2 ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP, armv84a),
32168 ARM_ARCH_OPT2 ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP, armv85a),
aab2c27d 32169 ARM_ARCH_OPT2 ("armv8.6-a", ARM_ARCH_V8_6A, FPU_ARCH_VFP, armv86a),
b3e4d932
RS
32170 ARM_ARCH_OPT2 ("armv8.7-a", ARM_ARCH_V8_7A, FPU_ARCH_VFP, armv87a),
32171 ARM_ARCH_OPT2 ("armv8.8-a", ARM_ARCH_V8_8A, FPU_ARCH_VFP, armv88a),
b3b647dc 32172 ARM_ARCH_OPT2 ("armv8.9-a", ARM_ARCH_V8_9A, FPU_ARCH_VFP, armv89a),
a2b1ea81
RS
32173 ARM_ARCH_OPT2 ("armv9-a", ARM_ARCH_V9A, FPU_ARCH_VFP, armv9a),
32174 ARM_ARCH_OPT2 ("armv9.1-a", ARM_ARCH_V9_1A, FPU_ARCH_VFP, armv91a),
32175 ARM_ARCH_OPT2 ("armv9.2-a", ARM_ARCH_V9_2A, FPU_ARCH_VFP, armv92a),
32176 ARM_ARCH_OPT2 ("armv9.3-a", ARM_ARCH_V9_2A, FPU_ARCH_VFP, armv93a),
b3b647dc 32177 ARM_ARCH_OPT2 ("armv9.4-a", ARM_ARCH_V9_4A, FPU_ARCH_VFP, armv94a),
b47cef7c 32178 ARM_ARCH_OPT2 ("armv9.5-a", ARM_ARCH_V9_5A, FPU_ARCH_VFP, armv95a),
497d849d
TP
32179 ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
32180 ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
32181 ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP),
34ef62f4 32182 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 32183};
f3bad469 32184#undef ARM_ARCH_OPT
7ed4c4c5 32185
69133863 32186/* ISA extensions in the co-processor and main instruction set space. */
0198d5e6 32187
69133863 32188struct arm_option_extension_value_table
c19d1205 32189{
0198d5e6
TC
32190 const char * name;
32191 size_t name_len;
32192 const arm_feature_set merge_value;
32193 const arm_feature_set clear_value;
d942732e
TP
32194 /* List of architectures for which an extension is available. ARM_ARCH_NONE
32195 indicates that an extension is available for all architectures while
32196 ARM_ANY marks an empty entry. */
0198d5e6 32197 const arm_feature_set allowed_archs[2];
c19d1205 32198};
7ed4c4c5 32199
0198d5e6
TC
32200/* The following table must be in alphabetical order with a NULL last entry. */
32201
d942732e
TP
32202#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
32203#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
0198d5e6 32204
34ef62f4
AV
32205/* DEPRECATED: Refrain from using this table to add any new extensions, instead
32206 use the context sensitive approach using arm_ext_table's. */
69133863 32207static const struct arm_option_extension_value_table arm_extensions[] =
c19d1205 32208{
8b301fbb
MI
32209 ARM_EXT_OPT ("crc", ARM_FEATURE_CORE_HIGH(ARM_EXT2_CRC),
32210 ARM_FEATURE_CORE_HIGH(ARM_EXT2_CRC),
823d2571 32211 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
bca38921 32212 ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
823d2571
TG
32213 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
32214 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
c604a79a
JW
32215 ARM_EXT_OPT ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8,
32216 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
32217 ARM_ARCH_V8_2A),
15afaa63
TP
32218 ARM_EXT_OPT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
32219 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
32220 ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
823d2571
TG
32221 ARM_EXT_OPT ("fp", FPU_ARCH_VFP_ARMV8, ARM_FEATURE_COPROC (FPU_VFP_ARMV8),
32222 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
b8ec4e87
JW
32223 ARM_EXT_OPT ("fp16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
32224 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
32225 ARM_ARCH_V8_2A),
01f48020
TC
32226 ARM_EXT_OPT ("fp16fml", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
32227 | ARM_EXT2_FP16_FML),
32228 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
32229 | ARM_EXT2_FP16_FML),
32230 ARM_ARCH_V8_2A),
d942732e 32231 ARM_EXT_OPT2 ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
823d2571 32232 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
d942732e
TP
32233 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
32234 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
3d030cdb
TP
32235 /* Duplicate entry for the purpose of allowing ARMv7 to match in presence of
32236 Thumb divide instruction. Due to this having the same name as the
32237 previous entry, this will be ignored when doing command-line parsing and
32238 only considered by build attribute selection code. */
32239 ARM_EXT_OPT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
32240 ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
32241 ARM_FEATURE_CORE_LOW (ARM_EXT_V7)),
823d2571 32242 ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
d942732e 32243 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
823d2571 32244 ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
d942732e 32245 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ARCH_NONE),
823d2571 32246 ARM_EXT_OPT ("maverick", ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK),
d942732e
TP
32247 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ARCH_NONE),
32248 ARM_EXT_OPT2 ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
823d2571 32249 ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
d942732e
TP
32250 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
32251 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
823d2571
TG
32252 ARM_EXT_OPT ("os", ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
32253 ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
32254 ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
ddfded2f
MW
32255 ARM_EXT_OPT ("pan", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
32256 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
ced40572 32257 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
dad0c3bf
SD
32258 ARM_EXT_OPT ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
32259 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
32260 ARM_ARCH_V8A),
4d1464f2
MW
32261 ARM_EXT_OPT ("ras", ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
32262 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
ced40572 32263 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
643afb90
MW
32264 ARM_EXT_OPT ("rdma", FPU_ARCH_NEON_VFP_ARMV8_1,
32265 ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
ced40572 32266 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
7fadb25d
SD
32267 ARM_EXT_OPT ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
32268 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
32269 ARM_ARCH_V8A),
d942732e 32270 ARM_EXT_OPT2 ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
823d2571 32271 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
d942732e
TP
32272 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
32273 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
643afb90
MW
32274 ARM_EXT_OPT ("simd", FPU_ARCH_NEON_VFP_ARMV8,
32275 ARM_FEATURE_COPROC (FPU_NEON_ARMV8),
32276 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
823d2571
TG
32277 ARM_EXT_OPT ("virt", ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT | ARM_EXT_ADIV
32278 | ARM_EXT_DIV),
32279 ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT),
32280 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
32281 ARM_EXT_OPT ("xscale",ARM_FEATURE_COPROC (ARM_CEXT_XSCALE),
d942732e
TP
32282 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ARCH_NONE),
32283 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, { ARM_ARCH_NONE, ARM_ARCH_NONE } }
69133863 32284};
f3bad469 32285#undef ARM_EXT_OPT
69133863
MGD
32286
32287/* ISA floating-point and Advanced SIMD extensions. */
32288struct arm_option_fpu_value_table
32289{
0198d5e6
TC
32290 const char * name;
32291 const arm_feature_set value;
c19d1205 32292};
7ed4c4c5 32293
c19d1205
ZW
32294/* This list should, at a minimum, contain all the fpu names
32295 recognized by GCC. */
69133863 32296static const struct arm_option_fpu_value_table arm_fpus[] =
c19d1205
ZW
32297{
32298 {"softfpa", FPU_NONE},
32299 {"fpe", FPU_ARCH_FPE},
32300 {"fpe2", FPU_ARCH_FPE},
32301 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
32302 {"fpa", FPU_ARCH_FPA},
32303 {"fpa10", FPU_ARCH_FPA},
32304 {"fpa11", FPU_ARCH_FPA},
32305 {"arm7500fe", FPU_ARCH_FPA},
32306 {"softvfp", FPU_ARCH_VFP},
32307 {"softvfp+vfp", FPU_ARCH_VFP_V2},
32308 {"vfp", FPU_ARCH_VFP_V2},
32309 {"vfp9", FPU_ARCH_VFP_V2},
d5e0ba9c 32310 {"vfp3", FPU_ARCH_VFP_V3}, /* Undocumented, use vfpv3. */
c19d1205
ZW
32311 {"vfp10", FPU_ARCH_VFP_V2},
32312 {"vfp10-r0", FPU_ARCH_VFP_V1},
32313 {"vfpxd", FPU_ARCH_VFP_V1xD},
b1cc4aeb
PB
32314 {"vfpv2", FPU_ARCH_VFP_V2},
32315 {"vfpv3", FPU_ARCH_VFP_V3},
62f3b8c8 32316 {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16},
b1cc4aeb 32317 {"vfpv3-d16", FPU_ARCH_VFP_V3D16},
62f3b8c8
PB
32318 {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16},
32319 {"vfpv3xd", FPU_ARCH_VFP_V3xD},
32320 {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16},
c19d1205
ZW
32321 {"arm1020t", FPU_ARCH_VFP_V1},
32322 {"arm1020e", FPU_ARCH_VFP_V2},
d5e0ba9c 32323 {"arm1136jfs", FPU_ARCH_VFP_V2}, /* Undocumented, use arm1136jf-s. */
c19d1205
ZW
32324 {"arm1136jf-s", FPU_ARCH_VFP_V2},
32325 {"maverick", FPU_ARCH_MAVERICK},
d5e0ba9c 32326 {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
d3375ddd 32327 {"neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
8e79c3df 32328 {"neon-fp16", FPU_ARCH_NEON_FP16},
62f3b8c8
PB
32329 {"vfpv4", FPU_ARCH_VFP_V4},
32330 {"vfpv4-d16", FPU_ARCH_VFP_V4D16},
ada65aa3 32331 {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16},
a715796b
TG
32332 {"fpv5-d16", FPU_ARCH_VFP_V5D16},
32333 {"fpv5-sp-d16", FPU_ARCH_VFP_V5_SP_D16},
62f3b8c8 32334 {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4},
bca38921
MGD
32335 {"fp-armv8", FPU_ARCH_VFP_ARMV8},
32336 {"neon-fp-armv8", FPU_ARCH_NEON_VFP_ARMV8},
32337 {"crypto-neon-fp-armv8",
32338 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8},
d6b4b13e 32339 {"neon-fp-armv8.1", FPU_ARCH_NEON_VFP_ARMV8_1},
081e4c7d
MW
32340 {"crypto-neon-fp-armv8.1",
32341 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1},
e74cfd16
PB
32342 {NULL, ARM_ARCH_NONE}
32343};
32344
32345struct arm_option_value_table
32346{
e0471c16 32347 const char *name;
e74cfd16 32348 long value;
c19d1205 32349};
7ed4c4c5 32350
e74cfd16 32351static const struct arm_option_value_table arm_float_abis[] =
c19d1205
ZW
32352{
32353 {"hard", ARM_FLOAT_ABI_HARD},
32354 {"softfp", ARM_FLOAT_ABI_SOFTFP},
32355 {"soft", ARM_FLOAT_ABI_SOFT},
e74cfd16 32356 {NULL, 0}
c19d1205 32357};
7ed4c4c5 32358
c19d1205 32359#ifdef OBJ_ELF
3a4a14e9 32360/* We only know how to output GNU and ver 4/5 (AAELF) formats. */
e74cfd16 32361static const struct arm_option_value_table arm_eabis[] =
c19d1205
ZW
32362{
32363 {"gnu", EF_ARM_EABI_UNKNOWN},
32364 {"4", EF_ARM_EABI_VER4},
3a4a14e9 32365 {"5", EF_ARM_EABI_VER5},
e74cfd16 32366 {NULL, 0}
c19d1205
ZW
32367};
32368#endif
7ed4c4c5 32369
c19d1205
ZW
32370struct arm_long_option_table
32371{
5b7c81bd
AM
32372 const char *option; /* Substring to match. */
32373 const char *help; /* Help information. */
32374 bool (*func) (const char *subopt); /* Function to decode sub-option. */
32375 const char *deprecated; /* If non-null, print this message. */
c19d1205 32376};
7ed4c4c5 32377
5b7c81bd 32378static bool
c168ce07 32379arm_parse_extension (const char *str, const arm_feature_set *opt_set,
34ef62f4
AV
32380 arm_feature_set *ext_set,
32381 const struct arm_ext_table *ext_table)
7ed4c4c5 32382{
69133863 32383 /* We insist on extensions being specified in alphabetical order, and with
fa94de6b
RM
32384 extensions being added before being removed. We achieve this by having
32385 the global ARM_EXTENSIONS table in alphabetical order, and using the
69133863 32386 ADDING_VALUE variable to indicate whether we are adding an extension (1)
fa94de6b 32387 or removing it (0) and only allowing it to change in the order
69133863
MGD
32388 -1 -> 1 -> 0. */
32389 const struct arm_option_extension_value_table * opt = NULL;
d942732e 32390 const arm_feature_set arm_any = ARM_ANY;
69133863
MGD
32391 int adding_value = -1;
32392
c19d1205 32393 while (str != NULL && *str != 0)
7ed4c4c5 32394 {
82b8a785 32395 const char *ext;
f3bad469 32396 size_t len;
7ed4c4c5 32397
c19d1205
ZW
32398 if (*str != '+')
32399 {
32400 as_bad (_("invalid architectural extension"));
5b7c81bd 32401 return false;
c19d1205 32402 }
7ed4c4c5 32403
c19d1205
ZW
32404 str++;
32405 ext = strchr (str, '+');
7ed4c4c5 32406
c19d1205 32407 if (ext != NULL)
f3bad469 32408 len = ext - str;
c19d1205 32409 else
f3bad469 32410 len = strlen (str);
7ed4c4c5 32411
d34049e8 32412 if (len >= 2 && startswith (str, "no"))
69133863
MGD
32413 {
32414 if (adding_value != 0)
32415 {
32416 adding_value = 0;
32417 opt = arm_extensions;
32418 }
32419
f3bad469 32420 len -= 2;
69133863
MGD
32421 str += 2;
32422 }
f3bad469 32423 else if (len > 0)
69133863
MGD
32424 {
32425 if (adding_value == -1)
32426 {
32427 adding_value = 1;
32428 opt = arm_extensions;
32429 }
32430 else if (adding_value != 1)
32431 {
32432 as_bad (_("must specify extensions to add before specifying "
32433 "those to remove"));
5b7c81bd 32434 return false;
69133863
MGD
32435 }
32436 }
32437
f3bad469 32438 if (len == 0)
c19d1205
ZW
32439 {
32440 as_bad (_("missing architectural extension"));
5b7c81bd 32441 return false;
c19d1205 32442 }
7ed4c4c5 32443
69133863
MGD
32444 gas_assert (adding_value != -1);
32445 gas_assert (opt != NULL);
32446
34ef62f4
AV
32447 if (ext_table != NULL)
32448 {
32449 const struct arm_ext_table * ext_opt = ext_table;
5b7c81bd 32450 bool found = false;
34ef62f4
AV
32451 for (; ext_opt->name != NULL; ext_opt++)
32452 if (ext_opt->name_len == len
32453 && strncmp (ext_opt->name, str, len) == 0)
32454 {
32455 if (adding_value)
32456 {
32457 if (ARM_FEATURE_ZERO (ext_opt->merge))
32458 /* TODO: Option not supported. When we remove the
32459 legacy table this case should error out. */
32460 continue;
32461
32462 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, ext_opt->merge);
32463 }
32464 else
32465 {
32466 if (ARM_FEATURE_ZERO (ext_opt->clear))
32467 /* TODO: Option not supported. When we remove the
32468 legacy table this case should error out. */
32469 continue;
32470 ARM_CLEAR_FEATURE (*ext_set, *ext_set, ext_opt->clear);
32471 }
5b7c81bd 32472 found = true;
34ef62f4
AV
32473 break;
32474 }
32475 if (found)
32476 {
32477 str = ext;
32478 continue;
32479 }
32480 }
32481
69133863
MGD
32482 /* Scan over the options table trying to find an exact match. */
32483 for (; opt->name != NULL; opt++)
f3bad469 32484 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32485 {
d942732e
TP
32486 int i, nb_allowed_archs =
32487 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
69133863 32488 /* Check we can apply the extension to this architecture. */
d942732e
TP
32489 for (i = 0; i < nb_allowed_archs; i++)
32490 {
32491 /* Empty entry. */
32492 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
32493 continue;
c168ce07 32494 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set))
d942732e
TP
32495 break;
32496 }
32497 if (i == nb_allowed_archs)
69133863
MGD
32498 {
32499 as_bad (_("extension does not apply to the base architecture"));
5b7c81bd 32500 return false;
69133863
MGD
32501 }
32502
32503 /* Add or remove the extension. */
32504 if (adding_value)
4d354d8b 32505 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value);
69133863 32506 else
4d354d8b 32507 ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value);
69133863 32508
3d030cdb
TP
32509 /* Allowing Thumb division instructions for ARMv7 in autodetection
32510 rely on this break so that duplicate extensions (extensions
32511 with the same name as a previous extension in the list) are not
32512 considered for command-line parsing. */
c19d1205
ZW
32513 break;
32514 }
7ed4c4c5 32515
c19d1205
ZW
32516 if (opt->name == NULL)
32517 {
69133863
MGD
32518 /* Did we fail to find an extension because it wasn't specified in
32519 alphabetical order, or because it does not exist? */
32520
32521 for (opt = arm_extensions; opt->name != NULL; opt++)
f3bad469 32522 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
69133863
MGD
32523 break;
32524
32525 if (opt->name == NULL)
32526 as_bad (_("unknown architectural extension `%s'"), str);
32527 else
32528 as_bad (_("architectural extensions must be specified in "
32529 "alphabetical order"));
32530
5b7c81bd 32531 return false;
c19d1205 32532 }
69133863
MGD
32533 else
32534 {
32535 /* We should skip the extension we've just matched the next time
32536 round. */
32537 opt++;
32538 }
7ed4c4c5 32539
c19d1205
ZW
32540 str = ext;
32541 };
7ed4c4c5 32542
5b7c81bd 32543 return true;
c19d1205 32544}
7ed4c4c5 32545
5b7c81bd 32546static bool
5312fe52
BW
32547arm_parse_fp16_opt (const char *str)
32548{
32549 if (strcasecmp (str, "ieee") == 0)
32550 fp16_format = ARM_FP16_FORMAT_IEEE;
32551 else if (strcasecmp (str, "alternative") == 0)
32552 fp16_format = ARM_FP16_FORMAT_ALTERNATIVE;
32553 else
32554 {
32555 as_bad (_("unrecognised float16 format \"%s\""), str);
5b7c81bd 32556 return false;
5312fe52
BW
32557 }
32558
5b7c81bd 32559 return true;
5312fe52
BW
32560}
32561
5b7c81bd 32562static bool
17b9d67d 32563arm_parse_cpu (const char *str)
7ed4c4c5 32564{
f3bad469 32565 const struct arm_cpu_option_table *opt;
82b8a785 32566 const char *ext = strchr (str, '+');
f3bad469 32567 size_t len;
7ed4c4c5 32568
c19d1205 32569 if (ext != NULL)
f3bad469 32570 len = ext - str;
7ed4c4c5 32571 else
f3bad469 32572 len = strlen (str);
7ed4c4c5 32573
f3bad469 32574 if (len == 0)
7ed4c4c5 32575 {
c19d1205 32576 as_bad (_("missing cpu name `%s'"), str);
5b7c81bd 32577 return false;
7ed4c4c5
NC
32578 }
32579
c19d1205 32580 for (opt = arm_cpus; opt->name != NULL; opt++)
f3bad469 32581 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32582 {
c168ce07 32583 mcpu_cpu_opt = &opt->value;
4d354d8b
TP
32584 if (mcpu_ext_opt == NULL)
32585 mcpu_ext_opt = XNEW (arm_feature_set);
32586 *mcpu_ext_opt = opt->ext;
e74cfd16 32587 mcpu_fpu_opt = &opt->default_fpu;
ee065d83 32588 if (opt->canonical_name)
ef8e6722
JW
32589 {
32590 gas_assert (sizeof selected_cpu_name > strlen (opt->canonical_name));
32591 strcpy (selected_cpu_name, opt->canonical_name);
32592 }
ee065d83
PB
32593 else
32594 {
f3bad469 32595 size_t i;
c921be7d 32596
ef8e6722
JW
32597 if (len >= sizeof selected_cpu_name)
32598 len = (sizeof selected_cpu_name) - 1;
32599
f3bad469 32600 for (i = 0; i < len; i++)
ee065d83
PB
32601 selected_cpu_name[i] = TOUPPER (opt->name[i]);
32602 selected_cpu_name[i] = 0;
32603 }
7ed4c4c5 32604
c19d1205 32605 if (ext != NULL)
34ef62f4 32606 return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt, NULL);
7ed4c4c5 32607
5b7c81bd 32608 return true;
c19d1205 32609 }
7ed4c4c5 32610
c19d1205 32611 as_bad (_("unknown cpu `%s'"), str);
5b7c81bd 32612 return false;
7ed4c4c5
NC
32613}
32614
5b7c81bd 32615static bool
17b9d67d 32616arm_parse_arch (const char *str)
7ed4c4c5 32617{
e74cfd16 32618 const struct arm_arch_option_table *opt;
82b8a785 32619 const char *ext = strchr (str, '+');
f3bad469 32620 size_t len;
7ed4c4c5 32621
c19d1205 32622 if (ext != NULL)
f3bad469 32623 len = ext - str;
7ed4c4c5 32624 else
f3bad469 32625 len = strlen (str);
7ed4c4c5 32626
f3bad469 32627 if (len == 0)
7ed4c4c5 32628 {
c19d1205 32629 as_bad (_("missing architecture name `%s'"), str);
5b7c81bd 32630 return false;
7ed4c4c5
NC
32631 }
32632
c19d1205 32633 for (opt = arm_archs; opt->name != NULL; opt++)
f3bad469 32634 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32635 {
e74cfd16 32636 march_cpu_opt = &opt->value;
4d354d8b
TP
32637 if (march_ext_opt == NULL)
32638 march_ext_opt = XNEW (arm_feature_set);
32639 *march_ext_opt = arm_arch_none;
e74cfd16 32640 march_fpu_opt = &opt->default_fpu;
e20f9590 32641 selected_ctx_ext_table = opt->ext_table;
5f4273c7 32642 strcpy (selected_cpu_name, opt->name);
7ed4c4c5 32643
c19d1205 32644 if (ext != NULL)
34ef62f4
AV
32645 return arm_parse_extension (ext, march_cpu_opt, march_ext_opt,
32646 opt->ext_table);
7ed4c4c5 32647
5b7c81bd 32648 return true;
c19d1205
ZW
32649 }
32650
32651 as_bad (_("unknown architecture `%s'\n"), str);
5b7c81bd 32652 return false;
7ed4c4c5 32653}
eb043451 32654
5b7c81bd 32655static bool
17b9d67d 32656arm_parse_fpu (const char * str)
c19d1205 32657{
69133863 32658 const struct arm_option_fpu_value_table * opt;
b99bd4ef 32659
c19d1205
ZW
32660 for (opt = arm_fpus; opt->name != NULL; opt++)
32661 if (streq (opt->name, str))
32662 {
e74cfd16 32663 mfpu_opt = &opt->value;
5b7c81bd 32664 return true;
c19d1205 32665 }
b99bd4ef 32666
c19d1205 32667 as_bad (_("unknown floating point format `%s'\n"), str);
5b7c81bd 32668 return false;
c19d1205
ZW
32669}
32670
5b7c81bd 32671static bool
17b9d67d 32672arm_parse_float_abi (const char * str)
b99bd4ef 32673{
e74cfd16 32674 const struct arm_option_value_table * opt;
b99bd4ef 32675
c19d1205
ZW
32676 for (opt = arm_float_abis; opt->name != NULL; opt++)
32677 if (streq (opt->name, str))
32678 {
32679 mfloat_abi_opt = opt->value;
5b7c81bd 32680 return true;
c19d1205 32681 }
cc8a6dd0 32682
c19d1205 32683 as_bad (_("unknown floating point abi `%s'\n"), str);
5b7c81bd 32684 return false;
c19d1205 32685}
b99bd4ef 32686
c19d1205 32687#ifdef OBJ_ELF
5b7c81bd 32688static bool
17b9d67d 32689arm_parse_eabi (const char * str)
c19d1205 32690{
e74cfd16 32691 const struct arm_option_value_table *opt;
cc8a6dd0 32692
c19d1205
ZW
32693 for (opt = arm_eabis; opt->name != NULL; opt++)
32694 if (streq (opt->name, str))
32695 {
32696 meabi_flags = opt->value;
5b7c81bd 32697 return true;
c19d1205
ZW
32698 }
32699 as_bad (_("unknown EABI `%s'\n"), str);
5b7c81bd 32700 return false;
c19d1205
ZW
32701}
32702#endif
cc8a6dd0 32703
5b7c81bd 32704static bool
17b9d67d 32705arm_parse_it_mode (const char * str)
e07e6e58 32706{
5b7c81bd 32707 bool ret = true;
e07e6e58
NC
32708
32709 if (streq ("arm", str))
32710 implicit_it_mode = IMPLICIT_IT_MODE_ARM;
32711 else if (streq ("thumb", str))
32712 implicit_it_mode = IMPLICIT_IT_MODE_THUMB;
32713 else if (streq ("always", str))
32714 implicit_it_mode = IMPLICIT_IT_MODE_ALWAYS;
32715 else if (streq ("never", str))
32716 implicit_it_mode = IMPLICIT_IT_MODE_NEVER;
32717 else
32718 {
32719 as_bad (_("unknown implicit IT mode `%s', should be "\
477330fc 32720 "arm, thumb, always, or never."), str);
5b7c81bd 32721 ret = false;
e07e6e58
NC
32722 }
32723
32724 return ret;
32725}
32726
5b7c81bd 32727static bool
17b9d67d 32728arm_ccs_mode (const char * unused ATTRIBUTE_UNUSED)
2e6976a8 32729{
5b7c81bd 32730 codecomposer_syntax = true;
2e6976a8
DG
32731 arm_comment_chars[0] = ';';
32732 arm_line_separator_chars[0] = 0;
5b7c81bd 32733 return true;
2e6976a8
DG
32734}
32735
c19d1205
ZW
32736struct arm_long_option_table arm_long_opts[] =
32737{
32738 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
32739 arm_parse_cpu, NULL},
32740 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
32741 arm_parse_arch, NULL},
32742 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
32743 arm_parse_fpu, NULL},
32744 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
32745 arm_parse_float_abi, NULL},
32746#ifdef OBJ_ELF
7fac0536 32747 {"meabi=", N_("<ver>\t\t assemble for eabi version <ver>"),
c19d1205
ZW
32748 arm_parse_eabi, NULL},
32749#endif
e07e6e58
NC
32750 {"mimplicit-it=", N_("<mode>\t controls implicit insertion of IT instructions"),
32751 arm_parse_it_mode, NULL},
2e6976a8
DG
32752 {"mccs", N_("\t\t\t TI CodeComposer Studio syntax compatibility mode"),
32753 arm_ccs_mode, NULL},
5312fe52
BW
32754 {"mfp16-format=",
32755 N_("[ieee|alternative]\n\
32756 set the encoding for half precision floating point "
32757 "numbers to IEEE\n\
32758 or Arm alternative format."),
32759 arm_parse_fp16_opt, NULL },
c19d1205
ZW
32760 {NULL, NULL, 0, NULL}
32761};
cc8a6dd0 32762
c19d1205 32763int
17b9d67d 32764md_parse_option (int c, const char * arg)
c19d1205
ZW
32765{
32766 struct arm_option_table *opt;
e74cfd16 32767 const struct arm_legacy_option_table *fopt;
c19d1205 32768 struct arm_long_option_table *lopt;
b99bd4ef 32769
c19d1205 32770 switch (c)
b99bd4ef 32771 {
c19d1205
ZW
32772#ifdef OPTION_EB
32773 case OPTION_EB:
32774 target_big_endian = 1;
32775 break;
32776#endif
cc8a6dd0 32777
c19d1205
ZW
32778#ifdef OPTION_EL
32779 case OPTION_EL:
32780 target_big_endian = 0;
32781 break;
32782#endif
b99bd4ef 32783
845b51d6 32784 case OPTION_FIX_V4BX:
5b7c81bd 32785 fix_v4bx = true;
845b51d6
PB
32786 break;
32787
18a20338
CL
32788#ifdef OBJ_ELF
32789 case OPTION_FDPIC:
5b7c81bd 32790 arm_fdpic = true;
18a20338
CL
32791 break;
32792#endif /* OBJ_ELF */
32793
c19d1205
ZW
32794 case 'a':
32795 /* Listing option. Just ignore these, we don't support additional
32796 ones. */
32797 return 0;
b99bd4ef 32798
c19d1205
ZW
32799 default:
32800 for (opt = arm_opts; opt->option != NULL; opt++)
32801 {
32802 if (c == opt->option[0]
32803 && ((arg == NULL && opt->option[1] == 0)
32804 || streq (arg, opt->option + 1)))
32805 {
c19d1205 32806 /* If the option is deprecated, tell the user. */
278df34e 32807 if (warn_on_deprecated && opt->deprecated != NULL)
c19d1205
ZW
32808 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
32809 arg ? arg : "", _(opt->deprecated));
b99bd4ef 32810
c19d1205
ZW
32811 if (opt->var != NULL)
32812 *opt->var = opt->value;
cc8a6dd0 32813
c19d1205
ZW
32814 return 1;
32815 }
32816 }
b99bd4ef 32817
e74cfd16
PB
32818 for (fopt = arm_legacy_opts; fopt->option != NULL; fopt++)
32819 {
32820 if (c == fopt->option[0]
32821 && ((arg == NULL && fopt->option[1] == 0)
32822 || streq (arg, fopt->option + 1)))
32823 {
e74cfd16 32824 /* If the option is deprecated, tell the user. */
278df34e 32825 if (warn_on_deprecated && fopt->deprecated != NULL)
e74cfd16
PB
32826 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
32827 arg ? arg : "", _(fopt->deprecated));
e74cfd16
PB
32828
32829 if (fopt->var != NULL)
32830 *fopt->var = &fopt->value;
32831
32832 return 1;
32833 }
32834 }
32835
c19d1205
ZW
32836 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
32837 {
32838 /* These options are expected to have an argument. */
32839 if (c == lopt->option[0]
32840 && arg != NULL
32841 && strncmp (arg, lopt->option + 1,
32842 strlen (lopt->option + 1)) == 0)
32843 {
c19d1205 32844 /* If the option is deprecated, tell the user. */
278df34e 32845 if (warn_on_deprecated && lopt->deprecated != NULL)
c19d1205
ZW
32846 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
32847 _(lopt->deprecated));
b99bd4ef 32848
c19d1205
ZW
32849 /* Call the sup-option parser. */
32850 return lopt->func (arg + strlen (lopt->option) - 1);
32851 }
32852 }
a737bd4d 32853
c19d1205
ZW
32854 return 0;
32855 }
a394c00f 32856
c19d1205
ZW
32857 return 1;
32858}
a394c00f 32859
c19d1205
ZW
32860void
32861md_show_usage (FILE * fp)
a394c00f 32862{
c19d1205
ZW
32863 struct arm_option_table *opt;
32864 struct arm_long_option_table *lopt;
a394c00f 32865
c19d1205 32866 fprintf (fp, _(" ARM-specific assembler options:\n"));
a394c00f 32867
c19d1205
ZW
32868 for (opt = arm_opts; opt->option != NULL; opt++)
32869 if (opt->help != NULL)
32870 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
a394c00f 32871
c19d1205
ZW
32872 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
32873 if (lopt->help != NULL)
32874 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
a394c00f 32875
c19d1205
ZW
32876#ifdef OPTION_EB
32877 fprintf (fp, _("\
32878 -EB assemble code for a big-endian cpu\n"));
a394c00f
NC
32879#endif
32880
c19d1205
ZW
32881#ifdef OPTION_EL
32882 fprintf (fp, _("\
32883 -EL assemble code for a little-endian cpu\n"));
a737bd4d 32884#endif
845b51d6
PB
32885
32886 fprintf (fp, _("\
32887 --fix-v4bx Allow BX in ARMv4 code\n"));
18a20338
CL
32888
32889#ifdef OBJ_ELF
32890 fprintf (fp, _("\
32891 --fdpic generate an FDPIC object file\n"));
32892#endif /* OBJ_ELF */
c19d1205 32893}
ee065d83 32894
ee065d83 32895#ifdef OBJ_ELF
0198d5e6 32896
62b3e311
PB
32897typedef struct
32898{
32899 int val;
32900 arm_feature_set flags;
32901} cpu_arch_ver_table;
32902
2c6b98ea
TP
32903/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
32904 chronologically for architectures, with an exception for ARMv6-M and
32905 ARMv6S-M due to legacy reasons. No new architecture should have a
32906 special case. This allows for build attribute selection results to be
32907 stable when new architectures are added. */
62b3e311
PB
32908static const cpu_arch_ver_table cpu_arch_ver[] =
32909{
031254f2
AV
32910 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V1},
32911 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2},
32912 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2S},
32913 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3},
32914 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3M},
32915 {TAG_CPU_ARCH_V4, ARM_ARCH_V4xM},
32916 {TAG_CPU_ARCH_V4, ARM_ARCH_V4},
32917 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4TxM},
32918 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4T},
32919 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5xM},
32920 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5},
32921 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5TxM},
32922 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5T},
32923 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TExP},
32924 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TE},
32925 {TAG_CPU_ARCH_V5TEJ, ARM_ARCH_V5TEJ},
32926 {TAG_CPU_ARCH_V6, ARM_ARCH_V6},
32927 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6Z},
32928 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6KZ},
32929 {TAG_CPU_ARCH_V6K, ARM_ARCH_V6K},
32930 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6T2},
32931 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KT2},
32932 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6ZT2},
32933 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KZT2},
2c6b98ea
TP
32934
32935 /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
32936 always selected build attributes to match those of ARMv6-M
32937 (resp. ARMv6S-M). However, due to these architectures being a strict
32938 subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
32939 would be selected when fully respecting chronology of architectures.
32940 It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
32941 move them before ARMv7 architectures. */
031254f2
AV
32942 {TAG_CPU_ARCH_V6_M, ARM_ARCH_V6M},
32943 {TAG_CPU_ARCH_V6S_M, ARM_ARCH_V6SM},
32944
32945 {TAG_CPU_ARCH_V7, ARM_ARCH_V7},
32946 {TAG_CPU_ARCH_V7, ARM_ARCH_V7A},
32947 {TAG_CPU_ARCH_V7, ARM_ARCH_V7R},
32948 {TAG_CPU_ARCH_V7, ARM_ARCH_V7M},
32949 {TAG_CPU_ARCH_V7, ARM_ARCH_V7VE},
32950 {TAG_CPU_ARCH_V7E_M, ARM_ARCH_V7EM},
32951 {TAG_CPU_ARCH_V8, ARM_ARCH_V8A},
32952 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_1A},
32953 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_2A},
32954 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_3A},
32955 {TAG_CPU_ARCH_V8M_BASE, ARM_ARCH_V8M_BASE},
32956 {TAG_CPU_ARCH_V8M_MAIN, ARM_ARCH_V8M_MAIN},
32957 {TAG_CPU_ARCH_V8R, ARM_ARCH_V8R},
32958 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_4A},
32959 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_5A},
32960 {TAG_CPU_ARCH_V8_1M_MAIN, ARM_ARCH_V8_1M_MAIN},
aab2c27d 32961 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_6A},
b3e4d932
RS
32962 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_7A},
32963 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_8A},
b3b647dc 32964 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_9A},
3197e593 32965 {TAG_CPU_ARCH_V9, ARM_ARCH_V9A},
a2b1ea81
RS
32966 {TAG_CPU_ARCH_V9, ARM_ARCH_V9_1A},
32967 {TAG_CPU_ARCH_V9, ARM_ARCH_V9_2A},
32968 {TAG_CPU_ARCH_V9, ARM_ARCH_V9_3A},
b3b647dc 32969 {TAG_CPU_ARCH_V9, ARM_ARCH_V9_4A},
b47cef7c 32970 {TAG_CPU_ARCH_V9, ARM_ARCH_V9_5A},
aab2c27d 32971 {-1, ARM_ARCH_NONE}
62b3e311
PB
32972};
32973
ee3c0378 32974/* Set an attribute if it has not already been set by the user. */
0198d5e6 32975
ee3c0378
AS
32976static void
32977aeabi_set_attribute_int (int tag, int value)
32978{
32979 if (tag < 1
32980 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
32981 || !attributes_set_explicitly[tag])
a1d1634d
AM
32982 if (!bfd_elf_add_proc_attr_int (stdoutput, tag, value))
32983 as_fatal (_("error adding attribute: %s"),
32984 bfd_errmsg (bfd_get_error ()));
ee3c0378
AS
32985}
32986
32987static void
32988aeabi_set_attribute_string (int tag, const char *value)
32989{
32990 if (tag < 1
32991 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
32992 || !attributes_set_explicitly[tag])
a1d1634d
AM
32993 if (!bfd_elf_add_proc_attr_string (stdoutput, tag, value))
32994 as_fatal (_("error adding attribute: %s"),
32995 bfd_errmsg (bfd_get_error ()));
ee3c0378
AS
32996}
32997
2c6b98ea
TP
32998/* Return whether features in the *NEEDED feature set are available via
32999 extensions for the architecture whose feature set is *ARCH_FSET. */
0198d5e6 33000
5b7c81bd 33001static bool
2c6b98ea
TP
33002have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
33003 const arm_feature_set *needed)
33004{
33005 int i, nb_allowed_archs;
33006 arm_feature_set ext_fset;
33007 const struct arm_option_extension_value_table *opt;
33008
33009 ext_fset = arm_arch_none;
33010 for (opt = arm_extensions; opt->name != NULL; opt++)
33011 {
33012 /* Extension does not provide any feature we need. */
33013 if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
33014 continue;
33015
33016 nb_allowed_archs =
33017 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
33018 for (i = 0; i < nb_allowed_archs; i++)
33019 {
33020 /* Empty entry. */
33021 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
33022 break;
33023
33024 /* Extension is available, add it. */
33025 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
33026 ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
33027 }
33028 }
33029
33030 /* Can we enable all features in *needed? */
33031 return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
33032}
33033
33034/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
33035 a given architecture feature set *ARCH_EXT_FSET including extension feature
33036 set *EXT_FSET. Selection logic used depend on EXACT_MATCH:
33037 - if true, check for an exact match of the architecture modulo extensions;
33038 - otherwise, select build attribute value of the first superset
33039 architecture released so that results remains stable when new architectures
33040 are added.
33041 For -march/-mcpu=all the build attribute value of the most featureful
33042 architecture is returned. Tag_CPU_arch_profile result is returned in
33043 PROFILE. */
0198d5e6 33044
2c6b98ea
TP
33045static int
33046get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
33047 const arm_feature_set *ext_fset,
33048 char *profile, int exact_match)
33049{
33050 arm_feature_set arch_fset;
33051 const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
33052
33053 /* Select most featureful architecture with all its extensions if building
33054 for -march=all as the feature sets used to set build attributes. */
33055 if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
33056 {
33057 /* Force revisiting of decision for each new architecture. */
3197e593 33058 gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V9);
2c6b98ea 33059 *profile = 'A';
3197e593 33060 return TAG_CPU_ARCH_V9;
2c6b98ea
TP
33061 }
33062
33063 ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
33064
33065 for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
33066 {
33067 arm_feature_set known_arch_fset;
33068
33069 ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
33070 if (exact_match)
33071 {
33072 /* Base architecture match user-specified architecture and
33073 extensions, eg. ARMv6S-M matching -march=armv6-m+os. */
33074 if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
33075 {
33076 p_ver_ret = p_ver;
33077 goto found;
33078 }
33079 /* Base architecture match user-specified architecture only
33080 (eg. ARMv6-M in the same case as above). Record it in case we
33081 find a match with above condition. */
33082 else if (p_ver_ret == NULL
33083 && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
33084 p_ver_ret = p_ver;
33085 }
33086 else
33087 {
33088
33089 /* Architecture has all features wanted. */
33090 if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
33091 {
33092 arm_feature_set added_fset;
33093
33094 /* Compute features added by this architecture over the one
33095 recorded in p_ver_ret. */
33096 if (p_ver_ret != NULL)
33097 ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
33098 p_ver_ret->flags);
33099 /* First architecture that match incl. with extensions, or the
33100 only difference in features over the recorded match is
33101 features that were optional and are now mandatory. */
33102 if (p_ver_ret == NULL
33103 || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
33104 {
33105 p_ver_ret = p_ver;
33106 goto found;
33107 }
33108 }
33109 else if (p_ver_ret == NULL)
33110 {
33111 arm_feature_set needed_ext_fset;
33112
33113 ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
33114
33115 /* Architecture has all features needed when using some
33116 extensions. Record it and continue searching in case there
33117 exist an architecture providing all needed features without
33118 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
33119 OS extension). */
33120 if (have_ext_for_needed_feat_p (&known_arch_fset,
33121 &needed_ext_fset))
33122 p_ver_ret = p_ver;
33123 }
33124 }
33125 }
33126
33127 if (p_ver_ret == NULL)
33128 return -1;
33129
dc1e8a47 33130 found:
2c6b98ea 33131 /* Tag_CPU_arch_profile. */
164446e0
AF
33132 if (!ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8r)
33133 && (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
33134 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
33135 || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
33136 && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only))))
2c6b98ea 33137 *profile = 'A';
164446e0
AF
33138 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r)
33139 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8r))
2c6b98ea
TP
33140 *profile = 'R';
33141 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
33142 *profile = 'M';
33143 else
33144 *profile = '\0';
33145 return p_ver_ret->val;
33146}
33147
ee065d83 33148/* Set the public EABI object attributes. */
0198d5e6 33149
c168ce07 33150static void
ee065d83
PB
33151aeabi_set_public_attributes (void)
33152{
b90d5ba0 33153 char profile = '\0';
2c6b98ea 33154 int arch = -1;
90ec0d68 33155 int virt_sec = 0;
bca38921 33156 int fp16_optional = 0;
2c6b98ea
TP
33157 int skip_exact_match = 0;
33158 arm_feature_set flags, flags_arch, flags_ext;
ee065d83 33159
54bab281
TP
33160 /* Autodetection mode, choose the architecture based the instructions
33161 actually used. */
33162 if (no_cpu_selected ())
33163 {
33164 ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
ddd7f988 33165
54bab281
TP
33166 if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
33167 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
ddd7f988 33168
54bab281
TP
33169 if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
33170 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
ddd7f988 33171
54bab281 33172 /* Code run during relaxation relies on selected_cpu being set. */
4d354d8b
TP
33173 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
33174 flags_ext = arm_arch_none;
33175 ARM_CLEAR_FEATURE (selected_arch, flags_arch, flags_ext);
33176 selected_ext = flags_ext;
54bab281
TP
33177 selected_cpu = flags;
33178 }
33179 /* Otherwise, choose the architecture based on the capabilities of the
33180 requested cpu. */
33181 else
4d354d8b
TP
33182 {
33183 ARM_MERGE_FEATURE_SETS (flags_arch, selected_arch, selected_ext);
33184 ARM_CLEAR_FEATURE (flags_arch, flags_arch, fpu_any);
33185 flags_ext = selected_ext;
33186 flags = selected_cpu;
33187 }
33188 ARM_MERGE_FEATURE_SETS (flags, flags, selected_fpu);
7f78eb34 33189
ddd7f988 33190 /* Allow the user to override the reported architecture. */
4d354d8b 33191 if (!ARM_FEATURE_ZERO (selected_object_arch))
7a1d4c38 33192 {
4d354d8b 33193 ARM_CLEAR_FEATURE (flags_arch, selected_object_arch, fpu_any);
2c6b98ea 33194 flags_ext = arm_arch_none;
7a1d4c38 33195 }
2c6b98ea 33196 else
4d354d8b 33197 skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
2c6b98ea
TP
33198
33199 /* When this function is run again after relaxation has happened there is no
33200 way to determine whether an architecture or CPU was specified by the user:
33201 - selected_cpu is set above for relaxation to work;
33202 - march_cpu_opt is not set if only -mcpu or .cpu is used;
33203 - mcpu_cpu_opt is set to arm_arch_any for autodetection.
33204 Therefore, if not in -march=all case we first try an exact match and fall
33205 back to autodetection. */
33206 if (!skip_exact_match)
33207 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
33208 if (arch == -1)
33209 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
33210 if (arch == -1)
33211 as_bad (_("no architecture contains all the instructions used\n"));
9e3c6df6 33212
ee065d83
PB
33213 /* Tag_CPU_name. */
33214 if (selected_cpu_name[0])
33215 {
91d6fa6a 33216 char *q;
ee065d83 33217
91d6fa6a 33218 q = selected_cpu_name;
d34049e8 33219 if (startswith (q, "armv"))
ee065d83
PB
33220 {
33221 int i;
5f4273c7 33222
91d6fa6a
NC
33223 q += 4;
33224 for (i = 0; q[i]; i++)
33225 q[i] = TOUPPER (q[i]);
ee065d83 33226 }
91d6fa6a 33227 aeabi_set_attribute_string (Tag_CPU_name, q);
ee065d83 33228 }
62f3b8c8 33229
ee065d83 33230 /* Tag_CPU_arch. */
ee3c0378 33231 aeabi_set_attribute_int (Tag_CPU_arch, arch);
62f3b8c8 33232
62b3e311 33233 /* Tag_CPU_arch_profile. */
69239280
MGD
33234 if (profile != '\0')
33235 aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
62f3b8c8 33236
15afaa63 33237 /* Tag_DSP_extension. */
4d354d8b 33238 if (ARM_CPU_HAS_FEATURE (selected_ext, arm_ext_dsp))
6c290d53 33239 aeabi_set_attribute_int (Tag_DSP_extension, 1);
15afaa63 33240
2c6b98ea 33241 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
ee065d83 33242 /* Tag_ARM_ISA_use. */
ee3c0378 33243 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
2c6b98ea 33244 || ARM_FEATURE_ZERO (flags_arch))
ee3c0378 33245 aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
62f3b8c8 33246
ee065d83 33247 /* Tag_THUMB_ISA_use. */
ee3c0378 33248 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
2c6b98ea 33249 || ARM_FEATURE_ZERO (flags_arch))
4ed7ed8d
TP
33250 {
33251 int thumb_isa_use;
33252
33253 if (!ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
16a1fa25 33254 && ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only))
4ed7ed8d
TP
33255 thumb_isa_use = 3;
33256 else if (ARM_CPU_HAS_FEATURE (flags, arm_arch_t2))
33257 thumb_isa_use = 2;
33258 else
33259 thumb_isa_use = 1;
33260 aeabi_set_attribute_int (Tag_THUMB_ISA_use, thumb_isa_use);
33261 }
62f3b8c8 33262
ee065d83 33263 /* Tag_VFP_arch. */
a715796b
TG
33264 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_armv8xd))
33265 aeabi_set_attribute_int (Tag_VFP_arch,
33266 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
33267 ? 7 : 8);
bca38921 33268 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_fma))
62f3b8c8
PB
33269 aeabi_set_attribute_int (Tag_VFP_arch,
33270 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
33271 ? 5 : 6);
33272 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32))
bca38921
MGD
33273 {
33274 fp16_optional = 1;
33275 aeabi_set_attribute_int (Tag_VFP_arch, 3);
33276 }
ada65aa3 33277 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v3xd))
bca38921
MGD
33278 {
33279 aeabi_set_attribute_int (Tag_VFP_arch, 4);
33280 fp16_optional = 1;
33281 }
ee3c0378
AS
33282 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v2))
33283 aeabi_set_attribute_int (Tag_VFP_arch, 2);
33284 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1)
477330fc 33285 || ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd))
ee3c0378 33286 aeabi_set_attribute_int (Tag_VFP_arch, 1);
62f3b8c8 33287
4547cb56
NC
33288 /* Tag_ABI_HardFP_use. */
33289 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd)
33290 && !ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1))
33291 aeabi_set_attribute_int (Tag_ABI_HardFP_use, 1);
33292
ee065d83 33293 /* Tag_WMMX_arch. */
ee3c0378
AS
33294 if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt2))
33295 aeabi_set_attribute_int (Tag_WMMX_arch, 2);
33296 else if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt))
33297 aeabi_set_attribute_int (Tag_WMMX_arch, 1);
62f3b8c8 33298
ee3c0378 33299 /* Tag_Advanced_SIMD_arch (formerly Tag_NEON_arch). */
9411fd44
MW
33300 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v8_1))
33301 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 4);
33302 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_armv8))
bca38921
MGD
33303 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 3);
33304 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v1))
33305 {
33306 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_fma))
33307 {
33308 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 2);
33309 }
33310 else
33311 {
33312 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 1);
33313 fp16_optional = 1;
33314 }
33315 }
fa94de6b 33316
a7ad558c
AV
33317 if (ARM_CPU_HAS_FEATURE (flags, mve_fp_ext))
33318 aeabi_set_attribute_int (Tag_MVE_arch, 2);
33319 else if (ARM_CPU_HAS_FEATURE (flags, mve_ext))
33320 aeabi_set_attribute_int (Tag_MVE_arch, 1);
33321
ee3c0378 33322 /* Tag_VFP_HP_extension (formerly Tag_NEON_FP16_arch). */
bca38921 33323 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_fp16) && fp16_optional)
ee3c0378 33324 aeabi_set_attribute_int (Tag_VFP_HP_extension, 1);
4547cb56 33325
69239280
MGD
33326 /* Tag_DIV_use.
33327
33328 We set Tag_DIV_use to two when integer divide instructions have been used
33329 in ARM state, or when Thumb integer divide instructions have been used,
33330 but we have no architecture profile set, nor have we any ARM instructions.
33331
4ed7ed8d
TP
33332 For ARMv8-A and ARMv8-M we set the tag to 0 as integer divide is implied
33333 by the base architecture.
bca38921 33334
69239280 33335 For new architectures we will have to check these tests. */
3197e593 33336 gas_assert (arch <= TAG_CPU_ARCH_V9);
4ed7ed8d
TP
33337 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
33338 || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
bca38921
MGD
33339 aeabi_set_attribute_int (Tag_DIV_use, 0);
33340 else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_adiv)
33341 || (profile == '\0'
33342 && ARM_CPU_HAS_FEATURE (flags, arm_ext_div)
33343 && !ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any)))
eea54501 33344 aeabi_set_attribute_int (Tag_DIV_use, 2);
60e5ef9f
MGD
33345
33346 /* Tag_MP_extension_use. */
33347 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_mp))
33348 aeabi_set_attribute_int (Tag_MPextension_use, 1);
f4c65163
MGD
33349
33350 /* Tag Virtualization_use. */
33351 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_sec))
90ec0d68
MGD
33352 virt_sec |= 1;
33353 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_virt))
33354 virt_sec |= 2;
33355 if (virt_sec != 0)
33356 aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
5312fe52
BW
33357
33358 if (fp16_format != ARM_FP16_FORMAT_DEFAULT)
33359 aeabi_set_attribute_int (Tag_ABI_FP_16bit_format, fp16_format);
ee065d83
PB
33360}
33361
c168ce07
TP
33362/* Post relaxation hook. Recompute ARM attributes now that relaxation is
33363 finished and free extension feature bits which will not be used anymore. */
0198d5e6 33364
c168ce07
TP
33365void
33366arm_md_post_relax (void)
33367{
33368 aeabi_set_public_attributes ();
4d354d8b
TP
33369 XDELETE (mcpu_ext_opt);
33370 mcpu_ext_opt = NULL;
33371 XDELETE (march_ext_opt);
33372 march_ext_opt = NULL;
c168ce07
TP
33373}
33374
104d59d1 33375/* Add the default contents for the .ARM.attributes section. */
0198d5e6 33376
ee065d83 33377void
ed2917de 33378arm_md_finish (void)
ee065d83 33379{
ee065d83
PB
33380 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
33381 return;
33382
33383 aeabi_set_public_attributes ();
ee065d83 33384}
8463be01 33385#endif /* OBJ_ELF */
ee065d83 33386
ee065d83
PB
33387/* Parse a .cpu directive. */
33388
33389static void
33390s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
33391{
e74cfd16 33392 const struct arm_cpu_option_table *opt;
ee065d83
PB
33393 char *name;
33394 char saved_char;
33395
33396 name = input_line_pointer;
a37854f9 33397 input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
ee065d83
PB
33398 saved_char = *input_line_pointer;
33399 *input_line_pointer = 0;
33400
a37854f9
RE
33401 if (!*name)
33402 {
33403 as_bad (_(".cpu: missing cpu name"));
33404 *input_line_pointer = saved_char;
33405 return;
33406 }
33407
ee065d83
PB
33408 /* Skip the first "all" entry. */
33409 for (opt = arm_cpus + 1; opt->name != NULL; opt++)
33410 if (streq (opt->name, name))
33411 {
4d354d8b
TP
33412 selected_arch = opt->value;
33413 selected_ext = opt->ext;
33414 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
ee065d83 33415 if (opt->canonical_name)
5f4273c7 33416 strcpy (selected_cpu_name, opt->canonical_name);
ee065d83
PB
33417 else
33418 {
33419 int i;
33420 for (i = 0; opt->name[i]; i++)
33421 selected_cpu_name[i] = TOUPPER (opt->name[i]);
f3bad469 33422
ee065d83
PB
33423 selected_cpu_name[i] = 0;
33424 }
4d354d8b
TP
33425 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
33426
ee065d83
PB
33427 *input_line_pointer = saved_char;
33428 demand_empty_rest_of_line ();
33429 return;
33430 }
33431 as_bad (_("unknown cpu `%s'"), name);
33432 *input_line_pointer = saved_char;
ee065d83
PB
33433}
33434
ee065d83
PB
33435/* Parse a .arch directive. */
33436
33437static void
33438s_arm_arch (int ignored ATTRIBUTE_UNUSED)
33439{
e74cfd16 33440 const struct arm_arch_option_table *opt;
ee065d83
PB
33441 char saved_char;
33442 char *name;
33443
33444 name = input_line_pointer;
a37854f9 33445 input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
ee065d83
PB
33446 saved_char = *input_line_pointer;
33447 *input_line_pointer = 0;
33448
a37854f9
RE
33449 if (!*name)
33450 {
33451 as_bad (_(".arch: missing architecture name"));
33452 *input_line_pointer = saved_char;
33453 return;
33454 }
33455
ee065d83
PB
33456 /* Skip the first "all" entry. */
33457 for (opt = arm_archs + 1; opt->name != NULL; opt++)
33458 if (streq (opt->name, name))
33459 {
4d354d8b 33460 selected_arch = opt->value;
0e7aaa72 33461 selected_ctx_ext_table = opt->ext_table;
4d354d8b
TP
33462 selected_ext = arm_arch_none;
33463 selected_cpu = selected_arch;
5f4273c7 33464 strcpy (selected_cpu_name, opt->name);
4d354d8b 33465 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
33466 *input_line_pointer = saved_char;
33467 demand_empty_rest_of_line ();
33468 return;
33469 }
33470
33471 as_bad (_("unknown architecture `%s'\n"), name);
33472 *input_line_pointer = saved_char;
33473 ignore_rest_of_line ();
33474}
33475
7a1d4c38
PB
33476/* Parse a .object_arch directive. */
33477
33478static void
33479s_arm_object_arch (int ignored ATTRIBUTE_UNUSED)
33480{
33481 const struct arm_arch_option_table *opt;
33482 char saved_char;
33483 char *name;
33484
33485 name = input_line_pointer;
a37854f9 33486 input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
7a1d4c38
PB
33487 saved_char = *input_line_pointer;
33488 *input_line_pointer = 0;
33489
a37854f9
RE
33490 if (!*name)
33491 {
33492 as_bad (_(".object_arch: missing architecture name"));
33493 *input_line_pointer = saved_char;
33494 return;
33495 }
33496
7a1d4c38
PB
33497 /* Skip the first "all" entry. */
33498 for (opt = arm_archs + 1; opt->name != NULL; opt++)
33499 if (streq (opt->name, name))
33500 {
4d354d8b 33501 selected_object_arch = opt->value;
7a1d4c38
PB
33502 *input_line_pointer = saved_char;
33503 demand_empty_rest_of_line ();
33504 return;
33505 }
33506
33507 as_bad (_("unknown architecture `%s'\n"), name);
33508 *input_line_pointer = saved_char;
33509 ignore_rest_of_line ();
33510}
33511
69133863
MGD
33512/* Parse a .arch_extension directive. */
33513
33514static void
33515s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
33516{
33517 const struct arm_option_extension_value_table *opt;
33518 char saved_char;
33519 char *name;
33520 int adding_value = 1;
33521
33522 name = input_line_pointer;
a37854f9 33523 input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
69133863
MGD
33524 saved_char = *input_line_pointer;
33525 *input_line_pointer = 0;
33526
a37854f9
RE
33527 if (!*name)
33528 {
33529 as_bad (_(".arch_extension: missing architecture extension"));
33530 *input_line_pointer = saved_char;
33531 return;
33532 }
33533
69133863 33534 if (strlen (name) >= 2
d34049e8 33535 && startswith (name, "no"))
69133863
MGD
33536 {
33537 adding_value = 0;
33538 name += 2;
33539 }
33540
e20f9590
MI
33541 /* Check the context specific extension table */
33542 if (selected_ctx_ext_table)
33543 {
33544 const struct arm_ext_table * ext_opt;
33545 for (ext_opt = selected_ctx_ext_table; ext_opt->name != NULL; ext_opt++)
33546 {
33547 if (streq (ext_opt->name, name))
33548 {
33549 if (adding_value)
33550 {
33551 if (ARM_FEATURE_ZERO (ext_opt->merge))
33552 /* TODO: Option not supported. When we remove the
33553 legacy table this case should error out. */
33554 continue;
33555 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
33556 ext_opt->merge);
33557 }
33558 else
33559 ARM_CLEAR_FEATURE (selected_ext, selected_ext, ext_opt->clear);
33560
33561 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
33562 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
33563 *input_line_pointer = saved_char;
33564 demand_empty_rest_of_line ();
33565 return;
33566 }
33567 }
33568 }
33569
69133863
MGD
33570 for (opt = arm_extensions; opt->name != NULL; opt++)
33571 if (streq (opt->name, name))
33572 {
d942732e
TP
33573 int i, nb_allowed_archs =
33574 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[i]);
33575 for (i = 0; i < nb_allowed_archs; i++)
33576 {
33577 /* Empty entry. */
4d354d8b 33578 if (ARM_CPU_IS_ANY (opt->allowed_archs[i]))
d942732e 33579 continue;
4d354d8b 33580 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], selected_arch))
d942732e
TP
33581 break;
33582 }
33583
33584 if (i == nb_allowed_archs)
69133863
MGD
33585 {
33586 as_bad (_("architectural extension `%s' is not allowed for the "
33587 "current base architecture"), name);
33588 break;
33589 }
33590
33591 if (adding_value)
4d354d8b 33592 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
5a70a223 33593 opt->merge_value);
69133863 33594 else
4d354d8b 33595 ARM_CLEAR_FEATURE (selected_ext, selected_ext, opt->clear_value);
69133863 33596
4d354d8b
TP
33597 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
33598 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
69133863
MGD
33599 *input_line_pointer = saved_char;
33600 demand_empty_rest_of_line ();
3d030cdb
TP
33601 /* Allowing Thumb division instructions for ARMv7 in autodetection rely
33602 on this return so that duplicate extensions (extensions with the
33603 same name as a previous extension in the list) are not considered
33604 for command-line parsing. */
69133863
MGD
33605 return;
33606 }
33607
33608 if (opt->name == NULL)
e673710a 33609 as_bad (_("unknown architecture extension `%s'\n"), name);
69133863
MGD
33610
33611 *input_line_pointer = saved_char;
69133863
MGD
33612}
33613
ee065d83
PB
33614/* Parse a .fpu directive. */
33615
33616static void
33617s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
33618{
69133863 33619 const struct arm_option_fpu_value_table *opt;
ee065d83
PB
33620 char saved_char;
33621 char *name;
33622
33623 name = input_line_pointer;
a37854f9 33624 input_line_pointer = find_end_of_line (input_line_pointer, flag_m68k_mri);
ee065d83
PB
33625 saved_char = *input_line_pointer;
33626 *input_line_pointer = 0;
5f4273c7 33627
a37854f9
RE
33628 if (!*name)
33629 {
33630 as_bad (_(".fpu: missing fpu name"));
33631 *input_line_pointer = saved_char;
33632 return;
33633 }
33634
ee065d83
PB
33635 for (opt = arm_fpus; opt->name != NULL; opt++)
33636 if (streq (opt->name, name))
33637 {
4d354d8b 33638 selected_fpu = opt->value;
f4399880 33639 ARM_CLEAR_FEATURE (selected_cpu, selected_cpu, fpu_any);
4d354d8b
TP
33640#ifndef CPU_DEFAULT
33641 if (no_cpu_selected ())
33642 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
33643 else
33644#endif
33645 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 33646 *input_line_pointer = saved_char;
ee065d83
PB
33647 return;
33648 }
33649
33650 as_bad (_("unknown floating point format `%s'\n"), name);
33651 *input_line_pointer = saved_char;
33652 ignore_rest_of_line ();
33653}
ee065d83 33654
794ba86a 33655/* Copy symbol information. */
f31fef98 33656
794ba86a
DJ
33657void
33658arm_copy_symbol_attributes (symbolS *dest, symbolS *src)
33659{
33660 ARM_GET_FLAG (dest) = ARM_GET_FLAG (src);
33661}
e04befd0 33662
f31fef98 33663#ifdef OBJ_ELF
e04befd0
AS
33664/* Given a symbolic attribute NAME, return the proper integer value.
33665 Returns -1 if the attribute is not known. */
f31fef98 33666
e04befd0
AS
33667int
33668arm_convert_symbolic_attribute (const char *name)
33669{
f31fef98
NC
33670 static const struct
33671 {
33672 const char * name;
33673 const int tag;
33674 }
33675 attribute_table[] =
33676 {
33677 /* When you modify this table you should
33678 also modify the list in doc/c-arm.texi. */
e04befd0 33679#define T(tag) {#tag, tag}
f31fef98
NC
33680 T (Tag_CPU_raw_name),
33681 T (Tag_CPU_name),
33682 T (Tag_CPU_arch),
33683 T (Tag_CPU_arch_profile),
33684 T (Tag_ARM_ISA_use),
33685 T (Tag_THUMB_ISA_use),
75375b3e 33686 T (Tag_FP_arch),
f31fef98
NC
33687 T (Tag_VFP_arch),
33688 T (Tag_WMMX_arch),
33689 T (Tag_Advanced_SIMD_arch),
33690 T (Tag_PCS_config),
33691 T (Tag_ABI_PCS_R9_use),
33692 T (Tag_ABI_PCS_RW_data),
33693 T (Tag_ABI_PCS_RO_data),
33694 T (Tag_ABI_PCS_GOT_use),
33695 T (Tag_ABI_PCS_wchar_t),
33696 T (Tag_ABI_FP_rounding),
33697 T (Tag_ABI_FP_denormal),
33698 T (Tag_ABI_FP_exceptions),
33699 T (Tag_ABI_FP_user_exceptions),
33700 T (Tag_ABI_FP_number_model),
75375b3e 33701 T (Tag_ABI_align_needed),
f31fef98 33702 T (Tag_ABI_align8_needed),
75375b3e 33703 T (Tag_ABI_align_preserved),
f31fef98
NC
33704 T (Tag_ABI_align8_preserved),
33705 T (Tag_ABI_enum_size),
33706 T (Tag_ABI_HardFP_use),
33707 T (Tag_ABI_VFP_args),
33708 T (Tag_ABI_WMMX_args),
33709 T (Tag_ABI_optimization_goals),
33710 T (Tag_ABI_FP_optimization_goals),
33711 T (Tag_compatibility),
33712 T (Tag_CPU_unaligned_access),
75375b3e 33713 T (Tag_FP_HP_extension),
f31fef98
NC
33714 T (Tag_VFP_HP_extension),
33715 T (Tag_ABI_FP_16bit_format),
cd21e546
MGD
33716 T (Tag_MPextension_use),
33717 T (Tag_DIV_use),
f31fef98
NC
33718 T (Tag_nodefaults),
33719 T (Tag_also_compatible_with),
33720 T (Tag_conformance),
33721 T (Tag_T2EE_use),
33722 T (Tag_Virtualization_use),
15afaa63 33723 T (Tag_DSP_extension),
a7ad558c 33724 T (Tag_MVE_arch),
99db83d0 33725 T (Tag_PAC_extension),
4b535030 33726 T (Tag_BTI_extension),
b81ee92f 33727 T (Tag_BTI_use),
c9fed665 33728 T (Tag_PACRET_use),
cd21e546 33729 /* We deliberately do not include Tag_MPextension_use_legacy. */
e04befd0 33730#undef T
f31fef98 33731 };
e04befd0
AS
33732 unsigned int i;
33733
33734 if (name == NULL)
33735 return -1;
33736
f31fef98 33737 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
c921be7d 33738 if (streq (name, attribute_table[i].name))
e04befd0
AS
33739 return attribute_table[i].tag;
33740
33741 return -1;
33742}
267bf995 33743
93ef582d
NC
33744/* Apply sym value for relocations only in the case that they are for
33745 local symbols in the same segment as the fixup and you have the
33746 respective architectural feature for blx and simple switches. */
0198d5e6 33747
267bf995 33748int
93ef582d 33749arm_apply_sym_value (struct fix * fixP, segT this_seg)
267bf995
RR
33750{
33751 if (fixP->fx_addsy
33752 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
93ef582d
NC
33753 /* PR 17444: If the local symbol is in a different section then a reloc
33754 will always be generated for it, so applying the symbol value now
33755 will result in a double offset being stored in the relocation. */
33756 && (S_GET_SEGMENT (fixP->fx_addsy) == this_seg)
5b7c81bd 33757 && !S_FORCE_RELOC (fixP->fx_addsy, true))
267bf995
RR
33758 {
33759 switch (fixP->fx_r_type)
33760 {
33761 case BFD_RELOC_ARM_PCREL_BLX:
33762 case BFD_RELOC_THUMB_PCREL_BRANCH23:
33763 if (ARM_IS_FUNC (fixP->fx_addsy))
33764 return 1;
33765 break;
33766
33767 case BFD_RELOC_ARM_PCREL_CALL:
33768 case BFD_RELOC_THUMB_PCREL_BLX:
33769 if (THUMB_IS_FUNC (fixP->fx_addsy))
93ef582d 33770 return 1;
267bf995
RR
33771 break;
33772
33773 default:
33774 break;
33775 }
33776
33777 }
33778 return 0;
33779}
f31fef98 33780#endif /* OBJ_ELF */