Replace "if (x) free (x)" with "free (x)", binutils
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
CommitLineData
b99bd4ef 1/* tc-arm.c -- Assemble for the ARM
b3adc24a 2 Copyright (C) 1994-2020 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. */
112static bfd_boolean out_of_range_p (offsetT value, offsetT bits)
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. */
c19d1205
ZW
149static int uses_apcs_26 = FALSE;
150static int atpcs = FALSE;
b34976b6
AM
151static int support_interwork = FALSE;
152static int uses_apcs_float = FALSE;
c19d1205 153static int pic_code = FALSE;
845b51d6 154static int fix_v4bx = FALSE;
278df34e
NS
155/* Warn on using deprecated features. */
156static int warn_on_deprecated = TRUE;
24f19ccb 157static int warn_on_restrict_it = FALSE;
278df34e 158
2e6976a8
DG
159/* Understand CodeComposer Studio assembly syntax. */
160bfd_boolean 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);
e74cfd16 368
33a392fb 369static int mfloat_abi_opt = -1;
4d354d8b
TP
370/* Architecture feature bits selected by the last -mcpu/-march or .cpu/.arch
371 directive. */
372static arm_feature_set selected_arch = ARM_ARCH_NONE;
373/* Extension feature bits selected by the last -mcpu/-march or .arch_extension
374 directive. */
375static arm_feature_set selected_ext = ARM_ARCH_NONE;
376/* Feature bits selected by the last -mcpu/-march or by the combination of the
377 last .cpu/.arch directive .arch_extension directives since that
378 directive. */
e74cfd16 379static arm_feature_set selected_cpu = ARM_ARCH_NONE;
4d354d8b
TP
380/* FPU feature bits selected by the last -mfpu or .fpu directive. */
381static arm_feature_set selected_fpu = FPU_NONE;
382/* Feature bits selected by the last .object_arch directive. */
383static arm_feature_set selected_object_arch = ARM_ARCH_NONE;
ee065d83 384/* Must be long enough to hold any of the names in arm_cpus. */
e20f9590 385static const struct arm_ext_table * selected_ctx_ext_table = NULL;
ef8e6722 386static char selected_cpu_name[20];
8d67f500 387
aacf0b33
KT
388extern FLONUM_TYPE generic_floating_point_number;
389
8d67f500
NC
390/* Return if no cpu was selected on command-line. */
391static bfd_boolean
392no_cpu_selected (void)
393{
823d2571 394 return ARM_FEATURE_EQUAL (selected_cpu, arm_arch_none);
8d67f500
NC
395}
396
7cc69913 397#ifdef OBJ_ELF
deeaaff8
DJ
398# ifdef EABI_DEFAULT
399static int meabi_flags = EABI_DEFAULT;
400# else
d507cf36 401static int meabi_flags = EF_ARM_EABI_UNKNOWN;
deeaaff8 402# endif
e1da3f5b 403
ee3c0378
AS
404static int attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
405
e1da3f5b 406bfd_boolean
5f4273c7 407arm_is_eabi (void)
e1da3f5b
PB
408{
409 return (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4);
410}
7cc69913 411#endif
b99bd4ef 412
b99bd4ef 413#ifdef OBJ_ELF
c19d1205 414/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
b99bd4ef
NC
415symbolS * GOT_symbol;
416#endif
417
b99bd4ef
NC
418/* 0: assemble for ARM,
419 1: assemble for Thumb,
420 2: assemble for Thumb even though target CPU does not support thumb
421 instructions. */
422static int thumb_mode = 0;
8dc2430f
NC
423/* A value distinct from the possible values for thumb_mode that we
424 can use to record whether thumb_mode has been copied into the
425 tc_frag_data field of a frag. */
426#define MODE_RECORDED (1 << 4)
b99bd4ef 427
e07e6e58
NC
428/* Specifies the intrinsic IT insn behavior mode. */
429enum implicit_it_mode
430{
431 IMPLICIT_IT_MODE_NEVER = 0x00,
432 IMPLICIT_IT_MODE_ARM = 0x01,
433 IMPLICIT_IT_MODE_THUMB = 0x02,
434 IMPLICIT_IT_MODE_ALWAYS = (IMPLICIT_IT_MODE_ARM | IMPLICIT_IT_MODE_THUMB)
435};
436static int implicit_it_mode = IMPLICIT_IT_MODE_ARM;
437
c19d1205
ZW
438/* If unified_syntax is true, we are processing the new unified
439 ARM/Thumb syntax. Important differences from the old ARM mode:
440
441 - Immediate operands do not require a # prefix.
442 - Conditional affixes always appear at the end of the
443 instruction. (For backward compatibility, those instructions
444 that formerly had them in the middle, continue to accept them
445 there.)
446 - The IT instruction may appear, and if it does is validated
447 against subsequent conditional affixes. It does not generate
448 machine code.
449
450 Important differences from the old Thumb mode:
451
452 - Immediate operands do not require a # prefix.
453 - Most of the V6T2 instructions are only available in unified mode.
454 - The .N and .W suffixes are recognized and honored (it is an error
455 if they cannot be honored).
456 - All instructions set the flags if and only if they have an 's' affix.
457 - Conditional affixes may be used. They are validated against
458 preceding IT instructions. Unlike ARM mode, you cannot use a
459 conditional affix except in the scope of an IT instruction. */
460
461static bfd_boolean unified_syntax = FALSE;
b99bd4ef 462
bacebabc
RM
463/* An immediate operand can start with #, and ld*, st*, pld operands
464 can contain [ and ]. We need to tell APP not to elide whitespace
477330fc
RM
465 before a [, which can appear as the first operand for pld.
466 Likewise, a { can appear as the first operand for push, pop, vld*, etc. */
467const char arm_symbol_chars[] = "#[]{}";
bacebabc 468
5287ad62
JB
469enum neon_el_type
470{
dcbf9037 471 NT_invtype,
5287ad62
JB
472 NT_untyped,
473 NT_integer,
474 NT_float,
475 NT_poly,
476 NT_signed,
aab2c27d 477 NT_bfloat,
dcbf9037 478 NT_unsigned
5287ad62
JB
479};
480
481struct neon_type_el
482{
483 enum neon_el_type type;
484 unsigned size;
485};
486
5aae9ae9 487#define NEON_MAX_TYPE_ELS 5
5287ad62
JB
488
489struct neon_type
490{
491 struct neon_type_el el[NEON_MAX_TYPE_ELS];
492 unsigned elems;
493};
494
5ee91343 495enum pred_instruction_type
e07e6e58 496{
5ee91343
AV
497 OUTSIDE_PRED_INSN,
498 INSIDE_VPT_INSN,
e07e6e58
NC
499 INSIDE_IT_INSN,
500 INSIDE_IT_LAST_INSN,
501 IF_INSIDE_IT_LAST_INSN, /* Either outside or inside;
477330fc 502 if inside, should be the last one. */
e07e6e58 503 NEUTRAL_IT_INSN, /* This could be either inside or outside,
477330fc 504 i.e. BKPT and NOP. */
5ee91343
AV
505 IT_INSN, /* The IT insn has been parsed. */
506 VPT_INSN, /* The VPT/VPST insn has been parsed. */
35c228db 507 MVE_OUTSIDE_PRED_INSN , /* Instruction to indicate a MVE instruction without
5ee91343 508 a predication code. */
4934a27c 509 MVE_UNPREDICABLE_INSN, /* MVE instruction that is non-predicable. */
e07e6e58
NC
510};
511
ad6cec43
MGD
512/* The maximum number of operands we need. */
513#define ARM_IT_MAX_OPERANDS 6
e2b0ab59 514#define ARM_IT_MAX_RELOCS 3
ad6cec43 515
b99bd4ef
NC
516struct arm_it
517{
c19d1205 518 const char * error;
b99bd4ef 519 unsigned long instruction;
c19d1205
ZW
520 int size;
521 int size_req;
522 int cond;
037e8744
JB
523 /* "uncond_value" is set to the value in place of the conditional field in
524 unconditional versions of the instruction, or -1 if nothing is
525 appropriate. */
526 int uncond_value;
5287ad62 527 struct neon_type vectype;
88714cb8
DG
528 /* This does not indicate an actual NEON instruction, only that
529 the mnemonic accepts neon-style type suffixes. */
530 int is_neon;
0110f2b8
PB
531 /* Set to the opcode if the instruction needs relaxation.
532 Zero if the instruction is not relaxed. */
533 unsigned long relax;
b99bd4ef
NC
534 struct
535 {
536 bfd_reloc_code_real_type type;
c19d1205
ZW
537 expressionS exp;
538 int pc_rel;
e2b0ab59 539 } relocs[ARM_IT_MAX_RELOCS];
b99bd4ef 540
5ee91343 541 enum pred_instruction_type pred_insn_type;
e07e6e58 542
c19d1205
ZW
543 struct
544 {
545 unsigned reg;
ca3f61f7 546 signed int imm;
dcbf9037 547 struct neon_type_el vectype;
ca3f61f7
NC
548 unsigned present : 1; /* Operand present. */
549 unsigned isreg : 1; /* Operand was a register. */
f5f10c66
AV
550 unsigned immisreg : 2; /* .imm field is a second register.
551 0: imm, 1: gpr, 2: MVE Q-register. */
57785aa2
AV
552 unsigned isscalar : 2; /* Operand is a (SIMD) scalar:
553 0) not scalar,
554 1) Neon scalar,
555 2) MVE scalar. */
5287ad62 556 unsigned immisalign : 1; /* Immediate is an alignment specifier. */
c96612cc 557 unsigned immisfloat : 1; /* Immediate was parsed as a float. */
5287ad62
JB
558 /* Note: we abuse "regisimm" to mean "is Neon register" in VMOV
559 instructions. This allows us to disambiguate ARM <-> vector insns. */
560 unsigned regisimm : 1; /* 64-bit immediate, reg forms high 32 bits. */
037e8744 561 unsigned isvec : 1; /* Is a single, double or quad VFP/Neon reg. */
5ee91343 562 unsigned isquad : 1; /* Operand is SIMD quad register. */
037e8744 563 unsigned issingle : 1; /* Operand is VFP single-precision register. */
1b883319 564 unsigned iszr : 1; /* Operand is ZR register. */
ca3f61f7
NC
565 unsigned hasreloc : 1; /* Operand has relocation suffix. */
566 unsigned writeback : 1; /* Operand has trailing ! */
567 unsigned preind : 1; /* Preindexed address. */
568 unsigned postind : 1; /* Postindexed address. */
569 unsigned negative : 1; /* Index register was negated. */
570 unsigned shifted : 1; /* Shift applied to operation. */
571 unsigned shift_kind : 3; /* Shift operation (enum shift_kind). */
ad6cec43 572 } operands[ARM_IT_MAX_OPERANDS];
b99bd4ef
NC
573};
574
c19d1205 575static struct arm_it inst;
b99bd4ef
NC
576
577#define NUM_FLOAT_VALS 8
578
05d2d07e 579const char * fp_const[] =
b99bd4ef
NC
580{
581 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
582};
583
b99bd4ef
NC
584LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
585
586#define FAIL (-1)
587#define SUCCESS (0)
588
589#define SUFF_S 1
590#define SUFF_D 2
591#define SUFF_E 3
592#define SUFF_P 4
593
c19d1205
ZW
594#define CP_T_X 0x00008000
595#define CP_T_Y 0x00400000
b99bd4ef 596
c19d1205
ZW
597#define CONDS_BIT 0x00100000
598#define LOAD_BIT 0x00100000
b99bd4ef
NC
599
600#define DOUBLE_LOAD_FLAG 0x00000001
601
602struct asm_cond
603{
d3ce72d0 604 const char * template_name;
c921be7d 605 unsigned long value;
b99bd4ef
NC
606};
607
c19d1205 608#define COND_ALWAYS 0xE
b99bd4ef 609
b99bd4ef
NC
610struct asm_psr
611{
d3ce72d0 612 const char * template_name;
c921be7d 613 unsigned long field;
b99bd4ef
NC
614};
615
62b3e311
PB
616struct asm_barrier_opt
617{
e797f7e0
MGD
618 const char * template_name;
619 unsigned long value;
620 const arm_feature_set arch;
62b3e311
PB
621};
622
2d2255b5 623/* The bit that distinguishes CPSR and SPSR. */
b99bd4ef
NC
624#define SPSR_BIT (1 << 22)
625
c19d1205
ZW
626/* The individual PSR flag bits. */
627#define PSR_c (1 << 16)
628#define PSR_x (1 << 17)
629#define PSR_s (1 << 18)
630#define PSR_f (1 << 19)
b99bd4ef 631
c19d1205 632struct reloc_entry
bfae80f2 633{
0198d5e6 634 const char * name;
c921be7d 635 bfd_reloc_code_real_type reloc;
bfae80f2
RE
636};
637
5287ad62 638enum vfp_reg_pos
bfae80f2 639{
5287ad62
JB
640 VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn,
641 VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
bfae80f2
RE
642};
643
644enum vfp_ldstm_type
645{
646 VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
647};
648
dcbf9037
JB
649/* Bits for DEFINED field in neon_typed_alias. */
650#define NTA_HASTYPE 1
651#define NTA_HASINDEX 2
652
653struct neon_typed_alias
654{
c921be7d
NC
655 unsigned char defined;
656 unsigned char index;
657 struct neon_type_el eltype;
dcbf9037
JB
658};
659
c19d1205 660/* ARM register categories. This includes coprocessor numbers and various
5aa75429
TP
661 architecture extensions' registers. Each entry should have an error message
662 in reg_expected_msgs below. */
c19d1205 663enum arm_reg_type
bfae80f2 664{
c19d1205
ZW
665 REG_TYPE_RN,
666 REG_TYPE_CP,
667 REG_TYPE_CN,
668 REG_TYPE_FN,
669 REG_TYPE_VFS,
670 REG_TYPE_VFD,
5287ad62 671 REG_TYPE_NQ,
037e8744 672 REG_TYPE_VFSD,
5287ad62 673 REG_TYPE_NDQ,
dec41383 674 REG_TYPE_NSD,
037e8744 675 REG_TYPE_NSDQ,
c19d1205
ZW
676 REG_TYPE_VFC,
677 REG_TYPE_MVF,
678 REG_TYPE_MVD,
679 REG_TYPE_MVFX,
680 REG_TYPE_MVDX,
681 REG_TYPE_MVAX,
5ee91343 682 REG_TYPE_MQ,
c19d1205
ZW
683 REG_TYPE_DSPSC,
684 REG_TYPE_MMXWR,
685 REG_TYPE_MMXWC,
686 REG_TYPE_MMXWCG,
687 REG_TYPE_XSCALE,
5ee91343 688 REG_TYPE_RNB,
1b883319 689 REG_TYPE_ZR
bfae80f2
RE
690};
691
dcbf9037
JB
692/* Structure for a hash table entry for a register.
693 If TYPE is REG_TYPE_VFD or REG_TYPE_NQ, the NEON field can point to extra
694 information which states whether a vector type or index is specified (for a
695 register alias created with .dn or .qn). Otherwise NEON should be NULL. */
6c43fab6
RE
696struct reg_entry
697{
c921be7d 698 const char * name;
90ec0d68 699 unsigned int number;
c921be7d
NC
700 unsigned char type;
701 unsigned char builtin;
702 struct neon_typed_alias * neon;
6c43fab6
RE
703};
704
c19d1205 705/* Diagnostics used when we don't get a register of the expected type. */
c921be7d 706const char * const reg_expected_msgs[] =
c19d1205 707{
5aa75429
TP
708 [REG_TYPE_RN] = N_("ARM register expected"),
709 [REG_TYPE_CP] = N_("bad or missing co-processor number"),
710 [REG_TYPE_CN] = N_("co-processor register expected"),
711 [REG_TYPE_FN] = N_("FPA register expected"),
712 [REG_TYPE_VFS] = N_("VFP single precision register expected"),
713 [REG_TYPE_VFD] = N_("VFP/Neon double precision register expected"),
714 [REG_TYPE_NQ] = N_("Neon quad precision register expected"),
715 [REG_TYPE_VFSD] = N_("VFP single or double precision register expected"),
716 [REG_TYPE_NDQ] = N_("Neon double or quad precision register expected"),
717 [REG_TYPE_NSD] = N_("Neon single or double precision register expected"),
718 [REG_TYPE_NSDQ] = N_("VFP single, double or Neon quad precision register"
719 " expected"),
720 [REG_TYPE_VFC] = N_("VFP system register expected"),
721 [REG_TYPE_MVF] = N_("Maverick MVF register expected"),
722 [REG_TYPE_MVD] = N_("Maverick MVD register expected"),
723 [REG_TYPE_MVFX] = N_("Maverick MVFX register expected"),
724 [REG_TYPE_MVDX] = N_("Maverick MVDX register expected"),
725 [REG_TYPE_MVAX] = N_("Maverick MVAX register expected"),
726 [REG_TYPE_DSPSC] = N_("Maverick DSPSC register expected"),
727 [REG_TYPE_MMXWR] = N_("iWMMXt data register expected"),
728 [REG_TYPE_MMXWC] = N_("iWMMXt control register expected"),
729 [REG_TYPE_MMXWCG] = N_("iWMMXt scalar register expected"),
730 [REG_TYPE_XSCALE] = N_("XScale accumulator register expected"),
5ee91343 731 [REG_TYPE_MQ] = N_("MVE vector register expected"),
da3ec71f 732 [REG_TYPE_RNB] = ""
6c43fab6
RE
733};
734
c19d1205 735/* Some well known registers that we refer to directly elsewhere. */
bd340a04 736#define REG_R12 12
c19d1205
ZW
737#define REG_SP 13
738#define REG_LR 14
739#define REG_PC 15
404ff6b5 740
b99bd4ef
NC
741/* ARM instructions take 4bytes in the object file, Thumb instructions
742 take 2: */
c19d1205 743#define INSN_SIZE 4
b99bd4ef
NC
744
745struct asm_opcode
746{
747 /* Basic string to match. */
d3ce72d0 748 const char * template_name;
c19d1205
ZW
749
750 /* Parameters to instruction. */
5be8be5d 751 unsigned int operands[8];
c19d1205
ZW
752
753 /* Conditional tag - see opcode_lookup. */
754 unsigned int tag : 4;
b99bd4ef
NC
755
756 /* Basic instruction code. */
a302e574 757 unsigned int avalue;
b99bd4ef 758
c19d1205
ZW
759 /* Thumb-format instruction code. */
760 unsigned int tvalue;
b99bd4ef 761
90e4755a 762 /* Which architecture variant provides this instruction. */
c921be7d
NC
763 const arm_feature_set * avariant;
764 const arm_feature_set * tvariant;
c19d1205
ZW
765
766 /* Function to call to encode instruction in ARM format. */
767 void (* aencode) (void);
b99bd4ef 768
c19d1205
ZW
769 /* Function to call to encode instruction in Thumb format. */
770 void (* tencode) (void);
5ee91343
AV
771
772 /* Indicates whether this instruction may be vector predicated. */
773 unsigned int mayBeVecPred : 1;
b99bd4ef
NC
774};
775
a737bd4d
NC
776/* Defines for various bits that we will want to toggle. */
777#define INST_IMMEDIATE 0x02000000
778#define OFFSET_REG 0x02000000
c19d1205 779#define HWOFFSET_IMM 0x00400000
a737bd4d
NC
780#define SHIFT_BY_REG 0x00000010
781#define PRE_INDEX 0x01000000
782#define INDEX_UP 0x00800000
783#define WRITE_BACK 0x00200000
784#define LDM_TYPE_2_OR_3 0x00400000
a028a6f5 785#define CPSI_MMOD 0x00020000
90e4755a 786
a737bd4d
NC
787#define LITERAL_MASK 0xf000f000
788#define OPCODE_MASK 0xfe1fffff
789#define V4_STR_BIT 0x00000020
8335d6aa 790#define VLDR_VMOV_SAME 0x0040f000
90e4755a 791
efd81785
PB
792#define T2_SUBS_PC_LR 0xf3de8f00
793
a737bd4d 794#define DATA_OP_SHIFT 21
bada4342 795#define SBIT_SHIFT 20
90e4755a 796
ef8d22e6
PB
797#define T2_OPCODE_MASK 0xfe1fffff
798#define T2_DATA_OP_SHIFT 21
bada4342 799#define T2_SBIT_SHIFT 20
ef8d22e6 800
6530b175
NC
801#define A_COND_MASK 0xf0000000
802#define A_PUSH_POP_OP_MASK 0x0fff0000
803
804/* Opcodes for pushing/poping registers to/from the stack. */
805#define A1_OPCODE_PUSH 0x092d0000
806#define A2_OPCODE_PUSH 0x052d0004
807#define A2_OPCODE_POP 0x049d0004
808
a737bd4d
NC
809/* Codes to distinguish the arithmetic instructions. */
810#define OPCODE_AND 0
811#define OPCODE_EOR 1
812#define OPCODE_SUB 2
813#define OPCODE_RSB 3
814#define OPCODE_ADD 4
815#define OPCODE_ADC 5
816#define OPCODE_SBC 6
817#define OPCODE_RSC 7
818#define OPCODE_TST 8
819#define OPCODE_TEQ 9
820#define OPCODE_CMP 10
821#define OPCODE_CMN 11
822#define OPCODE_ORR 12
823#define OPCODE_MOV 13
824#define OPCODE_BIC 14
825#define OPCODE_MVN 15
90e4755a 826
ef8d22e6
PB
827#define T2_OPCODE_AND 0
828#define T2_OPCODE_BIC 1
829#define T2_OPCODE_ORR 2
830#define T2_OPCODE_ORN 3
831#define T2_OPCODE_EOR 4
832#define T2_OPCODE_ADD 8
833#define T2_OPCODE_ADC 10
834#define T2_OPCODE_SBC 11
835#define T2_OPCODE_SUB 13
836#define T2_OPCODE_RSB 14
837
a737bd4d
NC
838#define T_OPCODE_MUL 0x4340
839#define T_OPCODE_TST 0x4200
840#define T_OPCODE_CMN 0x42c0
841#define T_OPCODE_NEG 0x4240
842#define T_OPCODE_MVN 0x43c0
90e4755a 843
a737bd4d
NC
844#define T_OPCODE_ADD_R3 0x1800
845#define T_OPCODE_SUB_R3 0x1a00
846#define T_OPCODE_ADD_HI 0x4400
847#define T_OPCODE_ADD_ST 0xb000
848#define T_OPCODE_SUB_ST 0xb080
849#define T_OPCODE_ADD_SP 0xa800
850#define T_OPCODE_ADD_PC 0xa000
851#define T_OPCODE_ADD_I8 0x3000
852#define T_OPCODE_SUB_I8 0x3800
853#define T_OPCODE_ADD_I3 0x1c00
854#define T_OPCODE_SUB_I3 0x1e00
b99bd4ef 855
a737bd4d
NC
856#define T_OPCODE_ASR_R 0x4100
857#define T_OPCODE_LSL_R 0x4080
c19d1205
ZW
858#define T_OPCODE_LSR_R 0x40c0
859#define T_OPCODE_ROR_R 0x41c0
a737bd4d
NC
860#define T_OPCODE_ASR_I 0x1000
861#define T_OPCODE_LSL_I 0x0000
862#define T_OPCODE_LSR_I 0x0800
b99bd4ef 863
a737bd4d
NC
864#define T_OPCODE_MOV_I8 0x2000
865#define T_OPCODE_CMP_I8 0x2800
866#define T_OPCODE_CMP_LR 0x4280
867#define T_OPCODE_MOV_HR 0x4600
868#define T_OPCODE_CMP_HR 0x4500
b99bd4ef 869
a737bd4d
NC
870#define T_OPCODE_LDR_PC 0x4800
871#define T_OPCODE_LDR_SP 0x9800
872#define T_OPCODE_STR_SP 0x9000
873#define T_OPCODE_LDR_IW 0x6800
874#define T_OPCODE_STR_IW 0x6000
875#define T_OPCODE_LDR_IH 0x8800
876#define T_OPCODE_STR_IH 0x8000
877#define T_OPCODE_LDR_IB 0x7800
878#define T_OPCODE_STR_IB 0x7000
879#define T_OPCODE_LDR_RW 0x5800
880#define T_OPCODE_STR_RW 0x5000
881#define T_OPCODE_LDR_RH 0x5a00
882#define T_OPCODE_STR_RH 0x5200
883#define T_OPCODE_LDR_RB 0x5c00
884#define T_OPCODE_STR_RB 0x5400
c9b604bd 885
a737bd4d
NC
886#define T_OPCODE_PUSH 0xb400
887#define T_OPCODE_POP 0xbc00
b99bd4ef 888
2fc8bdac 889#define T_OPCODE_BRANCH 0xe000
b99bd4ef 890
a737bd4d 891#define THUMB_SIZE 2 /* Size of thumb instruction. */
a737bd4d 892#define THUMB_PP_PC_LR 0x0100
c19d1205 893#define THUMB_LOAD_BIT 0x0800
53365c0d 894#define THUMB2_LOAD_BIT 0x00100000
c19d1205 895
5ee91343 896#define BAD_SYNTAX _("syntax error")
c19d1205 897#define BAD_ARGS _("bad arguments to instruction")
fdfde340 898#define BAD_SP _("r13 not allowed here")
c19d1205 899#define BAD_PC _("r15 not allowed here")
a302e574
AV
900#define BAD_ODD _("Odd register not allowed here")
901#define BAD_EVEN _("Even register not allowed here")
c19d1205
ZW
902#define BAD_COND _("instruction cannot be conditional")
903#define BAD_OVERLAP _("registers may not be the same")
904#define BAD_HIREG _("lo register required")
905#define BAD_THUMB32 _("instruction not supported in Thumb16 mode")
35c228db 906#define BAD_ADDR_MODE _("instruction does not accept this addressing mode")
dfa9f0d5 907#define BAD_BRANCH _("branch must be last instruction in IT block")
e12437dc 908#define BAD_BRANCH_OFF _("branch out of range or not a multiple of 2")
4934a27c 909#define BAD_NO_VPT _("instruction not allowed in VPT block")
dfa9f0d5 910#define BAD_NOT_IT _("instruction not allowed in IT block")
5ee91343 911#define BAD_NOT_VPT _("instruction missing MVE vector predication code")
037e8744 912#define BAD_FPU _("selected FPU does not support instruction")
e07e6e58 913#define BAD_OUT_IT _("thumb conditional instruction should be in IT block")
5ee91343
AV
914#define BAD_OUT_VPT \
915 _("vector predicated instruction should be in VPT/VPST block")
e07e6e58 916#define BAD_IT_COND _("incorrect condition in IT block")
5ee91343 917#define BAD_VPT_COND _("incorrect condition in VPT/VPST block")
e07e6e58 918#define BAD_IT_IT _("IT falling in the range of a previous IT block")
921e5f0a 919#define MISSING_FNSTART _("missing .fnstart before unwinding directive")
5be8be5d
DG
920#define BAD_PC_ADDRESSING \
921 _("cannot use register index with PC-relative addressing")
922#define BAD_PC_WRITEBACK \
923 _("cannot use writeback with PC-relative addressing")
9db2f6b4
RL
924#define BAD_RANGE _("branch out of range")
925#define BAD_FP16 _("selected processor does not support fp16 instruction")
aab2c27d 926#define BAD_BF16 _("selected processor does not support bf16 instruction")
4934a27c
MM
927#define BAD_CDE _("selected processor does not support cde instruction")
928#define BAD_CDE_COPROC _("coprocessor for insn is not enabled for cde")
dd5181d5 929#define UNPRED_REG(R) _("using " R " results in unpredictable behaviour")
a9f02af8 930#define THUMB1_RELOC_ONLY _("relocation valid in thumb1 code only")
5ee91343
AV
931#define MVE_NOT_IT _("Warning: instruction is UNPREDICTABLE in an IT " \
932 "block")
933#define MVE_NOT_VPT _("Warning: instruction is UNPREDICTABLE in a VPT " \
934 "block")
935#define MVE_BAD_PC _("Warning: instruction is UNPREDICTABLE with PC" \
936 " operand")
937#define MVE_BAD_SP _("Warning: instruction is UNPREDICTABLE with SP" \
938 " operand")
a302e574 939#define BAD_SIMD_TYPE _("bad type in SIMD instruction")
886e1c73
AV
940#define BAD_MVE_AUTO \
941 _("GAS auto-detection mode and -march=all is deprecated for MVE, please" \
942 " use a valid -march or -mcpu option.")
943#define BAD_MVE_SRCDEST _("Warning: 32-bit element size and same destination "\
944 "and source operands makes instruction UNPREDICTABLE")
35c228db 945#define BAD_EL_TYPE _("bad element type for instruction")
1b883319 946#define MVE_BAD_QREG _("MVE vector register Q[0..7] expected")
c19d1205 947
c921be7d
NC
948static struct hash_control * arm_ops_hsh;
949static struct hash_control * arm_cond_hsh;
5ee91343 950static struct hash_control * arm_vcond_hsh;
c921be7d
NC
951static struct hash_control * arm_shift_hsh;
952static struct hash_control * arm_psr_hsh;
953static struct hash_control * arm_v7m_psr_hsh;
954static struct hash_control * arm_reg_hsh;
955static struct hash_control * arm_reloc_hsh;
956static struct hash_control * arm_barrier_opt_hsh;
b99bd4ef 957
b99bd4ef
NC
958/* Stuff needed to resolve the label ambiguity
959 As:
960 ...
961 label: <insn>
962 may differ from:
963 ...
964 label:
5f4273c7 965 <insn> */
b99bd4ef
NC
966
967symbolS * last_label_seen;
b34976b6 968static int label_is_thumb_function_name = FALSE;
e07e6e58 969
3d0c9500
NC
970/* Literal pool structure. Held on a per-section
971 and per-sub-section basis. */
a737bd4d 972
c19d1205 973#define MAX_LITERAL_POOL_SIZE 1024
3d0c9500 974typedef struct literal_pool
b99bd4ef 975{
c921be7d
NC
976 expressionS literals [MAX_LITERAL_POOL_SIZE];
977 unsigned int next_free_entry;
978 unsigned int id;
979 symbolS * symbol;
980 segT section;
981 subsegT sub_section;
a8040cf2
NC
982#ifdef OBJ_ELF
983 struct dwarf2_line_info locs [MAX_LITERAL_POOL_SIZE];
984#endif
c921be7d 985 struct literal_pool * next;
8335d6aa 986 unsigned int alignment;
3d0c9500 987} literal_pool;
b99bd4ef 988
3d0c9500
NC
989/* Pointer to a linked list of literal pools. */
990literal_pool * list_of_pools = NULL;
e27ec89e 991
2e6976a8
DG
992typedef enum asmfunc_states
993{
994 OUTSIDE_ASMFUNC,
995 WAITING_ASMFUNC_NAME,
996 WAITING_ENDASMFUNC
997} asmfunc_states;
998
999static asmfunc_states asmfunc_state = OUTSIDE_ASMFUNC;
1000
e07e6e58 1001#ifdef OBJ_ELF
5ee91343 1002# define now_pred seg_info (now_seg)->tc_segment_info_data.current_pred
e07e6e58 1003#else
5ee91343 1004static struct current_pred now_pred;
e07e6e58
NC
1005#endif
1006
1007static inline int
5ee91343 1008now_pred_compatible (int cond)
e07e6e58 1009{
5ee91343 1010 return (cond & ~1) == (now_pred.cc & ~1);
e07e6e58
NC
1011}
1012
1013static inline int
1014conditional_insn (void)
1015{
1016 return inst.cond != COND_ALWAYS;
1017}
1018
5ee91343 1019static int in_pred_block (void);
e07e6e58 1020
5ee91343 1021static int handle_pred_state (void);
e07e6e58
NC
1022
1023static void force_automatic_it_block_close (void);
1024
c921be7d
NC
1025static void it_fsm_post_encode (void);
1026
5ee91343 1027#define set_pred_insn_type(type) \
e07e6e58
NC
1028 do \
1029 { \
5ee91343
AV
1030 inst.pred_insn_type = type; \
1031 if (handle_pred_state () == FAIL) \
477330fc 1032 return; \
e07e6e58
NC
1033 } \
1034 while (0)
1035
5ee91343 1036#define set_pred_insn_type_nonvoid(type, failret) \
c921be7d
NC
1037 do \
1038 { \
5ee91343
AV
1039 inst.pred_insn_type = type; \
1040 if (handle_pred_state () == FAIL) \
477330fc 1041 return failret; \
c921be7d
NC
1042 } \
1043 while(0)
1044
5ee91343 1045#define set_pred_insn_type_last() \
e07e6e58
NC
1046 do \
1047 { \
1048 if (inst.cond == COND_ALWAYS) \
5ee91343 1049 set_pred_insn_type (IF_INSIDE_IT_LAST_INSN); \
e07e6e58 1050 else \
5ee91343 1051 set_pred_insn_type (INSIDE_IT_LAST_INSN); \
e07e6e58
NC
1052 } \
1053 while (0)
1054
e39c1607
SD
1055/* Toggle value[pos]. */
1056#define TOGGLE_BIT(value, pos) (value ^ (1 << pos))
1057
c19d1205 1058/* Pure syntax. */
b99bd4ef 1059
c19d1205
ZW
1060/* This array holds the chars that always start a comment. If the
1061 pre-processor is disabled, these aren't very useful. */
2e6976a8 1062char arm_comment_chars[] = "@";
3d0c9500 1063
c19d1205
ZW
1064/* This array holds the chars that only start a comment at the beginning of
1065 a line. If the line seems to have the form '# 123 filename'
1066 .line and .file directives will appear in the pre-processed output. */
1067/* Note that input_file.c hand checks for '#' at the beginning of the
1068 first line of the input file. This is because the compiler outputs
1069 #NO_APP at the beginning of its output. */
1070/* Also note that comments like this one will always work. */
1071const char line_comment_chars[] = "#";
3d0c9500 1072
2e6976a8 1073char arm_line_separator_chars[] = ";";
b99bd4ef 1074
c19d1205
ZW
1075/* Chars that can be used to separate mant
1076 from exp in floating point numbers. */
1077const char EXP_CHARS[] = "eE";
3d0c9500 1078
c19d1205
ZW
1079/* Chars that mean this number is a floating point constant. */
1080/* As in 0f12.456 */
1081/* or 0d1.2345e12 */
b99bd4ef 1082
5312fe52 1083const char FLT_CHARS[] = "rRsSfFdDxXeEpPHh";
3d0c9500 1084
c19d1205
ZW
1085/* Prefix characters that indicate the start of an immediate
1086 value. */
1087#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
3d0c9500 1088
c19d1205
ZW
1089/* Separator character handling. */
1090
1091#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
1092
5312fe52
BW
1093enum fp_16bit_format
1094{
1095 ARM_FP16_FORMAT_IEEE = 0x1,
1096 ARM_FP16_FORMAT_ALTERNATIVE = 0x2,
1097 ARM_FP16_FORMAT_DEFAULT = 0x3
1098};
1099
1100static enum fp_16bit_format fp16_format = ARM_FP16_FORMAT_DEFAULT;
1101
1102
c19d1205
ZW
1103static inline int
1104skip_past_char (char ** str, char c)
1105{
8ab8155f
NC
1106 /* PR gas/14987: Allow for whitespace before the expected character. */
1107 skip_whitespace (*str);
427d0db6 1108
c19d1205
ZW
1109 if (**str == c)
1110 {
1111 (*str)++;
1112 return SUCCESS;
3d0c9500 1113 }
c19d1205
ZW
1114 else
1115 return FAIL;
1116}
c921be7d 1117
c19d1205 1118#define skip_past_comma(str) skip_past_char (str, ',')
3d0c9500 1119
c19d1205
ZW
1120/* Arithmetic expressions (possibly involving symbols). */
1121
1122/* Return TRUE if anything in the expression is a bignum. */
1123
0198d5e6 1124static bfd_boolean
c19d1205
ZW
1125walk_no_bignums (symbolS * sp)
1126{
1127 if (symbol_get_value_expression (sp)->X_op == O_big)
0198d5e6 1128 return TRUE;
c19d1205
ZW
1129
1130 if (symbol_get_value_expression (sp)->X_add_symbol)
3d0c9500 1131 {
c19d1205
ZW
1132 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
1133 || (symbol_get_value_expression (sp)->X_op_symbol
1134 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
3d0c9500
NC
1135 }
1136
0198d5e6 1137 return FALSE;
3d0c9500
NC
1138}
1139
0198d5e6 1140static bfd_boolean in_my_get_expression = FALSE;
c19d1205
ZW
1141
1142/* Third argument to my_get_expression. */
1143#define GE_NO_PREFIX 0
1144#define GE_IMM_PREFIX 1
1145#define GE_OPT_PREFIX 2
5287ad62
JB
1146/* This is a bit of a hack. Use an optional prefix, and also allow big (64-bit)
1147 immediates, as can be used in Neon VMVN and VMOV immediate instructions. */
1148#define GE_OPT_PREFIX_BIG 3
a737bd4d 1149
b99bd4ef 1150static int
c19d1205 1151my_get_expression (expressionS * ep, char ** str, int prefix_mode)
b99bd4ef 1152{
c19d1205 1153 char * save_in;
b99bd4ef 1154
c19d1205
ZW
1155 /* In unified syntax, all prefixes are optional. */
1156 if (unified_syntax)
5287ad62 1157 prefix_mode = (prefix_mode == GE_OPT_PREFIX_BIG) ? prefix_mode
477330fc 1158 : GE_OPT_PREFIX;
b99bd4ef 1159
c19d1205 1160 switch (prefix_mode)
b99bd4ef 1161 {
c19d1205
ZW
1162 case GE_NO_PREFIX: break;
1163 case GE_IMM_PREFIX:
1164 if (!is_immediate_prefix (**str))
1165 {
1166 inst.error = _("immediate expression requires a # prefix");
1167 return FAIL;
1168 }
1169 (*str)++;
1170 break;
1171 case GE_OPT_PREFIX:
5287ad62 1172 case GE_OPT_PREFIX_BIG:
c19d1205
ZW
1173 if (is_immediate_prefix (**str))
1174 (*str)++;
1175 break;
0198d5e6
TC
1176 default:
1177 abort ();
c19d1205 1178 }
b99bd4ef 1179
c19d1205 1180 memset (ep, 0, sizeof (expressionS));
b99bd4ef 1181
c19d1205
ZW
1182 save_in = input_line_pointer;
1183 input_line_pointer = *str;
0198d5e6 1184 in_my_get_expression = TRUE;
2ac93be7 1185 expression (ep);
0198d5e6 1186 in_my_get_expression = FALSE;
c19d1205 1187
f86adc07 1188 if (ep->X_op == O_illegal || ep->X_op == O_absent)
b99bd4ef 1189 {
f86adc07 1190 /* We found a bad or missing expression in md_operand(). */
c19d1205
ZW
1191 *str = input_line_pointer;
1192 input_line_pointer = save_in;
1193 if (inst.error == NULL)
f86adc07
NS
1194 inst.error = (ep->X_op == O_absent
1195 ? _("missing expression") :_("bad expression"));
c19d1205
ZW
1196 return 1;
1197 }
b99bd4ef 1198
c19d1205
ZW
1199 /* Get rid of any bignums now, so that we don't generate an error for which
1200 we can't establish a line number later on. Big numbers are never valid
1201 in instructions, which is where this routine is always called. */
5287ad62
JB
1202 if (prefix_mode != GE_OPT_PREFIX_BIG
1203 && (ep->X_op == O_big
477330fc 1204 || (ep->X_add_symbol
5287ad62 1205 && (walk_no_bignums (ep->X_add_symbol)
477330fc 1206 || (ep->X_op_symbol
5287ad62 1207 && walk_no_bignums (ep->X_op_symbol))))))
c19d1205
ZW
1208 {
1209 inst.error = _("invalid constant");
1210 *str = input_line_pointer;
1211 input_line_pointer = save_in;
1212 return 1;
1213 }
b99bd4ef 1214
c19d1205
ZW
1215 *str = input_line_pointer;
1216 input_line_pointer = save_in;
0198d5e6 1217 return SUCCESS;
b99bd4ef
NC
1218}
1219
c19d1205
ZW
1220/* Turn a string in input_line_pointer into a floating point constant
1221 of type TYPE, and store the appropriate bytes in *LITP. The number
1222 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1223 returned, or NULL on OK.
b99bd4ef 1224
c19d1205
ZW
1225 Note that fp constants aren't represent in the normal way on the ARM.
1226 In big endian mode, things are as expected. However, in little endian
1227 mode fp constants are big-endian word-wise, and little-endian byte-wise
1228 within the words. For example, (double) 1.1 in big endian mode is
1229 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
1230 the byte sequence 99 99 f1 3f 9a 99 99 99.
b99bd4ef 1231
c19d1205 1232 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
b99bd4ef 1233
6d4af3c2 1234const char *
c19d1205
ZW
1235md_atof (int type, char * litP, int * sizeP)
1236{
1237 int prec;
1238 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1239 char *t;
1240 int i;
b99bd4ef 1241
c19d1205
ZW
1242 switch (type)
1243 {
5312fe52
BW
1244 case 'H':
1245 case 'h':
1246 prec = 1;
1247 break;
1248
27cce866
MM
1249 /* If this is a bfloat16, then parse it slightly differently, as it
1250 does not follow the IEEE specification for floating point numbers
1251 exactly. */
1252 case 'b':
1253 {
1254 FLONUM_TYPE generic_float;
1255
1256 t = atof_ieee_detail (input_line_pointer, 1, 8, words, &generic_float);
1257
1258 if (t)
1259 input_line_pointer = t;
1260 else
1261 return _("invalid floating point number");
1262
1263 switch (generic_float.sign)
1264 {
1265 /* Is +Inf. */
1266 case 'P':
1267 words[0] = 0x7f80;
1268 break;
1269
1270 /* Is -Inf. */
1271 case 'N':
1272 words[0] = 0xff80;
1273 break;
1274
1275 /* Is NaN. */
1276 /* bfloat16 has two types of NaN - quiet and signalling.
1277 Quiet NaN has bit[6] == 1 && faction != 0, whereas
1278 signalling NaN's have bit[0] == 0 && fraction != 0.
1279 Chosen this specific encoding as it is the same form
1280 as used by other IEEE 754 encodings in GAS. */
1281 case 0:
1282 words[0] = 0x7fff;
1283 break;
1284
1285 default:
1286 break;
1287 }
1288
1289 *sizeP = 2;
1290
1291 md_number_to_chars (litP, (valueT) words[0], sizeof (LITTLENUM_TYPE));
1292
1293 return NULL;
1294 }
c19d1205
ZW
1295 case 'f':
1296 case 'F':
1297 case 's':
1298 case 'S':
1299 prec = 2;
1300 break;
b99bd4ef 1301
c19d1205
ZW
1302 case 'd':
1303 case 'D':
1304 case 'r':
1305 case 'R':
1306 prec = 4;
1307 break;
b99bd4ef 1308
c19d1205
ZW
1309 case 'x':
1310 case 'X':
499ac353 1311 prec = 5;
c19d1205 1312 break;
b99bd4ef 1313
c19d1205
ZW
1314 case 'p':
1315 case 'P':
499ac353 1316 prec = 5;
c19d1205 1317 break;
a737bd4d 1318
c19d1205
ZW
1319 default:
1320 *sizeP = 0;
499ac353 1321 return _("Unrecognized or unsupported floating point constant");
c19d1205 1322 }
b99bd4ef 1323
c19d1205
ZW
1324 t = atof_ieee (input_line_pointer, type, words);
1325 if (t)
1326 input_line_pointer = t;
499ac353 1327 *sizeP = prec * sizeof (LITTLENUM_TYPE);
b99bd4ef 1328
72c03e30
BW
1329 if (target_big_endian || prec == 1)
1330 for (i = 0; i < prec; i++)
1331 {
1332 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1333 litP += sizeof (LITTLENUM_TYPE);
1334 }
1335 else if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
1336 for (i = prec - 1; i >= 0; i--)
1337 {
1338 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1339 litP += sizeof (LITTLENUM_TYPE);
1340 }
c19d1205 1341 else
72c03e30
BW
1342 /* For a 4 byte float the order of elements in `words' is 1 0.
1343 For an 8 byte float the order is 1 0 3 2. */
1344 for (i = 0; i < prec; i += 2)
1345 {
1346 md_number_to_chars (litP, (valueT) words[i + 1],
1347 sizeof (LITTLENUM_TYPE));
1348 md_number_to_chars (litP + sizeof (LITTLENUM_TYPE),
1349 (valueT) words[i], sizeof (LITTLENUM_TYPE));
1350 litP += 2 * sizeof (LITTLENUM_TYPE);
1351 }
b99bd4ef 1352
499ac353 1353 return NULL;
c19d1205 1354}
b99bd4ef 1355
c19d1205
ZW
1356/* We handle all bad expressions here, so that we can report the faulty
1357 instruction in the error message. */
0198d5e6 1358
c19d1205 1359void
91d6fa6a 1360md_operand (expressionS * exp)
c19d1205
ZW
1361{
1362 if (in_my_get_expression)
91d6fa6a 1363 exp->X_op = O_illegal;
b99bd4ef
NC
1364}
1365
c19d1205 1366/* Immediate values. */
b99bd4ef 1367
0198d5e6 1368#ifdef OBJ_ELF
c19d1205
ZW
1369/* Generic immediate-value read function for use in directives.
1370 Accepts anything that 'expression' can fold to a constant.
1371 *val receives the number. */
0198d5e6 1372
c19d1205
ZW
1373static int
1374immediate_for_directive (int *val)
b99bd4ef 1375{
c19d1205
ZW
1376 expressionS exp;
1377 exp.X_op = O_illegal;
b99bd4ef 1378
c19d1205
ZW
1379 if (is_immediate_prefix (*input_line_pointer))
1380 {
1381 input_line_pointer++;
1382 expression (&exp);
1383 }
b99bd4ef 1384
c19d1205
ZW
1385 if (exp.X_op != O_constant)
1386 {
1387 as_bad (_("expected #constant"));
1388 ignore_rest_of_line ();
1389 return FAIL;
1390 }
1391 *val = exp.X_add_number;
1392 return SUCCESS;
b99bd4ef 1393}
c19d1205 1394#endif
b99bd4ef 1395
c19d1205 1396/* Register parsing. */
b99bd4ef 1397
c19d1205
ZW
1398/* Generic register parser. CCP points to what should be the
1399 beginning of a register name. If it is indeed a valid register
1400 name, advance CCP over it and return the reg_entry structure;
1401 otherwise return NULL. Does not issue diagnostics. */
1402
1403static struct reg_entry *
1404arm_reg_parse_multi (char **ccp)
b99bd4ef 1405{
c19d1205
ZW
1406 char *start = *ccp;
1407 char *p;
1408 struct reg_entry *reg;
b99bd4ef 1409
477330fc
RM
1410 skip_whitespace (start);
1411
c19d1205
ZW
1412#ifdef REGISTER_PREFIX
1413 if (*start != REGISTER_PREFIX)
01cfc07f 1414 return NULL;
c19d1205
ZW
1415 start++;
1416#endif
1417#ifdef OPTIONAL_REGISTER_PREFIX
1418 if (*start == OPTIONAL_REGISTER_PREFIX)
1419 start++;
1420#endif
b99bd4ef 1421
c19d1205
ZW
1422 p = start;
1423 if (!ISALPHA (*p) || !is_name_beginner (*p))
1424 return NULL;
b99bd4ef 1425
c19d1205
ZW
1426 do
1427 p++;
1428 while (ISALPHA (*p) || ISDIGIT (*p) || *p == '_');
1429
1430 reg = (struct reg_entry *) hash_find_n (arm_reg_hsh, start, p - start);
1431
1432 if (!reg)
1433 return NULL;
1434
1435 *ccp = p;
1436 return reg;
b99bd4ef
NC
1437}
1438
1439static int
dcbf9037 1440arm_reg_alt_syntax (char **ccp, char *start, struct reg_entry *reg,
477330fc 1441 enum arm_reg_type type)
b99bd4ef 1442{
c19d1205
ZW
1443 /* Alternative syntaxes are accepted for a few register classes. */
1444 switch (type)
1445 {
1446 case REG_TYPE_MVF:
1447 case REG_TYPE_MVD:
1448 case REG_TYPE_MVFX:
1449 case REG_TYPE_MVDX:
1450 /* Generic coprocessor register names are allowed for these. */
79134647 1451 if (reg && reg->type == REG_TYPE_CN)
c19d1205
ZW
1452 return reg->number;
1453 break;
69b97547 1454
c19d1205
ZW
1455 case REG_TYPE_CP:
1456 /* For backward compatibility, a bare number is valid here. */
1457 {
1458 unsigned long processor = strtoul (start, ccp, 10);
1459 if (*ccp != start && processor <= 15)
1460 return processor;
1461 }
1a0670f3 1462 /* Fall through. */
6057a28f 1463
c19d1205
ZW
1464 case REG_TYPE_MMXWC:
1465 /* WC includes WCG. ??? I'm not sure this is true for all
1466 instructions that take WC registers. */
79134647 1467 if (reg && reg->type == REG_TYPE_MMXWCG)
c19d1205 1468 return reg->number;
6057a28f 1469 break;
c19d1205 1470
6057a28f 1471 default:
c19d1205 1472 break;
6057a28f
NC
1473 }
1474
dcbf9037
JB
1475 return FAIL;
1476}
1477
1478/* As arm_reg_parse_multi, but the register must be of type TYPE, and the
1479 return value is the register number or FAIL. */
1480
1481static int
1482arm_reg_parse (char **ccp, enum arm_reg_type type)
1483{
1484 char *start = *ccp;
1485 struct reg_entry *reg = arm_reg_parse_multi (ccp);
1486 int ret;
1487
1488 /* Do not allow a scalar (reg+index) to parse as a register. */
1489 if (reg && reg->neon && (reg->neon->defined & NTA_HASINDEX))
1490 return FAIL;
1491
1492 if (reg && reg->type == type)
1493 return reg->number;
1494
1495 if ((ret = arm_reg_alt_syntax (ccp, start, reg, type)) != FAIL)
1496 return ret;
1497
c19d1205
ZW
1498 *ccp = start;
1499 return FAIL;
1500}
69b97547 1501
dcbf9037
JB
1502/* Parse a Neon type specifier. *STR should point at the leading '.'
1503 character. Does no verification at this stage that the type fits the opcode
1504 properly. E.g.,
1505
1506 .i32.i32.s16
1507 .s32.f32
1508 .u16
1509
1510 Can all be legally parsed by this function.
1511
1512 Fills in neon_type struct pointer with parsed information, and updates STR
1513 to point after the parsed type specifier. Returns SUCCESS if this was a legal
1514 type, FAIL if not. */
1515
1516static int
1517parse_neon_type (struct neon_type *type, char **str)
1518{
1519 char *ptr = *str;
1520
1521 if (type)
1522 type->elems = 0;
1523
1524 while (type->elems < NEON_MAX_TYPE_ELS)
1525 {
1526 enum neon_el_type thistype = NT_untyped;
1527 unsigned thissize = -1u;
1528
1529 if (*ptr != '.')
1530 break;
1531
1532 ptr++;
1533
1534 /* Just a size without an explicit type. */
1535 if (ISDIGIT (*ptr))
1536 goto parsesize;
1537
1538 switch (TOLOWER (*ptr))
1539 {
1540 case 'i': thistype = NT_integer; break;
1541 case 'f': thistype = NT_float; break;
1542 case 'p': thistype = NT_poly; break;
1543 case 's': thistype = NT_signed; break;
1544 case 'u': thistype = NT_unsigned; break;
477330fc
RM
1545 case 'd':
1546 thistype = NT_float;
1547 thissize = 64;
1548 ptr++;
1549 goto done;
aab2c27d
MM
1550 case 'b':
1551 thistype = NT_bfloat;
1552 switch (TOLOWER (*(++ptr)))
1553 {
1554 case 'f':
1555 ptr += 1;
1556 thissize = strtoul (ptr, &ptr, 10);
1557 if (thissize != 16)
1558 {
1559 as_bad (_("bad size %d in type specifier"), thissize);
1560 return FAIL;
1561 }
1562 goto done;
1563 case '0': case '1': case '2': case '3': case '4':
1564 case '5': case '6': case '7': case '8': case '9':
1565 case ' ': case '.':
1566 as_bad (_("unexpected type character `b' -- did you mean `bf'?"));
1567 return FAIL;
1568 default:
1569 break;
1570 }
1571 break;
dcbf9037
JB
1572 default:
1573 as_bad (_("unexpected character `%c' in type specifier"), *ptr);
1574 return FAIL;
1575 }
1576
1577 ptr++;
1578
1579 /* .f is an abbreviation for .f32. */
1580 if (thistype == NT_float && !ISDIGIT (*ptr))
1581 thissize = 32;
1582 else
1583 {
1584 parsesize:
1585 thissize = strtoul (ptr, &ptr, 10);
1586
1587 if (thissize != 8 && thissize != 16 && thissize != 32
477330fc
RM
1588 && thissize != 64)
1589 {
1590 as_bad (_("bad size %d in type specifier"), thissize);
dcbf9037
JB
1591 return FAIL;
1592 }
1593 }
1594
037e8744 1595 done:
dcbf9037 1596 if (type)
477330fc
RM
1597 {
1598 type->el[type->elems].type = thistype;
dcbf9037
JB
1599 type->el[type->elems].size = thissize;
1600 type->elems++;
1601 }
1602 }
1603
1604 /* Empty/missing type is not a successful parse. */
1605 if (type->elems == 0)
1606 return FAIL;
1607
1608 *str = ptr;
1609
1610 return SUCCESS;
1611}
1612
1613/* Errors may be set multiple times during parsing or bit encoding
1614 (particularly in the Neon bits), but usually the earliest error which is set
1615 will be the most meaningful. Avoid overwriting it with later (cascading)
1616 errors by calling this function. */
1617
1618static void
1619first_error (const char *err)
1620{
1621 if (!inst.error)
1622 inst.error = err;
1623}
1624
1625/* Parse a single type, e.g. ".s32", leading period included. */
1626static int
1627parse_neon_operand_type (struct neon_type_el *vectype, char **ccp)
1628{
1629 char *str = *ccp;
1630 struct neon_type optype;
1631
1632 if (*str == '.')
1633 {
1634 if (parse_neon_type (&optype, &str) == SUCCESS)
477330fc
RM
1635 {
1636 if (optype.elems == 1)
1637 *vectype = optype.el[0];
1638 else
1639 {
1640 first_error (_("only one type should be specified for operand"));
1641 return FAIL;
1642 }
1643 }
dcbf9037 1644 else
477330fc
RM
1645 {
1646 first_error (_("vector type expected"));
1647 return FAIL;
1648 }
dcbf9037
JB
1649 }
1650 else
1651 return FAIL;
5f4273c7 1652
dcbf9037 1653 *ccp = str;
5f4273c7 1654
dcbf9037
JB
1655 return SUCCESS;
1656}
1657
1658/* Special meanings for indices (which have a range of 0-7), which will fit into
1659 a 4-bit integer. */
1660
1661#define NEON_ALL_LANES 15
1662#define NEON_INTERLEAVE_LANES 14
1663
5ee91343
AV
1664/* Record a use of the given feature. */
1665static void
1666record_feature_use (const arm_feature_set *feature)
1667{
1668 if (thumb_mode)
1669 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, *feature);
1670 else
1671 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, *feature);
1672}
1673
1674/* If the given feature available in the selected CPU, mark it as used.
1675 Returns TRUE iff feature is available. */
1676static bfd_boolean
1677mark_feature_used (const arm_feature_set *feature)
1678{
886e1c73
AV
1679
1680 /* Do not support the use of MVE only instructions when in auto-detection or
1681 -march=all. */
1682 if (((feature == &mve_ext) || (feature == &mve_fp_ext))
1683 && ARM_CPU_IS_ANY (cpu_variant))
1684 {
1685 first_error (BAD_MVE_AUTO);
1686 return FALSE;
1687 }
5ee91343
AV
1688 /* Ensure the option is valid on the current architecture. */
1689 if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
1690 return FALSE;
1691
1692 /* Add the appropriate architecture feature for the barrier option used.
1693 */
1694 record_feature_use (feature);
1695
1696 return TRUE;
1697}
1698
dcbf9037
JB
1699/* Parse either a register or a scalar, with an optional type. Return the
1700 register number, and optionally fill in the actual type of the register
1701 when multiple alternatives were given (NEON_TYPE_NDQ) in *RTYPE, and
1702 type/index information in *TYPEINFO. */
1703
1704static int
1705parse_typed_reg_or_scalar (char **ccp, enum arm_reg_type type,
477330fc
RM
1706 enum arm_reg_type *rtype,
1707 struct neon_typed_alias *typeinfo)
dcbf9037
JB
1708{
1709 char *str = *ccp;
1710 struct reg_entry *reg = arm_reg_parse_multi (&str);
1711 struct neon_typed_alias atype;
1712 struct neon_type_el parsetype;
1713
1714 atype.defined = 0;
1715 atype.index = -1;
1716 atype.eltype.type = NT_invtype;
1717 atype.eltype.size = -1;
1718
1719 /* Try alternate syntax for some types of register. Note these are mutually
1720 exclusive with the Neon syntax extensions. */
1721 if (reg == NULL)
1722 {
1723 int altreg = arm_reg_alt_syntax (&str, *ccp, reg, type);
1724 if (altreg != FAIL)
477330fc 1725 *ccp = str;
dcbf9037 1726 if (typeinfo)
477330fc 1727 *typeinfo = atype;
dcbf9037
JB
1728 return altreg;
1729 }
1730
037e8744
JB
1731 /* Undo polymorphism when a set of register types may be accepted. */
1732 if ((type == REG_TYPE_NDQ
1733 && (reg->type == REG_TYPE_NQ || reg->type == REG_TYPE_VFD))
1734 || (type == REG_TYPE_VFSD
477330fc 1735 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
037e8744 1736 || (type == REG_TYPE_NSDQ
477330fc
RM
1737 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD
1738 || reg->type == REG_TYPE_NQ))
dec41383
JW
1739 || (type == REG_TYPE_NSD
1740 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
f512f76f
NC
1741 || (type == REG_TYPE_MMXWC
1742 && (reg->type == REG_TYPE_MMXWCG)))
21d799b5 1743 type = (enum arm_reg_type) reg->type;
dcbf9037 1744
5ee91343
AV
1745 if (type == REG_TYPE_MQ)
1746 {
1747 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
1748 return FAIL;
1749
1750 if (!reg || reg->type != REG_TYPE_NQ)
1751 return FAIL;
1752
1753 if (reg->number > 14 && !mark_feature_used (&fpu_vfp_ext_d32))
1754 {
1755 first_error (_("expected MVE register [q0..q7]"));
1756 return FAIL;
1757 }
1758 type = REG_TYPE_NQ;
1759 }
1760 else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
1761 && (type == REG_TYPE_NQ))
1762 return FAIL;
1763
1764
dcbf9037
JB
1765 if (type != reg->type)
1766 return FAIL;
1767
1768 if (reg->neon)
1769 atype = *reg->neon;
5f4273c7 1770
dcbf9037
JB
1771 if (parse_neon_operand_type (&parsetype, &str) == SUCCESS)
1772 {
1773 if ((atype.defined & NTA_HASTYPE) != 0)
477330fc
RM
1774 {
1775 first_error (_("can't redefine type for operand"));
1776 return FAIL;
1777 }
dcbf9037
JB
1778 atype.defined |= NTA_HASTYPE;
1779 atype.eltype = parsetype;
1780 }
5f4273c7 1781
dcbf9037
JB
1782 if (skip_past_char (&str, '[') == SUCCESS)
1783 {
dec41383
JW
1784 if (type != REG_TYPE_VFD
1785 && !(type == REG_TYPE_VFS
57785aa2
AV
1786 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_2))
1787 && !(type == REG_TYPE_NQ
1788 && ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)))
477330fc 1789 {
57785aa2
AV
1790 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
1791 first_error (_("only D and Q registers may be indexed"));
1792 else
1793 first_error (_("only D registers may be indexed"));
477330fc
RM
1794 return FAIL;
1795 }
5f4273c7 1796
dcbf9037 1797 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
1798 {
1799 first_error (_("can't change index for operand"));
1800 return FAIL;
1801 }
dcbf9037
JB
1802
1803 atype.defined |= NTA_HASINDEX;
1804
1805 if (skip_past_char (&str, ']') == SUCCESS)
477330fc 1806 atype.index = NEON_ALL_LANES;
dcbf9037 1807 else
477330fc
RM
1808 {
1809 expressionS exp;
dcbf9037 1810
477330fc 1811 my_get_expression (&exp, &str, GE_NO_PREFIX);
dcbf9037 1812
477330fc
RM
1813 if (exp.X_op != O_constant)
1814 {
1815 first_error (_("constant expression required"));
1816 return FAIL;
1817 }
dcbf9037 1818
477330fc
RM
1819 if (skip_past_char (&str, ']') == FAIL)
1820 return FAIL;
dcbf9037 1821
477330fc
RM
1822 atype.index = exp.X_add_number;
1823 }
dcbf9037 1824 }
5f4273c7 1825
dcbf9037
JB
1826 if (typeinfo)
1827 *typeinfo = atype;
5f4273c7 1828
dcbf9037
JB
1829 if (rtype)
1830 *rtype = type;
5f4273c7 1831
dcbf9037 1832 *ccp = str;
5f4273c7 1833
dcbf9037
JB
1834 return reg->number;
1835}
1836
efd6b359 1837/* Like arm_reg_parse, but also allow the following extra features:
dcbf9037
JB
1838 - If RTYPE is non-zero, return the (possibly restricted) type of the
1839 register (e.g. Neon double or quad reg when either has been requested).
1840 - If this is a Neon vector type with additional type information, fill
1841 in the struct pointed to by VECTYPE (if non-NULL).
5f4273c7 1842 This function will fault on encountering a scalar. */
dcbf9037
JB
1843
1844static int
1845arm_typed_reg_parse (char **ccp, enum arm_reg_type type,
477330fc 1846 enum arm_reg_type *rtype, struct neon_type_el *vectype)
dcbf9037
JB
1847{
1848 struct neon_typed_alias atype;
1849 char *str = *ccp;
1850 int reg = parse_typed_reg_or_scalar (&str, type, rtype, &atype);
1851
1852 if (reg == FAIL)
1853 return FAIL;
1854
0855e32b
NS
1855 /* Do not allow regname(... to parse as a register. */
1856 if (*str == '(')
1857 return FAIL;
1858
dcbf9037
JB
1859 /* Do not allow a scalar (reg+index) to parse as a register. */
1860 if ((atype.defined & NTA_HASINDEX) != 0)
1861 {
1862 first_error (_("register operand expected, but got scalar"));
1863 return FAIL;
1864 }
1865
1866 if (vectype)
1867 *vectype = atype.eltype;
1868
1869 *ccp = str;
1870
1871 return reg;
1872}
1873
1874#define NEON_SCALAR_REG(X) ((X) >> 4)
1875#define NEON_SCALAR_INDEX(X) ((X) & 15)
1876
5287ad62
JB
1877/* Parse a Neon scalar. Most of the time when we're parsing a scalar, we don't
1878 have enough information to be able to do a good job bounds-checking. So, we
1879 just do easy checks here, and do further checks later. */
1880
1881static int
57785aa2
AV
1882parse_scalar (char **ccp, int elsize, struct neon_type_el *type, enum
1883 arm_reg_type reg_type)
5287ad62 1884{
dcbf9037 1885 int reg;
5287ad62 1886 char *str = *ccp;
dcbf9037 1887 struct neon_typed_alias atype;
57785aa2 1888 unsigned reg_size;
5f4273c7 1889
dec41383 1890 reg = parse_typed_reg_or_scalar (&str, reg_type, NULL, &atype);
5f4273c7 1891
57785aa2
AV
1892 switch (reg_type)
1893 {
1894 case REG_TYPE_VFS:
1895 reg_size = 32;
1896 break;
1897 case REG_TYPE_VFD:
1898 reg_size = 64;
1899 break;
1900 case REG_TYPE_MQ:
1901 reg_size = 128;
1902 break;
1903 default:
1904 gas_assert (0);
1905 return FAIL;
1906 }
1907
dcbf9037 1908 if (reg == FAIL || (atype.defined & NTA_HASINDEX) == 0)
5287ad62 1909 return FAIL;
5f4273c7 1910
57785aa2 1911 if (reg_type != REG_TYPE_MQ && atype.index == NEON_ALL_LANES)
5287ad62 1912 {
dcbf9037 1913 first_error (_("scalar must have an index"));
5287ad62
JB
1914 return FAIL;
1915 }
57785aa2 1916 else if (atype.index >= reg_size / elsize)
5287ad62 1917 {
dcbf9037 1918 first_error (_("scalar index out of range"));
5287ad62
JB
1919 return FAIL;
1920 }
5f4273c7 1921
dcbf9037
JB
1922 if (type)
1923 *type = atype.eltype;
5f4273c7 1924
5287ad62 1925 *ccp = str;
5f4273c7 1926
dcbf9037 1927 return reg * 16 + atype.index;
5287ad62
JB
1928}
1929
4b5a202f
AV
1930/* Types of registers in a list. */
1931
1932enum reg_list_els
1933{
1934 REGLIST_RN,
1935 REGLIST_CLRM,
1936 REGLIST_VFP_S,
efd6b359 1937 REGLIST_VFP_S_VPR,
4b5a202f 1938 REGLIST_VFP_D,
efd6b359 1939 REGLIST_VFP_D_VPR,
4b5a202f
AV
1940 REGLIST_NEON_D
1941};
1942
c19d1205 1943/* Parse an ARM register list. Returns the bitmask, or FAIL. */
e07e6e58 1944
c19d1205 1945static long
4b5a202f 1946parse_reg_list (char ** strp, enum reg_list_els etype)
c19d1205 1947{
4b5a202f
AV
1948 char *str = *strp;
1949 long range = 0;
1950 int another_range;
1951
1952 gas_assert (etype == REGLIST_RN || etype == REGLIST_CLRM);
a737bd4d 1953
c19d1205
ZW
1954 /* We come back here if we get ranges concatenated by '+' or '|'. */
1955 do
6057a28f 1956 {
477330fc
RM
1957 skip_whitespace (str);
1958
c19d1205 1959 another_range = 0;
a737bd4d 1960
c19d1205
ZW
1961 if (*str == '{')
1962 {
1963 int in_range = 0;
1964 int cur_reg = -1;
a737bd4d 1965
c19d1205
ZW
1966 str++;
1967 do
1968 {
1969 int reg;
4b5a202f
AV
1970 const char apsr_str[] = "apsr";
1971 int apsr_str_len = strlen (apsr_str);
6057a28f 1972
a65b5de6 1973 reg = arm_reg_parse (&str, REG_TYPE_RN);
4b5a202f 1974 if (etype == REGLIST_CLRM)
c19d1205 1975 {
4b5a202f
AV
1976 if (reg == REG_SP || reg == REG_PC)
1977 reg = FAIL;
1978 else if (reg == FAIL
1979 && !strncasecmp (str, apsr_str, apsr_str_len)
1980 && !ISALPHA (*(str + apsr_str_len)))
1981 {
1982 reg = 15;
1983 str += apsr_str_len;
1984 }
1985
1986 if (reg == FAIL)
1987 {
1988 first_error (_("r0-r12, lr or APSR expected"));
1989 return FAIL;
1990 }
1991 }
1992 else /* etype == REGLIST_RN. */
1993 {
1994 if (reg == FAIL)
1995 {
1996 first_error (_(reg_expected_msgs[REGLIST_RN]));
1997 return FAIL;
1998 }
c19d1205 1999 }
a737bd4d 2000
c19d1205
ZW
2001 if (in_range)
2002 {
2003 int i;
a737bd4d 2004
c19d1205
ZW
2005 if (reg <= cur_reg)
2006 {
dcbf9037 2007 first_error (_("bad range in register list"));
c19d1205
ZW
2008 return FAIL;
2009 }
40a18ebd 2010
c19d1205
ZW
2011 for (i = cur_reg + 1; i < reg; i++)
2012 {
2013 if (range & (1 << i))
2014 as_tsktsk
2015 (_("Warning: duplicated register (r%d) in register list"),
2016 i);
2017 else
2018 range |= 1 << i;
2019 }
2020 in_range = 0;
2021 }
a737bd4d 2022
c19d1205
ZW
2023 if (range & (1 << reg))
2024 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
2025 reg);
2026 else if (reg <= cur_reg)
2027 as_tsktsk (_("Warning: register range not in ascending order"));
a737bd4d 2028
c19d1205
ZW
2029 range |= 1 << reg;
2030 cur_reg = reg;
2031 }
2032 while (skip_past_comma (&str) != FAIL
2033 || (in_range = 1, *str++ == '-'));
2034 str--;
a737bd4d 2035
d996d970 2036 if (skip_past_char (&str, '}') == FAIL)
c19d1205 2037 {
dcbf9037 2038 first_error (_("missing `}'"));
c19d1205
ZW
2039 return FAIL;
2040 }
2041 }
4b5a202f 2042 else if (etype == REGLIST_RN)
c19d1205 2043 {
91d6fa6a 2044 expressionS exp;
40a18ebd 2045
91d6fa6a 2046 if (my_get_expression (&exp, &str, GE_NO_PREFIX))
c19d1205 2047 return FAIL;
40a18ebd 2048
91d6fa6a 2049 if (exp.X_op == O_constant)
c19d1205 2050 {
91d6fa6a
NC
2051 if (exp.X_add_number
2052 != (exp.X_add_number & 0x0000ffff))
c19d1205
ZW
2053 {
2054 inst.error = _("invalid register mask");
2055 return FAIL;
2056 }
a737bd4d 2057
91d6fa6a 2058 if ((range & exp.X_add_number) != 0)
c19d1205 2059 {
91d6fa6a 2060 int regno = range & exp.X_add_number;
a737bd4d 2061
c19d1205
ZW
2062 regno &= -regno;
2063 regno = (1 << regno) - 1;
2064 as_tsktsk
2065 (_("Warning: duplicated register (r%d) in register list"),
2066 regno);
2067 }
a737bd4d 2068
91d6fa6a 2069 range |= exp.X_add_number;
c19d1205
ZW
2070 }
2071 else
2072 {
e2b0ab59 2073 if (inst.relocs[0].type != 0)
c19d1205
ZW
2074 {
2075 inst.error = _("expression too complex");
2076 return FAIL;
2077 }
a737bd4d 2078
e2b0ab59
AV
2079 memcpy (&inst.relocs[0].exp, &exp, sizeof (expressionS));
2080 inst.relocs[0].type = BFD_RELOC_ARM_MULTI;
2081 inst.relocs[0].pc_rel = 0;
c19d1205
ZW
2082 }
2083 }
a737bd4d 2084
c19d1205
ZW
2085 if (*str == '|' || *str == '+')
2086 {
2087 str++;
2088 another_range = 1;
2089 }
a737bd4d 2090 }
c19d1205 2091 while (another_range);
a737bd4d 2092
c19d1205
ZW
2093 *strp = str;
2094 return range;
a737bd4d
NC
2095}
2096
c19d1205
ZW
2097/* Parse a VFP register list. If the string is invalid return FAIL.
2098 Otherwise return the number of registers, and set PBASE to the first
5287ad62
JB
2099 register. Parses registers of type ETYPE.
2100 If REGLIST_NEON_D is used, several syntax enhancements are enabled:
2101 - Q registers can be used to specify pairs of D registers
2102 - { } can be omitted from around a singleton register list
477330fc
RM
2103 FIXME: This is not implemented, as it would require backtracking in
2104 some cases, e.g.:
2105 vtbl.8 d3,d4,d5
2106 This could be done (the meaning isn't really ambiguous), but doesn't
2107 fit in well with the current parsing framework.
dcbf9037
JB
2108 - 32 D registers may be used (also true for VFPv3).
2109 FIXME: Types are ignored in these register lists, which is probably a
2110 bug. */
6057a28f 2111
c19d1205 2112static int
efd6b359
AV
2113parse_vfp_reg_list (char **ccp, unsigned int *pbase, enum reg_list_els etype,
2114 bfd_boolean *partial_match)
6057a28f 2115{
037e8744 2116 char *str = *ccp;
c19d1205
ZW
2117 int base_reg;
2118 int new_base;
21d799b5 2119 enum arm_reg_type regtype = (enum arm_reg_type) 0;
5287ad62 2120 int max_regs = 0;
c19d1205
ZW
2121 int count = 0;
2122 int warned = 0;
2123 unsigned long mask = 0;
a737bd4d 2124 int i;
efd6b359
AV
2125 bfd_boolean vpr_seen = FALSE;
2126 bfd_boolean expect_vpr =
2127 (etype == REGLIST_VFP_S_VPR) || (etype == REGLIST_VFP_D_VPR);
6057a28f 2128
477330fc 2129 if (skip_past_char (&str, '{') == FAIL)
5287ad62
JB
2130 {
2131 inst.error = _("expecting {");
2132 return FAIL;
2133 }
6057a28f 2134
5287ad62 2135 switch (etype)
c19d1205 2136 {
5287ad62 2137 case REGLIST_VFP_S:
efd6b359 2138 case REGLIST_VFP_S_VPR:
c19d1205
ZW
2139 regtype = REG_TYPE_VFS;
2140 max_regs = 32;
5287ad62 2141 break;
5f4273c7 2142
5287ad62 2143 case REGLIST_VFP_D:
efd6b359 2144 case REGLIST_VFP_D_VPR:
5287ad62 2145 regtype = REG_TYPE_VFD;
b7fc2769 2146 break;
5f4273c7 2147
b7fc2769
JB
2148 case REGLIST_NEON_D:
2149 regtype = REG_TYPE_NDQ;
2150 break;
4b5a202f
AV
2151
2152 default:
2153 gas_assert (0);
b7fc2769
JB
2154 }
2155
efd6b359 2156 if (etype != REGLIST_VFP_S && etype != REGLIST_VFP_S_VPR)
b7fc2769 2157 {
b1cc4aeb
PB
2158 /* VFPv3 allows 32 D registers, except for the VFPv3-D16 variant. */
2159 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
2160 {
2161 max_regs = 32;
2162 if (thumb_mode)
2163 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
2164 fpu_vfp_ext_d32);
2165 else
2166 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
2167 fpu_vfp_ext_d32);
2168 }
5287ad62 2169 else
477330fc 2170 max_regs = 16;
c19d1205 2171 }
6057a28f 2172
c19d1205 2173 base_reg = max_regs;
efd6b359 2174 *partial_match = FALSE;
a737bd4d 2175
c19d1205
ZW
2176 do
2177 {
5287ad62 2178 int setmask = 1, addregs = 1;
efd6b359
AV
2179 const char vpr_str[] = "vpr";
2180 int vpr_str_len = strlen (vpr_str);
dcbf9037 2181
037e8744 2182 new_base = arm_typed_reg_parse (&str, regtype, &regtype, NULL);
dcbf9037 2183
efd6b359
AV
2184 if (expect_vpr)
2185 {
2186 if (new_base == FAIL
2187 && !strncasecmp (str, vpr_str, vpr_str_len)
2188 && !ISALPHA (*(str + vpr_str_len))
2189 && !vpr_seen)
2190 {
2191 vpr_seen = TRUE;
2192 str += vpr_str_len;
2193 if (count == 0)
2194 base_reg = 0; /* Canonicalize VPR only on d0 with 0 regs. */
2195 }
2196 else if (vpr_seen)
2197 {
2198 first_error (_("VPR expected last"));
2199 return FAIL;
2200 }
2201 else if (new_base == FAIL)
2202 {
2203 if (regtype == REG_TYPE_VFS)
2204 first_error (_("VFP single precision register or VPR "
2205 "expected"));
2206 else /* regtype == REG_TYPE_VFD. */
2207 first_error (_("VFP/Neon double precision register or VPR "
2208 "expected"));
2209 return FAIL;
2210 }
2211 }
2212 else if (new_base == FAIL)
a737bd4d 2213 {
dcbf9037 2214 first_error (_(reg_expected_msgs[regtype]));
c19d1205
ZW
2215 return FAIL;
2216 }
5f4273c7 2217
efd6b359
AV
2218 *partial_match = TRUE;
2219 if (vpr_seen)
2220 continue;
2221
b7fc2769 2222 if (new_base >= max_regs)
477330fc
RM
2223 {
2224 first_error (_("register out of range in list"));
2225 return FAIL;
2226 }
5f4273c7 2227
5287ad62
JB
2228 /* Note: a value of 2 * n is returned for the register Q<n>. */
2229 if (regtype == REG_TYPE_NQ)
477330fc
RM
2230 {
2231 setmask = 3;
2232 addregs = 2;
2233 }
5287ad62 2234
c19d1205
ZW
2235 if (new_base < base_reg)
2236 base_reg = new_base;
a737bd4d 2237
5287ad62 2238 if (mask & (setmask << new_base))
c19d1205 2239 {
dcbf9037 2240 first_error (_("invalid register list"));
c19d1205 2241 return FAIL;
a737bd4d 2242 }
a737bd4d 2243
efd6b359 2244 if ((mask >> new_base) != 0 && ! warned && !vpr_seen)
c19d1205
ZW
2245 {
2246 as_tsktsk (_("register list not in ascending order"));
2247 warned = 1;
2248 }
0bbf2aa4 2249
5287ad62
JB
2250 mask |= setmask << new_base;
2251 count += addregs;
0bbf2aa4 2252
037e8744 2253 if (*str == '-') /* We have the start of a range expression */
c19d1205
ZW
2254 {
2255 int high_range;
0bbf2aa4 2256
037e8744 2257 str++;
0bbf2aa4 2258
037e8744 2259 if ((high_range = arm_typed_reg_parse (&str, regtype, NULL, NULL))
477330fc 2260 == FAIL)
c19d1205
ZW
2261 {
2262 inst.error = gettext (reg_expected_msgs[regtype]);
2263 return FAIL;
2264 }
0bbf2aa4 2265
477330fc
RM
2266 if (high_range >= max_regs)
2267 {
2268 first_error (_("register out of range in list"));
2269 return FAIL;
2270 }
b7fc2769 2271
477330fc
RM
2272 if (regtype == REG_TYPE_NQ)
2273 high_range = high_range + 1;
5287ad62 2274
c19d1205
ZW
2275 if (high_range <= new_base)
2276 {
2277 inst.error = _("register range not in ascending order");
2278 return FAIL;
2279 }
0bbf2aa4 2280
5287ad62 2281 for (new_base += addregs; new_base <= high_range; new_base += addregs)
0bbf2aa4 2282 {
5287ad62 2283 if (mask & (setmask << new_base))
0bbf2aa4 2284 {
c19d1205
ZW
2285 inst.error = _("invalid register list");
2286 return FAIL;
0bbf2aa4 2287 }
c19d1205 2288
5287ad62
JB
2289 mask |= setmask << new_base;
2290 count += addregs;
0bbf2aa4 2291 }
0bbf2aa4 2292 }
0bbf2aa4 2293 }
037e8744 2294 while (skip_past_comma (&str) != FAIL);
0bbf2aa4 2295
037e8744 2296 str++;
0bbf2aa4 2297
c19d1205 2298 /* Sanity check -- should have raised a parse error above. */
efd6b359 2299 if ((!vpr_seen && count == 0) || count > max_regs)
c19d1205
ZW
2300 abort ();
2301
2302 *pbase = base_reg;
2303
efd6b359
AV
2304 if (expect_vpr && !vpr_seen)
2305 {
2306 first_error (_("VPR expected last"));
2307 return FAIL;
2308 }
2309
c19d1205
ZW
2310 /* Final test -- the registers must be consecutive. */
2311 mask >>= base_reg;
2312 for (i = 0; i < count; i++)
2313 {
2314 if ((mask & (1u << i)) == 0)
2315 {
2316 inst.error = _("non-contiguous register range");
2317 return FAIL;
2318 }
2319 }
2320
037e8744
JB
2321 *ccp = str;
2322
c19d1205 2323 return count;
b99bd4ef
NC
2324}
2325
dcbf9037
JB
2326/* True if two alias types are the same. */
2327
c921be7d 2328static bfd_boolean
dcbf9037
JB
2329neon_alias_types_same (struct neon_typed_alias *a, struct neon_typed_alias *b)
2330{
2331 if (!a && !b)
c921be7d 2332 return TRUE;
5f4273c7 2333
dcbf9037 2334 if (!a || !b)
c921be7d 2335 return FALSE;
dcbf9037
JB
2336
2337 if (a->defined != b->defined)
c921be7d 2338 return FALSE;
5f4273c7 2339
dcbf9037
JB
2340 if ((a->defined & NTA_HASTYPE) != 0
2341 && (a->eltype.type != b->eltype.type
477330fc 2342 || a->eltype.size != b->eltype.size))
c921be7d 2343 return FALSE;
dcbf9037
JB
2344
2345 if ((a->defined & NTA_HASINDEX) != 0
2346 && (a->index != b->index))
c921be7d 2347 return FALSE;
5f4273c7 2348
c921be7d 2349 return TRUE;
dcbf9037
JB
2350}
2351
5287ad62
JB
2352/* Parse element/structure lists for Neon VLD<n> and VST<n> instructions.
2353 The base register is put in *PBASE.
dcbf9037 2354 The lane (or one of the NEON_*_LANES constants) is placed in bits [3:0] of
5287ad62
JB
2355 the return value.
2356 The register stride (minus one) is put in bit 4 of the return value.
dcbf9037
JB
2357 Bits [6:5] encode the list length (minus one).
2358 The type of the list elements is put in *ELTYPE, if non-NULL. */
5287ad62 2359
5287ad62 2360#define NEON_LANE(X) ((X) & 0xf)
dcbf9037 2361#define NEON_REG_STRIDE(X) ((((X) >> 4) & 1) + 1)
5287ad62
JB
2362#define NEON_REGLIST_LENGTH(X) ((((X) >> 5) & 3) + 1)
2363
2364static int
dcbf9037 2365parse_neon_el_struct_list (char **str, unsigned *pbase,
35c228db 2366 int mve,
477330fc 2367 struct neon_type_el *eltype)
5287ad62
JB
2368{
2369 char *ptr = *str;
2370 int base_reg = -1;
2371 int reg_incr = -1;
2372 int count = 0;
2373 int lane = -1;
2374 int leading_brace = 0;
2375 enum arm_reg_type rtype = REG_TYPE_NDQ;
35c228db
AV
2376 const char *const incr_error = mve ? _("register stride must be 1") :
2377 _("register stride must be 1 or 2");
20203fb9 2378 const char *const type_error = _("mismatched element/structure types in list");
dcbf9037 2379 struct neon_typed_alias firsttype;
f85d59c3
KT
2380 firsttype.defined = 0;
2381 firsttype.eltype.type = NT_invtype;
2382 firsttype.eltype.size = -1;
2383 firsttype.index = -1;
5f4273c7 2384
5287ad62
JB
2385 if (skip_past_char (&ptr, '{') == SUCCESS)
2386 leading_brace = 1;
5f4273c7 2387
5287ad62
JB
2388 do
2389 {
dcbf9037 2390 struct neon_typed_alias atype;
35c228db
AV
2391 if (mve)
2392 rtype = REG_TYPE_MQ;
dcbf9037
JB
2393 int getreg = parse_typed_reg_or_scalar (&ptr, rtype, &rtype, &atype);
2394
5287ad62 2395 if (getreg == FAIL)
477330fc
RM
2396 {
2397 first_error (_(reg_expected_msgs[rtype]));
2398 return FAIL;
2399 }
5f4273c7 2400
5287ad62 2401 if (base_reg == -1)
477330fc
RM
2402 {
2403 base_reg = getreg;
2404 if (rtype == REG_TYPE_NQ)
2405 {
2406 reg_incr = 1;
2407 }
2408 firsttype = atype;
2409 }
5287ad62 2410 else if (reg_incr == -1)
477330fc
RM
2411 {
2412 reg_incr = getreg - base_reg;
2413 if (reg_incr < 1 || reg_incr > 2)
2414 {
2415 first_error (_(incr_error));
2416 return FAIL;
2417 }
2418 }
5287ad62 2419 else if (getreg != base_reg + reg_incr * count)
477330fc
RM
2420 {
2421 first_error (_(incr_error));
2422 return FAIL;
2423 }
dcbf9037 2424
c921be7d 2425 if (! neon_alias_types_same (&atype, &firsttype))
477330fc
RM
2426 {
2427 first_error (_(type_error));
2428 return FAIL;
2429 }
5f4273c7 2430
5287ad62 2431 /* Handle Dn-Dm or Qn-Qm syntax. Can only be used with non-indexed list
477330fc 2432 modes. */
5287ad62 2433 if (ptr[0] == '-')
477330fc
RM
2434 {
2435 struct neon_typed_alias htype;
2436 int hireg, dregs = (rtype == REG_TYPE_NQ) ? 2 : 1;
2437 if (lane == -1)
2438 lane = NEON_INTERLEAVE_LANES;
2439 else if (lane != NEON_INTERLEAVE_LANES)
2440 {
2441 first_error (_(type_error));
2442 return FAIL;
2443 }
2444 if (reg_incr == -1)
2445 reg_incr = 1;
2446 else if (reg_incr != 1)
2447 {
2448 first_error (_("don't use Rn-Rm syntax with non-unit stride"));
2449 return FAIL;
2450 }
2451 ptr++;
2452 hireg = parse_typed_reg_or_scalar (&ptr, rtype, NULL, &htype);
2453 if (hireg == FAIL)
2454 {
2455 first_error (_(reg_expected_msgs[rtype]));
2456 return FAIL;
2457 }
2458 if (! neon_alias_types_same (&htype, &firsttype))
2459 {
2460 first_error (_(type_error));
2461 return FAIL;
2462 }
2463 count += hireg + dregs - getreg;
2464 continue;
2465 }
5f4273c7 2466
5287ad62
JB
2467 /* If we're using Q registers, we can't use [] or [n] syntax. */
2468 if (rtype == REG_TYPE_NQ)
477330fc
RM
2469 {
2470 count += 2;
2471 continue;
2472 }
5f4273c7 2473
dcbf9037 2474 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
2475 {
2476 if (lane == -1)
2477 lane = atype.index;
2478 else if (lane != atype.index)
2479 {
2480 first_error (_(type_error));
2481 return FAIL;
2482 }
2483 }
5287ad62 2484 else if (lane == -1)
477330fc 2485 lane = NEON_INTERLEAVE_LANES;
5287ad62 2486 else if (lane != NEON_INTERLEAVE_LANES)
477330fc
RM
2487 {
2488 first_error (_(type_error));
2489 return FAIL;
2490 }
5287ad62
JB
2491 count++;
2492 }
2493 while ((count != 1 || leading_brace) && skip_past_comma (&ptr) != FAIL);
5f4273c7 2494
5287ad62
JB
2495 /* No lane set by [x]. We must be interleaving structures. */
2496 if (lane == -1)
2497 lane = NEON_INTERLEAVE_LANES;
5f4273c7 2498
5287ad62 2499 /* Sanity check. */
35c228db 2500 if (lane == -1 || base_reg == -1 || count < 1 || (!mve && count > 4)
5287ad62
JB
2501 || (count > 1 && reg_incr == -1))
2502 {
dcbf9037 2503 first_error (_("error parsing element/structure list"));
5287ad62
JB
2504 return FAIL;
2505 }
2506
2507 if ((count > 1 || leading_brace) && skip_past_char (&ptr, '}') == FAIL)
2508 {
dcbf9037 2509 first_error (_("expected }"));
5287ad62
JB
2510 return FAIL;
2511 }
5f4273c7 2512
5287ad62
JB
2513 if (reg_incr == -1)
2514 reg_incr = 1;
2515
dcbf9037
JB
2516 if (eltype)
2517 *eltype = firsttype.eltype;
2518
5287ad62
JB
2519 *pbase = base_reg;
2520 *str = ptr;
5f4273c7 2521
5287ad62
JB
2522 return lane | ((reg_incr - 1) << 4) | ((count - 1) << 5);
2523}
2524
c19d1205
ZW
2525/* Parse an explicit relocation suffix on an expression. This is
2526 either nothing, or a word in parentheses. Note that if !OBJ_ELF,
2527 arm_reloc_hsh contains no entries, so this function can only
2528 succeed if there is no () after the word. Returns -1 on error,
2529 BFD_RELOC_UNUSED if there wasn't any suffix. */
3da1d841 2530
c19d1205
ZW
2531static int
2532parse_reloc (char **str)
b99bd4ef 2533{
c19d1205
ZW
2534 struct reloc_entry *r;
2535 char *p, *q;
b99bd4ef 2536
c19d1205
ZW
2537 if (**str != '(')
2538 return BFD_RELOC_UNUSED;
b99bd4ef 2539
c19d1205
ZW
2540 p = *str + 1;
2541 q = p;
2542
2543 while (*q && *q != ')' && *q != ',')
2544 q++;
2545 if (*q != ')')
2546 return -1;
2547
21d799b5
NC
2548 if ((r = (struct reloc_entry *)
2549 hash_find_n (arm_reloc_hsh, p, q - p)) == NULL)
c19d1205
ZW
2550 return -1;
2551
2552 *str = q + 1;
2553 return r->reloc;
b99bd4ef
NC
2554}
2555
c19d1205
ZW
2556/* Directives: register aliases. */
2557
dcbf9037 2558static struct reg_entry *
90ec0d68 2559insert_reg_alias (char *str, unsigned number, int type)
b99bd4ef 2560{
d3ce72d0 2561 struct reg_entry *new_reg;
c19d1205 2562 const char *name;
b99bd4ef 2563
d3ce72d0 2564 if ((new_reg = (struct reg_entry *) hash_find (arm_reg_hsh, str)) != 0)
c19d1205 2565 {
d3ce72d0 2566 if (new_reg->builtin)
c19d1205 2567 as_warn (_("ignoring attempt to redefine built-in register '%s'"), str);
b99bd4ef 2568
c19d1205
ZW
2569 /* Only warn about a redefinition if it's not defined as the
2570 same register. */
d3ce72d0 2571 else if (new_reg->number != number || new_reg->type != type)
c19d1205 2572 as_warn (_("ignoring redefinition of register alias '%s'"), str);
69b97547 2573
d929913e 2574 return NULL;
c19d1205 2575 }
b99bd4ef 2576
c19d1205 2577 name = xstrdup (str);
325801bd 2578 new_reg = XNEW (struct reg_entry);
b99bd4ef 2579
d3ce72d0
NC
2580 new_reg->name = name;
2581 new_reg->number = number;
2582 new_reg->type = type;
2583 new_reg->builtin = FALSE;
2584 new_reg->neon = NULL;
b99bd4ef 2585
d3ce72d0 2586 if (hash_insert (arm_reg_hsh, name, (void *) new_reg))
c19d1205 2587 abort ();
5f4273c7 2588
d3ce72d0 2589 return new_reg;
dcbf9037
JB
2590}
2591
2592static void
2593insert_neon_reg_alias (char *str, int number, int type,
477330fc 2594 struct neon_typed_alias *atype)
dcbf9037
JB
2595{
2596 struct reg_entry *reg = insert_reg_alias (str, number, type);
5f4273c7 2597
dcbf9037
JB
2598 if (!reg)
2599 {
2600 first_error (_("attempt to redefine typed alias"));
2601 return;
2602 }
5f4273c7 2603
dcbf9037
JB
2604 if (atype)
2605 {
325801bd 2606 reg->neon = XNEW (struct neon_typed_alias);
dcbf9037
JB
2607 *reg->neon = *atype;
2608 }
c19d1205 2609}
b99bd4ef 2610
c19d1205 2611/* Look for the .req directive. This is of the form:
b99bd4ef 2612
c19d1205 2613 new_register_name .req existing_register_name
b99bd4ef 2614
c19d1205 2615 If we find one, or if it looks sufficiently like one that we want to
d929913e 2616 handle any error here, return TRUE. Otherwise return FALSE. */
b99bd4ef 2617
d929913e 2618static bfd_boolean
c19d1205
ZW
2619create_register_alias (char * newname, char *p)
2620{
2621 struct reg_entry *old;
2622 char *oldname, *nbuf;
2623 size_t nlen;
b99bd4ef 2624
c19d1205
ZW
2625 /* The input scrubber ensures that whitespace after the mnemonic is
2626 collapsed to single spaces. */
2627 oldname = p;
2628 if (strncmp (oldname, " .req ", 6) != 0)
d929913e 2629 return FALSE;
b99bd4ef 2630
c19d1205
ZW
2631 oldname += 6;
2632 if (*oldname == '\0')
d929913e 2633 return FALSE;
b99bd4ef 2634
21d799b5 2635 old = (struct reg_entry *) hash_find (arm_reg_hsh, oldname);
c19d1205 2636 if (!old)
b99bd4ef 2637 {
c19d1205 2638 as_warn (_("unknown register '%s' -- .req ignored"), oldname);
d929913e 2639 return TRUE;
b99bd4ef
NC
2640 }
2641
c19d1205
ZW
2642 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2643 the desired alias name, and p points to its end. If not, then
2644 the desired alias name is in the global original_case_string. */
2645#ifdef TC_CASE_SENSITIVE
2646 nlen = p - newname;
2647#else
2648 newname = original_case_string;
2649 nlen = strlen (newname);
2650#endif
b99bd4ef 2651
29a2809e 2652 nbuf = xmemdup0 (newname, nlen);
b99bd4ef 2653
c19d1205
ZW
2654 /* Create aliases under the new name as stated; an all-lowercase
2655 version of the new name; and an all-uppercase version of the new
2656 name. */
d929913e
NC
2657 if (insert_reg_alias (nbuf, old->number, old->type) != NULL)
2658 {
2659 for (p = nbuf; *p; p++)
2660 *p = TOUPPER (*p);
c19d1205 2661
d929913e
NC
2662 if (strncmp (nbuf, newname, nlen))
2663 {
2664 /* If this attempt to create an additional alias fails, do not bother
2665 trying to create the all-lower case alias. We will fail and issue
2666 a second, duplicate error message. This situation arises when the
2667 programmer does something like:
2668 foo .req r0
2669 Foo .req r1
2670 The second .req creates the "Foo" alias but then fails to create
5f4273c7 2671 the artificial FOO alias because it has already been created by the
d929913e
NC
2672 first .req. */
2673 if (insert_reg_alias (nbuf, old->number, old->type) == NULL)
e1fa0163
NC
2674 {
2675 free (nbuf);
2676 return TRUE;
2677 }
d929913e 2678 }
c19d1205 2679
d929913e
NC
2680 for (p = nbuf; *p; p++)
2681 *p = TOLOWER (*p);
c19d1205 2682
d929913e
NC
2683 if (strncmp (nbuf, newname, nlen))
2684 insert_reg_alias (nbuf, old->number, old->type);
2685 }
c19d1205 2686
e1fa0163 2687 free (nbuf);
d929913e 2688 return TRUE;
b99bd4ef
NC
2689}
2690
dcbf9037
JB
2691/* Create a Neon typed/indexed register alias using directives, e.g.:
2692 X .dn d5.s32[1]
2693 Y .qn 6.s16
2694 Z .dn d7
2695 T .dn Z[0]
2696 These typed registers can be used instead of the types specified after the
2697 Neon mnemonic, so long as all operands given have types. Types can also be
2698 specified directly, e.g.:
5f4273c7 2699 vadd d0.s32, d1.s32, d2.s32 */
dcbf9037 2700
c921be7d 2701static bfd_boolean
dcbf9037
JB
2702create_neon_reg_alias (char *newname, char *p)
2703{
2704 enum arm_reg_type basetype;
2705 struct reg_entry *basereg;
2706 struct reg_entry mybasereg;
2707 struct neon_type ntype;
2708 struct neon_typed_alias typeinfo;
12d6b0b7 2709 char *namebuf, *nameend ATTRIBUTE_UNUSED;
dcbf9037 2710 int namelen;
5f4273c7 2711
dcbf9037
JB
2712 typeinfo.defined = 0;
2713 typeinfo.eltype.type = NT_invtype;
2714 typeinfo.eltype.size = -1;
2715 typeinfo.index = -1;
5f4273c7 2716
dcbf9037 2717 nameend = p;
5f4273c7 2718
dcbf9037
JB
2719 if (strncmp (p, " .dn ", 5) == 0)
2720 basetype = REG_TYPE_VFD;
2721 else if (strncmp (p, " .qn ", 5) == 0)
2722 basetype = REG_TYPE_NQ;
2723 else
c921be7d 2724 return FALSE;
5f4273c7 2725
dcbf9037 2726 p += 5;
5f4273c7 2727
dcbf9037 2728 if (*p == '\0')
c921be7d 2729 return FALSE;
5f4273c7 2730
dcbf9037
JB
2731 basereg = arm_reg_parse_multi (&p);
2732
2733 if (basereg && basereg->type != basetype)
2734 {
2735 as_bad (_("bad type for register"));
c921be7d 2736 return FALSE;
dcbf9037
JB
2737 }
2738
2739 if (basereg == NULL)
2740 {
2741 expressionS exp;
2742 /* Try parsing as an integer. */
2743 my_get_expression (&exp, &p, GE_NO_PREFIX);
2744 if (exp.X_op != O_constant)
477330fc
RM
2745 {
2746 as_bad (_("expression must be constant"));
2747 return FALSE;
2748 }
dcbf9037
JB
2749 basereg = &mybasereg;
2750 basereg->number = (basetype == REG_TYPE_NQ) ? exp.X_add_number * 2
477330fc 2751 : exp.X_add_number;
dcbf9037
JB
2752 basereg->neon = 0;
2753 }
2754
2755 if (basereg->neon)
2756 typeinfo = *basereg->neon;
2757
2758 if (parse_neon_type (&ntype, &p) == SUCCESS)
2759 {
2760 /* We got a type. */
2761 if (typeinfo.defined & NTA_HASTYPE)
477330fc
RM
2762 {
2763 as_bad (_("can't redefine the type of a register alias"));
2764 return FALSE;
2765 }
5f4273c7 2766
dcbf9037
JB
2767 typeinfo.defined |= NTA_HASTYPE;
2768 if (ntype.elems != 1)
477330fc
RM
2769 {
2770 as_bad (_("you must specify a single type only"));
2771 return FALSE;
2772 }
dcbf9037
JB
2773 typeinfo.eltype = ntype.el[0];
2774 }
5f4273c7 2775
dcbf9037
JB
2776 if (skip_past_char (&p, '[') == SUCCESS)
2777 {
2778 expressionS exp;
2779 /* We got a scalar index. */
5f4273c7 2780
dcbf9037 2781 if (typeinfo.defined & NTA_HASINDEX)
477330fc
RM
2782 {
2783 as_bad (_("can't redefine the index of a scalar alias"));
2784 return FALSE;
2785 }
5f4273c7 2786
dcbf9037 2787 my_get_expression (&exp, &p, GE_NO_PREFIX);
5f4273c7 2788
dcbf9037 2789 if (exp.X_op != O_constant)
477330fc
RM
2790 {
2791 as_bad (_("scalar index must be constant"));
2792 return FALSE;
2793 }
5f4273c7 2794
dcbf9037
JB
2795 typeinfo.defined |= NTA_HASINDEX;
2796 typeinfo.index = exp.X_add_number;
5f4273c7 2797
dcbf9037 2798 if (skip_past_char (&p, ']') == FAIL)
477330fc
RM
2799 {
2800 as_bad (_("expecting ]"));
2801 return FALSE;
2802 }
dcbf9037
JB
2803 }
2804
15735687
NS
2805 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2806 the desired alias name, and p points to its end. If not, then
2807 the desired alias name is in the global original_case_string. */
2808#ifdef TC_CASE_SENSITIVE
dcbf9037 2809 namelen = nameend - newname;
15735687
NS
2810#else
2811 newname = original_case_string;
2812 namelen = strlen (newname);
2813#endif
2814
29a2809e 2815 namebuf = xmemdup0 (newname, namelen);
5f4273c7 2816
dcbf9037 2817 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2818 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2819
dcbf9037
JB
2820 /* Insert name in all uppercase. */
2821 for (p = namebuf; *p; p++)
2822 *p = TOUPPER (*p);
5f4273c7 2823
dcbf9037
JB
2824 if (strncmp (namebuf, newname, namelen))
2825 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2826 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2827
dcbf9037
JB
2828 /* Insert name in all lowercase. */
2829 for (p = namebuf; *p; p++)
2830 *p = TOLOWER (*p);
5f4273c7 2831
dcbf9037
JB
2832 if (strncmp (namebuf, newname, namelen))
2833 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2834 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2835
e1fa0163 2836 free (namebuf);
c921be7d 2837 return TRUE;
dcbf9037
JB
2838}
2839
c19d1205
ZW
2840/* Should never be called, as .req goes between the alias and the
2841 register name, not at the beginning of the line. */
c921be7d 2842
b99bd4ef 2843static void
c19d1205 2844s_req (int a ATTRIBUTE_UNUSED)
b99bd4ef 2845{
c19d1205
ZW
2846 as_bad (_("invalid syntax for .req directive"));
2847}
b99bd4ef 2848
dcbf9037
JB
2849static void
2850s_dn (int a ATTRIBUTE_UNUSED)
2851{
2852 as_bad (_("invalid syntax for .dn directive"));
2853}
2854
2855static void
2856s_qn (int a ATTRIBUTE_UNUSED)
2857{
2858 as_bad (_("invalid syntax for .qn directive"));
2859}
2860
c19d1205
ZW
2861/* The .unreq directive deletes an alias which was previously defined
2862 by .req. For example:
b99bd4ef 2863
c19d1205
ZW
2864 my_alias .req r11
2865 .unreq my_alias */
b99bd4ef
NC
2866
2867static void
c19d1205 2868s_unreq (int a ATTRIBUTE_UNUSED)
b99bd4ef 2869{
c19d1205
ZW
2870 char * name;
2871 char saved_char;
b99bd4ef 2872
c19d1205
ZW
2873 name = input_line_pointer;
2874
2875 while (*input_line_pointer != 0
2876 && *input_line_pointer != ' '
2877 && *input_line_pointer != '\n')
2878 ++input_line_pointer;
2879
2880 saved_char = *input_line_pointer;
2881 *input_line_pointer = 0;
2882
2883 if (!*name)
2884 as_bad (_("invalid syntax for .unreq directive"));
2885 else
2886 {
21d799b5 2887 struct reg_entry *reg = (struct reg_entry *) hash_find (arm_reg_hsh,
477330fc 2888 name);
c19d1205
ZW
2889
2890 if (!reg)
2891 as_bad (_("unknown register alias '%s'"), name);
2892 else if (reg->builtin)
a1727c1a 2893 as_warn (_("ignoring attempt to use .unreq on fixed register name: '%s'"),
c19d1205
ZW
2894 name);
2895 else
2896 {
d929913e
NC
2897 char * p;
2898 char * nbuf;
2899
db0bc284 2900 hash_delete (arm_reg_hsh, name, FALSE);
c19d1205 2901 free ((char *) reg->name);
477330fc
RM
2902 if (reg->neon)
2903 free (reg->neon);
c19d1205 2904 free (reg);
d929913e
NC
2905
2906 /* Also locate the all upper case and all lower case versions.
2907 Do not complain if we cannot find one or the other as it
2908 was probably deleted above. */
5f4273c7 2909
d929913e
NC
2910 nbuf = strdup (name);
2911 for (p = nbuf; *p; p++)
2912 *p = TOUPPER (*p);
21d799b5 2913 reg = (struct reg_entry *) hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2914 if (reg)
2915 {
db0bc284 2916 hash_delete (arm_reg_hsh, nbuf, FALSE);
d929913e
NC
2917 free ((char *) reg->name);
2918 if (reg->neon)
2919 free (reg->neon);
2920 free (reg);
2921 }
2922
2923 for (p = nbuf; *p; p++)
2924 *p = TOLOWER (*p);
21d799b5 2925 reg = (struct reg_entry *) hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2926 if (reg)
2927 {
db0bc284 2928 hash_delete (arm_reg_hsh, nbuf, FALSE);
d929913e
NC
2929 free ((char *) reg->name);
2930 if (reg->neon)
2931 free (reg->neon);
2932 free (reg);
2933 }
2934
2935 free (nbuf);
c19d1205
ZW
2936 }
2937 }
b99bd4ef 2938
c19d1205 2939 *input_line_pointer = saved_char;
b99bd4ef
NC
2940 demand_empty_rest_of_line ();
2941}
2942
c19d1205
ZW
2943/* Directives: Instruction set selection. */
2944
2945#ifdef OBJ_ELF
2946/* This code is to handle mapping symbols as defined in the ARM ELF spec.
2947 (See "Mapping symbols", section 4.5.5, ARM AAELF version 1.0).
2948 Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
2949 and $d has type STT_OBJECT (BSF_OBJECT flag). Now all three are untyped. */
2950
cd000bff
DJ
2951/* Create a new mapping symbol for the transition to STATE. */
2952
2953static void
2954make_mapping_symbol (enum mstate state, valueT value, fragS *frag)
b99bd4ef 2955{
a737bd4d 2956 symbolS * symbolP;
c19d1205
ZW
2957 const char * symname;
2958 int type;
b99bd4ef 2959
c19d1205 2960 switch (state)
b99bd4ef 2961 {
c19d1205
ZW
2962 case MAP_DATA:
2963 symname = "$d";
2964 type = BSF_NO_FLAGS;
2965 break;
2966 case MAP_ARM:
2967 symname = "$a";
2968 type = BSF_NO_FLAGS;
2969 break;
2970 case MAP_THUMB:
2971 symname = "$t";
2972 type = BSF_NO_FLAGS;
2973 break;
c19d1205
ZW
2974 default:
2975 abort ();
2976 }
2977
cd000bff 2978 symbolP = symbol_new (symname, now_seg, value, frag);
c19d1205
ZW
2979 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2980
2981 switch (state)
2982 {
2983 case MAP_ARM:
2984 THUMB_SET_FUNC (symbolP, 0);
2985 ARM_SET_THUMB (symbolP, 0);
2986 ARM_SET_INTERWORK (symbolP, support_interwork);
2987 break;
2988
2989 case MAP_THUMB:
2990 THUMB_SET_FUNC (symbolP, 1);
2991 ARM_SET_THUMB (symbolP, 1);
2992 ARM_SET_INTERWORK (symbolP, support_interwork);
2993 break;
2994
2995 case MAP_DATA:
2996 default:
cd000bff
DJ
2997 break;
2998 }
2999
3000 /* Save the mapping symbols for future reference. Also check that
3001 we do not place two mapping symbols at the same offset within a
3002 frag. We'll handle overlap between frags in
2de7820f
JZ
3003 check_mapping_symbols.
3004
3005 If .fill or other data filling directive generates zero sized data,
3006 the mapping symbol for the following code will have the same value
3007 as the one generated for the data filling directive. In this case,
3008 we replace the old symbol with the new one at the same address. */
cd000bff
DJ
3009 if (value == 0)
3010 {
2de7820f
JZ
3011 if (frag->tc_frag_data.first_map != NULL)
3012 {
3013 know (S_GET_VALUE (frag->tc_frag_data.first_map) == 0);
3014 symbol_remove (frag->tc_frag_data.first_map, &symbol_rootP, &symbol_lastP);
3015 }
cd000bff
DJ
3016 frag->tc_frag_data.first_map = symbolP;
3017 }
3018 if (frag->tc_frag_data.last_map != NULL)
0f020cef
JZ
3019 {
3020 know (S_GET_VALUE (frag->tc_frag_data.last_map) <= S_GET_VALUE (symbolP));
0f020cef
JZ
3021 if (S_GET_VALUE (frag->tc_frag_data.last_map) == S_GET_VALUE (symbolP))
3022 symbol_remove (frag->tc_frag_data.last_map, &symbol_rootP, &symbol_lastP);
3023 }
cd000bff
DJ
3024 frag->tc_frag_data.last_map = symbolP;
3025}
3026
3027/* We must sometimes convert a region marked as code to data during
3028 code alignment, if an odd number of bytes have to be padded. The
3029 code mapping symbol is pushed to an aligned address. */
3030
3031static void
3032insert_data_mapping_symbol (enum mstate state,
3033 valueT value, fragS *frag, offsetT bytes)
3034{
3035 /* If there was already a mapping symbol, remove it. */
3036 if (frag->tc_frag_data.last_map != NULL
3037 && S_GET_VALUE (frag->tc_frag_data.last_map) == frag->fr_address + value)
3038 {
3039 symbolS *symp = frag->tc_frag_data.last_map;
3040
3041 if (value == 0)
3042 {
3043 know (frag->tc_frag_data.first_map == symp);
3044 frag->tc_frag_data.first_map = NULL;
3045 }
3046 frag->tc_frag_data.last_map = NULL;
3047 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
c19d1205 3048 }
cd000bff
DJ
3049
3050 make_mapping_symbol (MAP_DATA, value, frag);
3051 make_mapping_symbol (state, value + bytes, frag);
3052}
3053
3054static void mapping_state_2 (enum mstate state, int max_chars);
3055
3056/* Set the mapping state to STATE. Only call this when about to
3057 emit some STATE bytes to the file. */
3058
4e9aaefb 3059#define TRANSITION(from, to) (mapstate == (from) && state == (to))
cd000bff
DJ
3060void
3061mapping_state (enum mstate state)
3062{
940b5ce0
DJ
3063 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
3064
cd000bff
DJ
3065 if (mapstate == state)
3066 /* The mapping symbol has already been emitted.
3067 There is nothing else to do. */
3068 return;
49c62a33
NC
3069
3070 if (state == MAP_ARM || state == MAP_THUMB)
3071 /* PR gas/12931
3072 All ARM instructions require 4-byte alignment.
3073 (Almost) all Thumb instructions require 2-byte alignment.
3074
3075 When emitting instructions into any section, mark the section
3076 appropriately.
3077
3078 Some Thumb instructions are alignment-sensitive modulo 4 bytes,
3079 but themselves require 2-byte alignment; this applies to some
33eaf5de 3080 PC- relative forms. However, these cases will involve implicit
49c62a33
NC
3081 literal pool generation or an explicit .align >=2, both of
3082 which will cause the section to me marked with sufficient
3083 alignment. Thus, we don't handle those cases here. */
3084 record_alignment (now_seg, state == MAP_ARM ? 2 : 1);
3085
3086 if (TRANSITION (MAP_UNDEFINED, MAP_DATA))
4e9aaefb 3087 /* This case will be evaluated later. */
cd000bff 3088 return;
cd000bff
DJ
3089
3090 mapping_state_2 (state, 0);
cd000bff
DJ
3091}
3092
3093/* Same as mapping_state, but MAX_CHARS bytes have already been
3094 allocated. Put the mapping symbol that far back. */
3095
3096static void
3097mapping_state_2 (enum mstate state, int max_chars)
3098{
940b5ce0
DJ
3099 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
3100
3101 if (!SEG_NORMAL (now_seg))
3102 return;
3103
cd000bff
DJ
3104 if (mapstate == state)
3105 /* The mapping symbol has already been emitted.
3106 There is nothing else to do. */
3107 return;
3108
4e9aaefb
SA
3109 if (TRANSITION (MAP_UNDEFINED, MAP_ARM)
3110 || TRANSITION (MAP_UNDEFINED, MAP_THUMB))
3111 {
3112 struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
3113 const int add_symbol = (frag_now != frag_first) || (frag_now_fix () > 0);
3114
3115 if (add_symbol)
3116 make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
3117 }
3118
cd000bff
DJ
3119 seg_info (now_seg)->tc_segment_info_data.mapstate = state;
3120 make_mapping_symbol (state, (valueT) frag_now_fix () - max_chars, frag_now);
c19d1205 3121}
4e9aaefb 3122#undef TRANSITION
c19d1205 3123#else
d3106081
NS
3124#define mapping_state(x) ((void)0)
3125#define mapping_state_2(x, y) ((void)0)
c19d1205
ZW
3126#endif
3127
3128/* Find the real, Thumb encoded start of a Thumb function. */
3129
4343666d 3130#ifdef OBJ_COFF
c19d1205
ZW
3131static symbolS *
3132find_real_start (symbolS * symbolP)
3133{
3134 char * real_start;
3135 const char * name = S_GET_NAME (symbolP);
3136 symbolS * new_target;
3137
3138 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
3139#define STUB_NAME ".real_start_of"
3140
3141 if (name == NULL)
3142 abort ();
3143
37f6032b
ZW
3144 /* The compiler may generate BL instructions to local labels because
3145 it needs to perform a branch to a far away location. These labels
3146 do not have a corresponding ".real_start_of" label. We check
3147 both for S_IS_LOCAL and for a leading dot, to give a way to bypass
3148 the ".real_start_of" convention for nonlocal branches. */
3149 if (S_IS_LOCAL (symbolP) || name[0] == '.')
c19d1205
ZW
3150 return symbolP;
3151
e1fa0163 3152 real_start = concat (STUB_NAME, name, NULL);
c19d1205 3153 new_target = symbol_find (real_start);
e1fa0163 3154 free (real_start);
c19d1205
ZW
3155
3156 if (new_target == NULL)
3157 {
bd3ba5d1 3158 as_warn (_("Failed to find real start of function: %s\n"), name);
c19d1205
ZW
3159 new_target = symbolP;
3160 }
3161
c19d1205
ZW
3162 return new_target;
3163}
4343666d 3164#endif
c19d1205
ZW
3165
3166static void
3167opcode_select (int width)
3168{
3169 switch (width)
3170 {
3171 case 16:
3172 if (! thumb_mode)
3173 {
e74cfd16 3174 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
c19d1205
ZW
3175 as_bad (_("selected processor does not support THUMB opcodes"));
3176
3177 thumb_mode = 1;
3178 /* No need to force the alignment, since we will have been
3179 coming from ARM mode, which is word-aligned. */
3180 record_alignment (now_seg, 1);
3181 }
c19d1205
ZW
3182 break;
3183
3184 case 32:
3185 if (thumb_mode)
3186 {
e74cfd16 3187 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205
ZW
3188 as_bad (_("selected processor does not support ARM opcodes"));
3189
3190 thumb_mode = 0;
3191
3192 if (!need_pass_2)
3193 frag_align (2, 0, 0);
3194
3195 record_alignment (now_seg, 1);
3196 }
c19d1205
ZW
3197 break;
3198
3199 default:
3200 as_bad (_("invalid instruction size selected (%d)"), width);
3201 }
3202}
3203
3204static void
3205s_arm (int ignore ATTRIBUTE_UNUSED)
3206{
3207 opcode_select (32);
3208 demand_empty_rest_of_line ();
3209}
3210
3211static void
3212s_thumb (int ignore ATTRIBUTE_UNUSED)
3213{
3214 opcode_select (16);
3215 demand_empty_rest_of_line ();
3216}
3217
3218static void
3219s_code (int unused ATTRIBUTE_UNUSED)
3220{
3221 int temp;
3222
3223 temp = get_absolute_expression ();
3224 switch (temp)
3225 {
3226 case 16:
3227 case 32:
3228 opcode_select (temp);
3229 break;
3230
3231 default:
3232 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3233 }
3234}
3235
3236static void
3237s_force_thumb (int ignore ATTRIBUTE_UNUSED)
3238{
3239 /* If we are not already in thumb mode go into it, EVEN if
3240 the target processor does not support thumb instructions.
3241 This is used by gcc/config/arm/lib1funcs.asm for example
3242 to compile interworking support functions even if the
3243 target processor should not support interworking. */
3244 if (! thumb_mode)
3245 {
3246 thumb_mode = 2;
3247 record_alignment (now_seg, 1);
3248 }
3249
3250 demand_empty_rest_of_line ();
3251}
3252
3253static void
3254s_thumb_func (int ignore ATTRIBUTE_UNUSED)
3255{
3256 s_thumb (0);
3257
3258 /* The following label is the name/address of the start of a Thumb function.
3259 We need to know this for the interworking support. */
3260 label_is_thumb_function_name = TRUE;
3261}
3262
3263/* Perform a .set directive, but also mark the alias as
3264 being a thumb function. */
3265
3266static void
3267s_thumb_set (int equiv)
3268{
3269 /* XXX the following is a duplicate of the code for s_set() in read.c
3270 We cannot just call that code as we need to get at the symbol that
3271 is created. */
3272 char * name;
3273 char delim;
3274 char * end_name;
3275 symbolS * symbolP;
3276
3277 /* Especial apologies for the random logic:
3278 This just grew, and could be parsed much more simply!
3279 Dean - in haste. */
d02603dc 3280 delim = get_symbol_name (& name);
c19d1205 3281 end_name = input_line_pointer;
d02603dc 3282 (void) restore_line_pointer (delim);
c19d1205
ZW
3283
3284 if (*input_line_pointer != ',')
3285 {
3286 *end_name = 0;
3287 as_bad (_("expected comma after name \"%s\""), name);
b99bd4ef
NC
3288 *end_name = delim;
3289 ignore_rest_of_line ();
3290 return;
3291 }
3292
3293 input_line_pointer++;
3294 *end_name = 0;
3295
3296 if (name[0] == '.' && name[1] == '\0')
3297 {
3298 /* XXX - this should not happen to .thumb_set. */
3299 abort ();
3300 }
3301
3302 if ((symbolP = symbol_find (name)) == NULL
3303 && (symbolP = md_undefined_symbol (name)) == NULL)
3304 {
3305#ifndef NO_LISTING
3306 /* When doing symbol listings, play games with dummy fragments living
3307 outside the normal fragment chain to record the file and line info
c19d1205 3308 for this symbol. */
b99bd4ef
NC
3309 if (listing & LISTING_SYMBOLS)
3310 {
3311 extern struct list_info_struct * listing_tail;
21d799b5 3312 fragS * dummy_frag = (fragS * ) xmalloc (sizeof (fragS));
b99bd4ef
NC
3313
3314 memset (dummy_frag, 0, sizeof (fragS));
3315 dummy_frag->fr_type = rs_fill;
3316 dummy_frag->line = listing_tail;
3317 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3318 dummy_frag->fr_symbol = symbolP;
3319 }
3320 else
3321#endif
3322 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3323
3324#ifdef OBJ_COFF
3325 /* "set" symbols are local unless otherwise specified. */
3326 SF_SET_LOCAL (symbolP);
3327#endif /* OBJ_COFF */
3328 } /* Make a new symbol. */
3329
3330 symbol_table_insert (symbolP);
3331
3332 * end_name = delim;
3333
3334 if (equiv
3335 && S_IS_DEFINED (symbolP)
3336 && S_GET_SEGMENT (symbolP) != reg_section)
3337 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3338
3339 pseudo_set (symbolP);
3340
3341 demand_empty_rest_of_line ();
3342
c19d1205 3343 /* XXX Now we come to the Thumb specific bit of code. */
b99bd4ef
NC
3344
3345 THUMB_SET_FUNC (symbolP, 1);
3346 ARM_SET_THUMB (symbolP, 1);
3347#if defined OBJ_ELF || defined OBJ_COFF
3348 ARM_SET_INTERWORK (symbolP, support_interwork);
3349#endif
3350}
3351
c19d1205 3352/* Directives: Mode selection. */
b99bd4ef 3353
c19d1205
ZW
3354/* .syntax [unified|divided] - choose the new unified syntax
3355 (same for Arm and Thumb encoding, modulo slight differences in what
3356 can be represented) or the old divergent syntax for each mode. */
b99bd4ef 3357static void
c19d1205 3358s_syntax (int unused ATTRIBUTE_UNUSED)
b99bd4ef 3359{
c19d1205
ZW
3360 char *name, delim;
3361
d02603dc 3362 delim = get_symbol_name (& name);
c19d1205
ZW
3363
3364 if (!strcasecmp (name, "unified"))
3365 unified_syntax = TRUE;
3366 else if (!strcasecmp (name, "divided"))
3367 unified_syntax = FALSE;
3368 else
3369 {
3370 as_bad (_("unrecognized syntax mode \"%s\""), name);
3371 return;
3372 }
d02603dc 3373 (void) restore_line_pointer (delim);
b99bd4ef
NC
3374 demand_empty_rest_of_line ();
3375}
3376
c19d1205
ZW
3377/* Directives: sectioning and alignment. */
3378
c19d1205
ZW
3379static void
3380s_bss (int ignore ATTRIBUTE_UNUSED)
b99bd4ef 3381{
c19d1205
ZW
3382 /* We don't support putting frags in the BSS segment, we fake it by
3383 marking in_bss, then looking at s_skip for clues. */
3384 subseg_set (bss_section, 0);
3385 demand_empty_rest_of_line ();
cd000bff
DJ
3386
3387#ifdef md_elf_section_change_hook
3388 md_elf_section_change_hook ();
3389#endif
c19d1205 3390}
b99bd4ef 3391
c19d1205
ZW
3392static void
3393s_even (int ignore ATTRIBUTE_UNUSED)
3394{
3395 /* Never make frag if expect extra pass. */
3396 if (!need_pass_2)
3397 frag_align (1, 0, 0);
b99bd4ef 3398
c19d1205 3399 record_alignment (now_seg, 1);
b99bd4ef 3400
c19d1205 3401 demand_empty_rest_of_line ();
b99bd4ef
NC
3402}
3403
2e6976a8
DG
3404/* Directives: CodeComposer Studio. */
3405
3406/* .ref (for CodeComposer Studio syntax only). */
3407static void
3408s_ccs_ref (int unused ATTRIBUTE_UNUSED)
3409{
3410 if (codecomposer_syntax)
3411 ignore_rest_of_line ();
3412 else
3413 as_bad (_(".ref pseudo-op only available with -mccs flag."));
3414}
3415
3416/* If name is not NULL, then it is used for marking the beginning of a
2b0f3761 3417 function, whereas if it is NULL then it means the function end. */
2e6976a8
DG
3418static void
3419asmfunc_debug (const char * name)
3420{
3421 static const char * last_name = NULL;
3422
3423 if (name != NULL)
3424 {
3425 gas_assert (last_name == NULL);
3426 last_name = name;
3427
3428 if (debug_type == DEBUG_STABS)
3429 stabs_generate_asm_func (name, name);
3430 }
3431 else
3432 {
3433 gas_assert (last_name != NULL);
3434
3435 if (debug_type == DEBUG_STABS)
3436 stabs_generate_asm_endfunc (last_name, last_name);
3437
3438 last_name = NULL;
3439 }
3440}
3441
3442static void
3443s_ccs_asmfunc (int unused ATTRIBUTE_UNUSED)
3444{
3445 if (codecomposer_syntax)
3446 {
3447 switch (asmfunc_state)
3448 {
3449 case OUTSIDE_ASMFUNC:
3450 asmfunc_state = WAITING_ASMFUNC_NAME;
3451 break;
3452
3453 case WAITING_ASMFUNC_NAME:
3454 as_bad (_(".asmfunc repeated."));
3455 break;
3456
3457 case WAITING_ENDASMFUNC:
3458 as_bad (_(".asmfunc without function."));
3459 break;
3460 }
3461 demand_empty_rest_of_line ();
3462 }
3463 else
3464 as_bad (_(".asmfunc pseudo-op only available with -mccs flag."));
3465}
3466
3467static void
3468s_ccs_endasmfunc (int unused ATTRIBUTE_UNUSED)
3469{
3470 if (codecomposer_syntax)
3471 {
3472 switch (asmfunc_state)
3473 {
3474 case OUTSIDE_ASMFUNC:
3475 as_bad (_(".endasmfunc without a .asmfunc."));
3476 break;
3477
3478 case WAITING_ASMFUNC_NAME:
3479 as_bad (_(".endasmfunc without function."));
3480 break;
3481
3482 case WAITING_ENDASMFUNC:
3483 asmfunc_state = OUTSIDE_ASMFUNC;
3484 asmfunc_debug (NULL);
3485 break;
3486 }
3487 demand_empty_rest_of_line ();
3488 }
3489 else
3490 as_bad (_(".endasmfunc pseudo-op only available with -mccs flag."));
3491}
3492
3493static void
3494s_ccs_def (int name)
3495{
3496 if (codecomposer_syntax)
3497 s_globl (name);
3498 else
3499 as_bad (_(".def pseudo-op only available with -mccs flag."));
3500}
3501
c19d1205 3502/* Directives: Literal pools. */
a737bd4d 3503
c19d1205
ZW
3504static literal_pool *
3505find_literal_pool (void)
a737bd4d 3506{
c19d1205 3507 literal_pool * pool;
a737bd4d 3508
c19d1205 3509 for (pool = list_of_pools; pool != NULL; pool = pool->next)
a737bd4d 3510 {
c19d1205
ZW
3511 if (pool->section == now_seg
3512 && pool->sub_section == now_subseg)
3513 break;
a737bd4d
NC
3514 }
3515
c19d1205 3516 return pool;
a737bd4d
NC
3517}
3518
c19d1205
ZW
3519static literal_pool *
3520find_or_make_literal_pool (void)
a737bd4d 3521{
c19d1205
ZW
3522 /* Next literal pool ID number. */
3523 static unsigned int latest_pool_num = 1;
3524 literal_pool * pool;
a737bd4d 3525
c19d1205 3526 pool = find_literal_pool ();
a737bd4d 3527
c19d1205 3528 if (pool == NULL)
a737bd4d 3529 {
c19d1205 3530 /* Create a new pool. */
325801bd 3531 pool = XNEW (literal_pool);
c19d1205
ZW
3532 if (! pool)
3533 return NULL;
a737bd4d 3534
c19d1205
ZW
3535 pool->next_free_entry = 0;
3536 pool->section = now_seg;
3537 pool->sub_section = now_subseg;
3538 pool->next = list_of_pools;
3539 pool->symbol = NULL;
8335d6aa 3540 pool->alignment = 2;
c19d1205
ZW
3541
3542 /* Add it to the list. */
3543 list_of_pools = pool;
a737bd4d 3544 }
a737bd4d 3545
c19d1205
ZW
3546 /* New pools, and emptied pools, will have a NULL symbol. */
3547 if (pool->symbol == NULL)
a737bd4d 3548 {
c19d1205
ZW
3549 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
3550 (valueT) 0, &zero_address_frag);
3551 pool->id = latest_pool_num ++;
a737bd4d
NC
3552 }
3553
c19d1205
ZW
3554 /* Done. */
3555 return pool;
a737bd4d
NC
3556}
3557
c19d1205 3558/* Add the literal in the global 'inst'
5f4273c7 3559 structure to the relevant literal pool. */
b99bd4ef
NC
3560
3561static int
8335d6aa 3562add_to_lit_pool (unsigned int nbytes)
b99bd4ef 3563{
8335d6aa
JW
3564#define PADDING_SLOT 0x1
3565#define LIT_ENTRY_SIZE_MASK 0xFF
c19d1205 3566 literal_pool * pool;
8335d6aa
JW
3567 unsigned int entry, pool_size = 0;
3568 bfd_boolean padding_slot_p = FALSE;
e56c722b 3569 unsigned imm1 = 0;
8335d6aa
JW
3570 unsigned imm2 = 0;
3571
3572 if (nbytes == 8)
3573 {
3574 imm1 = inst.operands[1].imm;
3575 imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
e2b0ab59 3576 : inst.relocs[0].exp.X_unsigned ? 0
2569ceb0 3577 : ((bfd_int64_t) inst.operands[1].imm) >> 32);
8335d6aa
JW
3578 if (target_big_endian)
3579 {
3580 imm1 = imm2;
3581 imm2 = inst.operands[1].imm;
3582 }
3583 }
b99bd4ef 3584
c19d1205
ZW
3585 pool = find_or_make_literal_pool ();
3586
3587 /* Check if this literal value is already in the pool. */
3588 for (entry = 0; entry < pool->next_free_entry; entry ++)
b99bd4ef 3589 {
8335d6aa
JW
3590 if (nbytes == 4)
3591 {
e2b0ab59
AV
3592 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3593 && (inst.relocs[0].exp.X_op == O_constant)
8335d6aa 3594 && (pool->literals[entry].X_add_number
e2b0ab59 3595 == inst.relocs[0].exp.X_add_number)
8335d6aa
JW
3596 && (pool->literals[entry].X_md == nbytes)
3597 && (pool->literals[entry].X_unsigned
e2b0ab59 3598 == inst.relocs[0].exp.X_unsigned))
8335d6aa
JW
3599 break;
3600
e2b0ab59
AV
3601 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3602 && (inst.relocs[0].exp.X_op == O_symbol)
8335d6aa 3603 && (pool->literals[entry].X_add_number
e2b0ab59 3604 == inst.relocs[0].exp.X_add_number)
8335d6aa 3605 && (pool->literals[entry].X_add_symbol
e2b0ab59 3606 == inst.relocs[0].exp.X_add_symbol)
8335d6aa 3607 && (pool->literals[entry].X_op_symbol
e2b0ab59 3608 == inst.relocs[0].exp.X_op_symbol)
8335d6aa
JW
3609 && (pool->literals[entry].X_md == nbytes))
3610 break;
3611 }
3612 else if ((nbytes == 8)
3613 && !(pool_size & 0x7)
3614 && ((entry + 1) != pool->next_free_entry)
3615 && (pool->literals[entry].X_op == O_constant)
19f2f6a9 3616 && (pool->literals[entry].X_add_number == (offsetT) imm1)
8335d6aa 3617 && (pool->literals[entry].X_unsigned
e2b0ab59 3618 == inst.relocs[0].exp.X_unsigned)
8335d6aa 3619 && (pool->literals[entry + 1].X_op == O_constant)
19f2f6a9 3620 && (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
8335d6aa 3621 && (pool->literals[entry + 1].X_unsigned
e2b0ab59 3622 == inst.relocs[0].exp.X_unsigned))
c19d1205
ZW
3623 break;
3624
8335d6aa
JW
3625 padding_slot_p = ((pool->literals[entry].X_md >> 8) == PADDING_SLOT);
3626 if (padding_slot_p && (nbytes == 4))
c19d1205 3627 break;
8335d6aa
JW
3628
3629 pool_size += 4;
b99bd4ef
NC
3630 }
3631
c19d1205
ZW
3632 /* Do we need to create a new entry? */
3633 if (entry == pool->next_free_entry)
3634 {
3635 if (entry >= MAX_LITERAL_POOL_SIZE)
3636 {
3637 inst.error = _("literal pool overflow");
3638 return FAIL;
3639 }
3640
8335d6aa
JW
3641 if (nbytes == 8)
3642 {
3643 /* For 8-byte entries, we align to an 8-byte boundary,
3644 and split it into two 4-byte entries, because on 32-bit
3645 host, 8-byte constants are treated as big num, thus
3646 saved in "generic_bignum" which will be overwritten
3647 by later assignments.
3648
3649 We also need to make sure there is enough space for
3650 the split.
3651
3652 We also check to make sure the literal operand is a
3653 constant number. */
e2b0ab59
AV
3654 if (!(inst.relocs[0].exp.X_op == O_constant
3655 || inst.relocs[0].exp.X_op == O_big))
8335d6aa
JW
3656 {
3657 inst.error = _("invalid type for literal pool");
3658 return FAIL;
3659 }
3660 else if (pool_size & 0x7)
3661 {
3662 if ((entry + 2) >= MAX_LITERAL_POOL_SIZE)
3663 {
3664 inst.error = _("literal pool overflow");
3665 return FAIL;
3666 }
3667
e2b0ab59 3668 pool->literals[entry] = inst.relocs[0].exp;
a6684f0d 3669 pool->literals[entry].X_op = O_constant;
8335d6aa
JW
3670 pool->literals[entry].X_add_number = 0;
3671 pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
3672 pool->next_free_entry += 1;
3673 pool_size += 4;
3674 }
3675 else if ((entry + 1) >= MAX_LITERAL_POOL_SIZE)
3676 {
3677 inst.error = _("literal pool overflow");
3678 return FAIL;
3679 }
3680
e2b0ab59 3681 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3682 pool->literals[entry].X_op = O_constant;
3683 pool->literals[entry].X_add_number = imm1;
e2b0ab59 3684 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa 3685 pool->literals[entry++].X_md = 4;
e2b0ab59 3686 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3687 pool->literals[entry].X_op = O_constant;
3688 pool->literals[entry].X_add_number = imm2;
e2b0ab59 3689 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa
JW
3690 pool->literals[entry].X_md = 4;
3691 pool->alignment = 3;
3692 pool->next_free_entry += 1;
3693 }
3694 else
3695 {
e2b0ab59 3696 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3697 pool->literals[entry].X_md = 4;
3698 }
3699
a8040cf2
NC
3700#ifdef OBJ_ELF
3701 /* PR ld/12974: Record the location of the first source line to reference
3702 this entry in the literal pool. If it turns out during linking that the
3703 symbol does not exist we will be able to give an accurate line number for
3704 the (first use of the) missing reference. */
3705 if (debug_type == DEBUG_DWARF2)
3706 dwarf2_where (pool->locs + entry);
3707#endif
c19d1205
ZW
3708 pool->next_free_entry += 1;
3709 }
8335d6aa
JW
3710 else if (padding_slot_p)
3711 {
e2b0ab59 3712 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3713 pool->literals[entry].X_md = nbytes;
3714 }
b99bd4ef 3715
e2b0ab59
AV
3716 inst.relocs[0].exp.X_op = O_symbol;
3717 inst.relocs[0].exp.X_add_number = pool_size;
3718 inst.relocs[0].exp.X_add_symbol = pool->symbol;
b99bd4ef 3719
c19d1205 3720 return SUCCESS;
b99bd4ef
NC
3721}
3722
2e6976a8 3723bfd_boolean
2e57ce7b 3724tc_start_label_without_colon (void)
2e6976a8
DG
3725{
3726 bfd_boolean ret = TRUE;
3727
3728 if (codecomposer_syntax && asmfunc_state == WAITING_ASMFUNC_NAME)
3729 {
2e57ce7b 3730 const char *label = input_line_pointer;
2e6976a8
DG
3731
3732 while (!is_end_of_line[(int) label[-1]])
3733 --label;
3734
3735 if (*label == '.')
3736 {
3737 as_bad (_("Invalid label '%s'"), label);
3738 ret = FALSE;
3739 }
3740
3741 asmfunc_debug (label);
3742
3743 asmfunc_state = WAITING_ENDASMFUNC;
3744 }
3745
3746 return ret;
3747}
3748
c19d1205 3749/* Can't use symbol_new here, so have to create a symbol and then at
33eaf5de 3750 a later date assign it a value. That's what these functions do. */
e16bb312 3751
c19d1205
ZW
3752static void
3753symbol_locate (symbolS * symbolP,
3754 const char * name, /* It is copied, the caller can modify. */
3755 segT segment, /* Segment identifier (SEG_<something>). */
3756 valueT valu, /* Symbol value. */
3757 fragS * frag) /* Associated fragment. */
3758{
e57e6ddc 3759 size_t name_length;
c19d1205 3760 char * preserved_copy_of_name;
e16bb312 3761
c19d1205
ZW
3762 name_length = strlen (name) + 1; /* +1 for \0. */
3763 obstack_grow (&notes, name, name_length);
21d799b5 3764 preserved_copy_of_name = (char *) obstack_finish (&notes);
e16bb312 3765
c19d1205
ZW
3766#ifdef tc_canonicalize_symbol_name
3767 preserved_copy_of_name =
3768 tc_canonicalize_symbol_name (preserved_copy_of_name);
3769#endif
b99bd4ef 3770
c19d1205 3771 S_SET_NAME (symbolP, preserved_copy_of_name);
b99bd4ef 3772
c19d1205
ZW
3773 S_SET_SEGMENT (symbolP, segment);
3774 S_SET_VALUE (symbolP, valu);
3775 symbol_clear_list_pointers (symbolP);
b99bd4ef 3776
c19d1205 3777 symbol_set_frag (symbolP, frag);
b99bd4ef 3778
c19d1205
ZW
3779 /* Link to end of symbol chain. */
3780 {
3781 extern int symbol_table_frozen;
b99bd4ef 3782
c19d1205
ZW
3783 if (symbol_table_frozen)
3784 abort ();
3785 }
b99bd4ef 3786
c19d1205 3787 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
b99bd4ef 3788
c19d1205 3789 obj_symbol_new_hook (symbolP);
b99bd4ef 3790
c19d1205
ZW
3791#ifdef tc_symbol_new_hook
3792 tc_symbol_new_hook (symbolP);
3793#endif
3794
3795#ifdef DEBUG_SYMS
3796 verify_symbol_chain (symbol_rootP, symbol_lastP);
3797#endif /* DEBUG_SYMS */
b99bd4ef
NC
3798}
3799
c19d1205
ZW
3800static void
3801s_ltorg (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 3802{
c19d1205
ZW
3803 unsigned int entry;
3804 literal_pool * pool;
3805 char sym_name[20];
b99bd4ef 3806
c19d1205
ZW
3807 pool = find_literal_pool ();
3808 if (pool == NULL
3809 || pool->symbol == NULL
3810 || pool->next_free_entry == 0)
3811 return;
b99bd4ef 3812
c19d1205
ZW
3813 /* Align pool as you have word accesses.
3814 Only make a frag if we have to. */
3815 if (!need_pass_2)
8335d6aa 3816 frag_align (pool->alignment, 0, 0);
b99bd4ef 3817
c19d1205 3818 record_alignment (now_seg, 2);
b99bd4ef 3819
aaca88ef 3820#ifdef OBJ_ELF
47fc6e36
WN
3821 seg_info (now_seg)->tc_segment_info_data.mapstate = MAP_DATA;
3822 make_mapping_symbol (MAP_DATA, (valueT) frag_now_fix (), frag_now);
aaca88ef 3823#endif
c19d1205 3824 sprintf (sym_name, "$$lit_\002%x", pool->id);
b99bd4ef 3825
c19d1205
ZW
3826 symbol_locate (pool->symbol, sym_name, now_seg,
3827 (valueT) frag_now_fix (), frag_now);
3828 symbol_table_insert (pool->symbol);
b99bd4ef 3829
c19d1205 3830 ARM_SET_THUMB (pool->symbol, thumb_mode);
b99bd4ef 3831
c19d1205
ZW
3832#if defined OBJ_COFF || defined OBJ_ELF
3833 ARM_SET_INTERWORK (pool->symbol, support_interwork);
3834#endif
6c43fab6 3835
c19d1205 3836 for (entry = 0; entry < pool->next_free_entry; entry ++)
a8040cf2
NC
3837 {
3838#ifdef OBJ_ELF
3839 if (debug_type == DEBUG_DWARF2)
3840 dwarf2_gen_line_info (frag_now_fix (), pool->locs + entry);
3841#endif
3842 /* First output the expression in the instruction to the pool. */
8335d6aa
JW
3843 emit_expr (&(pool->literals[entry]),
3844 pool->literals[entry].X_md & LIT_ENTRY_SIZE_MASK);
a8040cf2 3845 }
b99bd4ef 3846
c19d1205
ZW
3847 /* Mark the pool as empty. */
3848 pool->next_free_entry = 0;
3849 pool->symbol = NULL;
b99bd4ef
NC
3850}
3851
c19d1205
ZW
3852#ifdef OBJ_ELF
3853/* Forward declarations for functions below, in the MD interface
3854 section. */
3855static void fix_new_arm (fragS *, int, short, expressionS *, int, int);
3856static valueT create_unwind_entry (int);
3857static void start_unwind_section (const segT, int);
3858static void add_unwind_opcode (valueT, int);
3859static void flush_pending_unwind (void);
b99bd4ef 3860
c19d1205 3861/* Directives: Data. */
b99bd4ef 3862
c19d1205
ZW
3863static void
3864s_arm_elf_cons (int nbytes)
3865{
3866 expressionS exp;
b99bd4ef 3867
c19d1205
ZW
3868#ifdef md_flush_pending_output
3869 md_flush_pending_output ();
3870#endif
b99bd4ef 3871
c19d1205 3872 if (is_it_end_of_statement ())
b99bd4ef 3873 {
c19d1205
ZW
3874 demand_empty_rest_of_line ();
3875 return;
b99bd4ef
NC
3876 }
3877
c19d1205
ZW
3878#ifdef md_cons_align
3879 md_cons_align (nbytes);
3880#endif
b99bd4ef 3881
c19d1205
ZW
3882 mapping_state (MAP_DATA);
3883 do
b99bd4ef 3884 {
c19d1205
ZW
3885 int reloc;
3886 char *base = input_line_pointer;
b99bd4ef 3887
c19d1205 3888 expression (& exp);
b99bd4ef 3889
c19d1205
ZW
3890 if (exp.X_op != O_symbol)
3891 emit_expr (&exp, (unsigned int) nbytes);
3892 else
3893 {
3894 char *before_reloc = input_line_pointer;
3895 reloc = parse_reloc (&input_line_pointer);
3896 if (reloc == -1)
3897 {
3898 as_bad (_("unrecognized relocation suffix"));
3899 ignore_rest_of_line ();
3900 return;
3901 }
3902 else if (reloc == BFD_RELOC_UNUSED)
3903 emit_expr (&exp, (unsigned int) nbytes);
3904 else
3905 {
21d799b5 3906 reloc_howto_type *howto = (reloc_howto_type *)
477330fc
RM
3907 bfd_reloc_type_lookup (stdoutput,
3908 (bfd_reloc_code_real_type) reloc);
c19d1205 3909 int size = bfd_get_reloc_size (howto);
b99bd4ef 3910
2fc8bdac
ZW
3911 if (reloc == BFD_RELOC_ARM_PLT32)
3912 {
3913 as_bad (_("(plt) is only valid on branch targets"));
3914 reloc = BFD_RELOC_UNUSED;
3915 size = 0;
3916 }
3917
c19d1205 3918 if (size > nbytes)
992a06ee
AM
3919 as_bad (ngettext ("%s relocations do not fit in %d byte",
3920 "%s relocations do not fit in %d bytes",
3921 nbytes),
c19d1205
ZW
3922 howto->name, nbytes);
3923 else
3924 {
3925 /* We've parsed an expression stopping at O_symbol.
3926 But there may be more expression left now that we
3927 have parsed the relocation marker. Parse it again.
3928 XXX Surely there is a cleaner way to do this. */
3929 char *p = input_line_pointer;
3930 int offset;
325801bd 3931 char *save_buf = XNEWVEC (char, input_line_pointer - base);
e1fa0163 3932
c19d1205
ZW
3933 memcpy (save_buf, base, input_line_pointer - base);
3934 memmove (base + (input_line_pointer - before_reloc),
3935 base, before_reloc - base);
3936
3937 input_line_pointer = base + (input_line_pointer-before_reloc);
3938 expression (&exp);
3939 memcpy (base, save_buf, p - base);
3940
3941 offset = nbytes - size;
4b1a927e
AM
3942 p = frag_more (nbytes);
3943 memset (p, 0, nbytes);
c19d1205 3944 fix_new_exp (frag_now, p - frag_now->fr_literal + offset,
21d799b5 3945 size, &exp, 0, (enum bfd_reloc_code_real) reloc);
e1fa0163 3946 free (save_buf);
c19d1205
ZW
3947 }
3948 }
3949 }
b99bd4ef 3950 }
c19d1205 3951 while (*input_line_pointer++ == ',');
b99bd4ef 3952
c19d1205
ZW
3953 /* Put terminator back into stream. */
3954 input_line_pointer --;
3955 demand_empty_rest_of_line ();
b99bd4ef
NC
3956}
3957
c921be7d
NC
3958/* Emit an expression containing a 32-bit thumb instruction.
3959 Implementation based on put_thumb32_insn. */
3960
3961static void
3962emit_thumb32_expr (expressionS * exp)
3963{
3964 expressionS exp_high = *exp;
3965
3966 exp_high.X_add_number = (unsigned long)exp_high.X_add_number >> 16;
3967 emit_expr (& exp_high, (unsigned int) THUMB_SIZE);
3968 exp->X_add_number &= 0xffff;
3969 emit_expr (exp, (unsigned int) THUMB_SIZE);
3970}
3971
3972/* Guess the instruction size based on the opcode. */
3973
3974static int
3975thumb_insn_size (int opcode)
3976{
3977 if ((unsigned int) opcode < 0xe800u)
3978 return 2;
3979 else if ((unsigned int) opcode >= 0xe8000000u)
3980 return 4;
3981 else
3982 return 0;
3983}
3984
3985static bfd_boolean
3986emit_insn (expressionS *exp, int nbytes)
3987{
3988 int size = 0;
3989
3990 if (exp->X_op == O_constant)
3991 {
3992 size = nbytes;
3993
3994 if (size == 0)
3995 size = thumb_insn_size (exp->X_add_number);
3996
3997 if (size != 0)
3998 {
3999 if (size == 2 && (unsigned int)exp->X_add_number > 0xffffu)
4000 {
4001 as_bad (_(".inst.n operand too big. "\
4002 "Use .inst.w instead"));
4003 size = 0;
4004 }
4005 else
4006 {
5ee91343
AV
4007 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
4008 set_pred_insn_type_nonvoid (OUTSIDE_PRED_INSN, 0);
c921be7d 4009 else
5ee91343 4010 set_pred_insn_type_nonvoid (NEUTRAL_IT_INSN, 0);
c921be7d
NC
4011
4012 if (thumb_mode && (size > THUMB_SIZE) && !target_big_endian)
4013 emit_thumb32_expr (exp);
4014 else
4015 emit_expr (exp, (unsigned int) size);
4016
4017 it_fsm_post_encode ();
4018 }
4019 }
4020 else
4021 as_bad (_("cannot determine Thumb instruction size. " \
4022 "Use .inst.n/.inst.w instead"));
4023 }
4024 else
4025 as_bad (_("constant expression required"));
4026
4027 return (size != 0);
4028}
4029
4030/* Like s_arm_elf_cons but do not use md_cons_align and
4031 set the mapping state to MAP_ARM/MAP_THUMB. */
4032
4033static void
4034s_arm_elf_inst (int nbytes)
4035{
4036 if (is_it_end_of_statement ())
4037 {
4038 demand_empty_rest_of_line ();
4039 return;
4040 }
4041
4042 /* Calling mapping_state () here will not change ARM/THUMB,
4043 but will ensure not to be in DATA state. */
4044
4045 if (thumb_mode)
4046 mapping_state (MAP_THUMB);
4047 else
4048 {
4049 if (nbytes != 0)
4050 {
4051 as_bad (_("width suffixes are invalid in ARM mode"));
4052 ignore_rest_of_line ();
4053 return;
4054 }
4055
4056 nbytes = 4;
4057
4058 mapping_state (MAP_ARM);
4059 }
4060
4061 do
4062 {
4063 expressionS exp;
4064
4065 expression (& exp);
4066
4067 if (! emit_insn (& exp, nbytes))
4068 {
4069 ignore_rest_of_line ();
4070 return;
4071 }
4072 }
4073 while (*input_line_pointer++ == ',');
4074
4075 /* Put terminator back into stream. */
4076 input_line_pointer --;
4077 demand_empty_rest_of_line ();
4078}
b99bd4ef 4079
c19d1205 4080/* Parse a .rel31 directive. */
b99bd4ef 4081
c19d1205
ZW
4082static void
4083s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
4084{
4085 expressionS exp;
4086 char *p;
4087 valueT highbit;
b99bd4ef 4088
c19d1205
ZW
4089 highbit = 0;
4090 if (*input_line_pointer == '1')
4091 highbit = 0x80000000;
4092 else if (*input_line_pointer != '0')
4093 as_bad (_("expected 0 or 1"));
b99bd4ef 4094
c19d1205
ZW
4095 input_line_pointer++;
4096 if (*input_line_pointer != ',')
4097 as_bad (_("missing comma"));
4098 input_line_pointer++;
b99bd4ef 4099
c19d1205
ZW
4100#ifdef md_flush_pending_output
4101 md_flush_pending_output ();
4102#endif
b99bd4ef 4103
c19d1205
ZW
4104#ifdef md_cons_align
4105 md_cons_align (4);
4106#endif
b99bd4ef 4107
c19d1205 4108 mapping_state (MAP_DATA);
b99bd4ef 4109
c19d1205 4110 expression (&exp);
b99bd4ef 4111
c19d1205
ZW
4112 p = frag_more (4);
4113 md_number_to_chars (p, highbit, 4);
4114 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
4115 BFD_RELOC_ARM_PREL31);
b99bd4ef 4116
c19d1205 4117 demand_empty_rest_of_line ();
b99bd4ef
NC
4118}
4119
c19d1205 4120/* Directives: AEABI stack-unwind tables. */
b99bd4ef 4121
c19d1205 4122/* Parse an unwind_fnstart directive. Simply records the current location. */
b99bd4ef 4123
c19d1205
ZW
4124static void
4125s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
4126{
4127 demand_empty_rest_of_line ();
921e5f0a
PB
4128 if (unwind.proc_start)
4129 {
c921be7d 4130 as_bad (_("duplicate .fnstart directive"));
921e5f0a
PB
4131 return;
4132 }
4133
c19d1205
ZW
4134 /* Mark the start of the function. */
4135 unwind.proc_start = expr_build_dot ();
b99bd4ef 4136
c19d1205
ZW
4137 /* Reset the rest of the unwind info. */
4138 unwind.opcode_count = 0;
4139 unwind.table_entry = NULL;
4140 unwind.personality_routine = NULL;
4141 unwind.personality_index = -1;
4142 unwind.frame_size = 0;
4143 unwind.fp_offset = 0;
fdfde340 4144 unwind.fp_reg = REG_SP;
c19d1205
ZW
4145 unwind.fp_used = 0;
4146 unwind.sp_restored = 0;
4147}
b99bd4ef 4148
b99bd4ef 4149
c19d1205
ZW
4150/* Parse a handlerdata directive. Creates the exception handling table entry
4151 for the function. */
b99bd4ef 4152
c19d1205
ZW
4153static void
4154s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
4155{
4156 demand_empty_rest_of_line ();
921e5f0a 4157 if (!unwind.proc_start)
c921be7d 4158 as_bad (MISSING_FNSTART);
921e5f0a 4159
c19d1205 4160 if (unwind.table_entry)
6decc662 4161 as_bad (_("duplicate .handlerdata directive"));
f02232aa 4162
c19d1205
ZW
4163 create_unwind_entry (1);
4164}
a737bd4d 4165
c19d1205 4166/* Parse an unwind_fnend directive. Generates the index table entry. */
b99bd4ef 4167
c19d1205
ZW
4168static void
4169s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
4170{
4171 long where;
4172 char *ptr;
4173 valueT val;
940b5ce0 4174 unsigned int marked_pr_dependency;
f02232aa 4175
c19d1205 4176 demand_empty_rest_of_line ();
f02232aa 4177
921e5f0a
PB
4178 if (!unwind.proc_start)
4179 {
c921be7d 4180 as_bad (_(".fnend directive without .fnstart"));
921e5f0a
PB
4181 return;
4182 }
4183
c19d1205
ZW
4184 /* Add eh table entry. */
4185 if (unwind.table_entry == NULL)
4186 val = create_unwind_entry (0);
4187 else
4188 val = 0;
f02232aa 4189
c19d1205
ZW
4190 /* Add index table entry. This is two words. */
4191 start_unwind_section (unwind.saved_seg, 1);
4192 frag_align (2, 0, 0);
4193 record_alignment (now_seg, 2);
b99bd4ef 4194
c19d1205 4195 ptr = frag_more (8);
5011093d 4196 memset (ptr, 0, 8);
c19d1205 4197 where = frag_now_fix () - 8;
f02232aa 4198
c19d1205
ZW
4199 /* Self relative offset of the function start. */
4200 fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
4201 BFD_RELOC_ARM_PREL31);
f02232aa 4202
c19d1205
ZW
4203 /* Indicate dependency on EHABI-defined personality routines to the
4204 linker, if it hasn't been done already. */
940b5ce0
DJ
4205 marked_pr_dependency
4206 = seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency;
c19d1205
ZW
4207 if (unwind.personality_index >= 0 && unwind.personality_index < 3
4208 && !(marked_pr_dependency & (1 << unwind.personality_index)))
4209 {
5f4273c7
NC
4210 static const char *const name[] =
4211 {
4212 "__aeabi_unwind_cpp_pr0",
4213 "__aeabi_unwind_cpp_pr1",
4214 "__aeabi_unwind_cpp_pr2"
4215 };
c19d1205
ZW
4216 symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
4217 fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
c19d1205 4218 seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
940b5ce0 4219 |= 1 << unwind.personality_index;
c19d1205 4220 }
f02232aa 4221
c19d1205
ZW
4222 if (val)
4223 /* Inline exception table entry. */
4224 md_number_to_chars (ptr + 4, val, 4);
4225 else
4226 /* Self relative offset of the table entry. */
4227 fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
4228 BFD_RELOC_ARM_PREL31);
f02232aa 4229
c19d1205
ZW
4230 /* Restore the original section. */
4231 subseg_set (unwind.saved_seg, unwind.saved_subseg);
921e5f0a
PB
4232
4233 unwind.proc_start = NULL;
c19d1205 4234}
f02232aa 4235
f02232aa 4236
c19d1205 4237/* Parse an unwind_cantunwind directive. */
b99bd4ef 4238
c19d1205
ZW
4239static void
4240s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
4241{
4242 demand_empty_rest_of_line ();
921e5f0a 4243 if (!unwind.proc_start)
c921be7d 4244 as_bad (MISSING_FNSTART);
921e5f0a 4245
c19d1205
ZW
4246 if (unwind.personality_routine || unwind.personality_index != -1)
4247 as_bad (_("personality routine specified for cantunwind frame"));
b99bd4ef 4248
c19d1205
ZW
4249 unwind.personality_index = -2;
4250}
b99bd4ef 4251
b99bd4ef 4252
c19d1205 4253/* Parse a personalityindex directive. */
b99bd4ef 4254
c19d1205
ZW
4255static void
4256s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
4257{
4258 expressionS exp;
b99bd4ef 4259
921e5f0a 4260 if (!unwind.proc_start)
c921be7d 4261 as_bad (MISSING_FNSTART);
921e5f0a 4262
c19d1205
ZW
4263 if (unwind.personality_routine || unwind.personality_index != -1)
4264 as_bad (_("duplicate .personalityindex directive"));
b99bd4ef 4265
c19d1205 4266 expression (&exp);
b99bd4ef 4267
c19d1205
ZW
4268 if (exp.X_op != O_constant
4269 || exp.X_add_number < 0 || exp.X_add_number > 15)
b99bd4ef 4270 {
c19d1205
ZW
4271 as_bad (_("bad personality routine number"));
4272 ignore_rest_of_line ();
4273 return;
b99bd4ef
NC
4274 }
4275
c19d1205 4276 unwind.personality_index = exp.X_add_number;
b99bd4ef 4277
c19d1205
ZW
4278 demand_empty_rest_of_line ();
4279}
e16bb312 4280
e16bb312 4281
c19d1205 4282/* Parse a personality directive. */
e16bb312 4283
c19d1205
ZW
4284static void
4285s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
4286{
4287 char *name, *p, c;
a737bd4d 4288
921e5f0a 4289 if (!unwind.proc_start)
c921be7d 4290 as_bad (MISSING_FNSTART);
921e5f0a 4291
c19d1205
ZW
4292 if (unwind.personality_routine || unwind.personality_index != -1)
4293 as_bad (_("duplicate .personality directive"));
a737bd4d 4294
d02603dc 4295 c = get_symbol_name (& name);
c19d1205 4296 p = input_line_pointer;
d02603dc
NC
4297 if (c == '"')
4298 ++ input_line_pointer;
c19d1205
ZW
4299 unwind.personality_routine = symbol_find_or_make (name);
4300 *p = c;
4301 demand_empty_rest_of_line ();
4302}
e16bb312 4303
e16bb312 4304
c19d1205 4305/* Parse a directive saving core registers. */
e16bb312 4306
c19d1205
ZW
4307static void
4308s_arm_unwind_save_core (void)
e16bb312 4309{
c19d1205
ZW
4310 valueT op;
4311 long range;
4312 int n;
e16bb312 4313
4b5a202f 4314 range = parse_reg_list (&input_line_pointer, REGLIST_RN);
c19d1205 4315 if (range == FAIL)
e16bb312 4316 {
c19d1205
ZW
4317 as_bad (_("expected register list"));
4318 ignore_rest_of_line ();
4319 return;
4320 }
e16bb312 4321
c19d1205 4322 demand_empty_rest_of_line ();
e16bb312 4323
c19d1205
ZW
4324 /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
4325 into .unwind_save {..., sp...}. We aren't bothered about the value of
4326 ip because it is clobbered by calls. */
4327 if (unwind.sp_restored && unwind.fp_reg == 12
4328 && (range & 0x3000) == 0x1000)
4329 {
4330 unwind.opcode_count--;
4331 unwind.sp_restored = 0;
4332 range = (range | 0x2000) & ~0x1000;
4333 unwind.pending_offset = 0;
4334 }
e16bb312 4335
01ae4198
DJ
4336 /* Pop r4-r15. */
4337 if (range & 0xfff0)
c19d1205 4338 {
01ae4198
DJ
4339 /* See if we can use the short opcodes. These pop a block of up to 8
4340 registers starting with r4, plus maybe r14. */
4341 for (n = 0; n < 8; n++)
4342 {
4343 /* Break at the first non-saved register. */
4344 if ((range & (1 << (n + 4))) == 0)
4345 break;
4346 }
4347 /* See if there are any other bits set. */
4348 if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
4349 {
4350 /* Use the long form. */
4351 op = 0x8000 | ((range >> 4) & 0xfff);
4352 add_unwind_opcode (op, 2);
4353 }
0dd132b6 4354 else
01ae4198
DJ
4355 {
4356 /* Use the short form. */
4357 if (range & 0x4000)
4358 op = 0xa8; /* Pop r14. */
4359 else
4360 op = 0xa0; /* Do not pop r14. */
4361 op |= (n - 1);
4362 add_unwind_opcode (op, 1);
4363 }
c19d1205 4364 }
0dd132b6 4365
c19d1205
ZW
4366 /* Pop r0-r3. */
4367 if (range & 0xf)
4368 {
4369 op = 0xb100 | (range & 0xf);
4370 add_unwind_opcode (op, 2);
0dd132b6
NC
4371 }
4372
c19d1205
ZW
4373 /* Record the number of bytes pushed. */
4374 for (n = 0; n < 16; n++)
4375 {
4376 if (range & (1 << n))
4377 unwind.frame_size += 4;
4378 }
0dd132b6
NC
4379}
4380
c19d1205
ZW
4381
4382/* Parse a directive saving FPA registers. */
b99bd4ef
NC
4383
4384static void
c19d1205 4385s_arm_unwind_save_fpa (int reg)
b99bd4ef 4386{
c19d1205
ZW
4387 expressionS exp;
4388 int num_regs;
4389 valueT op;
b99bd4ef 4390
c19d1205
ZW
4391 /* Get Number of registers to transfer. */
4392 if (skip_past_comma (&input_line_pointer) != FAIL)
4393 expression (&exp);
4394 else
4395 exp.X_op = O_illegal;
b99bd4ef 4396
c19d1205 4397 if (exp.X_op != O_constant)
b99bd4ef 4398 {
c19d1205
ZW
4399 as_bad (_("expected , <constant>"));
4400 ignore_rest_of_line ();
b99bd4ef
NC
4401 return;
4402 }
4403
c19d1205
ZW
4404 num_regs = exp.X_add_number;
4405
4406 if (num_regs < 1 || num_regs > 4)
b99bd4ef 4407 {
c19d1205
ZW
4408 as_bad (_("number of registers must be in the range [1:4]"));
4409 ignore_rest_of_line ();
b99bd4ef
NC
4410 return;
4411 }
4412
c19d1205 4413 demand_empty_rest_of_line ();
b99bd4ef 4414
c19d1205
ZW
4415 if (reg == 4)
4416 {
4417 /* Short form. */
4418 op = 0xb4 | (num_regs - 1);
4419 add_unwind_opcode (op, 1);
4420 }
b99bd4ef
NC
4421 else
4422 {
c19d1205
ZW
4423 /* Long form. */
4424 op = 0xc800 | (reg << 4) | (num_regs - 1);
4425 add_unwind_opcode (op, 2);
b99bd4ef 4426 }
c19d1205 4427 unwind.frame_size += num_regs * 12;
b99bd4ef
NC
4428}
4429
c19d1205 4430
fa073d69
MS
4431/* Parse a directive saving VFP registers for ARMv6 and above. */
4432
4433static void
4434s_arm_unwind_save_vfp_armv6 (void)
4435{
4436 int count;
4437 unsigned int start;
4438 valueT op;
4439 int num_vfpv3_regs = 0;
4440 int num_regs_below_16;
efd6b359 4441 bfd_boolean partial_match;
fa073d69 4442
efd6b359
AV
4443 count = parse_vfp_reg_list (&input_line_pointer, &start, REGLIST_VFP_D,
4444 &partial_match);
fa073d69
MS
4445 if (count == FAIL)
4446 {
4447 as_bad (_("expected register list"));
4448 ignore_rest_of_line ();
4449 return;
4450 }
4451
4452 demand_empty_rest_of_line ();
4453
4454 /* We always generate FSTMD/FLDMD-style unwinding opcodes (rather
4455 than FSTMX/FLDMX-style ones). */
4456
4457 /* Generate opcode for (VFPv3) registers numbered in the range 16 .. 31. */
4458 if (start >= 16)
4459 num_vfpv3_regs = count;
4460 else if (start + count > 16)
4461 num_vfpv3_regs = start + count - 16;
4462
4463 if (num_vfpv3_regs > 0)
4464 {
4465 int start_offset = start > 16 ? start - 16 : 0;
4466 op = 0xc800 | (start_offset << 4) | (num_vfpv3_regs - 1);
4467 add_unwind_opcode (op, 2);
4468 }
4469
4470 /* Generate opcode for registers numbered in the range 0 .. 15. */
4471 num_regs_below_16 = num_vfpv3_regs > 0 ? 16 - (int) start : count;
9c2799c2 4472 gas_assert (num_regs_below_16 + num_vfpv3_regs == count);
fa073d69
MS
4473 if (num_regs_below_16 > 0)
4474 {
4475 op = 0xc900 | (start << 4) | (num_regs_below_16 - 1);
4476 add_unwind_opcode (op, 2);
4477 }
4478
4479 unwind.frame_size += count * 8;
4480}
4481
4482
4483/* Parse a directive saving VFP registers for pre-ARMv6. */
b99bd4ef
NC
4484
4485static void
c19d1205 4486s_arm_unwind_save_vfp (void)
b99bd4ef 4487{
c19d1205 4488 int count;
ca3f61f7 4489 unsigned int reg;
c19d1205 4490 valueT op;
efd6b359 4491 bfd_boolean partial_match;
b99bd4ef 4492
efd6b359
AV
4493 count = parse_vfp_reg_list (&input_line_pointer, &reg, REGLIST_VFP_D,
4494 &partial_match);
c19d1205 4495 if (count == FAIL)
b99bd4ef 4496 {
c19d1205
ZW
4497 as_bad (_("expected register list"));
4498 ignore_rest_of_line ();
b99bd4ef
NC
4499 return;
4500 }
4501
c19d1205 4502 demand_empty_rest_of_line ();
b99bd4ef 4503
c19d1205 4504 if (reg == 8)
b99bd4ef 4505 {
c19d1205
ZW
4506 /* Short form. */
4507 op = 0xb8 | (count - 1);
4508 add_unwind_opcode (op, 1);
b99bd4ef 4509 }
c19d1205 4510 else
b99bd4ef 4511 {
c19d1205
ZW
4512 /* Long form. */
4513 op = 0xb300 | (reg << 4) | (count - 1);
4514 add_unwind_opcode (op, 2);
b99bd4ef 4515 }
c19d1205
ZW
4516 unwind.frame_size += count * 8 + 4;
4517}
b99bd4ef 4518
b99bd4ef 4519
c19d1205
ZW
4520/* Parse a directive saving iWMMXt data registers. */
4521
4522static void
4523s_arm_unwind_save_mmxwr (void)
4524{
4525 int reg;
4526 int hi_reg;
4527 int i;
4528 unsigned mask = 0;
4529 valueT op;
b99bd4ef 4530
c19d1205
ZW
4531 if (*input_line_pointer == '{')
4532 input_line_pointer++;
b99bd4ef 4533
c19d1205 4534 do
b99bd4ef 4535 {
dcbf9037 4536 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
b99bd4ef 4537
c19d1205 4538 if (reg == FAIL)
b99bd4ef 4539 {
9b7132d3 4540 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205 4541 goto error;
b99bd4ef
NC
4542 }
4543
c19d1205
ZW
4544 if (mask >> reg)
4545 as_tsktsk (_("register list not in ascending order"));
4546 mask |= 1 << reg;
b99bd4ef 4547
c19d1205
ZW
4548 if (*input_line_pointer == '-')
4549 {
4550 input_line_pointer++;
dcbf9037 4551 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
c19d1205
ZW
4552 if (hi_reg == FAIL)
4553 {
9b7132d3 4554 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205
ZW
4555 goto error;
4556 }
4557 else if (reg >= hi_reg)
4558 {
4559 as_bad (_("bad register range"));
4560 goto error;
4561 }
4562 for (; reg < hi_reg; reg++)
4563 mask |= 1 << reg;
4564 }
4565 }
4566 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4567
d996d970 4568 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4569
c19d1205 4570 demand_empty_rest_of_line ();
b99bd4ef 4571
708587a4 4572 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4573 the list. */
4574 flush_pending_unwind ();
b99bd4ef 4575
c19d1205 4576 for (i = 0; i < 16; i++)
b99bd4ef 4577 {
c19d1205
ZW
4578 if (mask & (1 << i))
4579 unwind.frame_size += 8;
b99bd4ef
NC
4580 }
4581
c19d1205
ZW
4582 /* Attempt to combine with a previous opcode. We do this because gcc
4583 likes to output separate unwind directives for a single block of
4584 registers. */
4585 if (unwind.opcode_count > 0)
b99bd4ef 4586 {
c19d1205
ZW
4587 i = unwind.opcodes[unwind.opcode_count - 1];
4588 if ((i & 0xf8) == 0xc0)
4589 {
4590 i &= 7;
4591 /* Only merge if the blocks are contiguous. */
4592 if (i < 6)
4593 {
4594 if ((mask & 0xfe00) == (1 << 9))
4595 {
4596 mask |= ((1 << (i + 11)) - 1) & 0xfc00;
4597 unwind.opcode_count--;
4598 }
4599 }
4600 else if (i == 6 && unwind.opcode_count >= 2)
4601 {
4602 i = unwind.opcodes[unwind.opcode_count - 2];
4603 reg = i >> 4;
4604 i &= 0xf;
b99bd4ef 4605
c19d1205
ZW
4606 op = 0xffff << (reg - 1);
4607 if (reg > 0
87a1fd79 4608 && ((mask & op) == (1u << (reg - 1))))
c19d1205
ZW
4609 {
4610 op = (1 << (reg + i + 1)) - 1;
4611 op &= ~((1 << reg) - 1);
4612 mask |= op;
4613 unwind.opcode_count -= 2;
4614 }
4615 }
4616 }
b99bd4ef
NC
4617 }
4618
c19d1205
ZW
4619 hi_reg = 15;
4620 /* We want to generate opcodes in the order the registers have been
4621 saved, ie. descending order. */
4622 for (reg = 15; reg >= -1; reg--)
b99bd4ef 4623 {
c19d1205
ZW
4624 /* Save registers in blocks. */
4625 if (reg < 0
4626 || !(mask & (1 << reg)))
4627 {
4628 /* We found an unsaved reg. Generate opcodes to save the
5f4273c7 4629 preceding block. */
c19d1205
ZW
4630 if (reg != hi_reg)
4631 {
4632 if (reg == 9)
4633 {
4634 /* Short form. */
4635 op = 0xc0 | (hi_reg - 10);
4636 add_unwind_opcode (op, 1);
4637 }
4638 else
4639 {
4640 /* Long form. */
4641 op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
4642 add_unwind_opcode (op, 2);
4643 }
4644 }
4645 hi_reg = reg - 1;
4646 }
b99bd4ef
NC
4647 }
4648
c19d1205 4649 return;
dc1e8a47 4650 error:
c19d1205 4651 ignore_rest_of_line ();
b99bd4ef
NC
4652}
4653
4654static void
c19d1205 4655s_arm_unwind_save_mmxwcg (void)
b99bd4ef 4656{
c19d1205
ZW
4657 int reg;
4658 int hi_reg;
4659 unsigned mask = 0;
4660 valueT op;
b99bd4ef 4661
c19d1205
ZW
4662 if (*input_line_pointer == '{')
4663 input_line_pointer++;
b99bd4ef 4664
477330fc
RM
4665 skip_whitespace (input_line_pointer);
4666
c19d1205 4667 do
b99bd4ef 4668 {
dcbf9037 4669 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
b99bd4ef 4670
c19d1205
ZW
4671 if (reg == FAIL)
4672 {
9b7132d3 4673 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4674 goto error;
4675 }
b99bd4ef 4676
c19d1205
ZW
4677 reg -= 8;
4678 if (mask >> reg)
4679 as_tsktsk (_("register list not in ascending order"));
4680 mask |= 1 << reg;
b99bd4ef 4681
c19d1205
ZW
4682 if (*input_line_pointer == '-')
4683 {
4684 input_line_pointer++;
dcbf9037 4685 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
c19d1205
ZW
4686 if (hi_reg == FAIL)
4687 {
9b7132d3 4688 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4689 goto error;
4690 }
4691 else if (reg >= hi_reg)
4692 {
4693 as_bad (_("bad register range"));
4694 goto error;
4695 }
4696 for (; reg < hi_reg; reg++)
4697 mask |= 1 << reg;
4698 }
b99bd4ef 4699 }
c19d1205 4700 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4701
d996d970 4702 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4703
c19d1205
ZW
4704 demand_empty_rest_of_line ();
4705
708587a4 4706 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4707 the list. */
4708 flush_pending_unwind ();
b99bd4ef 4709
c19d1205 4710 for (reg = 0; reg < 16; reg++)
b99bd4ef 4711 {
c19d1205
ZW
4712 if (mask & (1 << reg))
4713 unwind.frame_size += 4;
b99bd4ef 4714 }
c19d1205
ZW
4715 op = 0xc700 | mask;
4716 add_unwind_opcode (op, 2);
4717 return;
dc1e8a47 4718 error:
c19d1205 4719 ignore_rest_of_line ();
b99bd4ef
NC
4720}
4721
c19d1205 4722
fa073d69
MS
4723/* Parse an unwind_save directive.
4724 If the argument is non-zero, this is a .vsave directive. */
c19d1205 4725
b99bd4ef 4726static void
fa073d69 4727s_arm_unwind_save (int arch_v6)
b99bd4ef 4728{
c19d1205
ZW
4729 char *peek;
4730 struct reg_entry *reg;
4731 bfd_boolean had_brace = FALSE;
b99bd4ef 4732
921e5f0a 4733 if (!unwind.proc_start)
c921be7d 4734 as_bad (MISSING_FNSTART);
921e5f0a 4735
c19d1205
ZW
4736 /* Figure out what sort of save we have. */
4737 peek = input_line_pointer;
b99bd4ef 4738
c19d1205 4739 if (*peek == '{')
b99bd4ef 4740 {
c19d1205
ZW
4741 had_brace = TRUE;
4742 peek++;
b99bd4ef
NC
4743 }
4744
c19d1205 4745 reg = arm_reg_parse_multi (&peek);
b99bd4ef 4746
c19d1205 4747 if (!reg)
b99bd4ef 4748 {
c19d1205
ZW
4749 as_bad (_("register expected"));
4750 ignore_rest_of_line ();
b99bd4ef
NC
4751 return;
4752 }
4753
c19d1205 4754 switch (reg->type)
b99bd4ef 4755 {
c19d1205
ZW
4756 case REG_TYPE_FN:
4757 if (had_brace)
4758 {
4759 as_bad (_("FPA .unwind_save does not take a register list"));
4760 ignore_rest_of_line ();
4761 return;
4762 }
93ac2687 4763 input_line_pointer = peek;
c19d1205 4764 s_arm_unwind_save_fpa (reg->number);
b99bd4ef 4765 return;
c19d1205 4766
1f5afe1c
NC
4767 case REG_TYPE_RN:
4768 s_arm_unwind_save_core ();
4769 return;
4770
fa073d69
MS
4771 case REG_TYPE_VFD:
4772 if (arch_v6)
477330fc 4773 s_arm_unwind_save_vfp_armv6 ();
fa073d69 4774 else
477330fc 4775 s_arm_unwind_save_vfp ();
fa073d69 4776 return;
1f5afe1c
NC
4777
4778 case REG_TYPE_MMXWR:
4779 s_arm_unwind_save_mmxwr ();
4780 return;
4781
4782 case REG_TYPE_MMXWCG:
4783 s_arm_unwind_save_mmxwcg ();
4784 return;
c19d1205
ZW
4785
4786 default:
4787 as_bad (_(".unwind_save does not support this kind of register"));
4788 ignore_rest_of_line ();
b99bd4ef 4789 }
c19d1205 4790}
b99bd4ef 4791
b99bd4ef 4792
c19d1205
ZW
4793/* Parse an unwind_movsp directive. */
4794
4795static void
4796s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
4797{
4798 int reg;
4799 valueT op;
4fa3602b 4800 int offset;
c19d1205 4801
921e5f0a 4802 if (!unwind.proc_start)
c921be7d 4803 as_bad (MISSING_FNSTART);
921e5f0a 4804
dcbf9037 4805 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205 4806 if (reg == FAIL)
b99bd4ef 4807 {
9b7132d3 4808 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_RN]));
c19d1205 4809 ignore_rest_of_line ();
b99bd4ef
NC
4810 return;
4811 }
4fa3602b
PB
4812
4813 /* Optional constant. */
4814 if (skip_past_comma (&input_line_pointer) != FAIL)
4815 {
4816 if (immediate_for_directive (&offset) == FAIL)
4817 return;
4818 }
4819 else
4820 offset = 0;
4821
c19d1205 4822 demand_empty_rest_of_line ();
b99bd4ef 4823
c19d1205 4824 if (reg == REG_SP || reg == REG_PC)
b99bd4ef 4825 {
c19d1205 4826 as_bad (_("SP and PC not permitted in .unwind_movsp directive"));
b99bd4ef
NC
4827 return;
4828 }
4829
c19d1205
ZW
4830 if (unwind.fp_reg != REG_SP)
4831 as_bad (_("unexpected .unwind_movsp directive"));
b99bd4ef 4832
c19d1205
ZW
4833 /* Generate opcode to restore the value. */
4834 op = 0x90 | reg;
4835 add_unwind_opcode (op, 1);
4836
4837 /* Record the information for later. */
4838 unwind.fp_reg = reg;
4fa3602b 4839 unwind.fp_offset = unwind.frame_size - offset;
c19d1205 4840 unwind.sp_restored = 1;
b05fe5cf
ZW
4841}
4842
c19d1205
ZW
4843/* Parse an unwind_pad directive. */
4844
b05fe5cf 4845static void
c19d1205 4846s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
b05fe5cf 4847{
c19d1205 4848 int offset;
b05fe5cf 4849
921e5f0a 4850 if (!unwind.proc_start)
c921be7d 4851 as_bad (MISSING_FNSTART);
921e5f0a 4852
c19d1205
ZW
4853 if (immediate_for_directive (&offset) == FAIL)
4854 return;
b99bd4ef 4855
c19d1205
ZW
4856 if (offset & 3)
4857 {
4858 as_bad (_("stack increment must be multiple of 4"));
4859 ignore_rest_of_line ();
4860 return;
4861 }
b99bd4ef 4862
c19d1205
ZW
4863 /* Don't generate any opcodes, just record the details for later. */
4864 unwind.frame_size += offset;
4865 unwind.pending_offset += offset;
4866
4867 demand_empty_rest_of_line ();
4868}
4869
4870/* Parse an unwind_setfp directive. */
4871
4872static void
4873s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 4874{
c19d1205
ZW
4875 int sp_reg;
4876 int fp_reg;
4877 int offset;
4878
921e5f0a 4879 if (!unwind.proc_start)
c921be7d 4880 as_bad (MISSING_FNSTART);
921e5f0a 4881
dcbf9037 4882 fp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205
ZW
4883 if (skip_past_comma (&input_line_pointer) == FAIL)
4884 sp_reg = FAIL;
4885 else
dcbf9037 4886 sp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
b99bd4ef 4887
c19d1205
ZW
4888 if (fp_reg == FAIL || sp_reg == FAIL)
4889 {
4890 as_bad (_("expected <reg>, <reg>"));
4891 ignore_rest_of_line ();
4892 return;
4893 }
b99bd4ef 4894
c19d1205
ZW
4895 /* Optional constant. */
4896 if (skip_past_comma (&input_line_pointer) != FAIL)
4897 {
4898 if (immediate_for_directive (&offset) == FAIL)
4899 return;
4900 }
4901 else
4902 offset = 0;
a737bd4d 4903
c19d1205 4904 demand_empty_rest_of_line ();
a737bd4d 4905
fdfde340 4906 if (sp_reg != REG_SP && sp_reg != unwind.fp_reg)
a737bd4d 4907 {
c19d1205
ZW
4908 as_bad (_("register must be either sp or set by a previous"
4909 "unwind_movsp directive"));
4910 return;
a737bd4d
NC
4911 }
4912
c19d1205
ZW
4913 /* Don't generate any opcodes, just record the information for later. */
4914 unwind.fp_reg = fp_reg;
4915 unwind.fp_used = 1;
fdfde340 4916 if (sp_reg == REG_SP)
c19d1205
ZW
4917 unwind.fp_offset = unwind.frame_size - offset;
4918 else
4919 unwind.fp_offset -= offset;
a737bd4d
NC
4920}
4921
c19d1205
ZW
4922/* Parse an unwind_raw directive. */
4923
4924static void
4925s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
a737bd4d 4926{
c19d1205 4927 expressionS exp;
708587a4 4928 /* This is an arbitrary limit. */
c19d1205
ZW
4929 unsigned char op[16];
4930 int count;
a737bd4d 4931
921e5f0a 4932 if (!unwind.proc_start)
c921be7d 4933 as_bad (MISSING_FNSTART);
921e5f0a 4934
c19d1205
ZW
4935 expression (&exp);
4936 if (exp.X_op == O_constant
4937 && skip_past_comma (&input_line_pointer) != FAIL)
a737bd4d 4938 {
c19d1205
ZW
4939 unwind.frame_size += exp.X_add_number;
4940 expression (&exp);
4941 }
4942 else
4943 exp.X_op = O_illegal;
a737bd4d 4944
c19d1205
ZW
4945 if (exp.X_op != O_constant)
4946 {
4947 as_bad (_("expected <offset>, <opcode>"));
4948 ignore_rest_of_line ();
4949 return;
4950 }
a737bd4d 4951
c19d1205 4952 count = 0;
a737bd4d 4953
c19d1205
ZW
4954 /* Parse the opcode. */
4955 for (;;)
4956 {
4957 if (count >= 16)
4958 {
4959 as_bad (_("unwind opcode too long"));
4960 ignore_rest_of_line ();
a737bd4d 4961 }
c19d1205 4962 if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
a737bd4d 4963 {
c19d1205
ZW
4964 as_bad (_("invalid unwind opcode"));
4965 ignore_rest_of_line ();
4966 return;
a737bd4d 4967 }
c19d1205 4968 op[count++] = exp.X_add_number;
a737bd4d 4969
c19d1205
ZW
4970 /* Parse the next byte. */
4971 if (skip_past_comma (&input_line_pointer) == FAIL)
4972 break;
a737bd4d 4973
c19d1205
ZW
4974 expression (&exp);
4975 }
b99bd4ef 4976
c19d1205
ZW
4977 /* Add the opcode bytes in reverse order. */
4978 while (count--)
4979 add_unwind_opcode (op[count], 1);
b99bd4ef 4980
c19d1205 4981 demand_empty_rest_of_line ();
b99bd4ef 4982}
ee065d83
PB
4983
4984
4985/* Parse a .eabi_attribute directive. */
4986
4987static void
4988s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
4989{
0420f52b 4990 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
ee3c0378 4991
3076e594 4992 if (tag >= 0 && tag < NUM_KNOWN_OBJ_ATTRIBUTES)
ee3c0378 4993 attributes_set_explicitly[tag] = 1;
ee065d83
PB
4994}
4995
0855e32b
NS
4996/* Emit a tls fix for the symbol. */
4997
4998static void
4999s_arm_tls_descseq (int ignored ATTRIBUTE_UNUSED)
5000{
5001 char *p;
5002 expressionS exp;
5003#ifdef md_flush_pending_output
5004 md_flush_pending_output ();
5005#endif
5006
5007#ifdef md_cons_align
5008 md_cons_align (4);
5009#endif
5010
5011 /* Since we're just labelling the code, there's no need to define a
5012 mapping symbol. */
5013 expression (&exp);
5014 p = obstack_next_free (&frchain_now->frch_obstack);
5015 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
5016 thumb_mode ? BFD_RELOC_ARM_THM_TLS_DESCSEQ
5017 : BFD_RELOC_ARM_TLS_DESCSEQ);
5018}
cdf9ccec 5019#endif /* OBJ_ELF */
0855e32b 5020
ee065d83 5021static void s_arm_arch (int);
7a1d4c38 5022static void s_arm_object_arch (int);
ee065d83
PB
5023static void s_arm_cpu (int);
5024static void s_arm_fpu (int);
69133863 5025static void s_arm_arch_extension (int);
b99bd4ef 5026
f0927246
NC
5027#ifdef TE_PE
5028
5029static void
5f4273c7 5030pe_directive_secrel (int dummy ATTRIBUTE_UNUSED)
f0927246
NC
5031{
5032 expressionS exp;
5033
5034 do
5035 {
5036 expression (&exp);
5037 if (exp.X_op == O_symbol)
5038 exp.X_op = O_secrel;
5039
5040 emit_expr (&exp, 4);
5041 }
5042 while (*input_line_pointer++ == ',');
5043
5044 input_line_pointer--;
5045 demand_empty_rest_of_line ();
5046}
5047#endif /* TE_PE */
5048
5312fe52
BW
5049int
5050arm_is_largest_exponent_ok (int precision)
5051{
5052 /* precision == 1 ensures that this will only return
5053 true for 16 bit floats. */
5054 return (precision == 1) && (fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
5055}
5056
5057static void
5058set_fp16_format (int dummy ATTRIBUTE_UNUSED)
5059{
5060 char saved_char;
5061 char* name;
5062 enum fp_16bit_format new_format;
5063
5064 new_format = ARM_FP16_FORMAT_DEFAULT;
5065
5066 name = input_line_pointer;
5067 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
5068 input_line_pointer++;
5069
5070 saved_char = *input_line_pointer;
5071 *input_line_pointer = 0;
5072
5073 if (strcasecmp (name, "ieee") == 0)
5074 new_format = ARM_FP16_FORMAT_IEEE;
5075 else if (strcasecmp (name, "alternative") == 0)
5076 new_format = ARM_FP16_FORMAT_ALTERNATIVE;
5077 else
5078 {
5079 as_bad (_("unrecognised float16 format \"%s\""), name);
5080 goto cleanup;
5081 }
5082
5083 /* Only set fp16_format if it is still the default (aka not already
5084 been set yet). */
5085 if (fp16_format == ARM_FP16_FORMAT_DEFAULT)
5086 fp16_format = new_format;
5087 else
5088 {
5089 if (new_format != fp16_format)
5090 as_warn (_("float16 format cannot be set more than once, ignoring."));
5091 }
5092
dc1e8a47 5093 cleanup:
5312fe52
BW
5094 *input_line_pointer = saved_char;
5095 ignore_rest_of_line ();
5096}
5097
c19d1205
ZW
5098/* This table describes all the machine specific pseudo-ops the assembler
5099 has to support. The fields are:
5100 pseudo-op name without dot
5101 function to call to execute this pseudo-op
5102 Integer arg to pass to the function. */
b99bd4ef 5103
c19d1205 5104const pseudo_typeS md_pseudo_table[] =
b99bd4ef 5105{
c19d1205
ZW
5106 /* Never called because '.req' does not start a line. */
5107 { "req", s_req, 0 },
dcbf9037
JB
5108 /* Following two are likewise never called. */
5109 { "dn", s_dn, 0 },
5110 { "qn", s_qn, 0 },
c19d1205
ZW
5111 { "unreq", s_unreq, 0 },
5112 { "bss", s_bss, 0 },
db2ed2e0 5113 { "align", s_align_ptwo, 2 },
c19d1205
ZW
5114 { "arm", s_arm, 0 },
5115 { "thumb", s_thumb, 0 },
5116 { "code", s_code, 0 },
5117 { "force_thumb", s_force_thumb, 0 },
5118 { "thumb_func", s_thumb_func, 0 },
5119 { "thumb_set", s_thumb_set, 0 },
5120 { "even", s_even, 0 },
5121 { "ltorg", s_ltorg, 0 },
5122 { "pool", s_ltorg, 0 },
5123 { "syntax", s_syntax, 0 },
8463be01
PB
5124 { "cpu", s_arm_cpu, 0 },
5125 { "arch", s_arm_arch, 0 },
7a1d4c38 5126 { "object_arch", s_arm_object_arch, 0 },
8463be01 5127 { "fpu", s_arm_fpu, 0 },
69133863 5128 { "arch_extension", s_arm_arch_extension, 0 },
c19d1205 5129#ifdef OBJ_ELF
c921be7d
NC
5130 { "word", s_arm_elf_cons, 4 },
5131 { "long", s_arm_elf_cons, 4 },
5132 { "inst.n", s_arm_elf_inst, 2 },
5133 { "inst.w", s_arm_elf_inst, 4 },
5134 { "inst", s_arm_elf_inst, 0 },
5135 { "rel31", s_arm_rel31, 0 },
c19d1205
ZW
5136 { "fnstart", s_arm_unwind_fnstart, 0 },
5137 { "fnend", s_arm_unwind_fnend, 0 },
5138 { "cantunwind", s_arm_unwind_cantunwind, 0 },
5139 { "personality", s_arm_unwind_personality, 0 },
5140 { "personalityindex", s_arm_unwind_personalityindex, 0 },
5141 { "handlerdata", s_arm_unwind_handlerdata, 0 },
5142 { "save", s_arm_unwind_save, 0 },
fa073d69 5143 { "vsave", s_arm_unwind_save, 1 },
c19d1205
ZW
5144 { "movsp", s_arm_unwind_movsp, 0 },
5145 { "pad", s_arm_unwind_pad, 0 },
5146 { "setfp", s_arm_unwind_setfp, 0 },
5147 { "unwind_raw", s_arm_unwind_raw, 0 },
ee065d83 5148 { "eabi_attribute", s_arm_eabi_attribute, 0 },
0855e32b 5149 { "tlsdescseq", s_arm_tls_descseq, 0 },
c19d1205
ZW
5150#else
5151 { "word", cons, 4},
f0927246
NC
5152
5153 /* These are used for dwarf. */
5154 {"2byte", cons, 2},
5155 {"4byte", cons, 4},
5156 {"8byte", cons, 8},
5157 /* These are used for dwarf2. */
68d20676 5158 { "file", dwarf2_directive_file, 0 },
f0927246
NC
5159 { "loc", dwarf2_directive_loc, 0 },
5160 { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
c19d1205
ZW
5161#endif
5162 { "extend", float_cons, 'x' },
5163 { "ldouble", float_cons, 'x' },
5164 { "packed", float_cons, 'p' },
27cce866 5165 { "bfloat16", float_cons, 'b' },
f0927246
NC
5166#ifdef TE_PE
5167 {"secrel32", pe_directive_secrel, 0},
5168#endif
2e6976a8
DG
5169
5170 /* These are for compatibility with CodeComposer Studio. */
5171 {"ref", s_ccs_ref, 0},
5172 {"def", s_ccs_def, 0},
5173 {"asmfunc", s_ccs_asmfunc, 0},
5174 {"endasmfunc", s_ccs_endasmfunc, 0},
5175
5312fe52
BW
5176 {"float16", float_cons, 'h' },
5177 {"float16_format", set_fp16_format, 0 },
5178
c19d1205
ZW
5179 { 0, 0, 0 }
5180};
5312fe52 5181
c19d1205 5182/* Parser functions used exclusively in instruction operands. */
b99bd4ef 5183
c19d1205
ZW
5184/* Generic immediate-value read function for use in insn parsing.
5185 STR points to the beginning of the immediate (the leading #);
5186 VAL receives the value; if the value is outside [MIN, MAX]
5187 issue an error. PREFIX_OPT is true if the immediate prefix is
5188 optional. */
b99bd4ef 5189
c19d1205
ZW
5190static int
5191parse_immediate (char **str, int *val, int min, int max,
5192 bfd_boolean prefix_opt)
5193{
5194 expressionS exp;
0198d5e6 5195
c19d1205
ZW
5196 my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
5197 if (exp.X_op != O_constant)
b99bd4ef 5198 {
c19d1205
ZW
5199 inst.error = _("constant expression required");
5200 return FAIL;
5201 }
b99bd4ef 5202
c19d1205
ZW
5203 if (exp.X_add_number < min || exp.X_add_number > max)
5204 {
5205 inst.error = _("immediate value out of range");
5206 return FAIL;
5207 }
b99bd4ef 5208
c19d1205
ZW
5209 *val = exp.X_add_number;
5210 return SUCCESS;
5211}
b99bd4ef 5212
5287ad62 5213/* Less-generic immediate-value read function with the possibility of loading a
036dc3f7 5214 big (64-bit) immediate, as required by Neon VMOV, VMVN and logic immediate
5287ad62
JB
5215 instructions. Puts the result directly in inst.operands[i]. */
5216
5217static int
8335d6aa
JW
5218parse_big_immediate (char **str, int i, expressionS *in_exp,
5219 bfd_boolean allow_symbol_p)
5287ad62
JB
5220{
5221 expressionS exp;
8335d6aa 5222 expressionS *exp_p = in_exp ? in_exp : &exp;
5287ad62
JB
5223 char *ptr = *str;
5224
8335d6aa 5225 my_get_expression (exp_p, &ptr, GE_OPT_PREFIX_BIG);
5287ad62 5226
8335d6aa 5227 if (exp_p->X_op == O_constant)
036dc3f7 5228 {
8335d6aa 5229 inst.operands[i].imm = exp_p->X_add_number & 0xffffffff;
036dc3f7
PB
5230 /* If we're on a 64-bit host, then a 64-bit number can be returned using
5231 O_constant. We have to be careful not to break compilation for
5232 32-bit X_add_number, though. */
8335d6aa 5233 if ((exp_p->X_add_number & ~(offsetT)(0xffffffffU)) != 0)
036dc3f7 5234 {
8335d6aa
JW
5235 /* X >> 32 is illegal if sizeof (exp_p->X_add_number) == 4. */
5236 inst.operands[i].reg = (((exp_p->X_add_number >> 16) >> 16)
5237 & 0xffffffff);
036dc3f7
PB
5238 inst.operands[i].regisimm = 1;
5239 }
5240 }
8335d6aa
JW
5241 else if (exp_p->X_op == O_big
5242 && LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 32)
5287ad62
JB
5243 {
5244 unsigned parts = 32 / LITTLENUM_NUMBER_OF_BITS, j, idx = 0;
95b75c01 5245
5287ad62 5246 /* Bignums have their least significant bits in
477330fc
RM
5247 generic_bignum[0]. Make sure we put 32 bits in imm and
5248 32 bits in reg, in a (hopefully) portable way. */
9c2799c2 5249 gas_assert (parts != 0);
95b75c01
NC
5250
5251 /* Make sure that the number is not too big.
5252 PR 11972: Bignums can now be sign-extended to the
5253 size of a .octa so check that the out of range bits
5254 are all zero or all one. */
8335d6aa 5255 if (LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 64)
95b75c01
NC
5256 {
5257 LITTLENUM_TYPE m = -1;
5258
5259 if (generic_bignum[parts * 2] != 0
5260 && generic_bignum[parts * 2] != m)
5261 return FAIL;
5262
8335d6aa 5263 for (j = parts * 2 + 1; j < (unsigned) exp_p->X_add_number; j++)
95b75c01
NC
5264 if (generic_bignum[j] != generic_bignum[j-1])
5265 return FAIL;
5266 }
5267
5287ad62
JB
5268 inst.operands[i].imm = 0;
5269 for (j = 0; j < parts; j++, idx++)
477330fc
RM
5270 inst.operands[i].imm |= generic_bignum[idx]
5271 << (LITTLENUM_NUMBER_OF_BITS * j);
5287ad62
JB
5272 inst.operands[i].reg = 0;
5273 for (j = 0; j < parts; j++, idx++)
477330fc
RM
5274 inst.operands[i].reg |= generic_bignum[idx]
5275 << (LITTLENUM_NUMBER_OF_BITS * j);
5287ad62
JB
5276 inst.operands[i].regisimm = 1;
5277 }
8335d6aa 5278 else if (!(exp_p->X_op == O_symbol && allow_symbol_p))
5287ad62 5279 return FAIL;
5f4273c7 5280
5287ad62
JB
5281 *str = ptr;
5282
5283 return SUCCESS;
5284}
5285
c19d1205
ZW
5286/* Returns the pseudo-register number of an FPA immediate constant,
5287 or FAIL if there isn't a valid constant here. */
b99bd4ef 5288
c19d1205
ZW
5289static int
5290parse_fpa_immediate (char ** str)
5291{
5292 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5293 char * save_in;
5294 expressionS exp;
5295 int i;
5296 int j;
b99bd4ef 5297
c19d1205
ZW
5298 /* First try and match exact strings, this is to guarantee
5299 that some formats will work even for cross assembly. */
b99bd4ef 5300
c19d1205
ZW
5301 for (i = 0; fp_const[i]; i++)
5302 {
5303 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
b99bd4ef 5304 {
c19d1205 5305 char *start = *str;
b99bd4ef 5306
c19d1205
ZW
5307 *str += strlen (fp_const[i]);
5308 if (is_end_of_line[(unsigned char) **str])
5309 return i + 8;
5310 *str = start;
5311 }
5312 }
b99bd4ef 5313
c19d1205
ZW
5314 /* Just because we didn't get a match doesn't mean that the constant
5315 isn't valid, just that it is in a format that we don't
5316 automatically recognize. Try parsing it with the standard
5317 expression routines. */
b99bd4ef 5318
c19d1205 5319 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
b99bd4ef 5320
c19d1205
ZW
5321 /* Look for a raw floating point number. */
5322 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5323 && is_end_of_line[(unsigned char) *save_in])
5324 {
5325 for (i = 0; i < NUM_FLOAT_VALS; i++)
5326 {
5327 for (j = 0; j < MAX_LITTLENUMS; j++)
b99bd4ef 5328 {
c19d1205
ZW
5329 if (words[j] != fp_values[i][j])
5330 break;
b99bd4ef
NC
5331 }
5332
c19d1205 5333 if (j == MAX_LITTLENUMS)
b99bd4ef 5334 {
c19d1205
ZW
5335 *str = save_in;
5336 return i + 8;
b99bd4ef
NC
5337 }
5338 }
5339 }
b99bd4ef 5340
c19d1205
ZW
5341 /* Try and parse a more complex expression, this will probably fail
5342 unless the code uses a floating point prefix (eg "0f"). */
5343 save_in = input_line_pointer;
5344 input_line_pointer = *str;
5345 if (expression (&exp) == absolute_section
5346 && exp.X_op == O_big
5347 && exp.X_add_number < 0)
5348 {
5349 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5350 Ditto for 15. */
ba592044
AM
5351#define X_PRECISION 5
5352#define E_PRECISION 15L
5353 if (gen_to_words (words, X_PRECISION, E_PRECISION) == 0)
c19d1205
ZW
5354 {
5355 for (i = 0; i < NUM_FLOAT_VALS; i++)
5356 {
5357 for (j = 0; j < MAX_LITTLENUMS; j++)
5358 {
5359 if (words[j] != fp_values[i][j])
5360 break;
5361 }
b99bd4ef 5362
c19d1205
ZW
5363 if (j == MAX_LITTLENUMS)
5364 {
5365 *str = input_line_pointer;
5366 input_line_pointer = save_in;
5367 return i + 8;
5368 }
5369 }
5370 }
b99bd4ef
NC
5371 }
5372
c19d1205
ZW
5373 *str = input_line_pointer;
5374 input_line_pointer = save_in;
5375 inst.error = _("invalid FPA immediate expression");
5376 return FAIL;
b99bd4ef
NC
5377}
5378
136da414
JB
5379/* Returns 1 if a number has "quarter-precision" float format
5380 0baBbbbbbc defgh000 00000000 00000000. */
5381
5382static int
5383is_quarter_float (unsigned imm)
5384{
5385 int bs = (imm & 0x20000000) ? 0x3e000000 : 0x40000000;
5386 return (imm & 0x7ffff) == 0 && ((imm & 0x7e000000) ^ bs) == 0;
5387}
5388
aacf0b33
KT
5389
5390/* Detect the presence of a floating point or integer zero constant,
5391 i.e. #0.0 or #0. */
5392
5393static bfd_boolean
5394parse_ifimm_zero (char **in)
5395{
5396 int error_code;
5397
5398 if (!is_immediate_prefix (**in))
3c6452ae
TP
5399 {
5400 /* In unified syntax, all prefixes are optional. */
5401 if (!unified_syntax)
5402 return FALSE;
5403 }
5404 else
5405 ++*in;
0900a05b
JW
5406
5407 /* Accept #0x0 as a synonym for #0. */
5408 if (strncmp (*in, "0x", 2) == 0)
5409 {
5410 int val;
5411 if (parse_immediate (in, &val, 0, 0, TRUE) == FAIL)
5412 return FALSE;
5413 return TRUE;
5414 }
5415
aacf0b33
KT
5416 error_code = atof_generic (in, ".", EXP_CHARS,
5417 &generic_floating_point_number);
5418
5419 if (!error_code
5420 && generic_floating_point_number.sign == '+'
5421 && (generic_floating_point_number.low
5422 > generic_floating_point_number.leader))
5423 return TRUE;
5424
5425 return FALSE;
5426}
5427
136da414
JB
5428/* Parse an 8-bit "quarter-precision" floating point number of the form:
5429 0baBbbbbbc defgh000 00000000 00000000.
c96612cc
JB
5430 The zero and minus-zero cases need special handling, since they can't be
5431 encoded in the "quarter-precision" float format, but can nonetheless be
5432 loaded as integer constants. */
136da414
JB
5433
5434static unsigned
5435parse_qfloat_immediate (char **ccp, int *immed)
5436{
5437 char *str = *ccp;
c96612cc 5438 char *fpnum;
136da414 5439 LITTLENUM_TYPE words[MAX_LITTLENUMS];
c96612cc 5440 int found_fpchar = 0;
5f4273c7 5441
136da414 5442 skip_past_char (&str, '#');
5f4273c7 5443
c96612cc
JB
5444 /* We must not accidentally parse an integer as a floating-point number. Make
5445 sure that the value we parse is not an integer by checking for special
5446 characters '.' or 'e'.
5447 FIXME: This is a horrible hack, but doing better is tricky because type
5448 information isn't in a very usable state at parse time. */
5449 fpnum = str;
5450 skip_whitespace (fpnum);
5451
5452 if (strncmp (fpnum, "0x", 2) == 0)
5453 return FAIL;
5454 else
5455 {
5456 for (; *fpnum != '\0' && *fpnum != ' ' && *fpnum != '\n'; fpnum++)
477330fc
RM
5457 if (*fpnum == '.' || *fpnum == 'e' || *fpnum == 'E')
5458 {
5459 found_fpchar = 1;
5460 break;
5461 }
c96612cc
JB
5462
5463 if (!found_fpchar)
477330fc 5464 return FAIL;
c96612cc 5465 }
5f4273c7 5466
136da414
JB
5467 if ((str = atof_ieee (str, 's', words)) != NULL)
5468 {
5469 unsigned fpword = 0;
5470 int i;
5f4273c7 5471
136da414
JB
5472 /* Our FP word must be 32 bits (single-precision FP). */
5473 for (i = 0; i < 32 / LITTLENUM_NUMBER_OF_BITS; i++)
477330fc
RM
5474 {
5475 fpword <<= LITTLENUM_NUMBER_OF_BITS;
5476 fpword |= words[i];
5477 }
5f4273c7 5478
c96612cc 5479 if (is_quarter_float (fpword) || (fpword & 0x7fffffff) == 0)
477330fc 5480 *immed = fpword;
136da414 5481 else
477330fc 5482 return FAIL;
136da414
JB
5483
5484 *ccp = str;
5f4273c7 5485
136da414
JB
5486 return SUCCESS;
5487 }
5f4273c7 5488
136da414
JB
5489 return FAIL;
5490}
5491
c19d1205
ZW
5492/* Shift operands. */
5493enum shift_kind
b99bd4ef 5494{
f5f10c66 5495 SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX, SHIFT_UXTW
c19d1205 5496};
b99bd4ef 5497
c19d1205
ZW
5498struct asm_shift_name
5499{
5500 const char *name;
5501 enum shift_kind kind;
5502};
b99bd4ef 5503
c19d1205
ZW
5504/* Third argument to parse_shift. */
5505enum parse_shift_mode
5506{
5507 NO_SHIFT_RESTRICT, /* Any kind of shift is accepted. */
5508 SHIFT_IMMEDIATE, /* Shift operand must be an immediate. */
5509 SHIFT_LSL_OR_ASR_IMMEDIATE, /* Shift must be LSL or ASR immediate. */
5510 SHIFT_ASR_IMMEDIATE, /* Shift must be ASR immediate. */
5511 SHIFT_LSL_IMMEDIATE, /* Shift must be LSL immediate. */
f5f10c66 5512 SHIFT_UXTW_IMMEDIATE /* Shift must be UXTW immediate. */
c19d1205 5513};
b99bd4ef 5514
c19d1205
ZW
5515/* Parse a <shift> specifier on an ARM data processing instruction.
5516 This has three forms:
b99bd4ef 5517
c19d1205
ZW
5518 (LSL|LSR|ASL|ASR|ROR) Rs
5519 (LSL|LSR|ASL|ASR|ROR) #imm
5520 RRX
b99bd4ef 5521
c19d1205
ZW
5522 Note that ASL is assimilated to LSL in the instruction encoding, and
5523 RRX to ROR #0 (which cannot be written as such). */
b99bd4ef 5524
c19d1205
ZW
5525static int
5526parse_shift (char **str, int i, enum parse_shift_mode mode)
b99bd4ef 5527{
c19d1205
ZW
5528 const struct asm_shift_name *shift_name;
5529 enum shift_kind shift;
5530 char *s = *str;
5531 char *p = s;
5532 int reg;
b99bd4ef 5533
c19d1205
ZW
5534 for (p = *str; ISALPHA (*p); p++)
5535 ;
b99bd4ef 5536
c19d1205 5537 if (p == *str)
b99bd4ef 5538 {
c19d1205
ZW
5539 inst.error = _("shift expression expected");
5540 return FAIL;
b99bd4ef
NC
5541 }
5542
21d799b5 5543 shift_name = (const struct asm_shift_name *) hash_find_n (arm_shift_hsh, *str,
477330fc 5544 p - *str);
c19d1205
ZW
5545
5546 if (shift_name == NULL)
b99bd4ef 5547 {
c19d1205
ZW
5548 inst.error = _("shift expression expected");
5549 return FAIL;
b99bd4ef
NC
5550 }
5551
c19d1205 5552 shift = shift_name->kind;
b99bd4ef 5553
c19d1205
ZW
5554 switch (mode)
5555 {
5556 case NO_SHIFT_RESTRICT:
f5f10c66
AV
5557 case SHIFT_IMMEDIATE:
5558 if (shift == SHIFT_UXTW)
5559 {
5560 inst.error = _("'UXTW' not allowed here");
5561 return FAIL;
5562 }
5563 break;
b99bd4ef 5564
c19d1205
ZW
5565 case SHIFT_LSL_OR_ASR_IMMEDIATE:
5566 if (shift != SHIFT_LSL && shift != SHIFT_ASR)
5567 {
5568 inst.error = _("'LSL' or 'ASR' required");
5569 return FAIL;
5570 }
5571 break;
b99bd4ef 5572
c19d1205
ZW
5573 case SHIFT_LSL_IMMEDIATE:
5574 if (shift != SHIFT_LSL)
5575 {
5576 inst.error = _("'LSL' required");
5577 return FAIL;
5578 }
5579 break;
b99bd4ef 5580
c19d1205
ZW
5581 case SHIFT_ASR_IMMEDIATE:
5582 if (shift != SHIFT_ASR)
5583 {
5584 inst.error = _("'ASR' required");
5585 return FAIL;
5586 }
5587 break;
f5f10c66
AV
5588 case SHIFT_UXTW_IMMEDIATE:
5589 if (shift != SHIFT_UXTW)
5590 {
5591 inst.error = _("'UXTW' required");
5592 return FAIL;
5593 }
5594 break;
b99bd4ef 5595
c19d1205
ZW
5596 default: abort ();
5597 }
b99bd4ef 5598
c19d1205
ZW
5599 if (shift != SHIFT_RRX)
5600 {
5601 /* Whitespace can appear here if the next thing is a bare digit. */
5602 skip_whitespace (p);
b99bd4ef 5603
c19d1205 5604 if (mode == NO_SHIFT_RESTRICT
dcbf9037 5605 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5606 {
5607 inst.operands[i].imm = reg;
5608 inst.operands[i].immisreg = 1;
5609 }
e2b0ab59 5610 else if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
c19d1205
ZW
5611 return FAIL;
5612 }
5613 inst.operands[i].shift_kind = shift;
5614 inst.operands[i].shifted = 1;
5615 *str = p;
5616 return SUCCESS;
b99bd4ef
NC
5617}
5618
c19d1205 5619/* Parse a <shifter_operand> for an ARM data processing instruction:
b99bd4ef 5620
c19d1205
ZW
5621 #<immediate>
5622 #<immediate>, <rotate>
5623 <Rm>
5624 <Rm>, <shift>
b99bd4ef 5625
c19d1205
ZW
5626 where <shift> is defined by parse_shift above, and <rotate> is a
5627 multiple of 2 between 0 and 30. Validation of immediate operands
55cf6793 5628 is deferred to md_apply_fix. */
b99bd4ef 5629
c19d1205
ZW
5630static int
5631parse_shifter_operand (char **str, int i)
5632{
5633 int value;
91d6fa6a 5634 expressionS exp;
b99bd4ef 5635
dcbf9037 5636 if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5637 {
5638 inst.operands[i].reg = value;
5639 inst.operands[i].isreg = 1;
b99bd4ef 5640
c19d1205 5641 /* parse_shift will override this if appropriate */
e2b0ab59
AV
5642 inst.relocs[0].exp.X_op = O_constant;
5643 inst.relocs[0].exp.X_add_number = 0;
b99bd4ef 5644
c19d1205
ZW
5645 if (skip_past_comma (str) == FAIL)
5646 return SUCCESS;
b99bd4ef 5647
c19d1205
ZW
5648 /* Shift operation on register. */
5649 return parse_shift (str, i, NO_SHIFT_RESTRICT);
b99bd4ef
NC
5650 }
5651
e2b0ab59 5652 if (my_get_expression (&inst.relocs[0].exp, str, GE_IMM_PREFIX))
c19d1205 5653 return FAIL;
b99bd4ef 5654
c19d1205 5655 if (skip_past_comma (str) == SUCCESS)
b99bd4ef 5656 {
c19d1205 5657 /* #x, y -- ie explicit rotation by Y. */
91d6fa6a 5658 if (my_get_expression (&exp, str, GE_NO_PREFIX))
c19d1205 5659 return FAIL;
b99bd4ef 5660
e2b0ab59 5661 if (exp.X_op != O_constant || inst.relocs[0].exp.X_op != O_constant)
c19d1205
ZW
5662 {
5663 inst.error = _("constant expression expected");
5664 return FAIL;
5665 }
b99bd4ef 5666
91d6fa6a 5667 value = exp.X_add_number;
c19d1205
ZW
5668 if (value < 0 || value > 30 || value % 2 != 0)
5669 {
5670 inst.error = _("invalid rotation");
5671 return FAIL;
5672 }
e2b0ab59
AV
5673 if (inst.relocs[0].exp.X_add_number < 0
5674 || inst.relocs[0].exp.X_add_number > 255)
c19d1205
ZW
5675 {
5676 inst.error = _("invalid constant");
5677 return FAIL;
5678 }
09d92015 5679
a415b1cd 5680 /* Encode as specified. */
e2b0ab59 5681 inst.operands[i].imm = inst.relocs[0].exp.X_add_number | value << 7;
a415b1cd 5682 return SUCCESS;
09d92015
MM
5683 }
5684
e2b0ab59
AV
5685 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
5686 inst.relocs[0].pc_rel = 0;
c19d1205 5687 return SUCCESS;
09d92015
MM
5688}
5689
4962c51a
MS
5690/* Group relocation information. Each entry in the table contains the
5691 textual name of the relocation as may appear in assembler source
5692 and must end with a colon.
5693 Along with this textual name are the relocation codes to be used if
5694 the corresponding instruction is an ALU instruction (ADD or SUB only),
5695 an LDR, an LDRS, or an LDC. */
5696
5697struct group_reloc_table_entry
5698{
5699 const char *name;
5700 int alu_code;
5701 int ldr_code;
5702 int ldrs_code;
5703 int ldc_code;
5704};
5705
5706typedef enum
5707{
5708 /* Varieties of non-ALU group relocation. */
5709
5710 GROUP_LDR,
5711 GROUP_LDRS,
35c228db
AV
5712 GROUP_LDC,
5713 GROUP_MVE
4962c51a
MS
5714} group_reloc_type;
5715
5716static struct group_reloc_table_entry group_reloc_table[] =
5717 { /* Program counter relative: */
5718 { "pc_g0_nc",
5719 BFD_RELOC_ARM_ALU_PC_G0_NC, /* ALU */
5720 0, /* LDR */
5721 0, /* LDRS */
5722 0 }, /* LDC */
5723 { "pc_g0",
5724 BFD_RELOC_ARM_ALU_PC_G0, /* ALU */
5725 BFD_RELOC_ARM_LDR_PC_G0, /* LDR */
5726 BFD_RELOC_ARM_LDRS_PC_G0, /* LDRS */
5727 BFD_RELOC_ARM_LDC_PC_G0 }, /* LDC */
5728 { "pc_g1_nc",
5729 BFD_RELOC_ARM_ALU_PC_G1_NC, /* ALU */
5730 0, /* LDR */
5731 0, /* LDRS */
5732 0 }, /* LDC */
5733 { "pc_g1",
5734 BFD_RELOC_ARM_ALU_PC_G1, /* ALU */
5735 BFD_RELOC_ARM_LDR_PC_G1, /* LDR */
5736 BFD_RELOC_ARM_LDRS_PC_G1, /* LDRS */
5737 BFD_RELOC_ARM_LDC_PC_G1 }, /* LDC */
5738 { "pc_g2",
5739 BFD_RELOC_ARM_ALU_PC_G2, /* ALU */
5740 BFD_RELOC_ARM_LDR_PC_G2, /* LDR */
5741 BFD_RELOC_ARM_LDRS_PC_G2, /* LDRS */
5742 BFD_RELOC_ARM_LDC_PC_G2 }, /* LDC */
5743 /* Section base relative */
5744 { "sb_g0_nc",
5745 BFD_RELOC_ARM_ALU_SB_G0_NC, /* ALU */
5746 0, /* LDR */
5747 0, /* LDRS */
5748 0 }, /* LDC */
5749 { "sb_g0",
5750 BFD_RELOC_ARM_ALU_SB_G0, /* ALU */
5751 BFD_RELOC_ARM_LDR_SB_G0, /* LDR */
5752 BFD_RELOC_ARM_LDRS_SB_G0, /* LDRS */
5753 BFD_RELOC_ARM_LDC_SB_G0 }, /* LDC */
5754 { "sb_g1_nc",
5755 BFD_RELOC_ARM_ALU_SB_G1_NC, /* ALU */
5756 0, /* LDR */
5757 0, /* LDRS */
5758 0 }, /* LDC */
5759 { "sb_g1",
5760 BFD_RELOC_ARM_ALU_SB_G1, /* ALU */
5761 BFD_RELOC_ARM_LDR_SB_G1, /* LDR */
5762 BFD_RELOC_ARM_LDRS_SB_G1, /* LDRS */
5763 BFD_RELOC_ARM_LDC_SB_G1 }, /* LDC */
5764 { "sb_g2",
5765 BFD_RELOC_ARM_ALU_SB_G2, /* ALU */
5766 BFD_RELOC_ARM_LDR_SB_G2, /* LDR */
5767 BFD_RELOC_ARM_LDRS_SB_G2, /* LDRS */
72d98d16
MG
5768 BFD_RELOC_ARM_LDC_SB_G2 }, /* LDC */
5769 /* Absolute thumb alu relocations. */
5770 { "lower0_7",
5771 BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,/* ALU. */
5772 0, /* LDR. */
5773 0, /* LDRS. */
5774 0 }, /* LDC. */
5775 { "lower8_15",
5776 BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,/* ALU. */
5777 0, /* LDR. */
5778 0, /* LDRS. */
5779 0 }, /* LDC. */
5780 { "upper0_7",
5781 BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,/* ALU. */
5782 0, /* LDR. */
5783 0, /* LDRS. */
5784 0 }, /* LDC. */
5785 { "upper8_15",
5786 BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,/* ALU. */
5787 0, /* LDR. */
5788 0, /* LDRS. */
5789 0 } }; /* LDC. */
4962c51a
MS
5790
5791/* Given the address of a pointer pointing to the textual name of a group
5792 relocation as may appear in assembler source, attempt to find its details
5793 in group_reloc_table. The pointer will be updated to the character after
5794 the trailing colon. On failure, FAIL will be returned; SUCCESS
5795 otherwise. On success, *entry will be updated to point at the relevant
5796 group_reloc_table entry. */
5797
5798static int
5799find_group_reloc_table_entry (char **str, struct group_reloc_table_entry **out)
5800{
5801 unsigned int i;
5802 for (i = 0; i < ARRAY_SIZE (group_reloc_table); i++)
5803 {
5804 int length = strlen (group_reloc_table[i].name);
5805
5f4273c7
NC
5806 if (strncasecmp (group_reloc_table[i].name, *str, length) == 0
5807 && (*str)[length] == ':')
477330fc
RM
5808 {
5809 *out = &group_reloc_table[i];
5810 *str += (length + 1);
5811 return SUCCESS;
5812 }
4962c51a
MS
5813 }
5814
5815 return FAIL;
5816}
5817
5818/* Parse a <shifter_operand> for an ARM data processing instruction
5819 (as for parse_shifter_operand) where group relocations are allowed:
5820
5821 #<immediate>
5822 #<immediate>, <rotate>
5823 #:<group_reloc>:<expression>
5824 <Rm>
5825 <Rm>, <shift>
5826
5827 where <group_reloc> is one of the strings defined in group_reloc_table.
5828 The hashes are optional.
5829
5830 Everything else is as for parse_shifter_operand. */
5831
5832static parse_operand_result
5833parse_shifter_operand_group_reloc (char **str, int i)
5834{
5835 /* Determine if we have the sequence of characters #: or just :
5836 coming next. If we do, then we check for a group relocation.
5837 If we don't, punt the whole lot to parse_shifter_operand. */
5838
5839 if (((*str)[0] == '#' && (*str)[1] == ':')
5840 || (*str)[0] == ':')
5841 {
5842 struct group_reloc_table_entry *entry;
5843
5844 if ((*str)[0] == '#')
477330fc 5845 (*str) += 2;
4962c51a 5846 else
477330fc 5847 (*str)++;
4962c51a
MS
5848
5849 /* Try to parse a group relocation. Anything else is an error. */
5850 if (find_group_reloc_table_entry (str, &entry) == FAIL)
477330fc
RM
5851 {
5852 inst.error = _("unknown group relocation");
5853 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5854 }
4962c51a
MS
5855
5856 /* We now have the group relocation table entry corresponding to
477330fc 5857 the name in the assembler source. Next, we parse the expression. */
e2b0ab59 5858 if (my_get_expression (&inst.relocs[0].exp, str, GE_NO_PREFIX))
477330fc 5859 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
4962c51a
MS
5860
5861 /* Record the relocation type (always the ALU variant here). */
e2b0ab59
AV
5862 inst.relocs[0].type = (bfd_reloc_code_real_type) entry->alu_code;
5863 gas_assert (inst.relocs[0].type != 0);
4962c51a
MS
5864
5865 return PARSE_OPERAND_SUCCESS;
5866 }
5867 else
5868 return parse_shifter_operand (str, i) == SUCCESS
477330fc 5869 ? PARSE_OPERAND_SUCCESS : PARSE_OPERAND_FAIL;
4962c51a
MS
5870
5871 /* Never reached. */
5872}
5873
8e560766
MGD
5874/* Parse a Neon alignment expression. Information is written to
5875 inst.operands[i]. We assume the initial ':' has been skipped.
fa94de6b 5876
8e560766
MGD
5877 align .imm = align << 8, .immisalign=1, .preind=0 */
5878static parse_operand_result
5879parse_neon_alignment (char **str, int i)
5880{
5881 char *p = *str;
5882 expressionS exp;
5883
5884 my_get_expression (&exp, &p, GE_NO_PREFIX);
5885
5886 if (exp.X_op != O_constant)
5887 {
5888 inst.error = _("alignment must be constant");
5889 return PARSE_OPERAND_FAIL;
5890 }
5891
5892 inst.operands[i].imm = exp.X_add_number << 8;
5893 inst.operands[i].immisalign = 1;
5894 /* Alignments are not pre-indexes. */
5895 inst.operands[i].preind = 0;
5896
5897 *str = p;
5898 return PARSE_OPERAND_SUCCESS;
5899}
5900
c19d1205 5901/* Parse all forms of an ARM address expression. Information is written
e2b0ab59 5902 to inst.operands[i] and/or inst.relocs[0].
09d92015 5903
c19d1205 5904 Preindexed addressing (.preind=1):
09d92015 5905
e2b0ab59 5906 [Rn, #offset] .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5907 [Rn, +/-Rm] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5908 [Rn, +/-Rm, shift] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5909 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5910
c19d1205 5911 These three may have a trailing ! which causes .writeback to be set also.
09d92015 5912
c19d1205 5913 Postindexed addressing (.postind=1, .writeback=1):
09d92015 5914
e2b0ab59 5915 [Rn], #offset .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5916 [Rn], +/-Rm .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5917 [Rn], +/-Rm, shift .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5918 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5919
c19d1205 5920 Unindexed addressing (.preind=0, .postind=0):
09d92015 5921
c19d1205 5922 [Rn], {option} .reg=Rn .imm=option .immisreg=0
09d92015 5923
c19d1205 5924 Other:
09d92015 5925
c19d1205 5926 [Rn]{!} shorthand for [Rn,#0]{!}
e2b0ab59
AV
5927 =immediate .isreg=0 .relocs[0].exp=immediate
5928 label .reg=PC .relocs[0].pc_rel=1 .relocs[0].exp=label
09d92015 5929
c19d1205 5930 It is the caller's responsibility to check for addressing modes not
e2b0ab59 5931 supported by the instruction, and to set inst.relocs[0].type. */
c19d1205 5932
4962c51a
MS
5933static parse_operand_result
5934parse_address_main (char **str, int i, int group_relocations,
477330fc 5935 group_reloc_type group_type)
09d92015 5936{
c19d1205
ZW
5937 char *p = *str;
5938 int reg;
09d92015 5939
c19d1205 5940 if (skip_past_char (&p, '[') == FAIL)
09d92015 5941 {
c19d1205
ZW
5942 if (skip_past_char (&p, '=') == FAIL)
5943 {
974da60d 5944 /* Bare address - translate to PC-relative offset. */
e2b0ab59 5945 inst.relocs[0].pc_rel = 1;
c19d1205
ZW
5946 inst.operands[i].reg = REG_PC;
5947 inst.operands[i].isreg = 1;
5948 inst.operands[i].preind = 1;
09d92015 5949
e2b0ab59 5950 if (my_get_expression (&inst.relocs[0].exp, &p, GE_OPT_PREFIX_BIG))
8335d6aa
JW
5951 return PARSE_OPERAND_FAIL;
5952 }
e2b0ab59 5953 else if (parse_big_immediate (&p, i, &inst.relocs[0].exp,
8335d6aa 5954 /*allow_symbol_p=*/TRUE))
4962c51a 5955 return PARSE_OPERAND_FAIL;
09d92015 5956
c19d1205 5957 *str = p;
4962c51a 5958 return PARSE_OPERAND_SUCCESS;
09d92015
MM
5959 }
5960
8ab8155f
NC
5961 /* PR gas/14887: Allow for whitespace after the opening bracket. */
5962 skip_whitespace (p);
5963
f5f10c66
AV
5964 if (group_type == GROUP_MVE)
5965 {
5966 enum arm_reg_type rtype = REG_TYPE_MQ;
5967 struct neon_type_el et;
5968 if ((reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
5969 {
5970 inst.operands[i].isquad = 1;
5971 }
5972 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
5973 {
5974 inst.error = BAD_ADDR_MODE;
5975 return PARSE_OPERAND_FAIL;
5976 }
5977 }
5978 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
09d92015 5979 {
35c228db
AV
5980 if (group_type == GROUP_MVE)
5981 inst.error = BAD_ADDR_MODE;
5982 else
5983 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
4962c51a 5984 return PARSE_OPERAND_FAIL;
09d92015 5985 }
c19d1205
ZW
5986 inst.operands[i].reg = reg;
5987 inst.operands[i].isreg = 1;
09d92015 5988
c19d1205 5989 if (skip_past_comma (&p) == SUCCESS)
09d92015 5990 {
c19d1205 5991 inst.operands[i].preind = 1;
09d92015 5992
c19d1205
ZW
5993 if (*p == '+') p++;
5994 else if (*p == '-') p++, inst.operands[i].negative = 1;
5995
f5f10c66
AV
5996 enum arm_reg_type rtype = REG_TYPE_MQ;
5997 struct neon_type_el et;
5998 if (group_type == GROUP_MVE
5999 && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
6000 {
6001 inst.operands[i].immisreg = 2;
6002 inst.operands[i].imm = reg;
6003
6004 if (skip_past_comma (&p) == SUCCESS)
6005 {
6006 if (parse_shift (&p, i, SHIFT_UXTW_IMMEDIATE) == SUCCESS)
6007 {
6008 inst.operands[i].imm |= inst.relocs[0].exp.X_add_number << 5;
6009 inst.relocs[0].exp.X_add_number = 0;
6010 }
6011 else
6012 return PARSE_OPERAND_FAIL;
6013 }
6014 }
6015 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
09d92015 6016 {
c19d1205
ZW
6017 inst.operands[i].imm = reg;
6018 inst.operands[i].immisreg = 1;
6019
6020 if (skip_past_comma (&p) == SUCCESS)
6021 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 6022 return PARSE_OPERAND_FAIL;
c19d1205 6023 }
5287ad62 6024 else if (skip_past_char (&p, ':') == SUCCESS)
8e560766
MGD
6025 {
6026 /* FIXME: '@' should be used here, but it's filtered out by generic
6027 code before we get to see it here. This may be subject to
6028 change. */
6029 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 6030
8e560766
MGD
6031 if (result != PARSE_OPERAND_SUCCESS)
6032 return result;
6033 }
c19d1205
ZW
6034 else
6035 {
6036 if (inst.operands[i].negative)
6037 {
6038 inst.operands[i].negative = 0;
6039 p--;
6040 }
4962c51a 6041
5f4273c7
NC
6042 if (group_relocations
6043 && ((*p == '#' && *(p + 1) == ':') || *p == ':'))
4962c51a
MS
6044 {
6045 struct group_reloc_table_entry *entry;
6046
477330fc
RM
6047 /* Skip over the #: or : sequence. */
6048 if (*p == '#')
6049 p += 2;
6050 else
6051 p++;
4962c51a
MS
6052
6053 /* Try to parse a group relocation. Anything else is an
477330fc 6054 error. */
4962c51a
MS
6055 if (find_group_reloc_table_entry (&p, &entry) == FAIL)
6056 {
6057 inst.error = _("unknown group relocation");
6058 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6059 }
6060
6061 /* We now have the group relocation table entry corresponding to
6062 the name in the assembler source. Next, we parse the
477330fc 6063 expression. */
e2b0ab59 6064 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
4962c51a
MS
6065 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6066
6067 /* Record the relocation type. */
477330fc
RM
6068 switch (group_type)
6069 {
6070 case GROUP_LDR:
e2b0ab59
AV
6071 inst.relocs[0].type
6072 = (bfd_reloc_code_real_type) entry->ldr_code;
477330fc 6073 break;
4962c51a 6074
477330fc 6075 case GROUP_LDRS:
e2b0ab59
AV
6076 inst.relocs[0].type
6077 = (bfd_reloc_code_real_type) entry->ldrs_code;
477330fc 6078 break;
4962c51a 6079
477330fc 6080 case GROUP_LDC:
e2b0ab59
AV
6081 inst.relocs[0].type
6082 = (bfd_reloc_code_real_type) entry->ldc_code;
477330fc 6083 break;
4962c51a 6084
477330fc
RM
6085 default:
6086 gas_assert (0);
6087 }
4962c51a 6088
e2b0ab59 6089 if (inst.relocs[0].type == 0)
4962c51a
MS
6090 {
6091 inst.error = _("this group relocation is not allowed on this instruction");
6092 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
6093 }
477330fc
RM
6094 }
6095 else
26d97720
NS
6096 {
6097 char *q = p;
0198d5e6 6098
e2b0ab59 6099 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
26d97720
NS
6100 return PARSE_OPERAND_FAIL;
6101 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
6102 if (inst.relocs[0].exp.X_op == O_constant
6103 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
6104 {
6105 skip_whitespace (q);
6106 if (*q == '#')
6107 {
6108 q++;
6109 skip_whitespace (q);
6110 }
6111 if (*q == '-')
6112 inst.operands[i].negative = 1;
6113 }
6114 }
09d92015
MM
6115 }
6116 }
8e560766
MGD
6117 else if (skip_past_char (&p, ':') == SUCCESS)
6118 {
6119 /* FIXME: '@' should be used here, but it's filtered out by generic code
6120 before we get to see it here. This may be subject to change. */
6121 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 6122
8e560766
MGD
6123 if (result != PARSE_OPERAND_SUCCESS)
6124 return result;
6125 }
09d92015 6126
c19d1205 6127 if (skip_past_char (&p, ']') == FAIL)
09d92015 6128 {
c19d1205 6129 inst.error = _("']' expected");
4962c51a 6130 return PARSE_OPERAND_FAIL;
09d92015
MM
6131 }
6132
c19d1205
ZW
6133 if (skip_past_char (&p, '!') == SUCCESS)
6134 inst.operands[i].writeback = 1;
09d92015 6135
c19d1205 6136 else if (skip_past_comma (&p) == SUCCESS)
09d92015 6137 {
c19d1205
ZW
6138 if (skip_past_char (&p, '{') == SUCCESS)
6139 {
6140 /* [Rn], {expr} - unindexed, with option */
6141 if (parse_immediate (&p, &inst.operands[i].imm,
ca3f61f7 6142 0, 255, TRUE) == FAIL)
4962c51a 6143 return PARSE_OPERAND_FAIL;
09d92015 6144
c19d1205
ZW
6145 if (skip_past_char (&p, '}') == FAIL)
6146 {
6147 inst.error = _("'}' expected at end of 'option' field");
4962c51a 6148 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6149 }
6150 if (inst.operands[i].preind)
6151 {
6152 inst.error = _("cannot combine index with option");
4962c51a 6153 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6154 }
6155 *str = p;
4962c51a 6156 return PARSE_OPERAND_SUCCESS;
09d92015 6157 }
c19d1205
ZW
6158 else
6159 {
6160 inst.operands[i].postind = 1;
6161 inst.operands[i].writeback = 1;
09d92015 6162
c19d1205
ZW
6163 if (inst.operands[i].preind)
6164 {
6165 inst.error = _("cannot combine pre- and post-indexing");
4962c51a 6166 return PARSE_OPERAND_FAIL;
c19d1205 6167 }
09d92015 6168
c19d1205
ZW
6169 if (*p == '+') p++;
6170 else if (*p == '-') p++, inst.operands[i].negative = 1;
a737bd4d 6171
f5f10c66
AV
6172 enum arm_reg_type rtype = REG_TYPE_MQ;
6173 struct neon_type_el et;
6174 if (group_type == GROUP_MVE
6175 && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
6176 {
6177 inst.operands[i].immisreg = 2;
6178 inst.operands[i].imm = reg;
6179 }
6180 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205 6181 {
477330fc
RM
6182 /* We might be using the immediate for alignment already. If we
6183 are, OR the register number into the low-order bits. */
6184 if (inst.operands[i].immisalign)
6185 inst.operands[i].imm |= reg;
6186 else
6187 inst.operands[i].imm = reg;
c19d1205 6188 inst.operands[i].immisreg = 1;
a737bd4d 6189
c19d1205
ZW
6190 if (skip_past_comma (&p) == SUCCESS)
6191 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 6192 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6193 }
6194 else
6195 {
26d97720 6196 char *q = p;
0198d5e6 6197
c19d1205
ZW
6198 if (inst.operands[i].negative)
6199 {
6200 inst.operands[i].negative = 0;
6201 p--;
6202 }
e2b0ab59 6203 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
4962c51a 6204 return PARSE_OPERAND_FAIL;
26d97720 6205 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
6206 if (inst.relocs[0].exp.X_op == O_constant
6207 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
6208 {
6209 skip_whitespace (q);
6210 if (*q == '#')
6211 {
6212 q++;
6213 skip_whitespace (q);
6214 }
6215 if (*q == '-')
6216 inst.operands[i].negative = 1;
6217 }
c19d1205
ZW
6218 }
6219 }
a737bd4d
NC
6220 }
6221
c19d1205
ZW
6222 /* If at this point neither .preind nor .postind is set, we have a
6223 bare [Rn]{!}, which is shorthand for [Rn,#0]{!}. */
6224 if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
6225 {
6226 inst.operands[i].preind = 1;
e2b0ab59
AV
6227 inst.relocs[0].exp.X_op = O_constant;
6228 inst.relocs[0].exp.X_add_number = 0;
c19d1205
ZW
6229 }
6230 *str = p;
4962c51a
MS
6231 return PARSE_OPERAND_SUCCESS;
6232}
6233
6234static int
6235parse_address (char **str, int i)
6236{
21d799b5 6237 return parse_address_main (str, i, 0, GROUP_LDR) == PARSE_OPERAND_SUCCESS
477330fc 6238 ? SUCCESS : FAIL;
4962c51a
MS
6239}
6240
6241static parse_operand_result
6242parse_address_group_reloc (char **str, int i, group_reloc_type type)
6243{
6244 return parse_address_main (str, i, 1, type);
a737bd4d
NC
6245}
6246
b6895b4f
PB
6247/* Parse an operand for a MOVW or MOVT instruction. */
6248static int
6249parse_half (char **str)
6250{
6251 char * p;
5f4273c7 6252
b6895b4f
PB
6253 p = *str;
6254 skip_past_char (&p, '#');
5f4273c7 6255 if (strncasecmp (p, ":lower16:", 9) == 0)
e2b0ab59 6256 inst.relocs[0].type = BFD_RELOC_ARM_MOVW;
b6895b4f 6257 else if (strncasecmp (p, ":upper16:", 9) == 0)
e2b0ab59 6258 inst.relocs[0].type = BFD_RELOC_ARM_MOVT;
b6895b4f 6259
e2b0ab59 6260 if (inst.relocs[0].type != BFD_RELOC_UNUSED)
b6895b4f
PB
6261 {
6262 p += 9;
5f4273c7 6263 skip_whitespace (p);
b6895b4f
PB
6264 }
6265
e2b0ab59 6266 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
b6895b4f
PB
6267 return FAIL;
6268
e2b0ab59 6269 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 6270 {
e2b0ab59 6271 if (inst.relocs[0].exp.X_op != O_constant)
b6895b4f
PB
6272 {
6273 inst.error = _("constant expression expected");
6274 return FAIL;
6275 }
e2b0ab59
AV
6276 if (inst.relocs[0].exp.X_add_number < 0
6277 || inst.relocs[0].exp.X_add_number > 0xffff)
b6895b4f
PB
6278 {
6279 inst.error = _("immediate value out of range");
6280 return FAIL;
6281 }
6282 }
6283 *str = p;
6284 return SUCCESS;
6285}
6286
c19d1205 6287/* Miscellaneous. */
a737bd4d 6288
c19d1205
ZW
6289/* Parse a PSR flag operand. The value returned is FAIL on syntax error,
6290 or a bitmask suitable to be or-ed into the ARM msr instruction. */
6291static int
d2cd1205 6292parse_psr (char **str, bfd_boolean lhs)
09d92015 6293{
c19d1205
ZW
6294 char *p;
6295 unsigned long psr_field;
62b3e311
PB
6296 const struct asm_psr *psr;
6297 char *start;
d2cd1205 6298 bfd_boolean is_apsr = FALSE;
ac7f631b 6299 bfd_boolean m_profile = ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m);
09d92015 6300
a4482bb6
NC
6301 /* PR gas/12698: If the user has specified -march=all then m_profile will
6302 be TRUE, but we want to ignore it in this case as we are building for any
6303 CPU type, including non-m variants. */
823d2571 6304 if (ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
a4482bb6
NC
6305 m_profile = FALSE;
6306
c19d1205
ZW
6307 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
6308 feature for ease of use and backwards compatibility. */
6309 p = *str;
62b3e311 6310 if (strncasecmp (p, "SPSR", 4) == 0)
d2cd1205
JB
6311 {
6312 if (m_profile)
6313 goto unsupported_psr;
fa94de6b 6314
d2cd1205
JB
6315 psr_field = SPSR_BIT;
6316 }
6317 else if (strncasecmp (p, "CPSR", 4) == 0)
6318 {
6319 if (m_profile)
6320 goto unsupported_psr;
6321
6322 psr_field = 0;
6323 }
6324 else if (strncasecmp (p, "APSR", 4) == 0)
6325 {
6326 /* APSR[_<bits>] can be used as a synonym for CPSR[_<flags>] on ARMv7-A
6327 and ARMv7-R architecture CPUs. */
6328 is_apsr = TRUE;
6329 psr_field = 0;
6330 }
6331 else if (m_profile)
62b3e311
PB
6332 {
6333 start = p;
6334 do
6335 p++;
6336 while (ISALNUM (*p) || *p == '_');
6337
d2cd1205
JB
6338 if (strncasecmp (start, "iapsr", 5) == 0
6339 || strncasecmp (start, "eapsr", 5) == 0
6340 || strncasecmp (start, "xpsr", 4) == 0
6341 || strncasecmp (start, "psr", 3) == 0)
6342 p = start + strcspn (start, "rR") + 1;
6343
21d799b5 6344 psr = (const struct asm_psr *) hash_find_n (arm_v7m_psr_hsh, start,
477330fc 6345 p - start);
d2cd1205 6346
62b3e311
PB
6347 if (!psr)
6348 return FAIL;
09d92015 6349
d2cd1205
JB
6350 /* If APSR is being written, a bitfield may be specified. Note that
6351 APSR itself is handled above. */
6352 if (psr->field <= 3)
6353 {
6354 psr_field = psr->field;
6355 is_apsr = TRUE;
6356 goto check_suffix;
6357 }
6358
62b3e311 6359 *str = p;
d2cd1205
JB
6360 /* M-profile MSR instructions have the mask field set to "10", except
6361 *PSR variants which modify APSR, which may use a different mask (and
6362 have been handled already). Do that by setting the PSR_f field
6363 here. */
6364 return psr->field | (lhs ? PSR_f : 0);
62b3e311 6365 }
d2cd1205
JB
6366 else
6367 goto unsupported_psr;
09d92015 6368
62b3e311 6369 p += 4;
dc1e8a47 6370 check_suffix:
c19d1205
ZW
6371 if (*p == '_')
6372 {
6373 /* A suffix follows. */
c19d1205
ZW
6374 p++;
6375 start = p;
a737bd4d 6376
c19d1205
ZW
6377 do
6378 p++;
6379 while (ISALNUM (*p) || *p == '_');
a737bd4d 6380
d2cd1205
JB
6381 if (is_apsr)
6382 {
6383 /* APSR uses a notation for bits, rather than fields. */
6384 unsigned int nzcvq_bits = 0;
6385 unsigned int g_bit = 0;
6386 char *bit;
fa94de6b 6387
d2cd1205
JB
6388 for (bit = start; bit != p; bit++)
6389 {
6390 switch (TOLOWER (*bit))
477330fc 6391 {
d2cd1205
JB
6392 case 'n':
6393 nzcvq_bits |= (nzcvq_bits & 0x01) ? 0x20 : 0x01;
6394 break;
6395
6396 case 'z':
6397 nzcvq_bits |= (nzcvq_bits & 0x02) ? 0x20 : 0x02;
6398 break;
6399
6400 case 'c':
6401 nzcvq_bits |= (nzcvq_bits & 0x04) ? 0x20 : 0x04;
6402 break;
6403
6404 case 'v':
6405 nzcvq_bits |= (nzcvq_bits & 0x08) ? 0x20 : 0x08;
6406 break;
fa94de6b 6407
d2cd1205
JB
6408 case 'q':
6409 nzcvq_bits |= (nzcvq_bits & 0x10) ? 0x20 : 0x10;
6410 break;
fa94de6b 6411
d2cd1205
JB
6412 case 'g':
6413 g_bit |= (g_bit & 0x1) ? 0x2 : 0x1;
6414 break;
fa94de6b 6415
d2cd1205
JB
6416 default:
6417 inst.error = _("unexpected bit specified after APSR");
6418 return FAIL;
6419 }
6420 }
fa94de6b 6421
d2cd1205
JB
6422 if (nzcvq_bits == 0x1f)
6423 psr_field |= PSR_f;
fa94de6b 6424
d2cd1205
JB
6425 if (g_bit == 0x1)
6426 {
6427 if (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp))
477330fc 6428 {
d2cd1205
JB
6429 inst.error = _("selected processor does not "
6430 "support DSP extension");
6431 return FAIL;
6432 }
6433
6434 psr_field |= PSR_s;
6435 }
fa94de6b 6436
d2cd1205
JB
6437 if ((nzcvq_bits & 0x20) != 0
6438 || (nzcvq_bits != 0x1f && nzcvq_bits != 0)
6439 || (g_bit & 0x2) != 0)
6440 {
6441 inst.error = _("bad bitmask specified after APSR");
6442 return FAIL;
6443 }
6444 }
6445 else
477330fc 6446 {
d2cd1205 6447 psr = (const struct asm_psr *) hash_find_n (arm_psr_hsh, start,
477330fc 6448 p - start);
d2cd1205 6449 if (!psr)
477330fc 6450 goto error;
a737bd4d 6451
d2cd1205
JB
6452 psr_field |= psr->field;
6453 }
a737bd4d 6454 }
c19d1205 6455 else
a737bd4d 6456 {
c19d1205
ZW
6457 if (ISALNUM (*p))
6458 goto error; /* Garbage after "[CS]PSR". */
6459
d2cd1205 6460 /* Unadorned APSR is equivalent to APSR_nzcvq/CPSR_f (for writes). This
477330fc 6461 is deprecated, but allow it anyway. */
d2cd1205
JB
6462 if (is_apsr && lhs)
6463 {
6464 psr_field |= PSR_f;
6465 as_tsktsk (_("writing to APSR without specifying a bitmask is "
6466 "deprecated"));
6467 }
6468 else if (!m_profile)
6469 /* These bits are never right for M-profile devices: don't set them
6470 (only code paths which read/write APSR reach here). */
6471 psr_field |= (PSR_c | PSR_f);
a737bd4d 6472 }
c19d1205
ZW
6473 *str = p;
6474 return psr_field;
a737bd4d 6475
d2cd1205
JB
6476 unsupported_psr:
6477 inst.error = _("selected processor does not support requested special "
6478 "purpose register");
6479 return FAIL;
6480
c19d1205
ZW
6481 error:
6482 inst.error = _("flag for {c}psr instruction expected");
6483 return FAIL;
a737bd4d
NC
6484}
6485
32c36c3c
AV
6486static int
6487parse_sys_vldr_vstr (char **str)
6488{
6489 unsigned i;
6490 int val = FAIL;
6491 struct {
6492 const char *name;
6493 int regl;
6494 int regh;
6495 } sysregs[] = {
6496 {"FPSCR", 0x1, 0x0},
6497 {"FPSCR_nzcvqc", 0x2, 0x0},
6498 {"VPR", 0x4, 0x1},
6499 {"P0", 0x5, 0x1},
6500 {"FPCXTNS", 0x6, 0x1},
6501 {"FPCXTS", 0x7, 0x1}
6502 };
6503 char *op_end = strchr (*str, ',');
6504 size_t op_strlen = op_end - *str;
6505
6506 for (i = 0; i < sizeof (sysregs) / sizeof (sysregs[0]); i++)
6507 {
6508 if (!strncmp (*str, sysregs[i].name, op_strlen))
6509 {
6510 val = sysregs[i].regl | (sysregs[i].regh << 3);
6511 *str = op_end;
6512 break;
6513 }
6514 }
6515
6516 return val;
6517}
6518
c19d1205
ZW
6519/* Parse the flags argument to CPSI[ED]. Returns FAIL on error, or a
6520 value suitable for splatting into the AIF field of the instruction. */
a737bd4d 6521
c19d1205
ZW
6522static int
6523parse_cps_flags (char **str)
a737bd4d 6524{
c19d1205
ZW
6525 int val = 0;
6526 int saw_a_flag = 0;
6527 char *s = *str;
a737bd4d 6528
c19d1205
ZW
6529 for (;;)
6530 switch (*s++)
6531 {
6532 case '\0': case ',':
6533 goto done;
a737bd4d 6534
c19d1205
ZW
6535 case 'a': case 'A': saw_a_flag = 1; val |= 0x4; break;
6536 case 'i': case 'I': saw_a_flag = 1; val |= 0x2; break;
6537 case 'f': case 'F': saw_a_flag = 1; val |= 0x1; break;
a737bd4d 6538
c19d1205
ZW
6539 default:
6540 inst.error = _("unrecognized CPS flag");
6541 return FAIL;
6542 }
a737bd4d 6543
c19d1205
ZW
6544 done:
6545 if (saw_a_flag == 0)
a737bd4d 6546 {
c19d1205
ZW
6547 inst.error = _("missing CPS flags");
6548 return FAIL;
a737bd4d 6549 }
a737bd4d 6550
c19d1205
ZW
6551 *str = s - 1;
6552 return val;
a737bd4d
NC
6553}
6554
c19d1205
ZW
6555/* Parse an endian specifier ("BE" or "LE", case insensitive);
6556 returns 0 for big-endian, 1 for little-endian, FAIL for an error. */
a737bd4d
NC
6557
6558static int
c19d1205 6559parse_endian_specifier (char **str)
a737bd4d 6560{
c19d1205
ZW
6561 int little_endian;
6562 char *s = *str;
a737bd4d 6563
c19d1205
ZW
6564 if (strncasecmp (s, "BE", 2))
6565 little_endian = 0;
6566 else if (strncasecmp (s, "LE", 2))
6567 little_endian = 1;
6568 else
a737bd4d 6569 {
c19d1205 6570 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6571 return FAIL;
6572 }
6573
c19d1205 6574 if (ISALNUM (s[2]) || s[2] == '_')
a737bd4d 6575 {
c19d1205 6576 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6577 return FAIL;
6578 }
6579
c19d1205
ZW
6580 *str = s + 2;
6581 return little_endian;
6582}
a737bd4d 6583
c19d1205
ZW
6584/* Parse a rotation specifier: ROR #0, #8, #16, #24. *val receives a
6585 value suitable for poking into the rotate field of an sxt or sxta
6586 instruction, or FAIL on error. */
6587
6588static int
6589parse_ror (char **str)
6590{
6591 int rot;
6592 char *s = *str;
6593
6594 if (strncasecmp (s, "ROR", 3) == 0)
6595 s += 3;
6596 else
a737bd4d 6597 {
c19d1205 6598 inst.error = _("missing rotation field after comma");
a737bd4d
NC
6599 return FAIL;
6600 }
c19d1205
ZW
6601
6602 if (parse_immediate (&s, &rot, 0, 24, FALSE) == FAIL)
6603 return FAIL;
6604
6605 switch (rot)
a737bd4d 6606 {
c19d1205
ZW
6607 case 0: *str = s; return 0x0;
6608 case 8: *str = s; return 0x1;
6609 case 16: *str = s; return 0x2;
6610 case 24: *str = s; return 0x3;
6611
6612 default:
6613 inst.error = _("rotation can only be 0, 8, 16, or 24");
a737bd4d
NC
6614 return FAIL;
6615 }
c19d1205 6616}
a737bd4d 6617
c19d1205
ZW
6618/* Parse a conditional code (from conds[] below). The value returned is in the
6619 range 0 .. 14, or FAIL. */
6620static int
6621parse_cond (char **str)
6622{
c462b453 6623 char *q;
c19d1205 6624 const struct asm_cond *c;
c462b453
PB
6625 int n;
6626 /* Condition codes are always 2 characters, so matching up to
6627 3 characters is sufficient. */
6628 char cond[3];
a737bd4d 6629
c462b453
PB
6630 q = *str;
6631 n = 0;
6632 while (ISALPHA (*q) && n < 3)
6633 {
e07e6e58 6634 cond[n] = TOLOWER (*q);
c462b453
PB
6635 q++;
6636 n++;
6637 }
a737bd4d 6638
21d799b5 6639 c = (const struct asm_cond *) hash_find_n (arm_cond_hsh, cond, n);
c19d1205 6640 if (!c)
a737bd4d 6641 {
c19d1205 6642 inst.error = _("condition required");
a737bd4d
NC
6643 return FAIL;
6644 }
6645
c19d1205
ZW
6646 *str = q;
6647 return c->value;
6648}
6649
62b3e311
PB
6650/* Parse an option for a barrier instruction. Returns the encoding for the
6651 option, or FAIL. */
6652static int
6653parse_barrier (char **str)
6654{
6655 char *p, *q;
6656 const struct asm_barrier_opt *o;
6657
6658 p = q = *str;
6659 while (ISALPHA (*q))
6660 q++;
6661
21d799b5 6662 o = (const struct asm_barrier_opt *) hash_find_n (arm_barrier_opt_hsh, p,
477330fc 6663 q - p);
62b3e311
PB
6664 if (!o)
6665 return FAIL;
6666
e797f7e0
MGD
6667 if (!mark_feature_used (&o->arch))
6668 return FAIL;
6669
62b3e311
PB
6670 *str = q;
6671 return o->value;
6672}
6673
92e90b6e
PB
6674/* Parse the operands of a table branch instruction. Similar to a memory
6675 operand. */
6676static int
6677parse_tb (char **str)
6678{
6679 char * p = *str;
6680 int reg;
6681
6682 if (skip_past_char (&p, '[') == FAIL)
ab1eb5fe
PB
6683 {
6684 inst.error = _("'[' expected");
6685 return FAIL;
6686 }
92e90b6e 6687
dcbf9037 6688 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6689 {
6690 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6691 return FAIL;
6692 }
6693 inst.operands[0].reg = reg;
6694
6695 if (skip_past_comma (&p) == FAIL)
ab1eb5fe
PB
6696 {
6697 inst.error = _("',' expected");
6698 return FAIL;
6699 }
5f4273c7 6700
dcbf9037 6701 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6702 {
6703 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6704 return FAIL;
6705 }
6706 inst.operands[0].imm = reg;
6707
6708 if (skip_past_comma (&p) == SUCCESS)
6709 {
6710 if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
6711 return FAIL;
e2b0ab59 6712 if (inst.relocs[0].exp.X_add_number != 1)
92e90b6e
PB
6713 {
6714 inst.error = _("invalid shift");
6715 return FAIL;
6716 }
6717 inst.operands[0].shifted = 1;
6718 }
6719
6720 if (skip_past_char (&p, ']') == FAIL)
6721 {
6722 inst.error = _("']' expected");
6723 return FAIL;
6724 }
6725 *str = p;
6726 return SUCCESS;
6727}
6728
5287ad62
JB
6729/* Parse the operands of a Neon VMOV instruction. See do_neon_mov for more
6730 information on the types the operands can take and how they are encoded.
037e8744
JB
6731 Up to four operands may be read; this function handles setting the
6732 ".present" field for each read operand itself.
5287ad62
JB
6733 Updates STR and WHICH_OPERAND if parsing is successful and returns SUCCESS,
6734 else returns FAIL. */
6735
6736static int
6737parse_neon_mov (char **str, int *which_operand)
6738{
6739 int i = *which_operand, val;
6740 enum arm_reg_type rtype;
6741 char *ptr = *str;
dcbf9037 6742 struct neon_type_el optype;
5f4273c7 6743
57785aa2
AV
6744 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6745 {
6746 /* Cases 17 or 19. */
6747 inst.operands[i].reg = val;
6748 inst.operands[i].isvec = 1;
6749 inst.operands[i].isscalar = 2;
6750 inst.operands[i].vectype = optype;
6751 inst.operands[i++].present = 1;
6752
6753 if (skip_past_comma (&ptr) == FAIL)
6754 goto wanted_comma;
6755
6756 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
6757 {
6758 /* Case 17: VMOV<c>.<dt> <Qd[idx]>, <Rt> */
6759 inst.operands[i].reg = val;
6760 inst.operands[i].isreg = 1;
6761 inst.operands[i].present = 1;
6762 }
6763 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6764 {
6765 /* Case 19: VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2> */
6766 inst.operands[i].reg = val;
6767 inst.operands[i].isvec = 1;
6768 inst.operands[i].isscalar = 2;
6769 inst.operands[i].vectype = optype;
6770 inst.operands[i++].present = 1;
6771
6772 if (skip_past_comma (&ptr) == FAIL)
6773 goto wanted_comma;
6774
6775 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6776 goto wanted_arm;
6777
6778 inst.operands[i].reg = val;
6779 inst.operands[i].isreg = 1;
6780 inst.operands[i++].present = 1;
6781
6782 if (skip_past_comma (&ptr) == FAIL)
6783 goto wanted_comma;
6784
6785 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6786 goto wanted_arm;
6787
6788 inst.operands[i].reg = val;
6789 inst.operands[i].isreg = 1;
6790 inst.operands[i].present = 1;
6791 }
6792 else
6793 {
6794 first_error (_("expected ARM or MVE vector register"));
6795 return FAIL;
6796 }
6797 }
6798 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
5287ad62
JB
6799 {
6800 /* Case 4: VMOV<c><q>.<size> <Dn[x]>, <Rd>. */
6801 inst.operands[i].reg = val;
6802 inst.operands[i].isscalar = 1;
dcbf9037 6803 inst.operands[i].vectype = optype;
5287ad62
JB
6804 inst.operands[i++].present = 1;
6805
6806 if (skip_past_comma (&ptr) == FAIL)
477330fc 6807 goto wanted_comma;
5f4273c7 6808
dcbf9037 6809 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
477330fc 6810 goto wanted_arm;
5f4273c7 6811
5287ad62
JB
6812 inst.operands[i].reg = val;
6813 inst.operands[i].isreg = 1;
6814 inst.operands[i].present = 1;
6815 }
57785aa2
AV
6816 else if (((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype, &optype))
6817 != FAIL)
6818 || ((val = arm_typed_reg_parse (&ptr, REG_TYPE_MQ, &rtype, &optype))
6819 != FAIL))
5287ad62
JB
6820 {
6821 /* Cases 0, 1, 2, 3, 5 (D only). */
6822 if (skip_past_comma (&ptr) == FAIL)
477330fc 6823 goto wanted_comma;
5f4273c7 6824
5287ad62
JB
6825 inst.operands[i].reg = val;
6826 inst.operands[i].isreg = 1;
6827 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
037e8744
JB
6828 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6829 inst.operands[i].isvec = 1;
dcbf9037 6830 inst.operands[i].vectype = optype;
5287ad62
JB
6831 inst.operands[i++].present = 1;
6832
dcbf9037 6833 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc
RM
6834 {
6835 /* Case 5: VMOV<c><q> <Dm>, <Rd>, <Rn>.
6836 Case 13: VMOV <Sd>, <Rm> */
6837 inst.operands[i].reg = val;
6838 inst.operands[i].isreg = 1;
6839 inst.operands[i].present = 1;
6840
6841 if (rtype == REG_TYPE_NQ)
6842 {
6843 first_error (_("can't use Neon quad register here"));
6844 return FAIL;
6845 }
6846 else if (rtype != REG_TYPE_VFS)
6847 {
6848 i++;
6849 if (skip_past_comma (&ptr) == FAIL)
6850 goto wanted_comma;
6851 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6852 goto wanted_arm;
6853 inst.operands[i].reg = val;
6854 inst.operands[i].isreg = 1;
6855 inst.operands[i].present = 1;
6856 }
6857 }
c4a23bf8
SP
6858 else if (((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype,
6859 &optype)) != FAIL)
6860 || ((val = arm_typed_reg_parse (&ptr, REG_TYPE_MQ, &rtype,
6861 &optype)) != FAIL))
477330fc
RM
6862 {
6863 /* Case 0: VMOV<c><q> <Qd>, <Qm>
6864 Case 1: VMOV<c><q> <Dd>, <Dm>
6865 Case 8: VMOV.F32 <Sd>, <Sm>
6866 Case 15: VMOV <Sd>, <Se>, <Rn>, <Rm> */
6867
6868 inst.operands[i].reg = val;
6869 inst.operands[i].isreg = 1;
6870 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
6871 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6872 inst.operands[i].isvec = 1;
6873 inst.operands[i].vectype = optype;
6874 inst.operands[i].present = 1;
6875
6876 if (skip_past_comma (&ptr) == SUCCESS)
6877 {
6878 /* Case 15. */
6879 i++;
6880
6881 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6882 goto wanted_arm;
6883
6884 inst.operands[i].reg = val;
6885 inst.operands[i].isreg = 1;
6886 inst.operands[i++].present = 1;
6887
6888 if (skip_past_comma (&ptr) == FAIL)
6889 goto wanted_comma;
6890
6891 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6892 goto wanted_arm;
6893
6894 inst.operands[i].reg = val;
6895 inst.operands[i].isreg = 1;
6896 inst.operands[i].present = 1;
6897 }
6898 }
4641781c 6899 else if (parse_qfloat_immediate (&ptr, &inst.operands[i].imm) == SUCCESS)
477330fc
RM
6900 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<float-imm>
6901 Case 3: VMOV<c><q>.<dt> <Dd>, #<float-imm>
6902 Case 10: VMOV.F32 <Sd>, #<imm>
6903 Case 11: VMOV.F64 <Dd>, #<imm> */
6904 inst.operands[i].immisfloat = 1;
8335d6aa
JW
6905 else if (parse_big_immediate (&ptr, i, NULL, /*allow_symbol_p=*/FALSE)
6906 == SUCCESS)
477330fc
RM
6907 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<imm>
6908 Case 3: VMOV<c><q>.<dt> <Dd>, #<imm> */
6909 ;
5287ad62 6910 else
477330fc
RM
6911 {
6912 first_error (_("expected <Rm> or <Dm> or <Qm> operand"));
6913 return FAIL;
6914 }
5287ad62 6915 }
dcbf9037 6916 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
5287ad62 6917 {
57785aa2 6918 /* Cases 6, 7, 16, 18. */
5287ad62
JB
6919 inst.operands[i].reg = val;
6920 inst.operands[i].isreg = 1;
6921 inst.operands[i++].present = 1;
5f4273c7 6922
5287ad62 6923 if (skip_past_comma (&ptr) == FAIL)
477330fc 6924 goto wanted_comma;
5f4273c7 6925
57785aa2
AV
6926 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6927 {
6928 /* Case 18: VMOV<c>.<dt> <Rt>, <Qn[idx]> */
6929 inst.operands[i].reg = val;
6930 inst.operands[i].isscalar = 2;
6931 inst.operands[i].present = 1;
6932 inst.operands[i].vectype = optype;
6933 }
6934 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
477330fc
RM
6935 {
6936 /* Case 6: VMOV<c><q>.<dt> <Rd>, <Dn[x]> */
6937 inst.operands[i].reg = val;
6938 inst.operands[i].isscalar = 1;
6939 inst.operands[i].present = 1;
6940 inst.operands[i].vectype = optype;
6941 }
dcbf9037 6942 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc 6943 {
477330fc
RM
6944 inst.operands[i].reg = val;
6945 inst.operands[i].isreg = 1;
6946 inst.operands[i++].present = 1;
6947
6948 if (skip_past_comma (&ptr) == FAIL)
6949 goto wanted_comma;
6950
6951 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFSD, &rtype, &optype))
57785aa2 6952 != FAIL)
477330fc 6953 {
57785aa2 6954 /* Case 7: VMOV<c><q> <Rd>, <Rn>, <Dm> */
477330fc 6955
477330fc
RM
6956 inst.operands[i].reg = val;
6957 inst.operands[i].isreg = 1;
6958 inst.operands[i].isvec = 1;
57785aa2 6959 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
477330fc
RM
6960 inst.operands[i].vectype = optype;
6961 inst.operands[i].present = 1;
57785aa2
AV
6962
6963 if (rtype == REG_TYPE_VFS)
6964 {
6965 /* Case 14. */
6966 i++;
6967 if (skip_past_comma (&ptr) == FAIL)
6968 goto wanted_comma;
6969 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL,
6970 &optype)) == FAIL)
6971 {
6972 first_error (_(reg_expected_msgs[REG_TYPE_VFS]));
6973 return FAIL;
6974 }
6975 inst.operands[i].reg = val;
6976 inst.operands[i].isreg = 1;
6977 inst.operands[i].isvec = 1;
6978 inst.operands[i].issingle = 1;
6979 inst.operands[i].vectype = optype;
6980 inst.operands[i].present = 1;
6981 }
6982 }
6983 else
6984 {
6985 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
6986 != FAIL)
6987 {
6988 /* Case 16: VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]> */
6989 inst.operands[i].reg = val;
6990 inst.operands[i].isvec = 1;
6991 inst.operands[i].isscalar = 2;
6992 inst.operands[i].vectype = optype;
6993 inst.operands[i++].present = 1;
6994
6995 if (skip_past_comma (&ptr) == FAIL)
6996 goto wanted_comma;
6997
6998 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
6999 == FAIL)
7000 {
7001 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
7002 return FAIL;
7003 }
7004 inst.operands[i].reg = val;
7005 inst.operands[i].isvec = 1;
7006 inst.operands[i].isscalar = 2;
7007 inst.operands[i].vectype = optype;
7008 inst.operands[i].present = 1;
7009 }
7010 else
7011 {
7012 first_error (_("VFP single, double or MVE vector register"
7013 " expected"));
7014 return FAIL;
7015 }
477330fc
RM
7016 }
7017 }
037e8744 7018 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL, &optype))
477330fc
RM
7019 != FAIL)
7020 {
7021 /* Case 13. */
7022 inst.operands[i].reg = val;
7023 inst.operands[i].isreg = 1;
7024 inst.operands[i].isvec = 1;
7025 inst.operands[i].issingle = 1;
7026 inst.operands[i].vectype = optype;
7027 inst.operands[i].present = 1;
7028 }
5287ad62
JB
7029 }
7030 else
7031 {
dcbf9037 7032 first_error (_("parse error"));
5287ad62
JB
7033 return FAIL;
7034 }
7035
7036 /* Successfully parsed the operands. Update args. */
7037 *which_operand = i;
7038 *str = ptr;
7039 return SUCCESS;
7040
5f4273c7 7041 wanted_comma:
dcbf9037 7042 first_error (_("expected comma"));
5287ad62 7043 return FAIL;
5f4273c7
NC
7044
7045 wanted_arm:
dcbf9037 7046 first_error (_(reg_expected_msgs[REG_TYPE_RN]));
5287ad62 7047 return FAIL;
5287ad62
JB
7048}
7049
5be8be5d
DG
7050/* Use this macro when the operand constraints are different
7051 for ARM and THUMB (e.g. ldrd). */
7052#define MIX_ARM_THUMB_OPERANDS(arm_operand, thumb_operand) \
7053 ((arm_operand) | ((thumb_operand) << 16))
7054
c19d1205
ZW
7055/* Matcher codes for parse_operands. */
7056enum operand_parse_code
7057{
7058 OP_stop, /* end of line */
7059
7060 OP_RR, /* ARM register */
7061 OP_RRnpc, /* ARM register, not r15 */
5be8be5d 7062 OP_RRnpcsp, /* ARM register, neither r15 nor r13 (a.k.a. 'BadReg') */
c19d1205 7063 OP_RRnpcb, /* ARM register, not r15, in square brackets */
fa94de6b 7064 OP_RRnpctw, /* ARM register, not r15 in Thumb-state or with writeback,
55881a11 7065 optional trailing ! */
c19d1205
ZW
7066 OP_RRw, /* ARM register, not r15, optional trailing ! */
7067 OP_RCP, /* Coprocessor number */
7068 OP_RCN, /* Coprocessor register */
7069 OP_RF, /* FPA register */
7070 OP_RVS, /* VFP single precision register */
5287ad62
JB
7071 OP_RVD, /* VFP double precision register (0..15) */
7072 OP_RND, /* Neon double precision register (0..31) */
5ee91343
AV
7073 OP_RNDMQ, /* Neon double precision (0..31) or MVE vector register. */
7074 OP_RNDMQR, /* Neon double precision (0..31), MVE vector or ARM register.
7075 */
66d1f7cc
AV
7076 OP_RNSDMQR, /* Neon single or double precision, MVE vector or ARM register.
7077 */
5287ad62 7078 OP_RNQ, /* Neon quad precision register */
5ee91343 7079 OP_RNQMQ, /* Neon quad or MVE vector register. */
037e8744 7080 OP_RVSD, /* VFP single or double precision register */
1b883319 7081 OP_RVSD_COND, /* VFP single, double precision register or condition code. */
dd9634d9 7082 OP_RVSDMQ, /* VFP single, double precision or MVE vector register. */
dec41383 7083 OP_RNSD, /* Neon single or double precision register */
5287ad62 7084 OP_RNDQ, /* Neon double or quad precision register */
5ee91343 7085 OP_RNDQMQ, /* Neon double, quad or MVE vector register. */
7df54120 7086 OP_RNDQMQR, /* Neon double, quad, MVE vector or ARM register. */
037e8744 7087 OP_RNSDQ, /* Neon single, double or quad precision register */
5287ad62 7088 OP_RNSC, /* Neon scalar D[X] */
c19d1205
ZW
7089 OP_RVC, /* VFP control register */
7090 OP_RMF, /* Maverick F register */
7091 OP_RMD, /* Maverick D register */
7092 OP_RMFX, /* Maverick FX register */
7093 OP_RMDX, /* Maverick DX register */
7094 OP_RMAX, /* Maverick AX register */
7095 OP_RMDS, /* Maverick DSPSC register */
7096 OP_RIWR, /* iWMMXt wR register */
7097 OP_RIWC, /* iWMMXt wC register */
7098 OP_RIWG, /* iWMMXt wCG register */
7099 OP_RXA, /* XScale accumulator register */
7100
5aae9ae9 7101 OP_RNSDMQ, /* Neon single, double or MVE vector register */
5ee91343
AV
7102 OP_RNSDQMQ, /* Neon single, double or quad register or MVE vector register
7103 */
7104 OP_RNSDQMQR, /* Neon single, double or quad register, MVE vector register or
7105 GPR (no SP/SP) */
a302e574 7106 OP_RMQ, /* MVE vector register. */
1b883319 7107 OP_RMQRZ, /* MVE vector or ARM register including ZR. */
35d1cfc2 7108 OP_RMQRR, /* MVE vector or ARM register. */
a302e574 7109
60f993ce
AV
7110 /* New operands for Armv8.1-M Mainline. */
7111 OP_LR, /* ARM LR register */
a302e574
AV
7112 OP_RRe, /* ARM register, only even numbered. */
7113 OP_RRo, /* ARM register, only odd numbered, not r13 or r15. */
60f993ce 7114 OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
e39c1607 7115 OP_RR_ZR, /* ARM register or ZR but no PC */
60f993ce 7116
c19d1205 7117 OP_REGLST, /* ARM register list */
4b5a202f 7118 OP_CLRMLST, /* CLRM register list */
c19d1205
ZW
7119 OP_VRSLST, /* VFP single-precision register list */
7120 OP_VRDLST, /* VFP double-precision register list */
037e8744 7121 OP_VRSDLST, /* VFP single or double-precision register list (& quad) */
5287ad62
JB
7122 OP_NRDLST, /* Neon double-precision register list (d0-d31, qN aliases) */
7123 OP_NSTRLST, /* Neon element/structure list */
efd6b359 7124 OP_VRSDVLST, /* VFP single or double-precision register list and VPR */
35c228db
AV
7125 OP_MSTRLST2, /* MVE vector list with two elements. */
7126 OP_MSTRLST4, /* MVE vector list with four elements. */
5287ad62 7127
5287ad62 7128 OP_RNDQ_I0, /* Neon D or Q reg, or immediate zero. */
037e8744 7129 OP_RVSD_I0, /* VFP S or D reg, or immediate zero. */
aacf0b33 7130 OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero. */
1b883319
AV
7131 OP_RSVDMQ_FI0, /* VFP S, D, MVE vector register or floating point immediate
7132 zero. */
5287ad62 7133 OP_RR_RNSC, /* ARM reg or Neon scalar. */
dec41383 7134 OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar. */
037e8744 7135 OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar. */
886e1c73
AV
7136 OP_RNSDQ_RNSC_MQ, /* Vector S, D or Q reg, Neon scalar or MVE vector register.
7137 */
a8465a06
AV
7138 OP_RNSDQ_RNSC_MQ_RR, /* Vector S, D or Q reg, or MVE vector reg , or Neon
7139 scalar, or ARM register. */
5287ad62 7140 OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar. */
42b16635
AV
7141 OP_RNDQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, or ARM register. */
7142 OP_RNDQMQ_RNSC_RR, /* Neon D or Q reg, Neon scalar, MVE vector or ARM
7143 register. */
5d281bf0 7144 OP_RNDQMQ_RNSC, /* Neon D, Q or MVE vector reg, or Neon scalar. */
5287ad62
JB
7145 OP_RND_RNSC, /* Neon D reg, or Neon scalar. */
7146 OP_VMOV, /* Neon VMOV operands. */
4316f0d2 7147 OP_RNDQ_Ibig, /* Neon D or Q reg, or big immediate for logic and VMVN. */
f601a00c
AV
7148 /* Neon D, Q or MVE vector register, or big immediate for logic and VMVN. */
7149 OP_RNDQMQ_Ibig,
5287ad62 7150 OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift. */
5150f0d8
AV
7151 OP_RNDQMQ_I63b_RR, /* Neon D or Q reg, immediate for shift, MVE vector or
7152 ARM register. */
2d447fca 7153 OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2. */
32c36c3c 7154 OP_VLDR, /* VLDR operand. */
5287ad62
JB
7155
7156 OP_I0, /* immediate zero */
c19d1205
ZW
7157 OP_I7, /* immediate value 0 .. 7 */
7158 OP_I15, /* 0 .. 15 */
7159 OP_I16, /* 1 .. 16 */
5287ad62 7160 OP_I16z, /* 0 .. 16 */
c19d1205
ZW
7161 OP_I31, /* 0 .. 31 */
7162 OP_I31w, /* 0 .. 31, optional trailing ! */
7163 OP_I32, /* 1 .. 32 */
5287ad62 7164 OP_I32z, /* 0 .. 32 */
08132bdd 7165 OP_I48_I64, /* 48 or 64 */
5287ad62 7166 OP_I63, /* 0 .. 63 */
c19d1205 7167 OP_I63s, /* -64 .. 63 */
5287ad62
JB
7168 OP_I64, /* 1 .. 64 */
7169 OP_I64z, /* 0 .. 64 */
5aae9ae9 7170 OP_I127, /* 0 .. 127 */
c19d1205 7171 OP_I255, /* 0 .. 255 */
4934a27c 7172 OP_I511, /* 0 .. 511 */
5aae9ae9 7173 OP_I4095, /* 0 .. 4095 */
4934a27c 7174 OP_I8191, /* 0 .. 8191 */
c19d1205
ZW
7175 OP_I4b, /* immediate, prefix optional, 1 .. 4 */
7176 OP_I7b, /* 0 .. 7 */
7177 OP_I15b, /* 0 .. 15 */
7178 OP_I31b, /* 0 .. 31 */
7179
7180 OP_SH, /* shifter operand */
4962c51a 7181 OP_SHG, /* shifter operand with possible group relocation */
c19d1205 7182 OP_ADDR, /* Memory address expression (any mode) */
35c228db 7183 OP_ADDRMVE, /* Memory address expression for MVE's VSTR/VLDR. */
4962c51a
MS
7184 OP_ADDRGLDR, /* Mem addr expr (any mode) with possible LDR group reloc */
7185 OP_ADDRGLDRS, /* Mem addr expr (any mode) with possible LDRS group reloc */
7186 OP_ADDRGLDC, /* Mem addr expr (any mode) with possible LDC group reloc */
c19d1205
ZW
7187 OP_EXP, /* arbitrary expression */
7188 OP_EXPi, /* same, with optional immediate prefix */
7189 OP_EXPr, /* same, with optional relocation suffix */
e2b0ab59 7190 OP_EXPs, /* same, with optional non-first operand relocation suffix */
b6895b4f 7191 OP_HALF, /* 0 .. 65535 or low/high reloc. */
c28eeff2
SN
7192 OP_IROT1, /* VCADD rotate immediate: 90, 270. */
7193 OP_IROT2, /* VCMLA rotate immediate: 0, 90, 180, 270. */
c19d1205
ZW
7194
7195 OP_CPSF, /* CPS flags */
7196 OP_ENDI, /* Endianness specifier */
d2cd1205
JB
7197 OP_wPSR, /* CPSR/SPSR/APSR mask for msr (writing). */
7198 OP_rPSR, /* CPSR/SPSR/APSR mask for msr (reading). */
c19d1205 7199 OP_COND, /* conditional code */
92e90b6e 7200 OP_TB, /* Table branch. */
c19d1205 7201
037e8744
JB
7202 OP_APSR_RR, /* ARM register or "APSR_nzcv". */
7203
c19d1205 7204 OP_RRnpc_I0, /* ARM register or literal 0 */
33eaf5de 7205 OP_RR_EXr, /* ARM register or expression with opt. reloc stuff. */
c19d1205
ZW
7206 OP_RR_EXi, /* ARM register or expression with imm prefix */
7207 OP_RF_IF, /* FPA register or immediate */
7208 OP_RIWR_RIWC, /* iWMMXt R or C reg */
41adaa5c 7209 OP_RIWC_RIWG, /* iWMMXt wC or wCG reg */
c19d1205
ZW
7210
7211 /* Optional operands. */
7212 OP_oI7b, /* immediate, prefix optional, 0 .. 7 */
7213 OP_oI31b, /* 0 .. 31 */
5287ad62 7214 OP_oI32b, /* 1 .. 32 */
5f1af56b 7215 OP_oI32z, /* 0 .. 32 */
c19d1205
ZW
7216 OP_oIffffb, /* 0 .. 65535 */
7217 OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
7218
7219 OP_oRR, /* ARM register */
60f993ce 7220 OP_oLR, /* ARM LR register */
c19d1205 7221 OP_oRRnpc, /* ARM register, not the PC */
5be8be5d 7222 OP_oRRnpcsp, /* ARM register, neither the PC nor the SP (a.k.a. BadReg) */
b6702015 7223 OP_oRRw, /* ARM register, not r15, optional trailing ! */
5287ad62
JB
7224 OP_oRND, /* Optional Neon double precision register */
7225 OP_oRNQ, /* Optional Neon quad precision register */
5ee91343 7226 OP_oRNDQMQ, /* Optional Neon double, quad or MVE vector register. */
5287ad62 7227 OP_oRNDQ, /* Optional Neon double or quad precision register */
037e8744 7228 OP_oRNSDQ, /* Optional single, double or quad precision vector register */
5ee91343
AV
7229 OP_oRNSDQMQ, /* Optional single, double or quad register or MVE vector
7230 register. */
66d1f7cc
AV
7231 OP_oRNSDMQ, /* Optional single, double register or MVE vector
7232 register. */
c19d1205
ZW
7233 OP_oSHll, /* LSL immediate */
7234 OP_oSHar, /* ASR immediate */
7235 OP_oSHllar, /* LSL or ASR immediate */
7236 OP_oROR, /* ROR 0/8/16/24 */
52e7f43d 7237 OP_oBARRIER_I15, /* Option argument for a barrier instruction. */
c19d1205 7238
1b883319
AV
7239 OP_oRMQRZ, /* optional MVE vector or ARM register including ZR. */
7240
5be8be5d
DG
7241 /* Some pre-defined mixed (ARM/THUMB) operands. */
7242 OP_RR_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
7243 OP_RRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
7244 OP_oRRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_oRRnpc, OP_oRRnpcsp),
7245
c19d1205
ZW
7246 OP_FIRST_OPTIONAL = OP_oI7b
7247};
a737bd4d 7248
c19d1205
ZW
7249/* Generic instruction operand parser. This does no encoding and no
7250 semantic validation; it merely squirrels values away in the inst
7251 structure. Returns SUCCESS or FAIL depending on whether the
7252 specified grammar matched. */
7253static int
5be8be5d 7254parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
c19d1205 7255{
5be8be5d 7256 unsigned const int *upat = pattern;
c19d1205
ZW
7257 char *backtrack_pos = 0;
7258 const char *backtrack_error = 0;
99aad254 7259 int i, val = 0, backtrack_index = 0;
5287ad62 7260 enum arm_reg_type rtype;
4962c51a 7261 parse_operand_result result;
5be8be5d 7262 unsigned int op_parse_code;
efd6b359 7263 bfd_boolean partial_match;
c19d1205 7264
e07e6e58
NC
7265#define po_char_or_fail(chr) \
7266 do \
7267 { \
7268 if (skip_past_char (&str, chr) == FAIL) \
477330fc 7269 goto bad_args; \
e07e6e58
NC
7270 } \
7271 while (0)
c19d1205 7272
e07e6e58
NC
7273#define po_reg_or_fail(regtype) \
7274 do \
dcbf9037 7275 { \
e07e6e58 7276 val = arm_typed_reg_parse (& str, regtype, & rtype, \
477330fc 7277 & inst.operands[i].vectype); \
e07e6e58 7278 if (val == FAIL) \
477330fc
RM
7279 { \
7280 first_error (_(reg_expected_msgs[regtype])); \
7281 goto failure; \
7282 } \
e07e6e58
NC
7283 inst.operands[i].reg = val; \
7284 inst.operands[i].isreg = 1; \
7285 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7286 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7287 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc
RM
7288 || rtype == REG_TYPE_VFD \
7289 || rtype == REG_TYPE_NQ); \
1b883319 7290 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
dcbf9037 7291 } \
e07e6e58
NC
7292 while (0)
7293
7294#define po_reg_or_goto(regtype, label) \
7295 do \
7296 { \
7297 val = arm_typed_reg_parse (& str, regtype, & rtype, \
7298 & inst.operands[i].vectype); \
7299 if (val == FAIL) \
7300 goto label; \
dcbf9037 7301 \
e07e6e58
NC
7302 inst.operands[i].reg = val; \
7303 inst.operands[i].isreg = 1; \
7304 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7305 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7306 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc 7307 || rtype == REG_TYPE_VFD \
e07e6e58 7308 || rtype == REG_TYPE_NQ); \
1b883319 7309 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
e07e6e58
NC
7310 } \
7311 while (0)
7312
7313#define po_imm_or_fail(min, max, popt) \
7314 do \
7315 { \
7316 if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
7317 goto failure; \
7318 inst.operands[i].imm = val; \
7319 } \
7320 while (0)
7321
08132bdd
SP
7322#define po_imm1_or_imm2_or_fail(imm1, imm2, popt) \
7323 do \
7324 { \
7325 expressionS exp; \
7326 my_get_expression (&exp, &str, popt); \
7327 if (exp.X_op != O_constant) \
7328 { \
7329 inst.error = _("constant expression required"); \
7330 goto failure; \
7331 } \
7332 if (exp.X_add_number != imm1 && exp.X_add_number != imm2) \
7333 { \
7334 inst.error = _("immediate value 48 or 64 expected"); \
7335 goto failure; \
7336 } \
7337 inst.operands[i].imm = exp.X_add_number; \
7338 } \
7339 while (0)
7340
57785aa2 7341#define po_scalar_or_goto(elsz, label, reg_type) \
e07e6e58
NC
7342 do \
7343 { \
57785aa2
AV
7344 val = parse_scalar (& str, elsz, & inst.operands[i].vectype, \
7345 reg_type); \
e07e6e58
NC
7346 if (val == FAIL) \
7347 goto label; \
7348 inst.operands[i].reg = val; \
7349 inst.operands[i].isscalar = 1; \
7350 } \
7351 while (0)
7352
7353#define po_misc_or_fail(expr) \
7354 do \
7355 { \
7356 if (expr) \
7357 goto failure; \
7358 } \
7359 while (0)
7360
7361#define po_misc_or_fail_no_backtrack(expr) \
7362 do \
7363 { \
7364 result = expr; \
7365 if (result == PARSE_OPERAND_FAIL_NO_BACKTRACK) \
7366 backtrack_pos = 0; \
7367 if (result != PARSE_OPERAND_SUCCESS) \
7368 goto failure; \
7369 } \
7370 while (0)
4962c51a 7371
52e7f43d
RE
7372#define po_barrier_or_imm(str) \
7373 do \
7374 { \
7375 val = parse_barrier (&str); \
ccb84d65
JB
7376 if (val == FAIL && ! ISALPHA (*str)) \
7377 goto immediate; \
7378 if (val == FAIL \
7379 /* ISB can only take SY as an option. */ \
7380 || ((inst.instruction & 0xf0) == 0x60 \
7381 && val != 0xf)) \
52e7f43d 7382 { \
ccb84d65
JB
7383 inst.error = _("invalid barrier type"); \
7384 backtrack_pos = 0; \
7385 goto failure; \
52e7f43d
RE
7386 } \
7387 } \
7388 while (0)
7389
c19d1205
ZW
7390 skip_whitespace (str);
7391
7392 for (i = 0; upat[i] != OP_stop; i++)
7393 {
5be8be5d
DG
7394 op_parse_code = upat[i];
7395 if (op_parse_code >= 1<<16)
7396 op_parse_code = thumb ? (op_parse_code >> 16)
7397 : (op_parse_code & ((1<<16)-1));
7398
7399 if (op_parse_code >= OP_FIRST_OPTIONAL)
c19d1205
ZW
7400 {
7401 /* Remember where we are in case we need to backtrack. */
c19d1205
ZW
7402 backtrack_pos = str;
7403 backtrack_error = inst.error;
7404 backtrack_index = i;
7405 }
7406
b6702015 7407 if (i > 0 && (i > 1 || inst.operands[0].present))
c19d1205
ZW
7408 po_char_or_fail (',');
7409
5be8be5d 7410 switch (op_parse_code)
c19d1205
ZW
7411 {
7412 /* Registers */
7413 case OP_oRRnpc:
5be8be5d 7414 case OP_oRRnpcsp:
c19d1205 7415 case OP_RRnpc:
5be8be5d 7416 case OP_RRnpcsp:
c19d1205 7417 case OP_oRR:
a302e574
AV
7418 case OP_RRe:
7419 case OP_RRo:
60f993ce
AV
7420 case OP_LR:
7421 case OP_oLR:
c19d1205
ZW
7422 case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
7423 case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
7424 case OP_RCN: po_reg_or_fail (REG_TYPE_CN); break;
7425 case OP_RF: po_reg_or_fail (REG_TYPE_FN); break;
7426 case OP_RVS: po_reg_or_fail (REG_TYPE_VFS); break;
7427 case OP_RVD: po_reg_or_fail (REG_TYPE_VFD); break;
477330fc 7428 case OP_oRND:
66d1f7cc
AV
7429 case OP_RNSDMQR:
7430 po_reg_or_goto (REG_TYPE_VFS, try_rndmqr);
7431 break;
7432 try_rndmqr:
5ee91343
AV
7433 case OP_RNDMQR:
7434 po_reg_or_goto (REG_TYPE_RN, try_rndmq);
7435 break;
7436 try_rndmq:
7437 case OP_RNDMQ:
7438 po_reg_or_goto (REG_TYPE_MQ, try_rnd);
7439 break;
7440 try_rnd:
5287ad62 7441 case OP_RND: po_reg_or_fail (REG_TYPE_VFD); break;
cd2cf30b
PB
7442 case OP_RVC:
7443 po_reg_or_goto (REG_TYPE_VFC, coproc_reg);
7444 break;
7445 /* Also accept generic coprocessor regs for unknown registers. */
7446 coproc_reg:
ba6cd17f
SD
7447 po_reg_or_goto (REG_TYPE_CN, vpr_po);
7448 break;
7449 /* Also accept P0 or p0 for VPR.P0. Since P0 is already an
7450 existing register with a value of 0, this seems like the
7451 best way to parse P0. */
7452 vpr_po:
7453 if (strncasecmp (str, "P0", 2) == 0)
7454 {
7455 str += 2;
7456 inst.operands[i].isreg = 1;
7457 inst.operands[i].reg = 13;
7458 }
7459 else
7460 goto failure;
cd2cf30b 7461 break;
c19d1205
ZW
7462 case OP_RMF: po_reg_or_fail (REG_TYPE_MVF); break;
7463 case OP_RMD: po_reg_or_fail (REG_TYPE_MVD); break;
7464 case OP_RMFX: po_reg_or_fail (REG_TYPE_MVFX); break;
7465 case OP_RMDX: po_reg_or_fail (REG_TYPE_MVDX); break;
7466 case OP_RMAX: po_reg_or_fail (REG_TYPE_MVAX); break;
7467 case OP_RMDS: po_reg_or_fail (REG_TYPE_DSPSC); break;
7468 case OP_RIWR: po_reg_or_fail (REG_TYPE_MMXWR); break;
7469 case OP_RIWC: po_reg_or_fail (REG_TYPE_MMXWC); break;
7470 case OP_RIWG: po_reg_or_fail (REG_TYPE_MMXWCG); break;
7471 case OP_RXA: po_reg_or_fail (REG_TYPE_XSCALE); break;
477330fc 7472 case OP_oRNQ:
5ee91343
AV
7473 case OP_RNQMQ:
7474 po_reg_or_goto (REG_TYPE_MQ, try_nq);
7475 break;
7476 try_nq:
5287ad62 7477 case OP_RNQ: po_reg_or_fail (REG_TYPE_NQ); break;
dec41383 7478 case OP_RNSD: po_reg_or_fail (REG_TYPE_NSD); break;
7df54120
AV
7479 case OP_RNDQMQR:
7480 po_reg_or_goto (REG_TYPE_RN, try_rndqmq);
7481 break;
7482 try_rndqmq:
5ee91343
AV
7483 case OP_oRNDQMQ:
7484 case OP_RNDQMQ:
7485 po_reg_or_goto (REG_TYPE_MQ, try_rndq);
7486 break;
7487 try_rndq:
477330fc 7488 case OP_oRNDQ:
5287ad62 7489 case OP_RNDQ: po_reg_or_fail (REG_TYPE_NDQ); break;
dd9634d9
AV
7490 case OP_RVSDMQ:
7491 po_reg_or_goto (REG_TYPE_MQ, try_rvsd);
7492 break;
7493 try_rvsd:
477330fc 7494 case OP_RVSD: po_reg_or_fail (REG_TYPE_VFSD); break;
1b883319
AV
7495 case OP_RVSD_COND:
7496 po_reg_or_goto (REG_TYPE_VFSD, try_cond);
7497 break;
66d1f7cc 7498 case OP_oRNSDMQ:
5aae9ae9
MM
7499 case OP_RNSDMQ:
7500 po_reg_or_goto (REG_TYPE_NSD, try_mq2);
7501 break;
7502 try_mq2:
7503 po_reg_or_fail (REG_TYPE_MQ);
7504 break;
477330fc
RM
7505 case OP_oRNSDQ:
7506 case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ); break;
5ee91343
AV
7507 case OP_RNSDQMQR:
7508 po_reg_or_goto (REG_TYPE_RN, try_mq);
7509 break;
7510 try_mq:
7511 case OP_oRNSDQMQ:
7512 case OP_RNSDQMQ:
7513 po_reg_or_goto (REG_TYPE_MQ, try_nsdq2);
7514 break;
7515 try_nsdq2:
7516 po_reg_or_fail (REG_TYPE_NSDQ);
7517 inst.error = 0;
7518 break;
35d1cfc2
AV
7519 case OP_RMQRR:
7520 po_reg_or_goto (REG_TYPE_RN, try_rmq);
7521 break;
7522 try_rmq:
a302e574
AV
7523 case OP_RMQ:
7524 po_reg_or_fail (REG_TYPE_MQ);
7525 break;
477330fc
RM
7526 /* Neon scalar. Using an element size of 8 means that some invalid
7527 scalars are accepted here, so deal with those in later code. */
57785aa2 7528 case OP_RNSC: po_scalar_or_goto (8, failure, REG_TYPE_VFD); break;
477330fc
RM
7529
7530 case OP_RNDQ_I0:
7531 {
7532 po_reg_or_goto (REG_TYPE_NDQ, try_imm0);
7533 break;
7534 try_imm0:
7535 po_imm_or_fail (0, 0, TRUE);
7536 }
7537 break;
7538
7539 case OP_RVSD_I0:
7540 po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
7541 break;
7542
1b883319
AV
7543 case OP_RSVDMQ_FI0:
7544 po_reg_or_goto (REG_TYPE_MQ, try_rsvd_fi0);
7545 break;
7546 try_rsvd_fi0:
aacf0b33
KT
7547 case OP_RSVD_FI0:
7548 {
7549 po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
7550 break;
7551 try_ifimm0:
7552 if (parse_ifimm_zero (&str))
7553 inst.operands[i].imm = 0;
7554 else
7555 {
7556 inst.error
7557 = _("only floating point zero is allowed as immediate value");
7558 goto failure;
7559 }
7560 }
7561 break;
7562
477330fc
RM
7563 case OP_RR_RNSC:
7564 {
57785aa2 7565 po_scalar_or_goto (8, try_rr, REG_TYPE_VFD);
477330fc
RM
7566 break;
7567 try_rr:
7568 po_reg_or_fail (REG_TYPE_RN);
7569 }
7570 break;
7571
a8465a06
AV
7572 case OP_RNSDQ_RNSC_MQ_RR:
7573 po_reg_or_goto (REG_TYPE_RN, try_rnsdq_rnsc_mq);
7574 break;
7575 try_rnsdq_rnsc_mq:
886e1c73
AV
7576 case OP_RNSDQ_RNSC_MQ:
7577 po_reg_or_goto (REG_TYPE_MQ, try_rnsdq_rnsc);
7578 break;
7579 try_rnsdq_rnsc:
477330fc
RM
7580 case OP_RNSDQ_RNSC:
7581 {
57785aa2
AV
7582 po_scalar_or_goto (8, try_nsdq, REG_TYPE_VFD);
7583 inst.error = 0;
477330fc
RM
7584 break;
7585 try_nsdq:
7586 po_reg_or_fail (REG_TYPE_NSDQ);
57785aa2 7587 inst.error = 0;
477330fc
RM
7588 }
7589 break;
7590
dec41383
JW
7591 case OP_RNSD_RNSC:
7592 {
57785aa2 7593 po_scalar_or_goto (8, try_s_scalar, REG_TYPE_VFD);
dec41383
JW
7594 break;
7595 try_s_scalar:
57785aa2 7596 po_scalar_or_goto (4, try_nsd, REG_TYPE_VFS);
dec41383
JW
7597 break;
7598 try_nsd:
7599 po_reg_or_fail (REG_TYPE_NSD);
7600 }
7601 break;
7602
42b16635
AV
7603 case OP_RNDQMQ_RNSC_RR:
7604 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc_rr);
7605 break;
7606 try_rndq_rnsc_rr:
7607 case OP_RNDQ_RNSC_RR:
7608 po_reg_or_goto (REG_TYPE_RN, try_rndq_rnsc);
7609 break;
5d281bf0
AV
7610 case OP_RNDQMQ_RNSC:
7611 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc);
7612 break;
7613 try_rndq_rnsc:
477330fc
RM
7614 case OP_RNDQ_RNSC:
7615 {
57785aa2 7616 po_scalar_or_goto (8, try_ndq, REG_TYPE_VFD);
477330fc
RM
7617 break;
7618 try_ndq:
7619 po_reg_or_fail (REG_TYPE_NDQ);
7620 }
7621 break;
7622
7623 case OP_RND_RNSC:
7624 {
57785aa2 7625 po_scalar_or_goto (8, try_vfd, REG_TYPE_VFD);
477330fc
RM
7626 break;
7627 try_vfd:
7628 po_reg_or_fail (REG_TYPE_VFD);
7629 }
7630 break;
7631
7632 case OP_VMOV:
7633 /* WARNING: parse_neon_mov can move the operand counter, i. If we're
7634 not careful then bad things might happen. */
7635 po_misc_or_fail (parse_neon_mov (&str, &i) == FAIL);
7636 break;
7637
f601a00c
AV
7638 case OP_RNDQMQ_Ibig:
7639 po_reg_or_goto (REG_TYPE_MQ, try_rndq_ibig);
7640 break;
7641 try_rndq_ibig:
477330fc
RM
7642 case OP_RNDQ_Ibig:
7643 {
7644 po_reg_or_goto (REG_TYPE_NDQ, try_immbig);
7645 break;
7646 try_immbig:
7647 /* There's a possibility of getting a 64-bit immediate here, so
7648 we need special handling. */
8335d6aa
JW
7649 if (parse_big_immediate (&str, i, NULL, /*allow_symbol_p=*/FALSE)
7650 == FAIL)
477330fc
RM
7651 {
7652 inst.error = _("immediate value is out of range");
7653 goto failure;
7654 }
7655 }
7656 break;
7657
5150f0d8
AV
7658 case OP_RNDQMQ_I63b_RR:
7659 po_reg_or_goto (REG_TYPE_MQ, try_rndq_i63b_rr);
7660 break;
7661 try_rndq_i63b_rr:
7662 po_reg_or_goto (REG_TYPE_RN, try_rndq_i63b);
7663 break;
7664 try_rndq_i63b:
477330fc
RM
7665 case OP_RNDQ_I63b:
7666 {
7667 po_reg_or_goto (REG_TYPE_NDQ, try_shimm);
7668 break;
7669 try_shimm:
7670 po_imm_or_fail (0, 63, TRUE);
7671 }
7672 break;
c19d1205
ZW
7673
7674 case OP_RRnpcb:
7675 po_char_or_fail ('[');
7676 po_reg_or_fail (REG_TYPE_RN);
7677 po_char_or_fail (']');
7678 break;
a737bd4d 7679
55881a11 7680 case OP_RRnpctw:
c19d1205 7681 case OP_RRw:
b6702015 7682 case OP_oRRw:
c19d1205
ZW
7683 po_reg_or_fail (REG_TYPE_RN);
7684 if (skip_past_char (&str, '!') == SUCCESS)
7685 inst.operands[i].writeback = 1;
7686 break;
7687
7688 /* Immediates */
7689 case OP_I7: po_imm_or_fail ( 0, 7, FALSE); break;
7690 case OP_I15: po_imm_or_fail ( 0, 15, FALSE); break;
7691 case OP_I16: po_imm_or_fail ( 1, 16, FALSE); break;
477330fc 7692 case OP_I16z: po_imm_or_fail ( 0, 16, FALSE); break;
c19d1205
ZW
7693 case OP_I31: po_imm_or_fail ( 0, 31, FALSE); break;
7694 case OP_I32: po_imm_or_fail ( 1, 32, FALSE); break;
477330fc 7695 case OP_I32z: po_imm_or_fail ( 0, 32, FALSE); break;
08132bdd 7696 case OP_I48_I64: po_imm1_or_imm2_or_fail (48, 64, FALSE); break;
c19d1205 7697 case OP_I63s: po_imm_or_fail (-64, 63, FALSE); break;
477330fc
RM
7698 case OP_I63: po_imm_or_fail ( 0, 63, FALSE); break;
7699 case OP_I64: po_imm_or_fail ( 1, 64, FALSE); break;
7700 case OP_I64z: po_imm_or_fail ( 0, 64, FALSE); break;
5aae9ae9 7701 case OP_I127: po_imm_or_fail ( 0, 127, FALSE); break;
c19d1205 7702 case OP_I255: po_imm_or_fail ( 0, 255, FALSE); break;
4934a27c 7703 case OP_I511: po_imm_or_fail ( 0, 511, FALSE); break;
5aae9ae9 7704 case OP_I4095: po_imm_or_fail ( 0, 4095, FALSE); break;
4934a27c 7705 case OP_I8191: po_imm_or_fail ( 0, 8191, FALSE); break;
c19d1205
ZW
7706 case OP_I4b: po_imm_or_fail ( 1, 4, TRUE); break;
7707 case OP_oI7b:
7708 case OP_I7b: po_imm_or_fail ( 0, 7, TRUE); break;
7709 case OP_I15b: po_imm_or_fail ( 0, 15, TRUE); break;
7710 case OP_oI31b:
7711 case OP_I31b: po_imm_or_fail ( 0, 31, TRUE); break;
477330fc
RM
7712 case OP_oI32b: po_imm_or_fail ( 1, 32, TRUE); break;
7713 case OP_oI32z: po_imm_or_fail ( 0, 32, TRUE); break;
c19d1205
ZW
7714 case OP_oIffffb: po_imm_or_fail ( 0, 0xffff, TRUE); break;
7715
7716 /* Immediate variants */
7717 case OP_oI255c:
7718 po_char_or_fail ('{');
7719 po_imm_or_fail (0, 255, TRUE);
7720 po_char_or_fail ('}');
7721 break;
7722
7723 case OP_I31w:
7724 /* The expression parser chokes on a trailing !, so we have
7725 to find it first and zap it. */
7726 {
7727 char *s = str;
7728 while (*s && *s != ',')
7729 s++;
7730 if (s[-1] == '!')
7731 {
7732 s[-1] = '\0';
7733 inst.operands[i].writeback = 1;
7734 }
7735 po_imm_or_fail (0, 31, TRUE);
7736 if (str == s - 1)
7737 str = s;
7738 }
7739 break;
7740
7741 /* Expressions */
7742 case OP_EXPi: EXPi:
e2b0ab59 7743 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7744 GE_OPT_PREFIX));
7745 break;
7746
7747 case OP_EXP:
e2b0ab59 7748 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7749 GE_NO_PREFIX));
7750 break;
7751
7752 case OP_EXPr: EXPr:
e2b0ab59 7753 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205 7754 GE_NO_PREFIX));
e2b0ab59 7755 if (inst.relocs[0].exp.X_op == O_symbol)
a737bd4d 7756 {
c19d1205
ZW
7757 val = parse_reloc (&str);
7758 if (val == -1)
7759 {
7760 inst.error = _("unrecognized relocation suffix");
7761 goto failure;
7762 }
7763 else if (val != BFD_RELOC_UNUSED)
7764 {
7765 inst.operands[i].imm = val;
7766 inst.operands[i].hasreloc = 1;
7767 }
a737bd4d 7768 }
c19d1205 7769 break;
a737bd4d 7770
e2b0ab59
AV
7771 case OP_EXPs:
7772 po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
7773 GE_NO_PREFIX));
7774 if (inst.relocs[i].exp.X_op == O_symbol)
7775 {
7776 inst.operands[i].hasreloc = 1;
7777 }
7778 else if (inst.relocs[i].exp.X_op == O_constant)
7779 {
7780 inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
7781 inst.operands[i].hasreloc = 0;
7782 }
7783 break;
7784
b6895b4f
PB
7785 /* Operand for MOVW or MOVT. */
7786 case OP_HALF:
7787 po_misc_or_fail (parse_half (&str));
7788 break;
7789
e07e6e58 7790 /* Register or expression. */
c19d1205
ZW
7791 case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
7792 case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
a737bd4d 7793
e07e6e58 7794 /* Register or immediate. */
c19d1205
ZW
7795 case OP_RRnpc_I0: po_reg_or_goto (REG_TYPE_RN, I0); break;
7796 I0: po_imm_or_fail (0, 0, FALSE); break;
a737bd4d 7797
23d00a41
SD
7798 case OP_RRnpcsp_I32: po_reg_or_goto (REG_TYPE_RN, I32); break;
7799 I32: po_imm_or_fail (1, 32, FALSE); break;
7800
c19d1205
ZW
7801 case OP_RF_IF: po_reg_or_goto (REG_TYPE_FN, IF); break;
7802 IF:
7803 if (!is_immediate_prefix (*str))
7804 goto bad_args;
7805 str++;
7806 val = parse_fpa_immediate (&str);
7807 if (val == FAIL)
7808 goto failure;
7809 /* FPA immediates are encoded as registers 8-15.
7810 parse_fpa_immediate has already applied the offset. */
7811 inst.operands[i].reg = val;
7812 inst.operands[i].isreg = 1;
7813 break;
09d92015 7814
2d447fca
JM
7815 case OP_RIWR_I32z: po_reg_or_goto (REG_TYPE_MMXWR, I32z); break;
7816 I32z: po_imm_or_fail (0, 32, FALSE); break;
7817
e07e6e58 7818 /* Two kinds of register. */
c19d1205
ZW
7819 case OP_RIWR_RIWC:
7820 {
7821 struct reg_entry *rege = arm_reg_parse_multi (&str);
97f87066
JM
7822 if (!rege
7823 || (rege->type != REG_TYPE_MMXWR
7824 && rege->type != REG_TYPE_MMXWC
7825 && rege->type != REG_TYPE_MMXWCG))
c19d1205
ZW
7826 {
7827 inst.error = _("iWMMXt data or control register expected");
7828 goto failure;
7829 }
7830 inst.operands[i].reg = rege->number;
7831 inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
7832 }
7833 break;
09d92015 7834
41adaa5c
JM
7835 case OP_RIWC_RIWG:
7836 {
7837 struct reg_entry *rege = arm_reg_parse_multi (&str);
7838 if (!rege
7839 || (rege->type != REG_TYPE_MMXWC
7840 && rege->type != REG_TYPE_MMXWCG))
7841 {
7842 inst.error = _("iWMMXt control register expected");
7843 goto failure;
7844 }
7845 inst.operands[i].reg = rege->number;
7846 inst.operands[i].isreg = 1;
7847 }
7848 break;
7849
c19d1205
ZW
7850 /* Misc */
7851 case OP_CPSF: val = parse_cps_flags (&str); break;
7852 case OP_ENDI: val = parse_endian_specifier (&str); break;
7853 case OP_oROR: val = parse_ror (&str); break;
1b883319 7854 try_cond:
c19d1205 7855 case OP_COND: val = parse_cond (&str); break;
52e7f43d
RE
7856 case OP_oBARRIER_I15:
7857 po_barrier_or_imm (str); break;
7858 immediate:
7859 if (parse_immediate (&str, &val, 0, 15, TRUE) == FAIL)
477330fc 7860 goto failure;
52e7f43d 7861 break;
c19d1205 7862
fa94de6b 7863 case OP_wPSR:
d2cd1205 7864 case OP_rPSR:
90ec0d68
MGD
7865 po_reg_or_goto (REG_TYPE_RNB, try_psr);
7866 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_virt))
7867 {
7868 inst.error = _("Banked registers are not available with this "
7869 "architecture.");
7870 goto failure;
7871 }
7872 break;
d2cd1205
JB
7873 try_psr:
7874 val = parse_psr (&str, op_parse_code == OP_wPSR);
7875 break;
037e8744 7876
32c36c3c
AV
7877 case OP_VLDR:
7878 po_reg_or_goto (REG_TYPE_VFSD, try_sysreg);
7879 break;
7880 try_sysreg:
7881 val = parse_sys_vldr_vstr (&str);
7882 break;
7883
477330fc
RM
7884 case OP_APSR_RR:
7885 po_reg_or_goto (REG_TYPE_RN, try_apsr);
7886 break;
7887 try_apsr:
7888 /* Parse "APSR_nvzc" operand (for FMSTAT-equivalent MRS
7889 instruction). */
7890 if (strncasecmp (str, "APSR_", 5) == 0)
7891 {
7892 unsigned found = 0;
7893 str += 5;
7894 while (found < 15)
7895 switch (*str++)
7896 {
7897 case 'c': found = (found & 1) ? 16 : found | 1; break;
7898 case 'n': found = (found & 2) ? 16 : found | 2; break;
7899 case 'z': found = (found & 4) ? 16 : found | 4; break;
7900 case 'v': found = (found & 8) ? 16 : found | 8; break;
7901 default: found = 16;
7902 }
7903 if (found != 15)
7904 goto failure;
7905 inst.operands[i].isvec = 1;
f7c21dc7
NC
7906 /* APSR_nzcv is encoded in instructions as if it were the REG_PC. */
7907 inst.operands[i].reg = REG_PC;
477330fc
RM
7908 }
7909 else
7910 goto failure;
7911 break;
037e8744 7912
92e90b6e
PB
7913 case OP_TB:
7914 po_misc_or_fail (parse_tb (&str));
7915 break;
7916
e07e6e58 7917 /* Register lists. */
c19d1205 7918 case OP_REGLST:
4b5a202f 7919 val = parse_reg_list (&str, REGLIST_RN);
c19d1205
ZW
7920 if (*str == '^')
7921 {
5e0d7f77 7922 inst.operands[i].writeback = 1;
c19d1205
ZW
7923 str++;
7924 }
7925 break;
09d92015 7926
4b5a202f
AV
7927 case OP_CLRMLST:
7928 val = parse_reg_list (&str, REGLIST_CLRM);
7929 break;
7930
c19d1205 7931 case OP_VRSLST:
efd6b359
AV
7932 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_S,
7933 &partial_match);
c19d1205 7934 break;
09d92015 7935
c19d1205 7936 case OP_VRDLST:
efd6b359
AV
7937 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_D,
7938 &partial_match);
c19d1205 7939 break;
a737bd4d 7940
477330fc
RM
7941 case OP_VRSDLST:
7942 /* Allow Q registers too. */
7943 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7944 REGLIST_NEON_D, &partial_match);
477330fc
RM
7945 if (val == FAIL)
7946 {
7947 inst.error = NULL;
7948 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359
AV
7949 REGLIST_VFP_S, &partial_match);
7950 inst.operands[i].issingle = 1;
7951 }
7952 break;
7953
7954 case OP_VRSDVLST:
7955 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7956 REGLIST_VFP_D_VPR, &partial_match);
7957 if (val == FAIL && !partial_match)
7958 {
7959 inst.error = NULL;
7960 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7961 REGLIST_VFP_S_VPR, &partial_match);
477330fc
RM
7962 inst.operands[i].issingle = 1;
7963 }
7964 break;
7965
7966 case OP_NRDLST:
7967 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7968 REGLIST_NEON_D, &partial_match);
477330fc 7969 break;
5287ad62 7970
35c228db
AV
7971 case OP_MSTRLST4:
7972 case OP_MSTRLST2:
7973 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
7974 1, &inst.operands[i].vectype);
7975 if (val != (((op_parse_code == OP_MSTRLST2) ? 3 : 7) << 5 | 0xe))
7976 goto failure;
7977 break;
5287ad62 7978 case OP_NSTRLST:
477330fc 7979 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
35c228db 7980 0, &inst.operands[i].vectype);
477330fc 7981 break;
5287ad62 7982
c19d1205 7983 /* Addressing modes */
35c228db
AV
7984 case OP_ADDRMVE:
7985 po_misc_or_fail (parse_address_group_reloc (&str, i, GROUP_MVE));
7986 break;
7987
c19d1205
ZW
7988 case OP_ADDR:
7989 po_misc_or_fail (parse_address (&str, i));
7990 break;
09d92015 7991
4962c51a
MS
7992 case OP_ADDRGLDR:
7993 po_misc_or_fail_no_backtrack (
477330fc 7994 parse_address_group_reloc (&str, i, GROUP_LDR));
4962c51a
MS
7995 break;
7996
7997 case OP_ADDRGLDRS:
7998 po_misc_or_fail_no_backtrack (
477330fc 7999 parse_address_group_reloc (&str, i, GROUP_LDRS));
4962c51a
MS
8000 break;
8001
8002 case OP_ADDRGLDC:
8003 po_misc_or_fail_no_backtrack (
477330fc 8004 parse_address_group_reloc (&str, i, GROUP_LDC));
4962c51a
MS
8005 break;
8006
c19d1205
ZW
8007 case OP_SH:
8008 po_misc_or_fail (parse_shifter_operand (&str, i));
8009 break;
09d92015 8010
4962c51a
MS
8011 case OP_SHG:
8012 po_misc_or_fail_no_backtrack (
477330fc 8013 parse_shifter_operand_group_reloc (&str, i));
4962c51a
MS
8014 break;
8015
c19d1205
ZW
8016 case OP_oSHll:
8017 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_IMMEDIATE));
8018 break;
09d92015 8019
c19d1205
ZW
8020 case OP_oSHar:
8021 po_misc_or_fail (parse_shift (&str, i, SHIFT_ASR_IMMEDIATE));
8022 break;
09d92015 8023
c19d1205
ZW
8024 case OP_oSHllar:
8025 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
8026 break;
09d92015 8027
1b883319
AV
8028 case OP_RMQRZ:
8029 case OP_oRMQRZ:
8030 po_reg_or_goto (REG_TYPE_MQ, try_rr_zr);
8031 break;
e39c1607
SD
8032
8033 case OP_RR_ZR:
1b883319
AV
8034 try_rr_zr:
8035 po_reg_or_goto (REG_TYPE_RN, ZR);
8036 break;
8037 ZR:
8038 po_reg_or_fail (REG_TYPE_ZR);
8039 break;
8040
c19d1205 8041 default:
5be8be5d 8042 as_fatal (_("unhandled operand code %d"), op_parse_code);
c19d1205 8043 }
09d92015 8044
c19d1205
ZW
8045 /* Various value-based sanity checks and shared operations. We
8046 do not signal immediate failures for the register constraints;
8047 this allows a syntax error to take precedence. */
5be8be5d 8048 switch (op_parse_code)
c19d1205
ZW
8049 {
8050 case OP_oRRnpc:
8051 case OP_RRnpc:
8052 case OP_RRnpcb:
8053 case OP_RRw:
b6702015 8054 case OP_oRRw:
c19d1205
ZW
8055 case OP_RRnpc_I0:
8056 if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
8057 inst.error = BAD_PC;
8058 break;
09d92015 8059
5be8be5d
DG
8060 case OP_oRRnpcsp:
8061 case OP_RRnpcsp:
23d00a41 8062 case OP_RRnpcsp_I32:
5be8be5d
DG
8063 if (inst.operands[i].isreg)
8064 {
8065 if (inst.operands[i].reg == REG_PC)
8066 inst.error = BAD_PC;
5c8ed6a4
JW
8067 else if (inst.operands[i].reg == REG_SP
8068 /* The restriction on Rd/Rt/Rt2 on Thumb mode has been
8069 relaxed since ARMv8-A. */
8070 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
8071 {
8072 gas_assert (thumb);
8073 inst.error = BAD_SP;
8074 }
5be8be5d
DG
8075 }
8076 break;
8077
55881a11 8078 case OP_RRnpctw:
fa94de6b
RM
8079 if (inst.operands[i].isreg
8080 && inst.operands[i].reg == REG_PC
55881a11
MGD
8081 && (inst.operands[i].writeback || thumb))
8082 inst.error = BAD_PC;
8083 break;
8084
1b883319 8085 case OP_RVSD_COND:
32c36c3c
AV
8086 case OP_VLDR:
8087 if (inst.operands[i].isreg)
8088 break;
8089 /* fall through. */
1b883319 8090
c19d1205
ZW
8091 case OP_CPSF:
8092 case OP_ENDI:
8093 case OP_oROR:
d2cd1205
JB
8094 case OP_wPSR:
8095 case OP_rPSR:
c19d1205 8096 case OP_COND:
52e7f43d 8097 case OP_oBARRIER_I15:
c19d1205 8098 case OP_REGLST:
4b5a202f 8099 case OP_CLRMLST:
c19d1205
ZW
8100 case OP_VRSLST:
8101 case OP_VRDLST:
477330fc 8102 case OP_VRSDLST:
efd6b359 8103 case OP_VRSDVLST:
477330fc
RM
8104 case OP_NRDLST:
8105 case OP_NSTRLST:
35c228db
AV
8106 case OP_MSTRLST2:
8107 case OP_MSTRLST4:
c19d1205
ZW
8108 if (val == FAIL)
8109 goto failure;
8110 inst.operands[i].imm = val;
8111 break;
a737bd4d 8112
60f993ce
AV
8113 case OP_LR:
8114 case OP_oLR:
8115 if (inst.operands[i].reg != REG_LR)
8116 inst.error = _("operand must be LR register");
8117 break;
8118
1b883319
AV
8119 case OP_RMQRZ:
8120 case OP_oRMQRZ:
e39c1607 8121 case OP_RR_ZR:
1b883319
AV
8122 if (!inst.operands[i].iszr && inst.operands[i].reg == REG_PC)
8123 inst.error = BAD_PC;
8124 break;
8125
a302e574
AV
8126 case OP_RRe:
8127 if (inst.operands[i].isreg
8128 && (inst.operands[i].reg & 0x00000001) != 0)
8129 inst.error = BAD_ODD;
8130 break;
8131
8132 case OP_RRo:
8133 if (inst.operands[i].isreg)
8134 {
8135 if ((inst.operands[i].reg & 0x00000001) != 1)
8136 inst.error = BAD_EVEN;
8137 else if (inst.operands[i].reg == REG_SP)
8138 as_tsktsk (MVE_BAD_SP);
8139 else if (inst.operands[i].reg == REG_PC)
8140 inst.error = BAD_PC;
8141 }
8142 break;
8143
c19d1205
ZW
8144 default:
8145 break;
8146 }
09d92015 8147
c19d1205
ZW
8148 /* If we get here, this operand was successfully parsed. */
8149 inst.operands[i].present = 1;
8150 continue;
09d92015 8151
c19d1205 8152 bad_args:
09d92015 8153 inst.error = BAD_ARGS;
c19d1205
ZW
8154
8155 failure:
8156 if (!backtrack_pos)
d252fdde
PB
8157 {
8158 /* The parse routine should already have set inst.error, but set a
5f4273c7 8159 default here just in case. */
d252fdde 8160 if (!inst.error)
5ee91343 8161 inst.error = BAD_SYNTAX;
d252fdde
PB
8162 return FAIL;
8163 }
c19d1205
ZW
8164
8165 /* Do not backtrack over a trailing optional argument that
8166 absorbed some text. We will only fail again, with the
8167 'garbage following instruction' error message, which is
8168 probably less helpful than the current one. */
8169 if (backtrack_index == i && backtrack_pos != str
8170 && upat[i+1] == OP_stop)
d252fdde
PB
8171 {
8172 if (!inst.error)
5ee91343 8173 inst.error = BAD_SYNTAX;
d252fdde
PB
8174 return FAIL;
8175 }
c19d1205
ZW
8176
8177 /* Try again, skipping the optional argument at backtrack_pos. */
8178 str = backtrack_pos;
8179 inst.error = backtrack_error;
8180 inst.operands[backtrack_index].present = 0;
8181 i = backtrack_index;
8182 backtrack_pos = 0;
09d92015 8183 }
09d92015 8184
c19d1205
ZW
8185 /* Check that we have parsed all the arguments. */
8186 if (*str != '\0' && !inst.error)
8187 inst.error = _("garbage following instruction");
09d92015 8188
c19d1205 8189 return inst.error ? FAIL : SUCCESS;
09d92015
MM
8190}
8191
c19d1205
ZW
8192#undef po_char_or_fail
8193#undef po_reg_or_fail
8194#undef po_reg_or_goto
8195#undef po_imm_or_fail
5287ad62 8196#undef po_scalar_or_fail
52e7f43d 8197#undef po_barrier_or_imm
e07e6e58 8198
c19d1205 8199/* Shorthand macro for instruction encoding functions issuing errors. */
e07e6e58
NC
8200#define constraint(expr, err) \
8201 do \
c19d1205 8202 { \
e07e6e58
NC
8203 if (expr) \
8204 { \
8205 inst.error = err; \
8206 return; \
8207 } \
c19d1205 8208 } \
e07e6e58 8209 while (0)
c19d1205 8210
fdfde340
JM
8211/* Reject "bad registers" for Thumb-2 instructions. Many Thumb-2
8212 instructions are unpredictable if these registers are used. This
5c8ed6a4
JW
8213 is the BadReg predicate in ARM's Thumb-2 documentation.
8214
8215 Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few
8216 places, while the restriction on REG_SP was relaxed since ARMv8-A. */
8217#define reject_bad_reg(reg) \
8218 do \
8219 if (reg == REG_PC) \
8220 { \
8221 inst.error = BAD_PC; \
8222 return; \
8223 } \
8224 else if (reg == REG_SP \
8225 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) \
8226 { \
8227 inst.error = BAD_SP; \
8228 return; \
8229 } \
fdfde340
JM
8230 while (0)
8231
94206790
MM
8232/* If REG is R13 (the stack pointer), warn that its use is
8233 deprecated. */
8234#define warn_deprecated_sp(reg) \
8235 do \
8236 if (warn_on_deprecated && reg == REG_SP) \
5c3696f8 8237 as_tsktsk (_("use of r13 is deprecated")); \
94206790
MM
8238 while (0)
8239
c19d1205
ZW
8240/* Functions for operand encoding. ARM, then Thumb. */
8241
d840c081 8242#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31))
c19d1205 8243
9db2f6b4
RL
8244/* If the current inst is scalar ARMv8.2 fp16 instruction, do special encoding.
8245
8246 The only binary encoding difference is the Coprocessor number. Coprocessor
8247 9 is used for half-precision calculations or conversions. The format of the
2b0f3761 8248 instruction is the same as the equivalent Coprocessor 10 instruction that
9db2f6b4
RL
8249 exists for Single-Precision operation. */
8250
8251static void
8252do_scalar_fp16_v82_encode (void)
8253{
5ee91343 8254 if (inst.cond < COND_ALWAYS)
9db2f6b4
RL
8255 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
8256 " the behaviour is UNPREDICTABLE"));
8257 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
8258 _(BAD_FP16));
8259
8260 inst.instruction = (inst.instruction & 0xfffff0ff) | 0x900;
8261 mark_feature_used (&arm_ext_fp16);
8262}
8263
c19d1205
ZW
8264/* If VAL can be encoded in the immediate field of an ARM instruction,
8265 return the encoded form. Otherwise, return FAIL. */
8266
8267static unsigned int
8268encode_arm_immediate (unsigned int val)
09d92015 8269{
c19d1205
ZW
8270 unsigned int a, i;
8271
4f1d6205
L
8272 if (val <= 0xff)
8273 return val;
8274
8275 for (i = 2; i < 32; i += 2)
c19d1205
ZW
8276 if ((a = rotate_left (val, i)) <= 0xff)
8277 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
8278
8279 return FAIL;
09d92015
MM
8280}
8281
c19d1205
ZW
8282/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
8283 return the encoded form. Otherwise, return FAIL. */
8284static unsigned int
8285encode_thumb32_immediate (unsigned int val)
09d92015 8286{
c19d1205 8287 unsigned int a, i;
09d92015 8288
9c3c69f2 8289 if (val <= 0xff)
c19d1205 8290 return val;
a737bd4d 8291
9c3c69f2 8292 for (i = 1; i <= 24; i++)
09d92015 8293 {
9c3c69f2
PB
8294 a = val >> i;
8295 if ((val & ~(0xff << i)) == 0)
8296 return ((val >> i) & 0x7f) | ((32 - i) << 7);
09d92015 8297 }
a737bd4d 8298
c19d1205
ZW
8299 a = val & 0xff;
8300 if (val == ((a << 16) | a))
8301 return 0x100 | a;
8302 if (val == ((a << 24) | (a << 16) | (a << 8) | a))
8303 return 0x300 | a;
09d92015 8304
c19d1205
ZW
8305 a = val & 0xff00;
8306 if (val == ((a << 16) | a))
8307 return 0x200 | (a >> 8);
a737bd4d 8308
c19d1205 8309 return FAIL;
09d92015 8310}
5287ad62 8311/* Encode a VFP SP or DP register number into inst.instruction. */
09d92015
MM
8312
8313static void
5287ad62
JB
8314encode_arm_vfp_reg (int reg, enum vfp_reg_pos pos)
8315{
8316 if ((pos == VFP_REG_Dd || pos == VFP_REG_Dn || pos == VFP_REG_Dm)
8317 && reg > 15)
8318 {
b1cc4aeb 8319 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
8320 {
8321 if (thumb_mode)
8322 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
8323 fpu_vfp_ext_d32);
8324 else
8325 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
8326 fpu_vfp_ext_d32);
8327 }
5287ad62 8328 else
477330fc
RM
8329 {
8330 first_error (_("D register out of range for selected VFP version"));
8331 return;
8332 }
5287ad62
JB
8333 }
8334
c19d1205 8335 switch (pos)
09d92015 8336 {
c19d1205
ZW
8337 case VFP_REG_Sd:
8338 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8339 break;
8340
8341 case VFP_REG_Sn:
8342 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8343 break;
8344
8345 case VFP_REG_Sm:
8346 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8347 break;
8348
5287ad62
JB
8349 case VFP_REG_Dd:
8350 inst.instruction |= ((reg & 15) << 12) | ((reg >> 4) << 22);
8351 break;
5f4273c7 8352
5287ad62
JB
8353 case VFP_REG_Dn:
8354 inst.instruction |= ((reg & 15) << 16) | ((reg >> 4) << 7);
8355 break;
5f4273c7 8356
5287ad62
JB
8357 case VFP_REG_Dm:
8358 inst.instruction |= (reg & 15) | ((reg >> 4) << 5);
8359 break;
8360
c19d1205
ZW
8361 default:
8362 abort ();
09d92015 8363 }
09d92015
MM
8364}
8365
c19d1205 8366/* Encode a <shift> in an ARM-format instruction. The immediate,
55cf6793 8367 if any, is handled by md_apply_fix. */
09d92015 8368static void
c19d1205 8369encode_arm_shift (int i)
09d92015 8370{
008a97ef
RL
8371 /* register-shifted register. */
8372 if (inst.operands[i].immisreg)
8373 {
bf355b69
MR
8374 int op_index;
8375 for (op_index = 0; op_index <= i; ++op_index)
008a97ef 8376 {
5689c942
RL
8377 /* Check the operand only when it's presented. In pre-UAL syntax,
8378 if the destination register is the same as the first operand, two
8379 register form of the instruction can be used. */
bf355b69
MR
8380 if (inst.operands[op_index].present && inst.operands[op_index].isreg
8381 && inst.operands[op_index].reg == REG_PC)
008a97ef
RL
8382 as_warn (UNPRED_REG ("r15"));
8383 }
8384
8385 if (inst.operands[i].imm == REG_PC)
8386 as_warn (UNPRED_REG ("r15"));
8387 }
8388
c19d1205
ZW
8389 if (inst.operands[i].shift_kind == SHIFT_RRX)
8390 inst.instruction |= SHIFT_ROR << 5;
8391 else
09d92015 8392 {
c19d1205
ZW
8393 inst.instruction |= inst.operands[i].shift_kind << 5;
8394 if (inst.operands[i].immisreg)
8395 {
8396 inst.instruction |= SHIFT_BY_REG;
8397 inst.instruction |= inst.operands[i].imm << 8;
8398 }
8399 else
e2b0ab59 8400 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
09d92015 8401 }
c19d1205 8402}
09d92015 8403
c19d1205
ZW
8404static void
8405encode_arm_shifter_operand (int i)
8406{
8407 if (inst.operands[i].isreg)
09d92015 8408 {
c19d1205
ZW
8409 inst.instruction |= inst.operands[i].reg;
8410 encode_arm_shift (i);
09d92015 8411 }
c19d1205 8412 else
a415b1cd
JB
8413 {
8414 inst.instruction |= INST_IMMEDIATE;
e2b0ab59 8415 if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
a415b1cd
JB
8416 inst.instruction |= inst.operands[i].imm;
8417 }
09d92015
MM
8418}
8419
c19d1205 8420/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
09d92015 8421static void
c19d1205 8422encode_arm_addr_mode_common (int i, bfd_boolean is_t)
09d92015 8423{
2b2f5df9
NC
8424 /* PR 14260:
8425 Generate an error if the operand is not a register. */
8426 constraint (!inst.operands[i].isreg,
8427 _("Instruction does not support =N addresses"));
8428
c19d1205 8429 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 8430
c19d1205 8431 if (inst.operands[i].preind)
09d92015 8432 {
c19d1205
ZW
8433 if (is_t)
8434 {
8435 inst.error = _("instruction does not accept preindexed addressing");
8436 return;
8437 }
8438 inst.instruction |= PRE_INDEX;
8439 if (inst.operands[i].writeback)
8440 inst.instruction |= WRITE_BACK;
09d92015 8441
c19d1205
ZW
8442 }
8443 else if (inst.operands[i].postind)
8444 {
9c2799c2 8445 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
8446 if (is_t)
8447 inst.instruction |= WRITE_BACK;
8448 }
8449 else /* unindexed - only for coprocessor */
09d92015 8450 {
c19d1205 8451 inst.error = _("instruction does not accept unindexed addressing");
09d92015
MM
8452 return;
8453 }
8454
c19d1205
ZW
8455 if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
8456 && (((inst.instruction & 0x000f0000) >> 16)
8457 == ((inst.instruction & 0x0000f000) >> 12)))
8458 as_warn ((inst.instruction & LOAD_BIT)
8459 ? _("destination register same as write-back base")
8460 : _("source register same as write-back base"));
09d92015
MM
8461}
8462
c19d1205
ZW
8463/* inst.operands[i] was set up by parse_address. Encode it into an
8464 ARM-format mode 2 load or store instruction. If is_t is true,
8465 reject forms that cannot be used with a T instruction (i.e. not
8466 post-indexed). */
a737bd4d 8467static void
c19d1205 8468encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
09d92015 8469{
5be8be5d
DG
8470 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
8471
c19d1205 8472 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8473
c19d1205 8474 if (inst.operands[i].immisreg)
09d92015 8475 {
5be8be5d
DG
8476 constraint ((inst.operands[i].imm == REG_PC
8477 || (is_pc && inst.operands[i].writeback)),
8478 BAD_PC_ADDRESSING);
c19d1205
ZW
8479 inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
8480 inst.instruction |= inst.operands[i].imm;
8481 if (!inst.operands[i].negative)
8482 inst.instruction |= INDEX_UP;
8483 if (inst.operands[i].shifted)
8484 {
8485 if (inst.operands[i].shift_kind == SHIFT_RRX)
8486 inst.instruction |= SHIFT_ROR << 5;
8487 else
8488 {
8489 inst.instruction |= inst.operands[i].shift_kind << 5;
e2b0ab59 8490 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
c19d1205
ZW
8491 }
8492 }
09d92015 8493 }
e2b0ab59 8494 else /* immediate offset in inst.relocs[0] */
09d92015 8495 {
e2b0ab59 8496 if (is_pc && !inst.relocs[0].pc_rel)
5be8be5d
DG
8497 {
8498 const bfd_boolean is_load = ((inst.instruction & LOAD_BIT) != 0);
23a10334
JZ
8499
8500 /* If is_t is TRUE, it's called from do_ldstt. ldrt/strt
8501 cannot use PC in addressing.
8502 PC cannot be used in writeback addressing, either. */
8503 constraint ((is_t || inst.operands[i].writeback),
5be8be5d 8504 BAD_PC_ADDRESSING);
23a10334 8505
dc5ec521 8506 /* Use of PC in str is deprecated for ARMv7. */
23a10334
JZ
8507 if (warn_on_deprecated
8508 && !is_load
8509 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
5c3696f8 8510 as_tsktsk (_("use of PC in this instruction is deprecated"));
5be8be5d
DG
8511 }
8512
e2b0ab59 8513 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8514 {
8515 /* Prefer + for zero encoded value. */
8516 if (!inst.operands[i].negative)
8517 inst.instruction |= INDEX_UP;
e2b0ab59 8518 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
26d97720 8519 }
09d92015 8520 }
09d92015
MM
8521}
8522
c19d1205
ZW
8523/* inst.operands[i] was set up by parse_address. Encode it into an
8524 ARM-format mode 3 load or store instruction. Reject forms that
8525 cannot be used with such instructions. If is_t is true, reject
8526 forms that cannot be used with a T instruction (i.e. not
8527 post-indexed). */
8528static void
8529encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
09d92015 8530{
c19d1205 8531 if (inst.operands[i].immisreg && inst.operands[i].shifted)
09d92015 8532 {
c19d1205
ZW
8533 inst.error = _("instruction does not accept scaled register index");
8534 return;
09d92015 8535 }
a737bd4d 8536
c19d1205 8537 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8538
c19d1205
ZW
8539 if (inst.operands[i].immisreg)
8540 {
5be8be5d 8541 constraint ((inst.operands[i].imm == REG_PC
eb9f3f00 8542 || (is_t && inst.operands[i].reg == REG_PC)),
5be8be5d 8543 BAD_PC_ADDRESSING);
eb9f3f00
JB
8544 constraint (inst.operands[i].reg == REG_PC && inst.operands[i].writeback,
8545 BAD_PC_WRITEBACK);
c19d1205
ZW
8546 inst.instruction |= inst.operands[i].imm;
8547 if (!inst.operands[i].negative)
8548 inst.instruction |= INDEX_UP;
8549 }
e2b0ab59 8550 else /* immediate offset in inst.relocs[0] */
c19d1205 8551 {
e2b0ab59 8552 constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
5be8be5d
DG
8553 && inst.operands[i].writeback),
8554 BAD_PC_WRITEBACK);
c19d1205 8555 inst.instruction |= HWOFFSET_IMM;
e2b0ab59 8556 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8557 {
8558 /* Prefer + for zero encoded value. */
8559 if (!inst.operands[i].negative)
8560 inst.instruction |= INDEX_UP;
8561
e2b0ab59 8562 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
26d97720 8563 }
c19d1205 8564 }
a737bd4d
NC
8565}
8566
8335d6aa
JW
8567/* Write immediate bits [7:0] to the following locations:
8568
8569 |28/24|23 19|18 16|15 4|3 0|
8570 | 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|
8571
8572 This function is used by VMOV/VMVN/VORR/VBIC. */
8573
8574static void
8575neon_write_immbits (unsigned immbits)
8576{
8577 inst.instruction |= immbits & 0xf;
8578 inst.instruction |= ((immbits >> 4) & 0x7) << 16;
8579 inst.instruction |= ((immbits >> 7) & 0x1) << (thumb_mode ? 28 : 24);
8580}
8581
8582/* Invert low-order SIZE bits of XHI:XLO. */
8583
8584static void
8585neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
8586{
8587 unsigned immlo = xlo ? *xlo : 0;
8588 unsigned immhi = xhi ? *xhi : 0;
8589
8590 switch (size)
8591 {
8592 case 8:
8593 immlo = (~immlo) & 0xff;
8594 break;
8595
8596 case 16:
8597 immlo = (~immlo) & 0xffff;
8598 break;
8599
8600 case 64:
8601 immhi = (~immhi) & 0xffffffff;
8602 /* fall through. */
8603
8604 case 32:
8605 immlo = (~immlo) & 0xffffffff;
8606 break;
8607
8608 default:
8609 abort ();
8610 }
8611
8612 if (xlo)
8613 *xlo = immlo;
8614
8615 if (xhi)
8616 *xhi = immhi;
8617}
8618
8619/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
8620 A, B, C, D. */
09d92015 8621
c19d1205 8622static int
8335d6aa 8623neon_bits_same_in_bytes (unsigned imm)
09d92015 8624{
8335d6aa
JW
8625 return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
8626 && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
8627 && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
8628 && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
8629}
a737bd4d 8630
8335d6aa 8631/* For immediate of above form, return 0bABCD. */
09d92015 8632
8335d6aa
JW
8633static unsigned
8634neon_squash_bits (unsigned imm)
8635{
8636 return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
8637 | ((imm & 0x01000000) >> 21);
8638}
8639
8640/* Compress quarter-float representation to 0b...000 abcdefgh. */
8641
8642static unsigned
8643neon_qfloat_bits (unsigned imm)
8644{
8645 return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
8646}
8647
8648/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
8649 the instruction. *OP is passed as the initial value of the op field, and
8650 may be set to a different value depending on the constant (i.e.
8651 "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
8652 MVN). If the immediate looks like a repeated pattern then also
8653 try smaller element sizes. */
8654
8655static int
8656neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
8657 unsigned *immbits, int *op, int size,
8658 enum neon_el_type type)
8659{
8660 /* Only permit float immediates (including 0.0/-0.0) if the operand type is
8661 float. */
8662 if (type == NT_float && !float_p)
8663 return FAIL;
8664
8665 if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
09d92015 8666 {
8335d6aa
JW
8667 if (size != 32 || *op == 1)
8668 return FAIL;
8669 *immbits = neon_qfloat_bits (immlo);
8670 return 0xf;
8671 }
8672
8673 if (size == 64)
8674 {
8675 if (neon_bits_same_in_bytes (immhi)
8676 && neon_bits_same_in_bytes (immlo))
c19d1205 8677 {
8335d6aa
JW
8678 if (*op == 1)
8679 return FAIL;
8680 *immbits = (neon_squash_bits (immhi) << 4)
8681 | neon_squash_bits (immlo);
8682 *op = 1;
8683 return 0xe;
c19d1205 8684 }
a737bd4d 8685
8335d6aa
JW
8686 if (immhi != immlo)
8687 return FAIL;
8688 }
a737bd4d 8689
8335d6aa 8690 if (size >= 32)
09d92015 8691 {
8335d6aa 8692 if (immlo == (immlo & 0x000000ff))
c19d1205 8693 {
8335d6aa
JW
8694 *immbits = immlo;
8695 return 0x0;
c19d1205 8696 }
8335d6aa 8697 else if (immlo == (immlo & 0x0000ff00))
c19d1205 8698 {
8335d6aa
JW
8699 *immbits = immlo >> 8;
8700 return 0x2;
c19d1205 8701 }
8335d6aa
JW
8702 else if (immlo == (immlo & 0x00ff0000))
8703 {
8704 *immbits = immlo >> 16;
8705 return 0x4;
8706 }
8707 else if (immlo == (immlo & 0xff000000))
8708 {
8709 *immbits = immlo >> 24;
8710 return 0x6;
8711 }
8712 else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
8713 {
8714 *immbits = (immlo >> 8) & 0xff;
8715 return 0xc;
8716 }
8717 else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
8718 {
8719 *immbits = (immlo >> 16) & 0xff;
8720 return 0xd;
8721 }
8722
8723 if ((immlo & 0xffff) != (immlo >> 16))
8724 return FAIL;
8725 immlo &= 0xffff;
09d92015 8726 }
a737bd4d 8727
8335d6aa 8728 if (size >= 16)
4962c51a 8729 {
8335d6aa
JW
8730 if (immlo == (immlo & 0x000000ff))
8731 {
8732 *immbits = immlo;
8733 return 0x8;
8734 }
8735 else if (immlo == (immlo & 0x0000ff00))
8736 {
8737 *immbits = immlo >> 8;
8738 return 0xa;
8739 }
8740
8741 if ((immlo & 0xff) != (immlo >> 8))
8742 return FAIL;
8743 immlo &= 0xff;
4962c51a
MS
8744 }
8745
8335d6aa
JW
8746 if (immlo == (immlo & 0x000000ff))
8747 {
8748 /* Don't allow MVN with 8-bit immediate. */
8749 if (*op == 1)
8750 return FAIL;
8751 *immbits = immlo;
8752 return 0xe;
8753 }
26d97720 8754
8335d6aa 8755 return FAIL;
c19d1205 8756}
a737bd4d 8757
5fc177c8 8758#if defined BFD_HOST_64_BIT
ba592044
AM
8759/* Returns TRUE if double precision value V may be cast
8760 to single precision without loss of accuracy. */
8761
8762static bfd_boolean
5fc177c8 8763is_double_a_single (bfd_int64_t v)
ba592044 8764{
5fc177c8 8765 int exp = (int)((v >> 52) & 0x7FF);
8fe3f3d6 8766 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8767
8768 return (exp == 0 || exp == 0x7FF
8769 || (exp >= 1023 - 126 && exp <= 1023 + 127))
8770 && (mantissa & 0x1FFFFFFFl) == 0;
8771}
8772
3739860c 8773/* Returns a double precision value casted to single precision
ba592044
AM
8774 (ignoring the least significant bits in exponent and mantissa). */
8775
8776static int
5fc177c8 8777double_to_single (bfd_int64_t v)
ba592044
AM
8778{
8779 int sign = (int) ((v >> 63) & 1l);
5fc177c8 8780 int exp = (int) ((v >> 52) & 0x7FF);
8fe3f3d6 8781 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8782
8783 if (exp == 0x7FF)
8784 exp = 0xFF;
8785 else
8786 {
8787 exp = exp - 1023 + 127;
8788 if (exp >= 0xFF)
8789 {
8790 /* Infinity. */
8791 exp = 0x7F;
8792 mantissa = 0;
8793 }
8794 else if (exp < 0)
8795 {
8796 /* No denormalized numbers. */
8797 exp = 0;
8798 mantissa = 0;
8799 }
8800 }
8801 mantissa >>= 29;
8802 return (sign << 31) | (exp << 23) | mantissa;
8803}
5fc177c8 8804#endif /* BFD_HOST_64_BIT */
ba592044 8805
8335d6aa
JW
8806enum lit_type
8807{
8808 CONST_THUMB,
8809 CONST_ARM,
8810 CONST_VEC
8811};
8812
ba592044
AM
8813static void do_vfp_nsyn_opcode (const char *);
8814
e2b0ab59 8815/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
c19d1205
ZW
8816 Determine whether it can be performed with a move instruction; if
8817 it can, convert inst.instruction to that move instruction and
c921be7d
NC
8818 return TRUE; if it can't, convert inst.instruction to a literal-pool
8819 load and return FALSE. If this is not a valid thing to do in the
8820 current context, set inst.error and return TRUE.
a737bd4d 8821
c19d1205
ZW
8822 inst.operands[i] describes the destination register. */
8823
c921be7d 8824static bfd_boolean
8335d6aa 8825move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
c19d1205 8826{
53365c0d 8827 unsigned long tbit;
8335d6aa
JW
8828 bfd_boolean thumb_p = (t == CONST_THUMB);
8829 bfd_boolean arm_p = (t == CONST_ARM);
53365c0d
PB
8830
8831 if (thumb_p)
8832 tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
8833 else
8834 tbit = LOAD_BIT;
8835
8836 if ((inst.instruction & tbit) == 0)
09d92015 8837 {
c19d1205 8838 inst.error = _("invalid pseudo operation");
c921be7d 8839 return TRUE;
09d92015 8840 }
ba592044 8841
e2b0ab59
AV
8842 if (inst.relocs[0].exp.X_op != O_constant
8843 && inst.relocs[0].exp.X_op != O_symbol
8844 && inst.relocs[0].exp.X_op != O_big)
09d92015
MM
8845 {
8846 inst.error = _("constant expression expected");
c921be7d 8847 return TRUE;
09d92015 8848 }
ba592044 8849
e2b0ab59
AV
8850 if (inst.relocs[0].exp.X_op == O_constant
8851 || inst.relocs[0].exp.X_op == O_big)
8335d6aa 8852 {
5fc177c8
NC
8853#if defined BFD_HOST_64_BIT
8854 bfd_int64_t v;
8855#else
ba592044 8856 offsetT v;
5fc177c8 8857#endif
e2b0ab59 8858 if (inst.relocs[0].exp.X_op == O_big)
8335d6aa 8859 {
ba592044
AM
8860 LITTLENUM_TYPE w[X_PRECISION];
8861 LITTLENUM_TYPE * l;
8862
e2b0ab59 8863 if (inst.relocs[0].exp.X_add_number == -1)
8335d6aa 8864 {
ba592044
AM
8865 gen_to_words (w, X_PRECISION, E_PRECISION);
8866 l = w;
8867 /* FIXME: Should we check words w[2..5] ? */
8335d6aa 8868 }
ba592044
AM
8869 else
8870 l = generic_bignum;
3739860c 8871
5fc177c8
NC
8872#if defined BFD_HOST_64_BIT
8873 v =
8874 ((((((((bfd_int64_t) l[3] & LITTLENUM_MASK)
8875 << LITTLENUM_NUMBER_OF_BITS)
8876 | ((bfd_int64_t) l[2] & LITTLENUM_MASK))
8877 << LITTLENUM_NUMBER_OF_BITS)
8878 | ((bfd_int64_t) l[1] & LITTLENUM_MASK))
8879 << LITTLENUM_NUMBER_OF_BITS)
8880 | ((bfd_int64_t) l[0] & LITTLENUM_MASK));
8881#else
ba592044
AM
8882 v = ((l[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
8883 | (l[0] & LITTLENUM_MASK);
5fc177c8 8884#endif
8335d6aa 8885 }
ba592044 8886 else
e2b0ab59 8887 v = inst.relocs[0].exp.X_add_number;
ba592044
AM
8888
8889 if (!inst.operands[i].issingle)
8335d6aa 8890 {
12569877 8891 if (thumb_p)
8335d6aa 8892 {
53445554
TP
8893 /* LDR should not use lead in a flag-setting instruction being
8894 chosen so we do not check whether movs can be used. */
12569877 8895
53445554 8896 if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
ff8646ee 8897 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
53445554
TP
8898 && inst.operands[i].reg != 13
8899 && inst.operands[i].reg != 15)
12569877 8900 {
fc289b0a
TP
8901 /* Check if on thumb2 it can be done with a mov.w, mvn or
8902 movw instruction. */
12569877
AM
8903 unsigned int newimm;
8904 bfd_boolean isNegated;
8905
8906 newimm = encode_thumb32_immediate (v);
8907 if (newimm != (unsigned int) FAIL)
8908 isNegated = FALSE;
8909 else
8910 {
582cfe03 8911 newimm = encode_thumb32_immediate (~v);
12569877
AM
8912 if (newimm != (unsigned int) FAIL)
8913 isNegated = TRUE;
8914 }
8915
fc289b0a
TP
8916 /* The number can be loaded with a mov.w or mvn
8917 instruction. */
ff8646ee
TP
8918 if (newimm != (unsigned int) FAIL
8919 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
12569877 8920 {
fc289b0a 8921 inst.instruction = (0xf04f0000 /* MOV.W. */
582cfe03 8922 | (inst.operands[i].reg << 8));
fc289b0a 8923 /* Change to MOVN. */
582cfe03 8924 inst.instruction |= (isNegated ? 0x200000 : 0);
12569877
AM
8925 inst.instruction |= (newimm & 0x800) << 15;
8926 inst.instruction |= (newimm & 0x700) << 4;
8927 inst.instruction |= (newimm & 0x0ff);
8928 return TRUE;
8929 }
fc289b0a 8930 /* The number can be loaded with a movw instruction. */
ff8646ee
TP
8931 else if ((v & ~0xFFFF) == 0
8932 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
3739860c 8933 {
582cfe03 8934 int imm = v & 0xFFFF;
12569877 8935
582cfe03 8936 inst.instruction = 0xf2400000; /* MOVW. */
12569877
AM
8937 inst.instruction |= (inst.operands[i].reg << 8);
8938 inst.instruction |= (imm & 0xf000) << 4;
8939 inst.instruction |= (imm & 0x0800) << 15;
8940 inst.instruction |= (imm & 0x0700) << 4;
8941 inst.instruction |= (imm & 0x00ff);
8fe9a076
AV
8942 /* In case this replacement is being done on Armv8-M
8943 Baseline we need to make sure to disable the
8944 instruction size check, as otherwise GAS will reject
8945 the use of this T32 instruction. */
8946 inst.size_req = 0;
12569877
AM
8947 return TRUE;
8948 }
8949 }
8335d6aa 8950 }
12569877 8951 else if (arm_p)
ba592044
AM
8952 {
8953 int value = encode_arm_immediate (v);
12569877 8954
ba592044
AM
8955 if (value != FAIL)
8956 {
8957 /* This can be done with a mov instruction. */
8958 inst.instruction &= LITERAL_MASK;
8959 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
8960 inst.instruction |= value & 0xfff;
8961 return TRUE;
8962 }
8335d6aa 8963
ba592044
AM
8964 value = encode_arm_immediate (~ v);
8965 if (value != FAIL)
8966 {
8967 /* This can be done with a mvn instruction. */
8968 inst.instruction &= LITERAL_MASK;
8969 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
8970 inst.instruction |= value & 0xfff;
8971 return TRUE;
8972 }
8973 }
934c2632 8974 else if (t == CONST_VEC && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
8335d6aa 8975 {
ba592044
AM
8976 int op = 0;
8977 unsigned immbits = 0;
8978 unsigned immlo = inst.operands[1].imm;
8979 unsigned immhi = inst.operands[1].regisimm
8980 ? inst.operands[1].reg
e2b0ab59 8981 : inst.relocs[0].exp.X_unsigned
ba592044
AM
8982 ? 0
8983 : ((bfd_int64_t)((int) immlo)) >> 32;
8984 int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8985 &op, 64, NT_invtype);
8986
8987 if (cmode == FAIL)
8988 {
8989 neon_invert_size (&immlo, &immhi, 64);
8990 op = !op;
8991 cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8992 &op, 64, NT_invtype);
8993 }
8994
8995 if (cmode != FAIL)
8996 {
8997 inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
8998 | (1 << 23)
8999 | (cmode << 8)
9000 | (op << 5)
9001 | (1 << 4);
9002
9003 /* Fill other bits in vmov encoding for both thumb and arm. */
9004 if (thumb_mode)
eff0bc54 9005 inst.instruction |= (0x7U << 29) | (0xF << 24);
ba592044 9006 else
eff0bc54 9007 inst.instruction |= (0xFU << 28) | (0x1 << 25);
ba592044
AM
9008 neon_write_immbits (immbits);
9009 return TRUE;
9010 }
8335d6aa
JW
9011 }
9012 }
8335d6aa 9013
ba592044
AM
9014 if (t == CONST_VEC)
9015 {
9016 /* Check if vldr Rx, =constant could be optimized to vmov Rx, #constant. */
9017 if (inst.operands[i].issingle
9018 && is_quarter_float (inst.operands[1].imm)
9019 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3xd))
8335d6aa 9020 {
ba592044
AM
9021 inst.operands[1].imm =
9022 neon_qfloat_bits (v);
9023 do_vfp_nsyn_opcode ("fconsts");
9024 return TRUE;
8335d6aa 9025 }
5fc177c8
NC
9026
9027 /* If our host does not support a 64-bit type then we cannot perform
9028 the following optimization. This mean that there will be a
9029 discrepancy between the output produced by an assembler built for
9030 a 32-bit-only host and the output produced from a 64-bit host, but
9031 this cannot be helped. */
9032#if defined BFD_HOST_64_BIT
ba592044
AM
9033 else if (!inst.operands[1].issingle
9034 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
8335d6aa 9035 {
ba592044
AM
9036 if (is_double_a_single (v)
9037 && is_quarter_float (double_to_single (v)))
9038 {
9039 inst.operands[1].imm =
9040 neon_qfloat_bits (double_to_single (v));
9041 do_vfp_nsyn_opcode ("fconstd");
9042 return TRUE;
9043 }
8335d6aa 9044 }
5fc177c8 9045#endif
8335d6aa
JW
9046 }
9047 }
9048
9049 if (add_to_lit_pool ((!inst.operands[i].isvec
9050 || inst.operands[i].issingle) ? 4 : 8) == FAIL)
9051 return TRUE;
9052
9053 inst.operands[1].reg = REG_PC;
9054 inst.operands[1].isreg = 1;
9055 inst.operands[1].preind = 1;
e2b0ab59
AV
9056 inst.relocs[0].pc_rel = 1;
9057 inst.relocs[0].type = (thumb_p
8335d6aa
JW
9058 ? BFD_RELOC_ARM_THUMB_OFFSET
9059 : (mode_3
9060 ? BFD_RELOC_ARM_HWLITERAL
9061 : BFD_RELOC_ARM_LITERAL));
9062 return FALSE;
9063}
9064
9065/* inst.operands[i] was set up by parse_address. Encode it into an
9066 ARM-format instruction. Reject all forms which cannot be encoded
9067 into a coprocessor load/store instruction. If wb_ok is false,
9068 reject use of writeback; if unind_ok is false, reject use of
9069 unindexed addressing. If reloc_override is not 0, use it instead
9070 of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
9071 (in which case it is preserved). */
9072
9073static int
9074encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
9075{
9076 if (!inst.operands[i].isreg)
9077 {
99b2a2dd
NC
9078 /* PR 18256 */
9079 if (! inst.operands[0].isvec)
9080 {
9081 inst.error = _("invalid co-processor operand");
9082 return FAIL;
9083 }
8335d6aa
JW
9084 if (move_or_literal_pool (0, CONST_VEC, /*mode_3=*/FALSE))
9085 return SUCCESS;
9086 }
9087
9088 inst.instruction |= inst.operands[i].reg << 16;
9089
9090 gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
9091
9092 if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
9093 {
9094 gas_assert (!inst.operands[i].writeback);
9095 if (!unind_ok)
9096 {
9097 inst.error = _("instruction does not support unindexed addressing");
9098 return FAIL;
9099 }
9100 inst.instruction |= inst.operands[i].imm;
9101 inst.instruction |= INDEX_UP;
9102 return SUCCESS;
9103 }
9104
9105 if (inst.operands[i].preind)
9106 inst.instruction |= PRE_INDEX;
9107
9108 if (inst.operands[i].writeback)
09d92015 9109 {
8335d6aa 9110 if (inst.operands[i].reg == REG_PC)
c19d1205 9111 {
8335d6aa
JW
9112 inst.error = _("pc may not be used with write-back");
9113 return FAIL;
c19d1205 9114 }
8335d6aa 9115 if (!wb_ok)
c19d1205 9116 {
8335d6aa
JW
9117 inst.error = _("instruction does not support writeback");
9118 return FAIL;
c19d1205 9119 }
8335d6aa 9120 inst.instruction |= WRITE_BACK;
09d92015
MM
9121 }
9122
8335d6aa 9123 if (reloc_override)
e2b0ab59
AV
9124 inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
9125 else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
9126 || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
9127 && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
c19d1205 9128 {
8335d6aa 9129 if (thumb_mode)
e2b0ab59 9130 inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
8335d6aa 9131 else
e2b0ab59 9132 inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
c19d1205 9133 }
8335d6aa
JW
9134
9135 /* Prefer + for zero encoded value. */
9136 if (!inst.operands[i].negative)
9137 inst.instruction |= INDEX_UP;
9138
9139 return SUCCESS;
09d92015
MM
9140}
9141
5f4273c7 9142/* Functions for instruction encoding, sorted by sub-architecture.
c19d1205
ZW
9143 First some generics; their names are taken from the conventional
9144 bit positions for register arguments in ARM format instructions. */
09d92015 9145
a737bd4d 9146static void
c19d1205 9147do_noargs (void)
09d92015 9148{
c19d1205 9149}
a737bd4d 9150
c19d1205
ZW
9151static void
9152do_rd (void)
9153{
9154 inst.instruction |= inst.operands[0].reg << 12;
9155}
a737bd4d 9156
16a1fa25
TP
9157static void
9158do_rn (void)
9159{
9160 inst.instruction |= inst.operands[0].reg << 16;
9161}
9162
c19d1205
ZW
9163static void
9164do_rd_rm (void)
9165{
9166 inst.instruction |= inst.operands[0].reg << 12;
9167 inst.instruction |= inst.operands[1].reg;
9168}
09d92015 9169
9eb6c0f1
MGD
9170static void
9171do_rm_rn (void)
9172{
9173 inst.instruction |= inst.operands[0].reg;
9174 inst.instruction |= inst.operands[1].reg << 16;
9175}
9176
c19d1205
ZW
9177static void
9178do_rd_rn (void)
9179{
9180 inst.instruction |= inst.operands[0].reg << 12;
9181 inst.instruction |= inst.operands[1].reg << 16;
9182}
a737bd4d 9183
c19d1205
ZW
9184static void
9185do_rn_rd (void)
9186{
9187 inst.instruction |= inst.operands[0].reg << 16;
9188 inst.instruction |= inst.operands[1].reg << 12;
9189}
09d92015 9190
4ed7ed8d
TP
9191static void
9192do_tt (void)
9193{
9194 inst.instruction |= inst.operands[0].reg << 8;
9195 inst.instruction |= inst.operands[1].reg << 16;
9196}
9197
59d09be6
MGD
9198static bfd_boolean
9199check_obsolete (const arm_feature_set *feature, const char *msg)
9200{
9201 if (ARM_CPU_IS_ANY (cpu_variant))
9202 {
5c3696f8 9203 as_tsktsk ("%s", msg);
59d09be6
MGD
9204 return TRUE;
9205 }
9206 else if (ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
9207 {
9208 as_bad ("%s", msg);
9209 return TRUE;
9210 }
9211
9212 return FALSE;
9213}
9214
c19d1205
ZW
9215static void
9216do_rd_rm_rn (void)
9217{
9a64e435 9218 unsigned Rn = inst.operands[2].reg;
708587a4 9219 /* Enforce restrictions on SWP instruction. */
9a64e435 9220 if ((inst.instruction & 0x0fbfffff) == 0x01000090)
56adecf4
DG
9221 {
9222 constraint (Rn == inst.operands[0].reg || Rn == inst.operands[1].reg,
9223 _("Rn must not overlap other operands"));
9224
59d09be6
MGD
9225 /* SWP{b} is obsolete for ARMv8-A, and deprecated for ARMv6* and ARMv7.
9226 */
9227 if (!check_obsolete (&arm_ext_v8,
9228 _("swp{b} use is obsoleted for ARMv8 and later"))
9229 && warn_on_deprecated
9230 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6))
5c3696f8 9231 as_tsktsk (_("swp{b} use is deprecated for ARMv6 and ARMv7"));
56adecf4 9232 }
59d09be6 9233
c19d1205
ZW
9234 inst.instruction |= inst.operands[0].reg << 12;
9235 inst.instruction |= inst.operands[1].reg;
9a64e435 9236 inst.instruction |= Rn << 16;
c19d1205 9237}
09d92015 9238
c19d1205
ZW
9239static void
9240do_rd_rn_rm (void)
9241{
9242 inst.instruction |= inst.operands[0].reg << 12;
9243 inst.instruction |= inst.operands[1].reg << 16;
9244 inst.instruction |= inst.operands[2].reg;
9245}
a737bd4d 9246
c19d1205
ZW
9247static void
9248do_rm_rd_rn (void)
9249{
5be8be5d 9250 constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
e2b0ab59
AV
9251 constraint (((inst.relocs[0].exp.X_op != O_constant
9252 && inst.relocs[0].exp.X_op != O_illegal)
9253 || inst.relocs[0].exp.X_add_number != 0),
5be8be5d 9254 BAD_ADDR_MODE);
c19d1205
ZW
9255 inst.instruction |= inst.operands[0].reg;
9256 inst.instruction |= inst.operands[1].reg << 12;
9257 inst.instruction |= inst.operands[2].reg << 16;
9258}
09d92015 9259
c19d1205
ZW
9260static void
9261do_imm0 (void)
9262{
9263 inst.instruction |= inst.operands[0].imm;
9264}
09d92015 9265
c19d1205
ZW
9266static void
9267do_rd_cpaddr (void)
9268{
9269 inst.instruction |= inst.operands[0].reg << 12;
9270 encode_arm_cp_address (1, TRUE, TRUE, 0);
09d92015 9271}
a737bd4d 9272
c19d1205
ZW
9273/* ARM instructions, in alphabetical order by function name (except
9274 that wrapper functions appear immediately after the function they
9275 wrap). */
09d92015 9276
c19d1205
ZW
9277/* This is a pseudo-op of the form "adr rd, label" to be converted
9278 into a relative address of the form "add rd, pc, #label-.-8". */
09d92015
MM
9279
9280static void
c19d1205 9281do_adr (void)
09d92015 9282{
c19d1205 9283 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9284
c19d1205
ZW
9285 /* Frag hacking will turn this into a sub instruction if the offset turns
9286 out to be negative. */
e2b0ab59
AV
9287 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9288 inst.relocs[0].pc_rel = 1;
9289 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9290
fc6141f0 9291 if (support_interwork
e2b0ab59
AV
9292 && inst.relocs[0].exp.X_op == O_symbol
9293 && inst.relocs[0].exp.X_add_symbol != NULL
9294 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9295 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9296 inst.relocs[0].exp.X_add_number |= 1;
c19d1205 9297}
b99bd4ef 9298
c19d1205
ZW
9299/* This is a pseudo-op of the form "adrl rd, label" to be converted
9300 into a relative address of the form:
9301 add rd, pc, #low(label-.-8)"
9302 add rd, rd, #high(label-.-8)" */
b99bd4ef 9303
c19d1205
ZW
9304static void
9305do_adrl (void)
9306{
9307 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9308
c19d1205
ZW
9309 /* Frag hacking will turn this into a sub instruction if the offset turns
9310 out to be negative. */
e2b0ab59
AV
9311 inst.relocs[0].type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
9312 inst.relocs[0].pc_rel = 1;
c19d1205 9313 inst.size = INSN_SIZE * 2;
e2b0ab59 9314 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9315
fc6141f0 9316 if (support_interwork
e2b0ab59
AV
9317 && inst.relocs[0].exp.X_op == O_symbol
9318 && inst.relocs[0].exp.X_add_symbol != NULL
9319 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9320 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9321 inst.relocs[0].exp.X_add_number |= 1;
b99bd4ef
NC
9322}
9323
b99bd4ef 9324static void
c19d1205 9325do_arit (void)
b99bd4ef 9326{
e2b0ab59
AV
9327 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9328 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9329 THUMB1_RELOC_ONLY);
c19d1205
ZW
9330 if (!inst.operands[1].present)
9331 inst.operands[1].reg = inst.operands[0].reg;
9332 inst.instruction |= inst.operands[0].reg << 12;
9333 inst.instruction |= inst.operands[1].reg << 16;
9334 encode_arm_shifter_operand (2);
9335}
b99bd4ef 9336
62b3e311
PB
9337static void
9338do_barrier (void)
9339{
9340 if (inst.operands[0].present)
ccb84d65 9341 inst.instruction |= inst.operands[0].imm;
62b3e311
PB
9342 else
9343 inst.instruction |= 0xf;
9344}
9345
c19d1205
ZW
9346static void
9347do_bfc (void)
9348{
9349 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
9350 constraint (msb > 32, _("bit-field extends past end of register"));
9351 /* The instruction encoding stores the LSB and MSB,
9352 not the LSB and width. */
9353 inst.instruction |= inst.operands[0].reg << 12;
9354 inst.instruction |= inst.operands[1].imm << 7;
9355 inst.instruction |= (msb - 1) << 16;
9356}
b99bd4ef 9357
c19d1205
ZW
9358static void
9359do_bfi (void)
9360{
9361 unsigned int msb;
b99bd4ef 9362
c19d1205
ZW
9363 /* #0 in second position is alternative syntax for bfc, which is
9364 the same instruction but with REG_PC in the Rm field. */
9365 if (!inst.operands[1].isreg)
9366 inst.operands[1].reg = REG_PC;
b99bd4ef 9367
c19d1205
ZW
9368 msb = inst.operands[2].imm + inst.operands[3].imm;
9369 constraint (msb > 32, _("bit-field extends past end of register"));
9370 /* The instruction encoding stores the LSB and MSB,
9371 not the LSB and width. */
9372 inst.instruction |= inst.operands[0].reg << 12;
9373 inst.instruction |= inst.operands[1].reg;
9374 inst.instruction |= inst.operands[2].imm << 7;
9375 inst.instruction |= (msb - 1) << 16;
b99bd4ef
NC
9376}
9377
b99bd4ef 9378static void
c19d1205 9379do_bfx (void)
b99bd4ef 9380{
c19d1205
ZW
9381 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
9382 _("bit-field extends past end of register"));
9383 inst.instruction |= inst.operands[0].reg << 12;
9384 inst.instruction |= inst.operands[1].reg;
9385 inst.instruction |= inst.operands[2].imm << 7;
9386 inst.instruction |= (inst.operands[3].imm - 1) << 16;
9387}
09d92015 9388
c19d1205
ZW
9389/* ARM V5 breakpoint instruction (argument parse)
9390 BKPT <16 bit unsigned immediate>
9391 Instruction is not conditional.
9392 The bit pattern given in insns[] has the COND_ALWAYS condition,
9393 and it is an error if the caller tried to override that. */
b99bd4ef 9394
c19d1205
ZW
9395static void
9396do_bkpt (void)
9397{
9398 /* Top 12 of 16 bits to bits 19:8. */
9399 inst.instruction |= (inst.operands[0].imm & 0xfff0) << 4;
09d92015 9400
c19d1205
ZW
9401 /* Bottom 4 of 16 bits to bits 3:0. */
9402 inst.instruction |= inst.operands[0].imm & 0xf;
9403}
09d92015 9404
c19d1205
ZW
9405static void
9406encode_branch (int default_reloc)
9407{
9408 if (inst.operands[0].hasreloc)
9409 {
0855e32b
NS
9410 constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
9411 && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
9412 _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
e2b0ab59 9413 inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
0855e32b
NS
9414 ? BFD_RELOC_ARM_PLT32
9415 : thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
c19d1205 9416 }
b99bd4ef 9417 else
e2b0ab59
AV
9418 inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
9419 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
9420}
9421
b99bd4ef 9422static void
c19d1205 9423do_branch (void)
b99bd4ef 9424{
39b41c9c
PB
9425#ifdef OBJ_ELF
9426 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9427 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9428 else
9429#endif
9430 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
9431}
9432
9433static void
9434do_bl (void)
9435{
9436#ifdef OBJ_ELF
9437 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9438 {
9439 if (inst.cond == COND_ALWAYS)
9440 encode_branch (BFD_RELOC_ARM_PCREL_CALL);
9441 else
9442 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9443 }
9444 else
9445#endif
9446 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
c19d1205 9447}
b99bd4ef 9448
c19d1205
ZW
9449/* ARM V5 branch-link-exchange instruction (argument parse)
9450 BLX <target_addr> ie BLX(1)
9451 BLX{<condition>} <Rm> ie BLX(2)
9452 Unfortunately, there are two different opcodes for this mnemonic.
9453 So, the insns[].value is not used, and the code here zaps values
9454 into inst.instruction.
9455 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
b99bd4ef 9456
c19d1205
ZW
9457static void
9458do_blx (void)
9459{
9460 if (inst.operands[0].isreg)
b99bd4ef 9461 {
c19d1205
ZW
9462 /* Arg is a register; the opcode provided by insns[] is correct.
9463 It is not illegal to do "blx pc", just useless. */
9464 if (inst.operands[0].reg == REG_PC)
9465 as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
b99bd4ef 9466
c19d1205
ZW
9467 inst.instruction |= inst.operands[0].reg;
9468 }
9469 else
b99bd4ef 9470 {
c19d1205 9471 /* Arg is an address; this instruction cannot be executed
267bf995
RR
9472 conditionally, and the opcode must be adjusted.
9473 We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
9474 where we generate out a BFD_RELOC_ARM_PCREL_CALL instead. */
c19d1205 9475 constraint (inst.cond != COND_ALWAYS, BAD_COND);
2fc8bdac 9476 inst.instruction = 0xfa000000;
267bf995 9477 encode_branch (BFD_RELOC_ARM_PCREL_BLX);
b99bd4ef 9478 }
c19d1205
ZW
9479}
9480
9481static void
9482do_bx (void)
9483{
845b51d6
PB
9484 bfd_boolean want_reloc;
9485
c19d1205
ZW
9486 if (inst.operands[0].reg == REG_PC)
9487 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
b99bd4ef 9488
c19d1205 9489 inst.instruction |= inst.operands[0].reg;
845b51d6
PB
9490 /* Output R_ARM_V4BX relocations if is an EABI object that looks like
9491 it is for ARMv4t or earlier. */
9492 want_reloc = !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5);
4d354d8b
TP
9493 if (!ARM_FEATURE_ZERO (selected_object_arch)
9494 && !ARM_CPU_HAS_FEATURE (selected_object_arch, arm_ext_v5))
845b51d6
PB
9495 want_reloc = TRUE;
9496
5ad34203 9497#ifdef OBJ_ELF
845b51d6 9498 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
5ad34203 9499#endif
584206db 9500 want_reloc = FALSE;
845b51d6
PB
9501
9502 if (want_reloc)
e2b0ab59 9503 inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
09d92015
MM
9504}
9505
c19d1205
ZW
9506
9507/* ARM v5TEJ. Jump to Jazelle code. */
a737bd4d
NC
9508
9509static void
c19d1205 9510do_bxj (void)
a737bd4d 9511{
c19d1205
ZW
9512 if (inst.operands[0].reg == REG_PC)
9513 as_tsktsk (_("use of r15 in bxj is not really useful"));
9514
9515 inst.instruction |= inst.operands[0].reg;
a737bd4d
NC
9516}
9517
c19d1205
ZW
9518/* Co-processor data operation:
9519 CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
9520 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>} */
9521static void
9522do_cdp (void)
9523{
9524 inst.instruction |= inst.operands[0].reg << 8;
9525 inst.instruction |= inst.operands[1].imm << 20;
9526 inst.instruction |= inst.operands[2].reg << 12;
9527 inst.instruction |= inst.operands[3].reg << 16;
9528 inst.instruction |= inst.operands[4].reg;
9529 inst.instruction |= inst.operands[5].imm << 5;
9530}
a737bd4d
NC
9531
9532static void
c19d1205 9533do_cmp (void)
a737bd4d 9534{
c19d1205
ZW
9535 inst.instruction |= inst.operands[0].reg << 16;
9536 encode_arm_shifter_operand (1);
a737bd4d
NC
9537}
9538
c19d1205
ZW
9539/* Transfer between coprocessor and ARM registers.
9540 MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
9541 MRC2
9542 MCR{cond}
9543 MCR2
9544
9545 No special properties. */
09d92015 9546
dcbd0d71
MGD
9547struct deprecated_coproc_regs_s
9548{
9549 unsigned cp;
9550 int opc1;
9551 unsigned crn;
9552 unsigned crm;
9553 int opc2;
9554 arm_feature_set deprecated;
9555 arm_feature_set obsoleted;
9556 const char *dep_msg;
9557 const char *obs_msg;
9558};
9559
9560#define DEPR_ACCESS_V8 \
9561 N_("This coprocessor register access is deprecated in ARMv8")
9562
9563/* Table of all deprecated coprocessor registers. */
9564static struct deprecated_coproc_regs_s deprecated_coproc_regs[] =
9565{
9566 {15, 0, 7, 10, 5, /* CP15DMB. */
823d2571 9567 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9568 DEPR_ACCESS_V8, NULL},
9569 {15, 0, 7, 10, 4, /* CP15DSB. */
823d2571 9570 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9571 DEPR_ACCESS_V8, NULL},
9572 {15, 0, 7, 5, 4, /* CP15ISB. */
823d2571 9573 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9574 DEPR_ACCESS_V8, NULL},
9575 {14, 6, 1, 0, 0, /* TEEHBR. */
823d2571 9576 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9577 DEPR_ACCESS_V8, NULL},
9578 {14, 6, 0, 0, 0, /* TEECR. */
823d2571 9579 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9580 DEPR_ACCESS_V8, NULL},
9581};
9582
9583#undef DEPR_ACCESS_V8
9584
9585static const size_t deprecated_coproc_reg_count =
9586 sizeof (deprecated_coproc_regs) / sizeof (deprecated_coproc_regs[0]);
9587
09d92015 9588static void
c19d1205 9589do_co_reg (void)
09d92015 9590{
fdfde340 9591 unsigned Rd;
dcbd0d71 9592 size_t i;
fdfde340
JM
9593
9594 Rd = inst.operands[2].reg;
9595 if (thumb_mode)
9596 {
9597 if (inst.instruction == 0xee000010
9598 || inst.instruction == 0xfe000010)
9599 /* MCR, MCR2 */
9600 reject_bad_reg (Rd);
5c8ed6a4 9601 else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
fdfde340
JM
9602 /* MRC, MRC2 */
9603 constraint (Rd == REG_SP, BAD_SP);
9604 }
9605 else
9606 {
9607 /* MCR */
9608 if (inst.instruction == 0xe000010)
9609 constraint (Rd == REG_PC, BAD_PC);
9610 }
9611
dcbd0d71
MGD
9612 for (i = 0; i < deprecated_coproc_reg_count; ++i)
9613 {
9614 const struct deprecated_coproc_regs_s *r =
9615 deprecated_coproc_regs + i;
9616
9617 if (inst.operands[0].reg == r->cp
9618 && inst.operands[1].imm == r->opc1
9619 && inst.operands[3].reg == r->crn
9620 && inst.operands[4].reg == r->crm
9621 && inst.operands[5].imm == r->opc2)
9622 {
b10bf8c5 9623 if (! ARM_CPU_IS_ANY (cpu_variant)
477330fc 9624 && warn_on_deprecated
dcbd0d71 9625 && ARM_CPU_HAS_FEATURE (cpu_variant, r->deprecated))
5c3696f8 9626 as_tsktsk ("%s", r->dep_msg);
dcbd0d71
MGD
9627 }
9628 }
fdfde340 9629
c19d1205
ZW
9630 inst.instruction |= inst.operands[0].reg << 8;
9631 inst.instruction |= inst.operands[1].imm << 21;
fdfde340 9632 inst.instruction |= Rd << 12;
c19d1205
ZW
9633 inst.instruction |= inst.operands[3].reg << 16;
9634 inst.instruction |= inst.operands[4].reg;
9635 inst.instruction |= inst.operands[5].imm << 5;
9636}
09d92015 9637
c19d1205
ZW
9638/* Transfer between coprocessor register and pair of ARM registers.
9639 MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
9640 MCRR2
9641 MRRC{cond}
9642 MRRC2
b99bd4ef 9643
c19d1205 9644 Two XScale instructions are special cases of these:
09d92015 9645
c19d1205
ZW
9646 MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
9647 MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
b99bd4ef 9648
5f4273c7 9649 Result unpredictable if Rd or Rn is R15. */
a737bd4d 9650
c19d1205
ZW
9651static void
9652do_co_reg2c (void)
9653{
fdfde340
JM
9654 unsigned Rd, Rn;
9655
9656 Rd = inst.operands[2].reg;
9657 Rn = inst.operands[3].reg;
9658
9659 if (thumb_mode)
9660 {
9661 reject_bad_reg (Rd);
9662 reject_bad_reg (Rn);
9663 }
9664 else
9665 {
9666 constraint (Rd == REG_PC, BAD_PC);
9667 constraint (Rn == REG_PC, BAD_PC);
9668 }
9669
873f10f0
TC
9670 /* Only check the MRRC{2} variants. */
9671 if ((inst.instruction & 0x0FF00000) == 0x0C500000)
9672 {
9673 /* If Rd == Rn, error that the operation is
9674 unpredictable (example MRRC p3,#1,r1,r1,c4). */
9675 constraint (Rd == Rn, BAD_OVERLAP);
9676 }
9677
c19d1205
ZW
9678 inst.instruction |= inst.operands[0].reg << 8;
9679 inst.instruction |= inst.operands[1].imm << 4;
fdfde340
JM
9680 inst.instruction |= Rd << 12;
9681 inst.instruction |= Rn << 16;
c19d1205 9682 inst.instruction |= inst.operands[4].reg;
b99bd4ef
NC
9683}
9684
c19d1205
ZW
9685static void
9686do_cpsi (void)
9687{
9688 inst.instruction |= inst.operands[0].imm << 6;
a028a6f5
PB
9689 if (inst.operands[1].present)
9690 {
9691 inst.instruction |= CPSI_MMOD;
9692 inst.instruction |= inst.operands[1].imm;
9693 }
c19d1205 9694}
b99bd4ef 9695
62b3e311
PB
9696static void
9697do_dbg (void)
9698{
9699 inst.instruction |= inst.operands[0].imm;
9700}
9701
eea54501
MGD
9702static void
9703do_div (void)
9704{
9705 unsigned Rd, Rn, Rm;
9706
9707 Rd = inst.operands[0].reg;
9708 Rn = (inst.operands[1].present
9709 ? inst.operands[1].reg : Rd);
9710 Rm = inst.operands[2].reg;
9711
9712 constraint ((Rd == REG_PC), BAD_PC);
9713 constraint ((Rn == REG_PC), BAD_PC);
9714 constraint ((Rm == REG_PC), BAD_PC);
9715
9716 inst.instruction |= Rd << 16;
9717 inst.instruction |= Rn << 0;
9718 inst.instruction |= Rm << 8;
9719}
9720
b99bd4ef 9721static void
c19d1205 9722do_it (void)
b99bd4ef 9723{
c19d1205 9724 /* There is no IT instruction in ARM mode. We
e07e6e58
NC
9725 process it to do the validation as if in
9726 thumb mode, just in case the code gets
9727 assembled for thumb using the unified syntax. */
9728
c19d1205 9729 inst.size = 0;
e07e6e58
NC
9730 if (unified_syntax)
9731 {
5ee91343
AV
9732 set_pred_insn_type (IT_INSN);
9733 now_pred.mask = (inst.instruction & 0xf) | 0x10;
9734 now_pred.cc = inst.operands[0].imm;
e07e6e58 9735 }
09d92015 9736}
b99bd4ef 9737
6530b175
NC
9738/* If there is only one register in the register list,
9739 then return its register number. Otherwise return -1. */
9740static int
9741only_one_reg_in_list (int range)
9742{
9743 int i = ffs (range) - 1;
9744 return (i > 15 || range != (1 << i)) ? -1 : i;
9745}
9746
09d92015 9747static void
6530b175 9748encode_ldmstm(int from_push_pop_mnem)
ea6ef066 9749{
c19d1205
ZW
9750 int base_reg = inst.operands[0].reg;
9751 int range = inst.operands[1].imm;
6530b175 9752 int one_reg;
ea6ef066 9753
c19d1205
ZW
9754 inst.instruction |= base_reg << 16;
9755 inst.instruction |= range;
ea6ef066 9756
c19d1205
ZW
9757 if (inst.operands[1].writeback)
9758 inst.instruction |= LDM_TYPE_2_OR_3;
09d92015 9759
c19d1205 9760 if (inst.operands[0].writeback)
ea6ef066 9761 {
c19d1205
ZW
9762 inst.instruction |= WRITE_BACK;
9763 /* Check for unpredictable uses of writeback. */
9764 if (inst.instruction & LOAD_BIT)
09d92015 9765 {
c19d1205
ZW
9766 /* Not allowed in LDM type 2. */
9767 if ((inst.instruction & LDM_TYPE_2_OR_3)
9768 && ((range & (1 << REG_PC)) == 0))
9769 as_warn (_("writeback of base register is UNPREDICTABLE"));
9770 /* Only allowed if base reg not in list for other types. */
9771 else if (range & (1 << base_reg))
9772 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
9773 }
9774 else /* STM. */
9775 {
9776 /* Not allowed for type 2. */
9777 if (inst.instruction & LDM_TYPE_2_OR_3)
9778 as_warn (_("writeback of base register is UNPREDICTABLE"));
9779 /* Only allowed if base reg not in list, or first in list. */
9780 else if ((range & (1 << base_reg))
9781 && (range & ((1 << base_reg) - 1)))
9782 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
09d92015 9783 }
ea6ef066 9784 }
6530b175
NC
9785
9786 /* If PUSH/POP has only one register, then use the A2 encoding. */
9787 one_reg = only_one_reg_in_list (range);
9788 if (from_push_pop_mnem && one_reg >= 0)
9789 {
9790 int is_push = (inst.instruction & A_PUSH_POP_OP_MASK) == A1_OPCODE_PUSH;
9791
4f588891
NC
9792 if (is_push && one_reg == 13 /* SP */)
9793 /* PR 22483: The A2 encoding cannot be used when
9794 pushing the stack pointer as this is UNPREDICTABLE. */
9795 return;
9796
6530b175
NC
9797 inst.instruction &= A_COND_MASK;
9798 inst.instruction |= is_push ? A2_OPCODE_PUSH : A2_OPCODE_POP;
9799 inst.instruction |= one_reg << 12;
9800 }
9801}
9802
9803static void
9804do_ldmstm (void)
9805{
9806 encode_ldmstm (/*from_push_pop_mnem=*/FALSE);
a737bd4d
NC
9807}
9808
c19d1205
ZW
9809/* ARMv5TE load-consecutive (argument parse)
9810 Mode is like LDRH.
9811
9812 LDRccD R, mode
9813 STRccD R, mode. */
9814
a737bd4d 9815static void
c19d1205 9816do_ldrd (void)
a737bd4d 9817{
c19d1205 9818 constraint (inst.operands[0].reg % 2 != 0,
c56791bb 9819 _("first transfer register must be even"));
c19d1205
ZW
9820 constraint (inst.operands[1].present
9821 && inst.operands[1].reg != inst.operands[0].reg + 1,
c56791bb 9822 _("can only transfer two consecutive registers"));
c19d1205
ZW
9823 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
9824 constraint (!inst.operands[2].isreg, _("'[' expected"));
a737bd4d 9825
c19d1205
ZW
9826 if (!inst.operands[1].present)
9827 inst.operands[1].reg = inst.operands[0].reg + 1;
5f4273c7 9828
c56791bb
RE
9829 /* encode_arm_addr_mode_3 will diagnose overlap between the base
9830 register and the first register written; we have to diagnose
9831 overlap between the base and the second register written here. */
ea6ef066 9832
c56791bb
RE
9833 if (inst.operands[2].reg == inst.operands[1].reg
9834 && (inst.operands[2].writeback || inst.operands[2].postind))
9835 as_warn (_("base register written back, and overlaps "
9836 "second transfer register"));
b05fe5cf 9837
c56791bb
RE
9838 if (!(inst.instruction & V4_STR_BIT))
9839 {
c19d1205 9840 /* For an index-register load, the index register must not overlap the
c56791bb
RE
9841 destination (even if not write-back). */
9842 if (inst.operands[2].immisreg
9843 && ((unsigned) inst.operands[2].imm == inst.operands[0].reg
9844 || (unsigned) inst.operands[2].imm == inst.operands[1].reg))
9845 as_warn (_("index register overlaps transfer register"));
b05fe5cf 9846 }
c19d1205
ZW
9847 inst.instruction |= inst.operands[0].reg << 12;
9848 encode_arm_addr_mode_3 (2, /*is_t=*/FALSE);
b05fe5cf
ZW
9849}
9850
9851static void
c19d1205 9852do_ldrex (void)
b05fe5cf 9853{
c19d1205
ZW
9854 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
9855 || inst.operands[1].postind || inst.operands[1].writeback
9856 || inst.operands[1].immisreg || inst.operands[1].shifted
01cfc07f
NC
9857 || inst.operands[1].negative
9858 /* This can arise if the programmer has written
9859 strex rN, rM, foo
9860 or if they have mistakenly used a register name as the last
9861 operand, eg:
9862 strex rN, rM, rX
9863 It is very difficult to distinguish between these two cases
9864 because "rX" might actually be a label. ie the register
9865 name has been occluded by a symbol of the same name. So we
9866 just generate a general 'bad addressing mode' type error
9867 message and leave it up to the programmer to discover the
9868 true cause and fix their mistake. */
9869 || (inst.operands[1].reg == REG_PC),
9870 BAD_ADDR_MODE);
b05fe5cf 9871
e2b0ab59
AV
9872 constraint (inst.relocs[0].exp.X_op != O_constant
9873 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9874 _("offset must be zero in ARM encoding"));
b05fe5cf 9875
5be8be5d
DG
9876 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
9877
c19d1205
ZW
9878 inst.instruction |= inst.operands[0].reg << 12;
9879 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 9880 inst.relocs[0].type = BFD_RELOC_UNUSED;
b05fe5cf
ZW
9881}
9882
9883static void
c19d1205 9884do_ldrexd (void)
b05fe5cf 9885{
c19d1205
ZW
9886 constraint (inst.operands[0].reg % 2 != 0,
9887 _("even register required"));
9888 constraint (inst.operands[1].present
9889 && inst.operands[1].reg != inst.operands[0].reg + 1,
9890 _("can only load two consecutive registers"));
9891 /* If op 1 were present and equal to PC, this function wouldn't
9892 have been called in the first place. */
9893 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
b05fe5cf 9894
c19d1205
ZW
9895 inst.instruction |= inst.operands[0].reg << 12;
9896 inst.instruction |= inst.operands[2].reg << 16;
b05fe5cf
ZW
9897}
9898
1be5fd2e
NC
9899/* In both ARM and thumb state 'ldr pc, #imm' with an immediate
9900 which is not a multiple of four is UNPREDICTABLE. */
9901static void
9902check_ldr_r15_aligned (void)
9903{
9904 constraint (!(inst.operands[1].immisreg)
9905 && (inst.operands[0].reg == REG_PC
9906 && inst.operands[1].reg == REG_PC
e2b0ab59 9907 && (inst.relocs[0].exp.X_add_number & 0x3)),
de194d85 9908 _("ldr to register 15 must be 4-byte aligned"));
1be5fd2e
NC
9909}
9910
b05fe5cf 9911static void
c19d1205 9912do_ldst (void)
b05fe5cf 9913{
c19d1205
ZW
9914 inst.instruction |= inst.operands[0].reg << 12;
9915 if (!inst.operands[1].isreg)
8335d6aa 9916 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/FALSE))
b05fe5cf 9917 return;
c19d1205 9918 encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
1be5fd2e 9919 check_ldr_r15_aligned ();
b05fe5cf
ZW
9920}
9921
9922static void
c19d1205 9923do_ldstt (void)
b05fe5cf 9924{
c19d1205
ZW
9925 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9926 reject [Rn,...]. */
9927 if (inst.operands[1].preind)
b05fe5cf 9928 {
e2b0ab59
AV
9929 constraint (inst.relocs[0].exp.X_op != O_constant
9930 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9931 _("this instruction requires a post-indexed address"));
b05fe5cf 9932
c19d1205
ZW
9933 inst.operands[1].preind = 0;
9934 inst.operands[1].postind = 1;
9935 inst.operands[1].writeback = 1;
b05fe5cf 9936 }
c19d1205
ZW
9937 inst.instruction |= inst.operands[0].reg << 12;
9938 encode_arm_addr_mode_2 (1, /*is_t=*/TRUE);
9939}
b05fe5cf 9940
c19d1205 9941/* Halfword and signed-byte load/store operations. */
b05fe5cf 9942
c19d1205
ZW
9943static void
9944do_ldstv4 (void)
9945{
ff4a8d2b 9946 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205
ZW
9947 inst.instruction |= inst.operands[0].reg << 12;
9948 if (!inst.operands[1].isreg)
8335d6aa 9949 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/TRUE))
b05fe5cf 9950 return;
c19d1205 9951 encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
b05fe5cf
ZW
9952}
9953
9954static void
c19d1205 9955do_ldsttv4 (void)
b05fe5cf 9956{
c19d1205
ZW
9957 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9958 reject [Rn,...]. */
9959 if (inst.operands[1].preind)
b05fe5cf 9960 {
e2b0ab59
AV
9961 constraint (inst.relocs[0].exp.X_op != O_constant
9962 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9963 _("this instruction requires a post-indexed address"));
b05fe5cf 9964
c19d1205
ZW
9965 inst.operands[1].preind = 0;
9966 inst.operands[1].postind = 1;
9967 inst.operands[1].writeback = 1;
b05fe5cf 9968 }
c19d1205
ZW
9969 inst.instruction |= inst.operands[0].reg << 12;
9970 encode_arm_addr_mode_3 (1, /*is_t=*/TRUE);
9971}
b05fe5cf 9972
c19d1205
ZW
9973/* Co-processor register load/store.
9974 Format: <LDC|STC>{cond}[L] CP#,CRd,<address> */
9975static void
9976do_lstc (void)
9977{
9978 inst.instruction |= inst.operands[0].reg << 8;
9979 inst.instruction |= inst.operands[1].reg << 12;
9980 encode_arm_cp_address (2, TRUE, TRUE, 0);
b05fe5cf
ZW
9981}
9982
b05fe5cf 9983static void
c19d1205 9984do_mlas (void)
b05fe5cf 9985{
8fb9d7b9 9986 /* This restriction does not apply to mls (nor to mla in v6 or later). */
c19d1205 9987 if (inst.operands[0].reg == inst.operands[1].reg
8fb9d7b9 9988 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6)
c19d1205 9989 && !(inst.instruction & 0x00400000))
8fb9d7b9 9990 as_tsktsk (_("Rd and Rm should be different in mla"));
b05fe5cf 9991
c19d1205
ZW
9992 inst.instruction |= inst.operands[0].reg << 16;
9993 inst.instruction |= inst.operands[1].reg;
9994 inst.instruction |= inst.operands[2].reg << 8;
9995 inst.instruction |= inst.operands[3].reg << 12;
c19d1205 9996}
b05fe5cf 9997
c19d1205
ZW
9998static void
9999do_mov (void)
10000{
e2b0ab59
AV
10001 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
10002 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 10003 THUMB1_RELOC_ONLY);
c19d1205
ZW
10004 inst.instruction |= inst.operands[0].reg << 12;
10005 encode_arm_shifter_operand (1);
10006}
b05fe5cf 10007
c19d1205
ZW
10008/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
10009static void
10010do_mov16 (void)
10011{
b6895b4f
PB
10012 bfd_vma imm;
10013 bfd_boolean top;
10014
10015 top = (inst.instruction & 0x00400000) != 0;
e2b0ab59 10016 constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
33eaf5de 10017 _(":lower16: not allowed in this instruction"));
e2b0ab59 10018 constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
33eaf5de 10019 _(":upper16: not allowed in this instruction"));
c19d1205 10020 inst.instruction |= inst.operands[0].reg << 12;
e2b0ab59 10021 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 10022 {
e2b0ab59 10023 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
10024 /* The value is in two pieces: 0:11, 16:19. */
10025 inst.instruction |= (imm & 0x00000fff);
10026 inst.instruction |= (imm & 0x0000f000) << 4;
10027 }
b05fe5cf 10028}
b99bd4ef 10029
037e8744
JB
10030static int
10031do_vfp_nsyn_mrs (void)
10032{
10033 if (inst.operands[0].isvec)
10034 {
10035 if (inst.operands[1].reg != 1)
477330fc 10036 first_error (_("operand 1 must be FPSCR"));
037e8744
JB
10037 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
10038 memset (&inst.operands[1], '\0', sizeof (inst.operands[1]));
10039 do_vfp_nsyn_opcode ("fmstat");
10040 }
10041 else if (inst.operands[1].isvec)
10042 do_vfp_nsyn_opcode ("fmrx");
10043 else
10044 return FAIL;
5f4273c7 10045
037e8744
JB
10046 return SUCCESS;
10047}
10048
10049static int
10050do_vfp_nsyn_msr (void)
10051{
10052 if (inst.operands[0].isvec)
10053 do_vfp_nsyn_opcode ("fmxr");
10054 else
10055 return FAIL;
10056
10057 return SUCCESS;
10058}
10059
f7c21dc7
NC
10060static void
10061do_vmrs (void)
10062{
10063 unsigned Rt = inst.operands[0].reg;
fa94de6b 10064
16d02dc9 10065 if (thumb_mode && Rt == REG_SP)
f7c21dc7
NC
10066 {
10067 inst.error = BAD_SP;
10068 return;
10069 }
10070
ba6cd17f
SD
10071 switch (inst.operands[1].reg)
10072 {
10073 /* MVFR2 is only valid for Armv8-A. */
10074 case 5:
10075 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
10076 _(BAD_FPU));
10077 break;
10078
10079 /* Check for new Armv8.1-M Mainline changes to <spec_reg>. */
10080 case 1: /* fpscr. */
10081 constraint (!(ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10082 || ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10083 _(BAD_FPU));
10084 break;
10085
10086 case 14: /* fpcxt_ns. */
10087 case 15: /* fpcxt_s. */
10088 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main),
10089 _("selected processor does not support instruction"));
10090 break;
10091
10092 case 2: /* fpscr_nzcvqc. */
10093 case 12: /* vpr. */
10094 case 13: /* p0. */
10095 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main)
10096 || (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10097 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10098 _("selected processor does not support instruction"));
10099 if (inst.operands[0].reg != 2
10100 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
10101 as_warn (_("accessing MVE system register without MVE is UNPREDICTABLE"));
10102 break;
10103
10104 default:
10105 break;
10106 }
40c7d507 10107
f7c21dc7 10108 /* APSR_ sets isvec. All other refs to PC are illegal. */
16d02dc9 10109 if (!inst.operands[0].isvec && Rt == REG_PC)
f7c21dc7
NC
10110 {
10111 inst.error = BAD_PC;
10112 return;
10113 }
10114
16d02dc9
JB
10115 /* If we get through parsing the register name, we just insert the number
10116 generated into the instruction without further validation. */
10117 inst.instruction |= (inst.operands[1].reg << 16);
f7c21dc7
NC
10118 inst.instruction |= (Rt << 12);
10119}
10120
10121static void
10122do_vmsr (void)
10123{
10124 unsigned Rt = inst.operands[1].reg;
fa94de6b 10125
f7c21dc7
NC
10126 if (thumb_mode)
10127 reject_bad_reg (Rt);
10128 else if (Rt == REG_PC)
10129 {
10130 inst.error = BAD_PC;
10131 return;
10132 }
10133
ba6cd17f
SD
10134 switch (inst.operands[0].reg)
10135 {
10136 /* MVFR2 is only valid for Armv8-A. */
10137 case 5:
10138 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
10139 _(BAD_FPU));
10140 break;
10141
10142 /* Check for new Armv8.1-M Mainline changes to <spec_reg>. */
10143 case 1: /* fpcr. */
10144 constraint (!(ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10145 || ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10146 _(BAD_FPU));
10147 break;
10148
10149 case 14: /* fpcxt_ns. */
10150 case 15: /* fpcxt_s. */
10151 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main),
10152 _("selected processor does not support instruction"));
10153 break;
10154
10155 case 2: /* fpscr_nzcvqc. */
10156 case 12: /* vpr. */
10157 case 13: /* p0. */
10158 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_1m_main)
10159 || (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
10160 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)),
10161 _("selected processor does not support instruction"));
10162 if (inst.operands[0].reg != 2
10163 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
10164 as_warn (_("accessing MVE system register without MVE is UNPREDICTABLE"));
10165 break;
10166
10167 default:
10168 break;
10169 }
40c7d507 10170
16d02dc9
JB
10171 /* If we get through parsing the register name, we just insert the number
10172 generated into the instruction without further validation. */
10173 inst.instruction |= (inst.operands[0].reg << 16);
f7c21dc7
NC
10174 inst.instruction |= (Rt << 12);
10175}
10176
b99bd4ef 10177static void
c19d1205 10178do_mrs (void)
b99bd4ef 10179{
90ec0d68
MGD
10180 unsigned br;
10181
037e8744
JB
10182 if (do_vfp_nsyn_mrs () == SUCCESS)
10183 return;
10184
ff4a8d2b 10185 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205 10186 inst.instruction |= inst.operands[0].reg << 12;
90ec0d68
MGD
10187
10188 if (inst.operands[1].isreg)
10189 {
10190 br = inst.operands[1].reg;
806ab1c0 10191 if (((br & 0x200) == 0) && ((br & 0xf0000) != 0xf0000))
90ec0d68
MGD
10192 as_bad (_("bad register for mrs"));
10193 }
10194 else
10195 {
10196 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
10197 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
10198 != (PSR_c|PSR_f),
d2cd1205 10199 _("'APSR', 'CPSR' or 'SPSR' expected"));
90ec0d68
MGD
10200 br = (15<<16) | (inst.operands[1].imm & SPSR_BIT);
10201 }
10202
10203 inst.instruction |= br;
c19d1205 10204}
b99bd4ef 10205
c19d1205
ZW
10206/* Two possible forms:
10207 "{C|S}PSR_<field>, Rm",
10208 "{C|S}PSR_f, #expression". */
b99bd4ef 10209
c19d1205
ZW
10210static void
10211do_msr (void)
10212{
037e8744
JB
10213 if (do_vfp_nsyn_msr () == SUCCESS)
10214 return;
10215
c19d1205
ZW
10216 inst.instruction |= inst.operands[0].imm;
10217 if (inst.operands[1].isreg)
10218 inst.instruction |= inst.operands[1].reg;
10219 else
b99bd4ef 10220 {
c19d1205 10221 inst.instruction |= INST_IMMEDIATE;
e2b0ab59
AV
10222 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
10223 inst.relocs[0].pc_rel = 0;
b99bd4ef 10224 }
b99bd4ef
NC
10225}
10226
c19d1205
ZW
10227static void
10228do_mul (void)
a737bd4d 10229{
ff4a8d2b
NC
10230 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
10231
c19d1205
ZW
10232 if (!inst.operands[2].present)
10233 inst.operands[2].reg = inst.operands[0].reg;
10234 inst.instruction |= inst.operands[0].reg << 16;
10235 inst.instruction |= inst.operands[1].reg;
10236 inst.instruction |= inst.operands[2].reg << 8;
a737bd4d 10237
8fb9d7b9
MS
10238 if (inst.operands[0].reg == inst.operands[1].reg
10239 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
10240 as_tsktsk (_("Rd and Rm should be different in mul"));
a737bd4d
NC
10241}
10242
c19d1205
ZW
10243/* Long Multiply Parser
10244 UMULL RdLo, RdHi, Rm, Rs
10245 SMULL RdLo, RdHi, Rm, Rs
10246 UMLAL RdLo, RdHi, Rm, Rs
10247 SMLAL RdLo, RdHi, Rm, Rs. */
b99bd4ef
NC
10248
10249static void
c19d1205 10250do_mull (void)
b99bd4ef 10251{
c19d1205
ZW
10252 inst.instruction |= inst.operands[0].reg << 12;
10253 inst.instruction |= inst.operands[1].reg << 16;
10254 inst.instruction |= inst.operands[2].reg;
10255 inst.instruction |= inst.operands[3].reg << 8;
b99bd4ef 10256
682b27ad
PB
10257 /* rdhi and rdlo must be different. */
10258 if (inst.operands[0].reg == inst.operands[1].reg)
10259 as_tsktsk (_("rdhi and rdlo must be different"));
10260
10261 /* rdhi, rdlo and rm must all be different before armv6. */
10262 if ((inst.operands[0].reg == inst.operands[2].reg
c19d1205 10263 || inst.operands[1].reg == inst.operands[2].reg)
682b27ad 10264 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
c19d1205
ZW
10265 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
10266}
b99bd4ef 10267
c19d1205
ZW
10268static void
10269do_nop (void)
10270{
e7495e45
NS
10271 if (inst.operands[0].present
10272 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k))
c19d1205
ZW
10273 {
10274 /* Architectural NOP hints are CPSR sets with no bits selected. */
10275 inst.instruction &= 0xf0000000;
e7495e45
NS
10276 inst.instruction |= 0x0320f000;
10277 if (inst.operands[0].present)
10278 inst.instruction |= inst.operands[0].imm;
c19d1205 10279 }
b99bd4ef
NC
10280}
10281
c19d1205
ZW
10282/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
10283 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
10284 Condition defaults to COND_ALWAYS.
10285 Error if Rd, Rn or Rm are R15. */
b99bd4ef
NC
10286
10287static void
c19d1205 10288do_pkhbt (void)
b99bd4ef 10289{
c19d1205
ZW
10290 inst.instruction |= inst.operands[0].reg << 12;
10291 inst.instruction |= inst.operands[1].reg << 16;
10292 inst.instruction |= inst.operands[2].reg;
10293 if (inst.operands[3].present)
10294 encode_arm_shift (3);
10295}
b99bd4ef 10296
c19d1205 10297/* ARM V6 PKHTB (Argument Parse). */
b99bd4ef 10298
c19d1205
ZW
10299static void
10300do_pkhtb (void)
10301{
10302 if (!inst.operands[3].present)
b99bd4ef 10303 {
c19d1205
ZW
10304 /* If the shift specifier is omitted, turn the instruction
10305 into pkhbt rd, rm, rn. */
10306 inst.instruction &= 0xfff00010;
10307 inst.instruction |= inst.operands[0].reg << 12;
10308 inst.instruction |= inst.operands[1].reg;
10309 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
10310 }
10311 else
10312 {
c19d1205
ZW
10313 inst.instruction |= inst.operands[0].reg << 12;
10314 inst.instruction |= inst.operands[1].reg << 16;
10315 inst.instruction |= inst.operands[2].reg;
10316 encode_arm_shift (3);
b99bd4ef
NC
10317 }
10318}
10319
c19d1205 10320/* ARMv5TE: Preload-Cache
60e5ef9f 10321 MP Extensions: Preload for write
c19d1205 10322
60e5ef9f 10323 PLD(W) <addr_mode>
c19d1205
ZW
10324
10325 Syntactically, like LDR with B=1, W=0, L=1. */
b99bd4ef
NC
10326
10327static void
c19d1205 10328do_pld (void)
b99bd4ef 10329{
c19d1205
ZW
10330 constraint (!inst.operands[0].isreg,
10331 _("'[' expected after PLD mnemonic"));
10332 constraint (inst.operands[0].postind,
10333 _("post-indexed expression used in preload instruction"));
10334 constraint (inst.operands[0].writeback,
10335 _("writeback used in preload instruction"));
10336 constraint (!inst.operands[0].preind,
10337 _("unindexed addressing used in preload instruction"));
c19d1205
ZW
10338 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
10339}
b99bd4ef 10340
62b3e311
PB
10341/* ARMv7: PLI <addr_mode> */
10342static void
10343do_pli (void)
10344{
10345 constraint (!inst.operands[0].isreg,
10346 _("'[' expected after PLI mnemonic"));
10347 constraint (inst.operands[0].postind,
10348 _("post-indexed expression used in preload instruction"));
10349 constraint (inst.operands[0].writeback,
10350 _("writeback used in preload instruction"));
10351 constraint (!inst.operands[0].preind,
10352 _("unindexed addressing used in preload instruction"));
10353 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
10354 inst.instruction &= ~PRE_INDEX;
10355}
10356
c19d1205
ZW
10357static void
10358do_push_pop (void)
10359{
5e0d7f77
MP
10360 constraint (inst.operands[0].writeback,
10361 _("push/pop do not support {reglist}^"));
c19d1205
ZW
10362 inst.operands[1] = inst.operands[0];
10363 memset (&inst.operands[0], 0, sizeof inst.operands[0]);
10364 inst.operands[0].isreg = 1;
10365 inst.operands[0].writeback = 1;
10366 inst.operands[0].reg = REG_SP;
6530b175 10367 encode_ldmstm (/*from_push_pop_mnem=*/TRUE);
c19d1205 10368}
b99bd4ef 10369
c19d1205
ZW
10370/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
10371 word at the specified address and the following word
10372 respectively.
10373 Unconditionally executed.
10374 Error if Rn is R15. */
b99bd4ef 10375
c19d1205
ZW
10376static void
10377do_rfe (void)
10378{
10379 inst.instruction |= inst.operands[0].reg << 16;
10380 if (inst.operands[0].writeback)
10381 inst.instruction |= WRITE_BACK;
10382}
b99bd4ef 10383
c19d1205 10384/* ARM V6 ssat (argument parse). */
b99bd4ef 10385
c19d1205
ZW
10386static void
10387do_ssat (void)
10388{
10389 inst.instruction |= inst.operands[0].reg << 12;
10390 inst.instruction |= (inst.operands[1].imm - 1) << 16;
10391 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10392
c19d1205
ZW
10393 if (inst.operands[3].present)
10394 encode_arm_shift (3);
b99bd4ef
NC
10395}
10396
c19d1205 10397/* ARM V6 usat (argument parse). */
b99bd4ef
NC
10398
10399static void
c19d1205 10400do_usat (void)
b99bd4ef 10401{
c19d1205
ZW
10402 inst.instruction |= inst.operands[0].reg << 12;
10403 inst.instruction |= inst.operands[1].imm << 16;
10404 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10405
c19d1205
ZW
10406 if (inst.operands[3].present)
10407 encode_arm_shift (3);
b99bd4ef
NC
10408}
10409
c19d1205 10410/* ARM V6 ssat16 (argument parse). */
09d92015
MM
10411
10412static void
c19d1205 10413do_ssat16 (void)
09d92015 10414{
c19d1205
ZW
10415 inst.instruction |= inst.operands[0].reg << 12;
10416 inst.instruction |= ((inst.operands[1].imm - 1) << 16);
10417 inst.instruction |= inst.operands[2].reg;
09d92015
MM
10418}
10419
c19d1205
ZW
10420static void
10421do_usat16 (void)
a737bd4d 10422{
c19d1205
ZW
10423 inst.instruction |= inst.operands[0].reg << 12;
10424 inst.instruction |= inst.operands[1].imm << 16;
10425 inst.instruction |= inst.operands[2].reg;
10426}
a737bd4d 10427
c19d1205
ZW
10428/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
10429 preserving the other bits.
a737bd4d 10430
c19d1205
ZW
10431 setend <endian_specifier>, where <endian_specifier> is either
10432 BE or LE. */
a737bd4d 10433
c19d1205
ZW
10434static void
10435do_setend (void)
10436{
12e37cbc
MGD
10437 if (warn_on_deprecated
10438 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 10439 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 10440
c19d1205
ZW
10441 if (inst.operands[0].imm)
10442 inst.instruction |= 0x200;
a737bd4d
NC
10443}
10444
10445static void
c19d1205 10446do_shift (void)
a737bd4d 10447{
c19d1205
ZW
10448 unsigned int Rm = (inst.operands[1].present
10449 ? inst.operands[1].reg
10450 : inst.operands[0].reg);
a737bd4d 10451
c19d1205
ZW
10452 inst.instruction |= inst.operands[0].reg << 12;
10453 inst.instruction |= Rm;
10454 if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
a737bd4d 10455 {
c19d1205
ZW
10456 inst.instruction |= inst.operands[2].reg << 8;
10457 inst.instruction |= SHIFT_BY_REG;
94342ec3
NC
10458 /* PR 12854: Error on extraneous shifts. */
10459 constraint (inst.operands[2].shifted,
10460 _("extraneous shift as part of operand to shift insn"));
a737bd4d
NC
10461 }
10462 else
e2b0ab59 10463 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
a737bd4d
NC
10464}
10465
09d92015 10466static void
3eb17e6b 10467do_smc (void)
09d92015 10468{
ba85f98c
BW
10469 unsigned int value = inst.relocs[0].exp.X_add_number;
10470 constraint (value > 0xf, _("immediate too large (bigger than 0xF)"));
10471
e2b0ab59
AV
10472 inst.relocs[0].type = BFD_RELOC_ARM_SMC;
10473 inst.relocs[0].pc_rel = 0;
09d92015
MM
10474}
10475
90ec0d68
MGD
10476static void
10477do_hvc (void)
10478{
e2b0ab59
AV
10479 inst.relocs[0].type = BFD_RELOC_ARM_HVC;
10480 inst.relocs[0].pc_rel = 0;
90ec0d68
MGD
10481}
10482
09d92015 10483static void
c19d1205 10484do_swi (void)
09d92015 10485{
e2b0ab59
AV
10486 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
10487 inst.relocs[0].pc_rel = 0;
09d92015
MM
10488}
10489
ddfded2f
MW
10490static void
10491do_setpan (void)
10492{
10493 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10494 _("selected processor does not support SETPAN instruction"));
10495
10496 inst.instruction |= ((inst.operands[0].imm & 1) << 9);
10497}
10498
10499static void
10500do_t_setpan (void)
10501{
10502 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10503 _("selected processor does not support SETPAN instruction"));
10504
10505 inst.instruction |= (inst.operands[0].imm << 3);
10506}
10507
c19d1205
ZW
10508/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
10509 SMLAxy{cond} Rd,Rm,Rs,Rn
10510 SMLAWy{cond} Rd,Rm,Rs,Rn
10511 Error if any register is R15. */
e16bb312 10512
c19d1205
ZW
10513static void
10514do_smla (void)
e16bb312 10515{
c19d1205
ZW
10516 inst.instruction |= inst.operands[0].reg << 16;
10517 inst.instruction |= inst.operands[1].reg;
10518 inst.instruction |= inst.operands[2].reg << 8;
10519 inst.instruction |= inst.operands[3].reg << 12;
10520}
a737bd4d 10521
c19d1205
ZW
10522/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
10523 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
10524 Error if any register is R15.
10525 Warning if Rdlo == Rdhi. */
a737bd4d 10526
c19d1205
ZW
10527static void
10528do_smlal (void)
10529{
10530 inst.instruction |= inst.operands[0].reg << 12;
10531 inst.instruction |= inst.operands[1].reg << 16;
10532 inst.instruction |= inst.operands[2].reg;
10533 inst.instruction |= inst.operands[3].reg << 8;
a737bd4d 10534
c19d1205
ZW
10535 if (inst.operands[0].reg == inst.operands[1].reg)
10536 as_tsktsk (_("rdhi and rdlo must be different"));
10537}
a737bd4d 10538
c19d1205
ZW
10539/* ARM V5E (El Segundo) signed-multiply (argument parse)
10540 SMULxy{cond} Rd,Rm,Rs
10541 Error if any register is R15. */
a737bd4d 10542
c19d1205
ZW
10543static void
10544do_smul (void)
10545{
10546 inst.instruction |= inst.operands[0].reg << 16;
10547 inst.instruction |= inst.operands[1].reg;
10548 inst.instruction |= inst.operands[2].reg << 8;
10549}
a737bd4d 10550
b6702015
PB
10551/* ARM V6 srs (argument parse). The variable fields in the encoding are
10552 the same for both ARM and Thumb-2. */
a737bd4d 10553
c19d1205
ZW
10554static void
10555do_srs (void)
10556{
b6702015
PB
10557 int reg;
10558
10559 if (inst.operands[0].present)
10560 {
10561 reg = inst.operands[0].reg;
fdfde340 10562 constraint (reg != REG_SP, _("SRS base register must be r13"));
b6702015
PB
10563 }
10564 else
fdfde340 10565 reg = REG_SP;
b6702015
PB
10566
10567 inst.instruction |= reg << 16;
10568 inst.instruction |= inst.operands[1].imm;
10569 if (inst.operands[0].writeback || inst.operands[1].writeback)
c19d1205
ZW
10570 inst.instruction |= WRITE_BACK;
10571}
a737bd4d 10572
c19d1205 10573/* ARM V6 strex (argument parse). */
a737bd4d 10574
c19d1205
ZW
10575static void
10576do_strex (void)
10577{
10578 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10579 || inst.operands[2].postind || inst.operands[2].writeback
10580 || inst.operands[2].immisreg || inst.operands[2].shifted
01cfc07f
NC
10581 || inst.operands[2].negative
10582 /* See comment in do_ldrex(). */
10583 || (inst.operands[2].reg == REG_PC),
10584 BAD_ADDR_MODE);
a737bd4d 10585
c19d1205
ZW
10586 constraint (inst.operands[0].reg == inst.operands[1].reg
10587 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
a737bd4d 10588
e2b0ab59
AV
10589 constraint (inst.relocs[0].exp.X_op != O_constant
10590 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10591 _("offset must be zero in ARM encoding"));
a737bd4d 10592
c19d1205
ZW
10593 inst.instruction |= inst.operands[0].reg << 12;
10594 inst.instruction |= inst.operands[1].reg;
10595 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 10596 inst.relocs[0].type = BFD_RELOC_UNUSED;
e16bb312
NC
10597}
10598
877807f8
NC
10599static void
10600do_t_strexbh (void)
10601{
10602 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10603 || inst.operands[2].postind || inst.operands[2].writeback
10604 || inst.operands[2].immisreg || inst.operands[2].shifted
10605 || inst.operands[2].negative,
10606 BAD_ADDR_MODE);
10607
10608 constraint (inst.operands[0].reg == inst.operands[1].reg
10609 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10610
10611 do_rm_rd_rn ();
10612}
10613
e16bb312 10614static void
c19d1205 10615do_strexd (void)
e16bb312 10616{
c19d1205
ZW
10617 constraint (inst.operands[1].reg % 2 != 0,
10618 _("even register required"));
10619 constraint (inst.operands[2].present
10620 && inst.operands[2].reg != inst.operands[1].reg + 1,
10621 _("can only store two consecutive registers"));
10622 /* If op 2 were present and equal to PC, this function wouldn't
10623 have been called in the first place. */
10624 constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
e16bb312 10625
c19d1205
ZW
10626 constraint (inst.operands[0].reg == inst.operands[1].reg
10627 || inst.operands[0].reg == inst.operands[1].reg + 1
10628 || inst.operands[0].reg == inst.operands[3].reg,
10629 BAD_OVERLAP);
e16bb312 10630
c19d1205
ZW
10631 inst.instruction |= inst.operands[0].reg << 12;
10632 inst.instruction |= inst.operands[1].reg;
10633 inst.instruction |= inst.operands[3].reg << 16;
e16bb312
NC
10634}
10635
9eb6c0f1
MGD
10636/* ARM V8 STRL. */
10637static void
4b8c8c02 10638do_stlex (void)
9eb6c0f1
MGD
10639{
10640 constraint (inst.operands[0].reg == inst.operands[1].reg
10641 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10642
10643 do_rd_rm_rn ();
10644}
10645
10646static void
4b8c8c02 10647do_t_stlex (void)
9eb6c0f1
MGD
10648{
10649 constraint (inst.operands[0].reg == inst.operands[1].reg
10650 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10651
10652 do_rm_rd_rn ();
10653}
10654
c19d1205
ZW
10655/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
10656 extends it to 32-bits, and adds the result to a value in another
10657 register. You can specify a rotation by 0, 8, 16, or 24 bits
10658 before extracting the 16-bit value.
10659 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
10660 Condition defaults to COND_ALWAYS.
10661 Error if any register uses R15. */
10662
e16bb312 10663static void
c19d1205 10664do_sxtah (void)
e16bb312 10665{
c19d1205
ZW
10666 inst.instruction |= inst.operands[0].reg << 12;
10667 inst.instruction |= inst.operands[1].reg << 16;
10668 inst.instruction |= inst.operands[2].reg;
10669 inst.instruction |= inst.operands[3].imm << 10;
10670}
e16bb312 10671
c19d1205 10672/* ARM V6 SXTH.
e16bb312 10673
c19d1205
ZW
10674 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
10675 Condition defaults to COND_ALWAYS.
10676 Error if any register uses R15. */
e16bb312
NC
10677
10678static void
c19d1205 10679do_sxth (void)
e16bb312 10680{
c19d1205
ZW
10681 inst.instruction |= inst.operands[0].reg << 12;
10682 inst.instruction |= inst.operands[1].reg;
10683 inst.instruction |= inst.operands[2].imm << 10;
e16bb312 10684}
c19d1205
ZW
10685\f
10686/* VFP instructions. In a logical order: SP variant first, monad
10687 before dyad, arithmetic then move then load/store. */
e16bb312
NC
10688
10689static void
c19d1205 10690do_vfp_sp_monadic (void)
e16bb312 10691{
57785aa2
AV
10692 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10693 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10694 _(BAD_FPU));
10695
5287ad62
JB
10696 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10697 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10698}
10699
10700static void
c19d1205 10701do_vfp_sp_dyadic (void)
e16bb312 10702{
5287ad62
JB
10703 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10704 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
10705 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10706}
10707
10708static void
c19d1205 10709do_vfp_sp_compare_z (void)
e16bb312 10710{
5287ad62 10711 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
e16bb312
NC
10712}
10713
10714static void
c19d1205 10715do_vfp_dp_sp_cvt (void)
e16bb312 10716{
5287ad62
JB
10717 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10718 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10719}
10720
10721static void
c19d1205 10722do_vfp_sp_dp_cvt (void)
e16bb312 10723{
5287ad62
JB
10724 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10725 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
e16bb312
NC
10726}
10727
10728static void
c19d1205 10729do_vfp_reg_from_sp (void)
e16bb312 10730{
57785aa2
AV
10731 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10732 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10733 _(BAD_FPU));
10734
c19d1205 10735 inst.instruction |= inst.operands[0].reg << 12;
5287ad62 10736 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
e16bb312
NC
10737}
10738
10739static void
c19d1205 10740do_vfp_reg2_from_sp2 (void)
e16bb312 10741{
c19d1205
ZW
10742 constraint (inst.operands[2].imm != 2,
10743 _("only two consecutive VFP SP registers allowed here"));
10744 inst.instruction |= inst.operands[0].reg << 12;
10745 inst.instruction |= inst.operands[1].reg << 16;
5287ad62 10746 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10747}
10748
10749static void
c19d1205 10750do_vfp_sp_from_reg (void)
e16bb312 10751{
57785aa2
AV
10752 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10753 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10754 _(BAD_FPU));
10755
5287ad62 10756 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sn);
c19d1205 10757 inst.instruction |= inst.operands[1].reg << 12;
e16bb312
NC
10758}
10759
10760static void
c19d1205 10761do_vfp_sp2_from_reg2 (void)
e16bb312 10762{
c19d1205
ZW
10763 constraint (inst.operands[0].imm != 2,
10764 _("only two consecutive VFP SP registers allowed here"));
5287ad62 10765 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sm);
c19d1205
ZW
10766 inst.instruction |= inst.operands[1].reg << 12;
10767 inst.instruction |= inst.operands[2].reg << 16;
e16bb312
NC
10768}
10769
10770static void
c19d1205 10771do_vfp_sp_ldst (void)
e16bb312 10772{
5287ad62 10773 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
c19d1205 10774 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
10775}
10776
10777static void
c19d1205 10778do_vfp_dp_ldst (void)
e16bb312 10779{
5287ad62 10780 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
c19d1205 10781 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
10782}
10783
c19d1205 10784
e16bb312 10785static void
c19d1205 10786vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10787{
c19d1205
ZW
10788 if (inst.operands[0].writeback)
10789 inst.instruction |= WRITE_BACK;
10790 else
10791 constraint (ldstm_type != VFP_LDSTMIA,
10792 _("this addressing mode requires base-register writeback"));
10793 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10794 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sd);
c19d1205 10795 inst.instruction |= inst.operands[1].imm;
e16bb312
NC
10796}
10797
10798static void
c19d1205 10799vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10800{
c19d1205 10801 int count;
e16bb312 10802
c19d1205
ZW
10803 if (inst.operands[0].writeback)
10804 inst.instruction |= WRITE_BACK;
10805 else
10806 constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
10807 _("this addressing mode requires base-register writeback"));
e16bb312 10808
c19d1205 10809 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10810 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
e16bb312 10811
c19d1205
ZW
10812 count = inst.operands[1].imm << 1;
10813 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
10814 count += 1;
e16bb312 10815
c19d1205 10816 inst.instruction |= count;
e16bb312
NC
10817}
10818
10819static void
c19d1205 10820do_vfp_sp_ldstmia (void)
e16bb312 10821{
c19d1205 10822 vfp_sp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10823}
10824
10825static void
c19d1205 10826do_vfp_sp_ldstmdb (void)
e16bb312 10827{
c19d1205 10828 vfp_sp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10829}
10830
10831static void
c19d1205 10832do_vfp_dp_ldstmia (void)
e16bb312 10833{
c19d1205 10834 vfp_dp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10835}
10836
10837static void
c19d1205 10838do_vfp_dp_ldstmdb (void)
e16bb312 10839{
c19d1205 10840 vfp_dp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10841}
10842
10843static void
c19d1205 10844do_vfp_xp_ldstmia (void)
e16bb312 10845{
c19d1205
ZW
10846 vfp_dp_ldstm (VFP_LDSTMIAX);
10847}
e16bb312 10848
c19d1205
ZW
10849static void
10850do_vfp_xp_ldstmdb (void)
10851{
10852 vfp_dp_ldstm (VFP_LDSTMDBX);
e16bb312 10853}
5287ad62
JB
10854
10855static void
10856do_vfp_dp_rd_rm (void)
10857{
57785aa2
AV
10858 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
10859 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10860 _(BAD_FPU));
10861
5287ad62
JB
10862 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10863 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
10864}
10865
10866static void
10867do_vfp_dp_rn_rd (void)
10868{
10869 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dn);
10870 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10871}
10872
10873static void
10874do_vfp_dp_rd_rn (void)
10875{
10876 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10877 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10878}
10879
10880static void
10881do_vfp_dp_rd_rn_rm (void)
10882{
57785aa2
AV
10883 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10884 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10885 _(BAD_FPU));
10886
5287ad62
JB
10887 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10888 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10889 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dm);
10890}
10891
10892static void
10893do_vfp_dp_rd (void)
10894{
10895 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10896}
10897
10898static void
10899do_vfp_dp_rm_rd_rn (void)
10900{
57785aa2
AV
10901 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10902 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10903 _(BAD_FPU));
10904
5287ad62
JB
10905 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dm);
10906 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10907 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dn);
10908}
10909
10910/* VFPv3 instructions. */
10911static void
10912do_vfp_sp_const (void)
10913{
10914 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
00249aaa
PB
10915 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10916 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10917}
10918
10919static void
10920do_vfp_dp_const (void)
10921{
10922 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
00249aaa
PB
10923 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10924 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10925}
10926
10927static void
10928vfp_conv (int srcsize)
10929{
5f1af56b
MGD
10930 int immbits = srcsize - inst.operands[1].imm;
10931
fa94de6b
RM
10932 if (srcsize == 16 && !(immbits >= 0 && immbits <= srcsize))
10933 {
5f1af56b 10934 /* If srcsize is 16, inst.operands[1].imm must be in the range 0-16.
477330fc 10935 i.e. immbits must be in range 0 - 16. */
5f1af56b
MGD
10936 inst.error = _("immediate value out of range, expected range [0, 16]");
10937 return;
10938 }
fa94de6b 10939 else if (srcsize == 32 && !(immbits >= 0 && immbits < srcsize))
5f1af56b
MGD
10940 {
10941 /* If srcsize is 32, inst.operands[1].imm must be in the range 1-32.
477330fc 10942 i.e. immbits must be in range 0 - 31. */
5f1af56b
MGD
10943 inst.error = _("immediate value out of range, expected range [1, 32]");
10944 return;
10945 }
10946
5287ad62
JB
10947 inst.instruction |= (immbits & 1) << 5;
10948 inst.instruction |= (immbits >> 1);
10949}
10950
10951static void
10952do_vfp_sp_conv_16 (void)
10953{
10954 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10955 vfp_conv (16);
10956}
10957
10958static void
10959do_vfp_dp_conv_16 (void)
10960{
10961 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10962 vfp_conv (16);
10963}
10964
10965static void
10966do_vfp_sp_conv_32 (void)
10967{
10968 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10969 vfp_conv (32);
10970}
10971
10972static void
10973do_vfp_dp_conv_32 (void)
10974{
10975 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10976 vfp_conv (32);
10977}
c19d1205
ZW
10978\f
10979/* FPA instructions. Also in a logical order. */
e16bb312 10980
c19d1205
ZW
10981static void
10982do_fpa_cmp (void)
10983{
10984 inst.instruction |= inst.operands[0].reg << 16;
10985 inst.instruction |= inst.operands[1].reg;
10986}
b99bd4ef
NC
10987
10988static void
c19d1205 10989do_fpa_ldmstm (void)
b99bd4ef 10990{
c19d1205
ZW
10991 inst.instruction |= inst.operands[0].reg << 12;
10992 switch (inst.operands[1].imm)
10993 {
10994 case 1: inst.instruction |= CP_T_X; break;
10995 case 2: inst.instruction |= CP_T_Y; break;
10996 case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
10997 case 4: break;
10998 default: abort ();
10999 }
b99bd4ef 11000
c19d1205
ZW
11001 if (inst.instruction & (PRE_INDEX | INDEX_UP))
11002 {
11003 /* The instruction specified "ea" or "fd", so we can only accept
11004 [Rn]{!}. The instruction does not really support stacking or
11005 unstacking, so we have to emulate these by setting appropriate
11006 bits and offsets. */
e2b0ab59
AV
11007 constraint (inst.relocs[0].exp.X_op != O_constant
11008 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 11009 _("this instruction does not support indexing"));
b99bd4ef 11010
c19d1205 11011 if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
e2b0ab59 11012 inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
b99bd4ef 11013
c19d1205 11014 if (!(inst.instruction & INDEX_UP))
e2b0ab59 11015 inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
b99bd4ef 11016
c19d1205
ZW
11017 if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
11018 {
11019 inst.operands[2].preind = 0;
11020 inst.operands[2].postind = 1;
11021 }
11022 }
b99bd4ef 11023
c19d1205 11024 encode_arm_cp_address (2, TRUE, TRUE, 0);
b99bd4ef 11025}
c19d1205
ZW
11026\f
11027/* iWMMXt instructions: strictly in alphabetical order. */
b99bd4ef 11028
c19d1205
ZW
11029static void
11030do_iwmmxt_tandorc (void)
11031{
11032 constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
11033}
b99bd4ef 11034
c19d1205
ZW
11035static void
11036do_iwmmxt_textrc (void)
11037{
11038 inst.instruction |= inst.operands[0].reg << 12;
11039 inst.instruction |= inst.operands[1].imm;
11040}
b99bd4ef
NC
11041
11042static void
c19d1205 11043do_iwmmxt_textrm (void)
b99bd4ef 11044{
c19d1205
ZW
11045 inst.instruction |= inst.operands[0].reg << 12;
11046 inst.instruction |= inst.operands[1].reg << 16;
11047 inst.instruction |= inst.operands[2].imm;
11048}
b99bd4ef 11049
c19d1205
ZW
11050static void
11051do_iwmmxt_tinsr (void)
11052{
11053 inst.instruction |= inst.operands[0].reg << 16;
11054 inst.instruction |= inst.operands[1].reg << 12;
11055 inst.instruction |= inst.operands[2].imm;
11056}
b99bd4ef 11057
c19d1205
ZW
11058static void
11059do_iwmmxt_tmia (void)
11060{
11061 inst.instruction |= inst.operands[0].reg << 5;
11062 inst.instruction |= inst.operands[1].reg;
11063 inst.instruction |= inst.operands[2].reg << 12;
11064}
b99bd4ef 11065
c19d1205
ZW
11066static void
11067do_iwmmxt_waligni (void)
11068{
11069 inst.instruction |= inst.operands[0].reg << 12;
11070 inst.instruction |= inst.operands[1].reg << 16;
11071 inst.instruction |= inst.operands[2].reg;
11072 inst.instruction |= inst.operands[3].imm << 20;
11073}
b99bd4ef 11074
2d447fca
JM
11075static void
11076do_iwmmxt_wmerge (void)
11077{
11078 inst.instruction |= inst.operands[0].reg << 12;
11079 inst.instruction |= inst.operands[1].reg << 16;
11080 inst.instruction |= inst.operands[2].reg;
11081 inst.instruction |= inst.operands[3].imm << 21;
11082}
11083
c19d1205
ZW
11084static void
11085do_iwmmxt_wmov (void)
11086{
11087 /* WMOV rD, rN is an alias for WOR rD, rN, rN. */
11088 inst.instruction |= inst.operands[0].reg << 12;
11089 inst.instruction |= inst.operands[1].reg << 16;
11090 inst.instruction |= inst.operands[1].reg;
11091}
b99bd4ef 11092
c19d1205
ZW
11093static void
11094do_iwmmxt_wldstbh (void)
11095{
8f06b2d8 11096 int reloc;
c19d1205 11097 inst.instruction |= inst.operands[0].reg << 12;
8f06b2d8
PB
11098 if (thumb_mode)
11099 reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
11100 else
11101 reloc = BFD_RELOC_ARM_CP_OFF_IMM_S2;
11102 encode_arm_cp_address (1, TRUE, FALSE, reloc);
b99bd4ef
NC
11103}
11104
c19d1205
ZW
11105static void
11106do_iwmmxt_wldstw (void)
11107{
11108 /* RIWR_RIWC clears .isreg for a control register. */
11109 if (!inst.operands[0].isreg)
11110 {
11111 constraint (inst.cond != COND_ALWAYS, BAD_COND);
11112 inst.instruction |= 0xf0000000;
11113 }
b99bd4ef 11114
c19d1205
ZW
11115 inst.instruction |= inst.operands[0].reg << 12;
11116 encode_arm_cp_address (1, TRUE, TRUE, 0);
11117}
b99bd4ef
NC
11118
11119static void
c19d1205 11120do_iwmmxt_wldstd (void)
b99bd4ef 11121{
c19d1205 11122 inst.instruction |= inst.operands[0].reg << 12;
2d447fca
JM
11123 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)
11124 && inst.operands[1].immisreg)
11125 {
11126 inst.instruction &= ~0x1a000ff;
eff0bc54 11127 inst.instruction |= (0xfU << 28);
2d447fca
JM
11128 if (inst.operands[1].preind)
11129 inst.instruction |= PRE_INDEX;
11130 if (!inst.operands[1].negative)
11131 inst.instruction |= INDEX_UP;
11132 if (inst.operands[1].writeback)
11133 inst.instruction |= WRITE_BACK;
11134 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 11135 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
2d447fca
JM
11136 inst.instruction |= inst.operands[1].imm;
11137 }
11138 else
11139 encode_arm_cp_address (1, TRUE, FALSE, 0);
c19d1205 11140}
b99bd4ef 11141
c19d1205
ZW
11142static void
11143do_iwmmxt_wshufh (void)
11144{
11145 inst.instruction |= inst.operands[0].reg << 12;
11146 inst.instruction |= inst.operands[1].reg << 16;
11147 inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
11148 inst.instruction |= (inst.operands[2].imm & 0x0f);
11149}
b99bd4ef 11150
c19d1205
ZW
11151static void
11152do_iwmmxt_wzero (void)
11153{
11154 /* WZERO reg is an alias for WANDN reg, reg, reg. */
11155 inst.instruction |= inst.operands[0].reg;
11156 inst.instruction |= inst.operands[0].reg << 12;
11157 inst.instruction |= inst.operands[0].reg << 16;
11158}
2d447fca
JM
11159
11160static void
11161do_iwmmxt_wrwrwr_or_imm5 (void)
11162{
11163 if (inst.operands[2].isreg)
11164 do_rd_rn_rm ();
11165 else {
11166 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2),
11167 _("immediate operand requires iWMMXt2"));
11168 do_rd_rn ();
11169 if (inst.operands[2].imm == 0)
11170 {
11171 switch ((inst.instruction >> 20) & 0xf)
11172 {
11173 case 4:
11174 case 5:
11175 case 6:
5f4273c7 11176 case 7:
2d447fca
JM
11177 /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16. */
11178 inst.operands[2].imm = 16;
11179 inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
11180 break;
11181 case 8:
11182 case 9:
11183 case 10:
11184 case 11:
11185 /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32. */
11186 inst.operands[2].imm = 32;
11187 inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
11188 break;
11189 case 12:
11190 case 13:
11191 case 14:
11192 case 15:
11193 {
11194 /* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn. */
11195 unsigned long wrn;
11196 wrn = (inst.instruction >> 16) & 0xf;
11197 inst.instruction &= 0xff0fff0f;
11198 inst.instruction |= wrn;
11199 /* Bail out here; the instruction is now assembled. */
11200 return;
11201 }
11202 }
11203 }
11204 /* Map 32 -> 0, etc. */
11205 inst.operands[2].imm &= 0x1f;
eff0bc54 11206 inst.instruction |= (0xfU << 28) | ((inst.operands[2].imm & 0x10) << 4) | (inst.operands[2].imm & 0xf);
2d447fca
JM
11207 }
11208}
c19d1205
ZW
11209\f
11210/* Cirrus Maverick instructions. Simple 2-, 3-, and 4-register
11211 operations first, then control, shift, and load/store. */
b99bd4ef 11212
c19d1205 11213/* Insns like "foo X,Y,Z". */
b99bd4ef 11214
c19d1205
ZW
11215static void
11216do_mav_triple (void)
11217{
11218 inst.instruction |= inst.operands[0].reg << 16;
11219 inst.instruction |= inst.operands[1].reg;
11220 inst.instruction |= inst.operands[2].reg << 12;
11221}
b99bd4ef 11222
c19d1205
ZW
11223/* Insns like "foo W,X,Y,Z".
11224 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
a737bd4d 11225
c19d1205
ZW
11226static void
11227do_mav_quad (void)
11228{
11229 inst.instruction |= inst.operands[0].reg << 5;
11230 inst.instruction |= inst.operands[1].reg << 12;
11231 inst.instruction |= inst.operands[2].reg << 16;
11232 inst.instruction |= inst.operands[3].reg;
a737bd4d
NC
11233}
11234
c19d1205
ZW
11235/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
11236static void
11237do_mav_dspsc (void)
a737bd4d 11238{
c19d1205
ZW
11239 inst.instruction |= inst.operands[1].reg << 12;
11240}
a737bd4d 11241
c19d1205
ZW
11242/* Maverick shift immediate instructions.
11243 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
11244 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
a737bd4d 11245
c19d1205
ZW
11246static void
11247do_mav_shift (void)
11248{
11249 int imm = inst.operands[2].imm;
a737bd4d 11250
c19d1205
ZW
11251 inst.instruction |= inst.operands[0].reg << 12;
11252 inst.instruction |= inst.operands[1].reg << 16;
a737bd4d 11253
c19d1205
ZW
11254 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
11255 Bits 5-7 of the insn should have bits 4-6 of the immediate.
11256 Bit 4 should be 0. */
11257 imm = (imm & 0xf) | ((imm & 0x70) << 1);
a737bd4d 11258
c19d1205
ZW
11259 inst.instruction |= imm;
11260}
11261\f
11262/* XScale instructions. Also sorted arithmetic before move. */
a737bd4d 11263
c19d1205
ZW
11264/* Xscale multiply-accumulate (argument parse)
11265 MIAcc acc0,Rm,Rs
11266 MIAPHcc acc0,Rm,Rs
11267 MIAxycc acc0,Rm,Rs. */
a737bd4d 11268
c19d1205
ZW
11269static void
11270do_xsc_mia (void)
11271{
11272 inst.instruction |= inst.operands[1].reg;
11273 inst.instruction |= inst.operands[2].reg << 12;
11274}
a737bd4d 11275
c19d1205 11276/* Xscale move-accumulator-register (argument parse)
a737bd4d 11277
c19d1205 11278 MARcc acc0,RdLo,RdHi. */
b99bd4ef 11279
c19d1205
ZW
11280static void
11281do_xsc_mar (void)
11282{
11283 inst.instruction |= inst.operands[1].reg << 12;
11284 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
11285}
11286
c19d1205 11287/* Xscale move-register-accumulator (argument parse)
b99bd4ef 11288
c19d1205 11289 MRAcc RdLo,RdHi,acc0. */
b99bd4ef
NC
11290
11291static void
c19d1205 11292do_xsc_mra (void)
b99bd4ef 11293{
c19d1205
ZW
11294 constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
11295 inst.instruction |= inst.operands[0].reg << 12;
11296 inst.instruction |= inst.operands[1].reg << 16;
11297}
11298\f
11299/* Encoding functions relevant only to Thumb. */
b99bd4ef 11300
c19d1205
ZW
11301/* inst.operands[i] is a shifted-register operand; encode
11302 it into inst.instruction in the format used by Thumb32. */
11303
11304static void
11305encode_thumb32_shifted_operand (int i)
11306{
e2b0ab59 11307 unsigned int value = inst.relocs[0].exp.X_add_number;
c19d1205 11308 unsigned int shift = inst.operands[i].shift_kind;
b99bd4ef 11309
9c3c69f2
PB
11310 constraint (inst.operands[i].immisreg,
11311 _("shift by register not allowed in thumb mode"));
c19d1205
ZW
11312 inst.instruction |= inst.operands[i].reg;
11313 if (shift == SHIFT_RRX)
11314 inst.instruction |= SHIFT_ROR << 4;
11315 else
b99bd4ef 11316 {
e2b0ab59 11317 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
11318 _("expression too complex"));
11319
11320 constraint (value > 32
11321 || (value == 32 && (shift == SHIFT_LSL
11322 || shift == SHIFT_ROR)),
11323 _("shift expression is too large"));
11324
11325 if (value == 0)
11326 shift = SHIFT_LSL;
11327 else if (value == 32)
11328 value = 0;
11329
11330 inst.instruction |= shift << 4;
11331 inst.instruction |= (value & 0x1c) << 10;
11332 inst.instruction |= (value & 0x03) << 6;
b99bd4ef 11333 }
c19d1205 11334}
b99bd4ef 11335
b99bd4ef 11336
c19d1205
ZW
11337/* inst.operands[i] was set up by parse_address. Encode it into a
11338 Thumb32 format load or store instruction. Reject forms that cannot
11339 be used with such instructions. If is_t is true, reject forms that
11340 cannot be used with a T instruction; if is_d is true, reject forms
5be8be5d
DG
11341 that cannot be used with a D instruction. If it is a store insn,
11342 reject PC in Rn. */
b99bd4ef 11343
c19d1205
ZW
11344static void
11345encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
11346{
5be8be5d 11347 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
c19d1205
ZW
11348
11349 constraint (!inst.operands[i].isreg,
53365c0d 11350 _("Instruction does not support =N addresses"));
b99bd4ef 11351
c19d1205
ZW
11352 inst.instruction |= inst.operands[i].reg << 16;
11353 if (inst.operands[i].immisreg)
b99bd4ef 11354 {
5be8be5d 11355 constraint (is_pc, BAD_PC_ADDRESSING);
c19d1205
ZW
11356 constraint (is_t || is_d, _("cannot use register index with this instruction"));
11357 constraint (inst.operands[i].negative,
11358 _("Thumb does not support negative register indexing"));
11359 constraint (inst.operands[i].postind,
11360 _("Thumb does not support register post-indexing"));
11361 constraint (inst.operands[i].writeback,
11362 _("Thumb does not support register indexing with writeback"));
11363 constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
11364 _("Thumb supports only LSL in shifted register indexing"));
b99bd4ef 11365
f40d1643 11366 inst.instruction |= inst.operands[i].imm;
c19d1205 11367 if (inst.operands[i].shifted)
b99bd4ef 11368 {
e2b0ab59 11369 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 11370 _("expression too complex"));
e2b0ab59
AV
11371 constraint (inst.relocs[0].exp.X_add_number < 0
11372 || inst.relocs[0].exp.X_add_number > 3,
c19d1205 11373 _("shift out of range"));
e2b0ab59 11374 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
c19d1205 11375 }
e2b0ab59 11376 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
11377 }
11378 else if (inst.operands[i].preind)
11379 {
5be8be5d 11380 constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
f40d1643 11381 constraint (is_t && inst.operands[i].writeback,
c19d1205 11382 _("cannot use writeback with this instruction"));
4755303e
WN
11383 constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0),
11384 BAD_PC_ADDRESSING);
c19d1205
ZW
11385
11386 if (is_d)
11387 {
11388 inst.instruction |= 0x01000000;
11389 if (inst.operands[i].writeback)
11390 inst.instruction |= 0x00200000;
b99bd4ef 11391 }
c19d1205 11392 else
b99bd4ef 11393 {
c19d1205
ZW
11394 inst.instruction |= 0x00000c00;
11395 if (inst.operands[i].writeback)
11396 inst.instruction |= 0x00000100;
b99bd4ef 11397 }
e2b0ab59 11398 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
b99bd4ef 11399 }
c19d1205 11400 else if (inst.operands[i].postind)
b99bd4ef 11401 {
9c2799c2 11402 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
11403 constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
11404 constraint (is_t, _("cannot use post-indexing with this instruction"));
11405
11406 if (is_d)
11407 inst.instruction |= 0x00200000;
11408 else
11409 inst.instruction |= 0x00000900;
e2b0ab59 11410 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
c19d1205
ZW
11411 }
11412 else /* unindexed - only for coprocessor */
11413 inst.error = _("instruction does not accept unindexed addressing");
11414}
11415
e39c1607 11416/* Table of Thumb instructions which exist in 16- and/or 32-bit
c19d1205
ZW
11417 encodings (the latter only in post-V6T2 cores). The index is the
11418 value used in the insns table below. When there is more than one
11419 possible 16-bit encoding for the instruction, this table always
0110f2b8
PB
11420 holds variant (1).
11421 Also contains several pseudo-instructions used during relaxation. */
c19d1205 11422#define T16_32_TAB \
21d799b5
NC
11423 X(_adc, 4140, eb400000), \
11424 X(_adcs, 4140, eb500000), \
11425 X(_add, 1c00, eb000000), \
11426 X(_adds, 1c00, eb100000), \
11427 X(_addi, 0000, f1000000), \
11428 X(_addis, 0000, f1100000), \
11429 X(_add_pc,000f, f20f0000), \
11430 X(_add_sp,000d, f10d0000), \
11431 X(_adr, 000f, f20f0000), \
11432 X(_and, 4000, ea000000), \
11433 X(_ands, 4000, ea100000), \
11434 X(_asr, 1000, fa40f000), \
11435 X(_asrs, 1000, fa50f000), \
11436 X(_b, e000, f000b000), \
11437 X(_bcond, d000, f0008000), \
4389b29a 11438 X(_bf, 0000, f040e001), \
f6b2b12d 11439 X(_bfcsel,0000, f000e001), \
f1c7f421 11440 X(_bfx, 0000, f060e001), \
65d1bc05 11441 X(_bfl, 0000, f000c001), \
f1c7f421 11442 X(_bflx, 0000, f070e001), \
21d799b5
NC
11443 X(_bic, 4380, ea200000), \
11444 X(_bics, 4380, ea300000), \
e39c1607
SD
11445 X(_cinc, 0000, ea509000), \
11446 X(_cinv, 0000, ea50a000), \
21d799b5
NC
11447 X(_cmn, 42c0, eb100f00), \
11448 X(_cmp, 2800, ebb00f00), \
e39c1607 11449 X(_cneg, 0000, ea50b000), \
21d799b5
NC
11450 X(_cpsie, b660, f3af8400), \
11451 X(_cpsid, b670, f3af8600), \
11452 X(_cpy, 4600, ea4f0000), \
e39c1607
SD
11453 X(_csel, 0000, ea508000), \
11454 X(_cset, 0000, ea5f900f), \
11455 X(_csetm, 0000, ea5fa00f), \
11456 X(_csinc, 0000, ea509000), \
11457 X(_csinv, 0000, ea50a000), \
11458 X(_csneg, 0000, ea50b000), \
21d799b5 11459 X(_dec_sp,80dd, f1ad0d00), \
60f993ce 11460 X(_dls, 0000, f040e001), \
1f6234a3 11461 X(_dlstp, 0000, f000e001), \
21d799b5
NC
11462 X(_eor, 4040, ea800000), \
11463 X(_eors, 4040, ea900000), \
11464 X(_inc_sp,00dd, f10d0d00), \
1f6234a3 11465 X(_lctp, 0000, f00fe001), \
21d799b5
NC
11466 X(_ldmia, c800, e8900000), \
11467 X(_ldr, 6800, f8500000), \
11468 X(_ldrb, 7800, f8100000), \
11469 X(_ldrh, 8800, f8300000), \
11470 X(_ldrsb, 5600, f9100000), \
11471 X(_ldrsh, 5e00, f9300000), \
11472 X(_ldr_pc,4800, f85f0000), \
11473 X(_ldr_pc2,4800, f85f0000), \
11474 X(_ldr_sp,9800, f85d0000), \
60f993ce 11475 X(_le, 0000, f00fc001), \
1f6234a3 11476 X(_letp, 0000, f01fc001), \
21d799b5
NC
11477 X(_lsl, 0000, fa00f000), \
11478 X(_lsls, 0000, fa10f000), \
11479 X(_lsr, 0800, fa20f000), \
11480 X(_lsrs, 0800, fa30f000), \
11481 X(_mov, 2000, ea4f0000), \
11482 X(_movs, 2000, ea5f0000), \
11483 X(_mul, 4340, fb00f000), \
11484 X(_muls, 4340, ffffffff), /* no 32b muls */ \
11485 X(_mvn, 43c0, ea6f0000), \
11486 X(_mvns, 43c0, ea7f0000), \
11487 X(_neg, 4240, f1c00000), /* rsb #0 */ \
11488 X(_negs, 4240, f1d00000), /* rsbs #0 */ \
11489 X(_orr, 4300, ea400000), \
11490 X(_orrs, 4300, ea500000), \
11491 X(_pop, bc00, e8bd0000), /* ldmia sp!,... */ \
11492 X(_push, b400, e92d0000), /* stmdb sp!,... */ \
11493 X(_rev, ba00, fa90f080), \
11494 X(_rev16, ba40, fa90f090), \
11495 X(_revsh, bac0, fa90f0b0), \
11496 X(_ror, 41c0, fa60f000), \
11497 X(_rors, 41c0, fa70f000), \
11498 X(_sbc, 4180, eb600000), \
11499 X(_sbcs, 4180, eb700000), \
11500 X(_stmia, c000, e8800000), \
11501 X(_str, 6000, f8400000), \
11502 X(_strb, 7000, f8000000), \
11503 X(_strh, 8000, f8200000), \
11504 X(_str_sp,9000, f84d0000), \
11505 X(_sub, 1e00, eba00000), \
11506 X(_subs, 1e00, ebb00000), \
11507 X(_subi, 8000, f1a00000), \
11508 X(_subis, 8000, f1b00000), \
11509 X(_sxtb, b240, fa4ff080), \
11510 X(_sxth, b200, fa0ff080), \
11511 X(_tst, 4200, ea100f00), \
11512 X(_uxtb, b2c0, fa5ff080), \
11513 X(_uxth, b280, fa1ff080), \
11514 X(_nop, bf00, f3af8000), \
11515 X(_yield, bf10, f3af8001), \
11516 X(_wfe, bf20, f3af8002), \
11517 X(_wfi, bf30, f3af8003), \
60f993ce 11518 X(_wls, 0000, f040c001), \
1f6234a3 11519 X(_wlstp, 0000, f000c001), \
53c4b28b 11520 X(_sev, bf40, f3af8004), \
74db7efb
NC
11521 X(_sevl, bf50, f3af8005), \
11522 X(_udf, de00, f7f0a000)
c19d1205
ZW
11523
11524/* To catch errors in encoding functions, the codes are all offset by
11525 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
11526 as 16-bit instructions. */
21d799b5 11527#define X(a,b,c) T_MNEM##a
c19d1205
ZW
11528enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
11529#undef X
11530
11531#define X(a,b,c) 0x##b
11532static const unsigned short thumb_op16[] = { T16_32_TAB };
11533#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
11534#undef X
11535
11536#define X(a,b,c) 0x##c
11537static const unsigned int thumb_op32[] = { T16_32_TAB };
c921be7d
NC
11538#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
11539#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
c19d1205
ZW
11540#undef X
11541#undef T16_32_TAB
11542
11543/* Thumb instruction encoders, in alphabetical order. */
11544
92e90b6e 11545/* ADDW or SUBW. */
c921be7d 11546
92e90b6e
PB
11547static void
11548do_t_add_sub_w (void)
11549{
11550 int Rd, Rn;
11551
11552 Rd = inst.operands[0].reg;
11553 Rn = inst.operands[1].reg;
11554
539d4391
NC
11555 /* If Rn is REG_PC, this is ADR; if Rn is REG_SP, then this
11556 is the SP-{plus,minus}-immediate form of the instruction. */
11557 if (Rn == REG_SP)
11558 constraint (Rd == REG_PC, BAD_PC);
11559 else
11560 reject_bad_reg (Rd);
fdfde340 11561
92e90b6e 11562 inst.instruction |= (Rn << 16) | (Rd << 8);
e2b0ab59 11563 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
92e90b6e
PB
11564}
11565
c19d1205 11566/* Parse an add or subtract instruction. We get here with inst.instruction
33eaf5de 11567 equaling any of THUMB_OPCODE_add, adds, sub, or subs. */
c19d1205
ZW
11568
11569static void
11570do_t_add_sub (void)
11571{
11572 int Rd, Rs, Rn;
11573
11574 Rd = inst.operands[0].reg;
11575 Rs = (inst.operands[1].present
11576 ? inst.operands[1].reg /* Rd, Rs, foo */
11577 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11578
e07e6e58 11579 if (Rd == REG_PC)
5ee91343 11580 set_pred_insn_type_last ();
e07e6e58 11581
c19d1205
ZW
11582 if (unified_syntax)
11583 {
0110f2b8
PB
11584 bfd_boolean flags;
11585 bfd_boolean narrow;
11586 int opcode;
11587
11588 flags = (inst.instruction == T_MNEM_adds
11589 || inst.instruction == T_MNEM_subs);
11590 if (flags)
5ee91343 11591 narrow = !in_pred_block ();
0110f2b8 11592 else
5ee91343 11593 narrow = in_pred_block ();
c19d1205 11594 if (!inst.operands[2].isreg)
b99bd4ef 11595 {
16805f35
PB
11596 int add;
11597
5c8ed6a4
JW
11598 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11599 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340 11600
16805f35
PB
11601 add = (inst.instruction == T_MNEM_add
11602 || inst.instruction == T_MNEM_adds);
0110f2b8
PB
11603 opcode = 0;
11604 if (inst.size_req != 4)
11605 {
0110f2b8 11606 /* Attempt to use a narrow opcode, with relaxation if
477330fc 11607 appropriate. */
0110f2b8
PB
11608 if (Rd == REG_SP && Rs == REG_SP && !flags)
11609 opcode = add ? T_MNEM_inc_sp : T_MNEM_dec_sp;
11610 else if (Rd <= 7 && Rs == REG_SP && add && !flags)
11611 opcode = T_MNEM_add_sp;
11612 else if (Rd <= 7 && Rs == REG_PC && add && !flags)
11613 opcode = T_MNEM_add_pc;
11614 else if (Rd <= 7 && Rs <= 7 && narrow)
11615 {
11616 if (flags)
11617 opcode = add ? T_MNEM_addis : T_MNEM_subis;
11618 else
11619 opcode = add ? T_MNEM_addi : T_MNEM_subi;
11620 }
11621 if (opcode)
11622 {
11623 inst.instruction = THUMB_OP16(opcode);
11624 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59
AV
11625 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
11626 || (inst.relocs[0].type
11627 > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
a9f02af8
MG
11628 {
11629 if (inst.size_req == 2)
e2b0ab59 11630 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
a9f02af8
MG
11631 else
11632 inst.relax = opcode;
11633 }
0110f2b8
PB
11634 }
11635 else
11636 constraint (inst.size_req == 2, BAD_HIREG);
11637 }
11638 if (inst.size_req == 4
11639 || (inst.size_req != 2 && !opcode))
11640 {
e2b0ab59
AV
11641 constraint ((inst.relocs[0].type
11642 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
11643 && (inst.relocs[0].type
11644 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8 11645 THUMB1_RELOC_ONLY);
efd81785
PB
11646 if (Rd == REG_PC)
11647 {
fdfde340 11648 constraint (add, BAD_PC);
efd81785
PB
11649 constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
11650 _("only SUBS PC, LR, #const allowed"));
e2b0ab59 11651 constraint (inst.relocs[0].exp.X_op != O_constant,
efd81785 11652 _("expression too complex"));
e2b0ab59
AV
11653 constraint (inst.relocs[0].exp.X_add_number < 0
11654 || inst.relocs[0].exp.X_add_number > 0xff,
efd81785
PB
11655 _("immediate value out of range"));
11656 inst.instruction = T2_SUBS_PC_LR
e2b0ab59
AV
11657 | inst.relocs[0].exp.X_add_number;
11658 inst.relocs[0].type = BFD_RELOC_UNUSED;
efd81785
PB
11659 return;
11660 }
11661 else if (Rs == REG_PC)
16805f35
PB
11662 {
11663 /* Always use addw/subw. */
11664 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
e2b0ab59 11665 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
16805f35
PB
11666 }
11667 else
11668 {
11669 inst.instruction = THUMB_OP32 (inst.instruction);
11670 inst.instruction = (inst.instruction & 0xe1ffffff)
11671 | 0x10000000;
11672 if (flags)
e2b0ab59 11673 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
16805f35 11674 else
e2b0ab59 11675 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
16805f35 11676 }
dc4503c6
PB
11677 inst.instruction |= Rd << 8;
11678 inst.instruction |= Rs << 16;
0110f2b8 11679 }
b99bd4ef 11680 }
c19d1205
ZW
11681 else
11682 {
e2b0ab59 11683 unsigned int value = inst.relocs[0].exp.X_add_number;
5f4cb198
NC
11684 unsigned int shift = inst.operands[2].shift_kind;
11685
c19d1205
ZW
11686 Rn = inst.operands[2].reg;
11687 /* See if we can do this with a 16-bit instruction. */
11688 if (!inst.operands[2].shifted && inst.size_req != 4)
11689 {
e27ec89e
PB
11690 if (Rd > 7 || Rs > 7 || Rn > 7)
11691 narrow = FALSE;
11692
11693 if (narrow)
c19d1205 11694 {
e27ec89e
PB
11695 inst.instruction = ((inst.instruction == T_MNEM_adds
11696 || inst.instruction == T_MNEM_add)
c19d1205
ZW
11697 ? T_OPCODE_ADD_R3
11698 : T_OPCODE_SUB_R3);
11699 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
11700 return;
11701 }
b99bd4ef 11702
7e806470 11703 if (inst.instruction == T_MNEM_add && (Rd == Rs || Rd == Rn))
c19d1205 11704 {
7e806470
PB
11705 /* Thumb-1 cores (except v6-M) require at least one high
11706 register in a narrow non flag setting add. */
11707 if (Rd > 7 || Rn > 7
11708 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2)
11709 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_msr))
c19d1205 11710 {
7e806470
PB
11711 if (Rd == Rn)
11712 {
11713 Rn = Rs;
11714 Rs = Rd;
11715 }
c19d1205
ZW
11716 inst.instruction = T_OPCODE_ADD_HI;
11717 inst.instruction |= (Rd & 8) << 4;
11718 inst.instruction |= (Rd & 7);
11719 inst.instruction |= Rn << 3;
11720 return;
11721 }
c19d1205
ZW
11722 }
11723 }
c921be7d 11724
fdfde340 11725 constraint (Rd == REG_PC, BAD_PC);
5c8ed6a4
JW
11726 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11727 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340
JM
11728 constraint (Rs == REG_PC, BAD_PC);
11729 reject_bad_reg (Rn);
11730
c19d1205
ZW
11731 /* If we get here, it can't be done in 16 bits. */
11732 constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
11733 _("shift must be constant"));
11734 inst.instruction = THUMB_OP32 (inst.instruction);
11735 inst.instruction |= Rd << 8;
11736 inst.instruction |= Rs << 16;
5f4cb198
NC
11737 constraint (Rd == REG_SP && Rs == REG_SP && value > 3,
11738 _("shift value over 3 not allowed in thumb mode"));
11739 constraint (Rd == REG_SP && Rs == REG_SP && shift != SHIFT_LSL,
11740 _("only LSL shift allowed in thumb mode"));
c19d1205
ZW
11741 encode_thumb32_shifted_operand (2);
11742 }
11743 }
11744 else
11745 {
11746 constraint (inst.instruction == T_MNEM_adds
11747 || inst.instruction == T_MNEM_subs,
11748 BAD_THUMB32);
b99bd4ef 11749
c19d1205 11750 if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
b99bd4ef 11751 {
c19d1205
ZW
11752 constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
11753 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
11754 BAD_HIREG);
11755
11756 inst.instruction = (inst.instruction == T_MNEM_add
11757 ? 0x0000 : 0x8000);
11758 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59 11759 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
b99bd4ef
NC
11760 return;
11761 }
11762
c19d1205
ZW
11763 Rn = inst.operands[2].reg;
11764 constraint (inst.operands[2].shifted, _("unshifted register required"));
b99bd4ef 11765
c19d1205
ZW
11766 /* We now have Rd, Rs, and Rn set to registers. */
11767 if (Rd > 7 || Rs > 7 || Rn > 7)
b99bd4ef 11768 {
c19d1205
ZW
11769 /* Can't do this for SUB. */
11770 constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
11771 inst.instruction = T_OPCODE_ADD_HI;
11772 inst.instruction |= (Rd & 8) << 4;
11773 inst.instruction |= (Rd & 7);
11774 if (Rs == Rd)
11775 inst.instruction |= Rn << 3;
11776 else if (Rn == Rd)
11777 inst.instruction |= Rs << 3;
11778 else
11779 constraint (1, _("dest must overlap one source register"));
11780 }
11781 else
11782 {
11783 inst.instruction = (inst.instruction == T_MNEM_add
11784 ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
11785 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
b99bd4ef 11786 }
b99bd4ef 11787 }
b99bd4ef
NC
11788}
11789
c19d1205
ZW
11790static void
11791do_t_adr (void)
11792{
fdfde340
JM
11793 unsigned Rd;
11794
11795 Rd = inst.operands[0].reg;
11796 reject_bad_reg (Rd);
11797
11798 if (unified_syntax && inst.size_req == 0 && Rd <= 7)
0110f2b8
PB
11799 {
11800 /* Defer to section relaxation. */
11801 inst.relax = inst.instruction;
11802 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 11803 inst.instruction |= Rd << 4;
0110f2b8
PB
11804 }
11805 else if (unified_syntax && inst.size_req != 2)
e9f89963 11806 {
0110f2b8 11807 /* Generate a 32-bit opcode. */
e9f89963 11808 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 11809 inst.instruction |= Rd << 8;
e2b0ab59
AV
11810 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
11811 inst.relocs[0].pc_rel = 1;
e9f89963
PB
11812 }
11813 else
11814 {
0110f2b8 11815 /* Generate a 16-bit opcode. */
e9f89963 11816 inst.instruction = THUMB_OP16 (inst.instruction);
e2b0ab59
AV
11817 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
11818 inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust. */
11819 inst.relocs[0].pc_rel = 1;
fdfde340 11820 inst.instruction |= Rd << 4;
e9f89963 11821 }
52a86f84 11822
e2b0ab59
AV
11823 if (inst.relocs[0].exp.X_op == O_symbol
11824 && inst.relocs[0].exp.X_add_symbol != NULL
11825 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11826 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11827 inst.relocs[0].exp.X_add_number += 1;
c19d1205 11828}
b99bd4ef 11829
c19d1205
ZW
11830/* Arithmetic instructions for which there is just one 16-bit
11831 instruction encoding, and it allows only two low registers.
11832 For maximal compatibility with ARM syntax, we allow three register
11833 operands even when Thumb-32 instructions are not available, as long
11834 as the first two are identical. For instance, both "sbc r0,r1" and
11835 "sbc r0,r0,r1" are allowed. */
b99bd4ef 11836static void
c19d1205 11837do_t_arit3 (void)
b99bd4ef 11838{
c19d1205 11839 int Rd, Rs, Rn;
b99bd4ef 11840
c19d1205
ZW
11841 Rd = inst.operands[0].reg;
11842 Rs = (inst.operands[1].present
11843 ? inst.operands[1].reg /* Rd, Rs, foo */
11844 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11845 Rn = inst.operands[2].reg;
b99bd4ef 11846
fdfde340
JM
11847 reject_bad_reg (Rd);
11848 reject_bad_reg (Rs);
11849 if (inst.operands[2].isreg)
11850 reject_bad_reg (Rn);
11851
c19d1205 11852 if (unified_syntax)
b99bd4ef 11853 {
c19d1205
ZW
11854 if (!inst.operands[2].isreg)
11855 {
11856 /* For an immediate, we always generate a 32-bit opcode;
11857 section relaxation will shrink it later if possible. */
11858 inst.instruction = THUMB_OP32 (inst.instruction);
11859 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11860 inst.instruction |= Rd << 8;
11861 inst.instruction |= Rs << 16;
e2b0ab59 11862 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
c19d1205
ZW
11863 }
11864 else
11865 {
e27ec89e
PB
11866 bfd_boolean narrow;
11867
c19d1205 11868 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11869 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 11870 narrow = !in_pred_block ();
e27ec89e 11871 else
5ee91343 11872 narrow = in_pred_block ();
e27ec89e
PB
11873
11874 if (Rd > 7 || Rn > 7 || Rs > 7)
11875 narrow = FALSE;
11876 if (inst.operands[2].shifted)
11877 narrow = FALSE;
11878 if (inst.size_req == 4)
11879 narrow = FALSE;
11880
11881 if (narrow
c19d1205
ZW
11882 && Rd == Rs)
11883 {
11884 inst.instruction = THUMB_OP16 (inst.instruction);
11885 inst.instruction |= Rd;
11886 inst.instruction |= Rn << 3;
11887 return;
11888 }
b99bd4ef 11889
c19d1205
ZW
11890 /* If we get here, it can't be done in 16 bits. */
11891 constraint (inst.operands[2].shifted
11892 && inst.operands[2].immisreg,
11893 _("shift must be constant"));
11894 inst.instruction = THUMB_OP32 (inst.instruction);
11895 inst.instruction |= Rd << 8;
11896 inst.instruction |= Rs << 16;
11897 encode_thumb32_shifted_operand (2);
11898 }
a737bd4d 11899 }
c19d1205 11900 else
b99bd4ef 11901 {
c19d1205
ZW
11902 /* On its face this is a lie - the instruction does set the
11903 flags. However, the only supported mnemonic in this mode
11904 says it doesn't. */
11905 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11906
c19d1205
ZW
11907 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11908 _("unshifted register required"));
11909 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11910 constraint (Rd != Rs,
11911 _("dest and source1 must be the same register"));
a737bd4d 11912
c19d1205
ZW
11913 inst.instruction = THUMB_OP16 (inst.instruction);
11914 inst.instruction |= Rd;
11915 inst.instruction |= Rn << 3;
b99bd4ef 11916 }
a737bd4d 11917}
b99bd4ef 11918
c19d1205
ZW
11919/* Similarly, but for instructions where the arithmetic operation is
11920 commutative, so we can allow either of them to be different from
11921 the destination operand in a 16-bit instruction. For instance, all
11922 three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
11923 accepted. */
11924static void
11925do_t_arit3c (void)
a737bd4d 11926{
c19d1205 11927 int Rd, Rs, Rn;
b99bd4ef 11928
c19d1205
ZW
11929 Rd = inst.operands[0].reg;
11930 Rs = (inst.operands[1].present
11931 ? inst.operands[1].reg /* Rd, Rs, foo */
11932 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11933 Rn = inst.operands[2].reg;
c921be7d 11934
fdfde340
JM
11935 reject_bad_reg (Rd);
11936 reject_bad_reg (Rs);
11937 if (inst.operands[2].isreg)
11938 reject_bad_reg (Rn);
a737bd4d 11939
c19d1205 11940 if (unified_syntax)
a737bd4d 11941 {
c19d1205 11942 if (!inst.operands[2].isreg)
b99bd4ef 11943 {
c19d1205
ZW
11944 /* For an immediate, we always generate a 32-bit opcode;
11945 section relaxation will shrink it later if possible. */
11946 inst.instruction = THUMB_OP32 (inst.instruction);
11947 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11948 inst.instruction |= Rd << 8;
11949 inst.instruction |= Rs << 16;
e2b0ab59 11950 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 11951 }
c19d1205 11952 else
a737bd4d 11953 {
e27ec89e
PB
11954 bfd_boolean narrow;
11955
c19d1205 11956 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11957 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 11958 narrow = !in_pred_block ();
e27ec89e 11959 else
5ee91343 11960 narrow = in_pred_block ();
e27ec89e
PB
11961
11962 if (Rd > 7 || Rn > 7 || Rs > 7)
11963 narrow = FALSE;
11964 if (inst.operands[2].shifted)
11965 narrow = FALSE;
11966 if (inst.size_req == 4)
11967 narrow = FALSE;
11968
11969 if (narrow)
a737bd4d 11970 {
c19d1205 11971 if (Rd == Rs)
a737bd4d 11972 {
c19d1205
ZW
11973 inst.instruction = THUMB_OP16 (inst.instruction);
11974 inst.instruction |= Rd;
11975 inst.instruction |= Rn << 3;
11976 return;
a737bd4d 11977 }
c19d1205 11978 if (Rd == Rn)
a737bd4d 11979 {
c19d1205
ZW
11980 inst.instruction = THUMB_OP16 (inst.instruction);
11981 inst.instruction |= Rd;
11982 inst.instruction |= Rs << 3;
11983 return;
a737bd4d
NC
11984 }
11985 }
c19d1205
ZW
11986
11987 /* If we get here, it can't be done in 16 bits. */
11988 constraint (inst.operands[2].shifted
11989 && inst.operands[2].immisreg,
11990 _("shift must be constant"));
11991 inst.instruction = THUMB_OP32 (inst.instruction);
11992 inst.instruction |= Rd << 8;
11993 inst.instruction |= Rs << 16;
11994 encode_thumb32_shifted_operand (2);
a737bd4d 11995 }
b99bd4ef 11996 }
c19d1205
ZW
11997 else
11998 {
11999 /* On its face this is a lie - the instruction does set the
12000 flags. However, the only supported mnemonic in this mode
12001 says it doesn't. */
12002 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 12003
c19d1205
ZW
12004 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
12005 _("unshifted register required"));
12006 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
12007
12008 inst.instruction = THUMB_OP16 (inst.instruction);
12009 inst.instruction |= Rd;
12010
12011 if (Rd == Rs)
12012 inst.instruction |= Rn << 3;
12013 else if (Rd == Rn)
12014 inst.instruction |= Rs << 3;
12015 else
12016 constraint (1, _("dest must overlap one source register"));
12017 }
a737bd4d
NC
12018}
12019
c19d1205
ZW
12020static void
12021do_t_bfc (void)
a737bd4d 12022{
fdfde340 12023 unsigned Rd;
c19d1205
ZW
12024 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
12025 constraint (msb > 32, _("bit-field extends past end of register"));
12026 /* The instruction encoding stores the LSB and MSB,
12027 not the LSB and width. */
fdfde340
JM
12028 Rd = inst.operands[0].reg;
12029 reject_bad_reg (Rd);
12030 inst.instruction |= Rd << 8;
c19d1205
ZW
12031 inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
12032 inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
12033 inst.instruction |= msb - 1;
b99bd4ef
NC
12034}
12035
c19d1205
ZW
12036static void
12037do_t_bfi (void)
b99bd4ef 12038{
fdfde340 12039 int Rd, Rn;
c19d1205 12040 unsigned int msb;
b99bd4ef 12041
fdfde340
JM
12042 Rd = inst.operands[0].reg;
12043 reject_bad_reg (Rd);
12044
c19d1205
ZW
12045 /* #0 in second position is alternative syntax for bfc, which is
12046 the same instruction but with REG_PC in the Rm field. */
12047 if (!inst.operands[1].isreg)
fdfde340
JM
12048 Rn = REG_PC;
12049 else
12050 {
12051 Rn = inst.operands[1].reg;
12052 reject_bad_reg (Rn);
12053 }
b99bd4ef 12054
c19d1205
ZW
12055 msb = inst.operands[2].imm + inst.operands[3].imm;
12056 constraint (msb > 32, _("bit-field extends past end of register"));
12057 /* The instruction encoding stores the LSB and MSB,
12058 not the LSB and width. */
fdfde340
JM
12059 inst.instruction |= Rd << 8;
12060 inst.instruction |= Rn << 16;
c19d1205
ZW
12061 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
12062 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
12063 inst.instruction |= msb - 1;
b99bd4ef
NC
12064}
12065
c19d1205
ZW
12066static void
12067do_t_bfx (void)
b99bd4ef 12068{
fdfde340
JM
12069 unsigned Rd, Rn;
12070
12071 Rd = inst.operands[0].reg;
12072 Rn = inst.operands[1].reg;
12073
12074 reject_bad_reg (Rd);
12075 reject_bad_reg (Rn);
12076
c19d1205
ZW
12077 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
12078 _("bit-field extends past end of register"));
fdfde340
JM
12079 inst.instruction |= Rd << 8;
12080 inst.instruction |= Rn << 16;
c19d1205
ZW
12081 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
12082 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
12083 inst.instruction |= inst.operands[3].imm - 1;
12084}
b99bd4ef 12085
c19d1205
ZW
12086/* ARM V5 Thumb BLX (argument parse)
12087 BLX <target_addr> which is BLX(1)
12088 BLX <Rm> which is BLX(2)
12089 Unfortunately, there are two different opcodes for this mnemonic.
12090 So, the insns[].value is not used, and the code here zaps values
12091 into inst.instruction.
b99bd4ef 12092
c19d1205
ZW
12093 ??? How to take advantage of the additional two bits of displacement
12094 available in Thumb32 mode? Need new relocation? */
b99bd4ef 12095
c19d1205
ZW
12096static void
12097do_t_blx (void)
12098{
5ee91343 12099 set_pred_insn_type_last ();
e07e6e58 12100
c19d1205 12101 if (inst.operands[0].isreg)
fdfde340
JM
12102 {
12103 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
12104 /* We have a register, so this is BLX(2). */
12105 inst.instruction |= inst.operands[0].reg << 3;
12106 }
b99bd4ef
NC
12107 else
12108 {
c19d1205 12109 /* No register. This must be BLX(1). */
2fc8bdac 12110 inst.instruction = 0xf000e800;
0855e32b 12111 encode_branch (BFD_RELOC_THUMB_PCREL_BLX);
b99bd4ef
NC
12112 }
12113}
12114
c19d1205
ZW
12115static void
12116do_t_branch (void)
b99bd4ef 12117{
0110f2b8 12118 int opcode;
dfa9f0d5 12119 int cond;
2fe88214 12120 bfd_reloc_code_real_type reloc;
dfa9f0d5 12121
e07e6e58 12122 cond = inst.cond;
5ee91343 12123 set_pred_insn_type (IF_INSIDE_IT_LAST_INSN);
e07e6e58 12124
5ee91343 12125 if (in_pred_block ())
dfa9f0d5
PB
12126 {
12127 /* Conditional branches inside IT blocks are encoded as unconditional
477330fc 12128 branches. */
dfa9f0d5 12129 cond = COND_ALWAYS;
dfa9f0d5
PB
12130 }
12131 else
12132 cond = inst.cond;
12133
12134 if (cond != COND_ALWAYS)
0110f2b8
PB
12135 opcode = T_MNEM_bcond;
12136 else
12137 opcode = inst.instruction;
12138
12d6b0b7
RS
12139 if (unified_syntax
12140 && (inst.size_req == 4
10960bfb
PB
12141 || (inst.size_req != 2
12142 && (inst.operands[0].hasreloc
e2b0ab59 12143 || inst.relocs[0].exp.X_op == O_constant))))
c19d1205 12144 {
0110f2b8 12145 inst.instruction = THUMB_OP32(opcode);
dfa9f0d5 12146 if (cond == COND_ALWAYS)
9ae92b05 12147 reloc = BFD_RELOC_THUMB_PCREL_BRANCH25;
c19d1205
ZW
12148 else
12149 {
ff8646ee
TP
12150 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2),
12151 _("selected architecture does not support "
12152 "wide conditional branch instruction"));
12153
9c2799c2 12154 gas_assert (cond != 0xF);
dfa9f0d5 12155 inst.instruction |= cond << 22;
9ae92b05 12156 reloc = BFD_RELOC_THUMB_PCREL_BRANCH20;
c19d1205
ZW
12157 }
12158 }
b99bd4ef
NC
12159 else
12160 {
0110f2b8 12161 inst.instruction = THUMB_OP16(opcode);
dfa9f0d5 12162 if (cond == COND_ALWAYS)
9ae92b05 12163 reloc = BFD_RELOC_THUMB_PCREL_BRANCH12;
c19d1205 12164 else
b99bd4ef 12165 {
dfa9f0d5 12166 inst.instruction |= cond << 8;
9ae92b05 12167 reloc = BFD_RELOC_THUMB_PCREL_BRANCH9;
b99bd4ef 12168 }
0110f2b8
PB
12169 /* Allow section relaxation. */
12170 if (unified_syntax && inst.size_req != 2)
12171 inst.relax = opcode;
b99bd4ef 12172 }
e2b0ab59
AV
12173 inst.relocs[0].type = reloc;
12174 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
12175}
12176
8884b720 12177/* Actually do the work for Thumb state bkpt and hlt. The only difference
bacebabc 12178 between the two is the maximum immediate allowed - which is passed in
8884b720 12179 RANGE. */
b99bd4ef 12180static void
8884b720 12181do_t_bkpt_hlt1 (int range)
b99bd4ef 12182{
dfa9f0d5
PB
12183 constraint (inst.cond != COND_ALWAYS,
12184 _("instruction is always unconditional"));
c19d1205 12185 if (inst.operands[0].present)
b99bd4ef 12186 {
8884b720 12187 constraint (inst.operands[0].imm > range,
c19d1205
ZW
12188 _("immediate value out of range"));
12189 inst.instruction |= inst.operands[0].imm;
b99bd4ef 12190 }
8884b720 12191
5ee91343 12192 set_pred_insn_type (NEUTRAL_IT_INSN);
8884b720
MGD
12193}
12194
12195static void
12196do_t_hlt (void)
12197{
12198 do_t_bkpt_hlt1 (63);
12199}
12200
12201static void
12202do_t_bkpt (void)
12203{
12204 do_t_bkpt_hlt1 (255);
b99bd4ef
NC
12205}
12206
12207static void
c19d1205 12208do_t_branch23 (void)
b99bd4ef 12209{
5ee91343 12210 set_pred_insn_type_last ();
0855e32b 12211 encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
fa94de6b 12212
0855e32b
NS
12213 /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
12214 this file. We used to simply ignore the PLT reloc type here --
12215 the branch encoding is now needed to deal with TLSCALL relocs.
12216 So if we see a PLT reloc now, put it back to how it used to be to
12217 keep the preexisting behaviour. */
e2b0ab59
AV
12218 if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
12219 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
90e4755a 12220
4343666d 12221#if defined(OBJ_COFF)
c19d1205
ZW
12222 /* If the destination of the branch is a defined symbol which does not have
12223 the THUMB_FUNC attribute, then we must be calling a function which has
12224 the (interfacearm) attribute. We look for the Thumb entry point to that
12225 function and change the branch to refer to that function instead. */
e2b0ab59
AV
12226 if ( inst.relocs[0].exp.X_op == O_symbol
12227 && inst.relocs[0].exp.X_add_symbol != NULL
12228 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
12229 && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
12230 inst.relocs[0].exp.X_add_symbol
12231 = find_real_start (inst.relocs[0].exp.X_add_symbol);
4343666d 12232#endif
90e4755a
RE
12233}
12234
12235static void
c19d1205 12236do_t_bx (void)
90e4755a 12237{
5ee91343 12238 set_pred_insn_type_last ();
c19d1205
ZW
12239 inst.instruction |= inst.operands[0].reg << 3;
12240 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
12241 should cause the alignment to be checked once it is known. This is
12242 because BX PC only works if the instruction is word aligned. */
12243}
90e4755a 12244
c19d1205
ZW
12245static void
12246do_t_bxj (void)
12247{
fdfde340 12248 int Rm;
90e4755a 12249
5ee91343 12250 set_pred_insn_type_last ();
fdfde340
JM
12251 Rm = inst.operands[0].reg;
12252 reject_bad_reg (Rm);
12253 inst.instruction |= Rm << 16;
90e4755a
RE
12254}
12255
12256static void
c19d1205 12257do_t_clz (void)
90e4755a 12258{
fdfde340
JM
12259 unsigned Rd;
12260 unsigned Rm;
12261
12262 Rd = inst.operands[0].reg;
12263 Rm = inst.operands[1].reg;
12264
12265 reject_bad_reg (Rd);
12266 reject_bad_reg (Rm);
12267
12268 inst.instruction |= Rd << 8;
12269 inst.instruction |= Rm << 16;
12270 inst.instruction |= Rm;
c19d1205 12271}
90e4755a 12272
e39c1607
SD
12273/* For the Armv8.1-M conditional instructions. */
12274static void
12275do_t_cond (void)
12276{
12277 unsigned Rd, Rn, Rm;
12278 signed int cond;
12279
12280 constraint (inst.cond != COND_ALWAYS, BAD_COND);
12281
12282 Rd = inst.operands[0].reg;
12283 switch (inst.instruction)
12284 {
12285 case T_MNEM_csinc:
12286 case T_MNEM_csinv:
12287 case T_MNEM_csneg:
12288 case T_MNEM_csel:
12289 Rn = inst.operands[1].reg;
12290 Rm = inst.operands[2].reg;
12291 cond = inst.operands[3].imm;
12292 constraint (Rn == REG_SP, BAD_SP);
12293 constraint (Rm == REG_SP, BAD_SP);
12294 break;
12295
12296 case T_MNEM_cinc:
12297 case T_MNEM_cinv:
12298 case T_MNEM_cneg:
12299 Rn = inst.operands[1].reg;
12300 cond = inst.operands[2].imm;
12301 /* Invert the last bit to invert the cond. */
12302 cond = TOGGLE_BIT (cond, 0);
12303 constraint (Rn == REG_SP, BAD_SP);
12304 Rm = Rn;
12305 break;
12306
12307 case T_MNEM_csetm:
12308 case T_MNEM_cset:
12309 cond = inst.operands[1].imm;
12310 /* Invert the last bit to invert the cond. */
12311 cond = TOGGLE_BIT (cond, 0);
12312 Rn = REG_PC;
12313 Rm = REG_PC;
12314 break;
12315
12316 default: abort ();
12317 }
12318
12319 set_pred_insn_type (OUTSIDE_PRED_INSN);
12320 inst.instruction = THUMB_OP32 (inst.instruction);
12321 inst.instruction |= Rd << 8;
12322 inst.instruction |= Rn << 16;
12323 inst.instruction |= Rm;
12324 inst.instruction |= cond << 4;
12325}
12326
91d8b670
JG
12327static void
12328do_t_csdb (void)
12329{
5ee91343 12330 set_pred_insn_type (OUTSIDE_PRED_INSN);
91d8b670
JG
12331}
12332
dfa9f0d5
PB
12333static void
12334do_t_cps (void)
12335{
5ee91343 12336 set_pred_insn_type (OUTSIDE_PRED_INSN);
dfa9f0d5
PB
12337 inst.instruction |= inst.operands[0].imm;
12338}
12339
c19d1205
ZW
12340static void
12341do_t_cpsi (void)
12342{
5ee91343 12343 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205 12344 if (unified_syntax
62b3e311
PB
12345 && (inst.operands[1].present || inst.size_req == 4)
12346 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
90e4755a 12347 {
c19d1205
ZW
12348 unsigned int imod = (inst.instruction & 0x0030) >> 4;
12349 inst.instruction = 0xf3af8000;
12350 inst.instruction |= imod << 9;
12351 inst.instruction |= inst.operands[0].imm << 5;
12352 if (inst.operands[1].present)
12353 inst.instruction |= 0x100 | inst.operands[1].imm;
90e4755a 12354 }
c19d1205 12355 else
90e4755a 12356 {
62b3e311
PB
12357 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)
12358 && (inst.operands[0].imm & 4),
12359 _("selected processor does not support 'A' form "
12360 "of this instruction"));
12361 constraint (inst.operands[1].present || inst.size_req == 4,
c19d1205
ZW
12362 _("Thumb does not support the 2-argument "
12363 "form of this instruction"));
12364 inst.instruction |= inst.operands[0].imm;
90e4755a 12365 }
90e4755a
RE
12366}
12367
c19d1205
ZW
12368/* THUMB CPY instruction (argument parse). */
12369
90e4755a 12370static void
c19d1205 12371do_t_cpy (void)
90e4755a 12372{
c19d1205 12373 if (inst.size_req == 4)
90e4755a 12374 {
c19d1205
ZW
12375 inst.instruction = THUMB_OP32 (T_MNEM_mov);
12376 inst.instruction |= inst.operands[0].reg << 8;
12377 inst.instruction |= inst.operands[1].reg;
90e4755a 12378 }
c19d1205 12379 else
90e4755a 12380 {
c19d1205
ZW
12381 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
12382 inst.instruction |= (inst.operands[0].reg & 0x7);
12383 inst.instruction |= inst.operands[1].reg << 3;
90e4755a 12384 }
90e4755a
RE
12385}
12386
90e4755a 12387static void
25fe350b 12388do_t_cbz (void)
90e4755a 12389{
5ee91343 12390 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
12391 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12392 inst.instruction |= inst.operands[0].reg;
e2b0ab59
AV
12393 inst.relocs[0].pc_rel = 1;
12394 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
c19d1205 12395}
90e4755a 12396
62b3e311
PB
12397static void
12398do_t_dbg (void)
12399{
12400 inst.instruction |= inst.operands[0].imm;
12401}
12402
12403static void
12404do_t_div (void)
12405{
fdfde340
JM
12406 unsigned Rd, Rn, Rm;
12407
12408 Rd = inst.operands[0].reg;
12409 Rn = (inst.operands[1].present
12410 ? inst.operands[1].reg : Rd);
12411 Rm = inst.operands[2].reg;
12412
12413 reject_bad_reg (Rd);
12414 reject_bad_reg (Rn);
12415 reject_bad_reg (Rm);
12416
12417 inst.instruction |= Rd << 8;
12418 inst.instruction |= Rn << 16;
12419 inst.instruction |= Rm;
62b3e311
PB
12420}
12421
c19d1205
ZW
12422static void
12423do_t_hint (void)
12424{
12425 if (unified_syntax && inst.size_req == 4)
12426 inst.instruction = THUMB_OP32 (inst.instruction);
12427 else
12428 inst.instruction = THUMB_OP16 (inst.instruction);
12429}
90e4755a 12430
c19d1205
ZW
12431static void
12432do_t_it (void)
12433{
12434 unsigned int cond = inst.operands[0].imm;
e27ec89e 12435
5ee91343
AV
12436 set_pred_insn_type (IT_INSN);
12437 now_pred.mask = (inst.instruction & 0xf) | 0x10;
12438 now_pred.cc = cond;
12439 now_pred.warn_deprecated = FALSE;
12440 now_pred.type = SCALAR_PRED;
e27ec89e
PB
12441
12442 /* If the condition is a negative condition, invert the mask. */
c19d1205 12443 if ((cond & 0x1) == 0x0)
90e4755a 12444 {
c19d1205 12445 unsigned int mask = inst.instruction & 0x000f;
90e4755a 12446
c19d1205 12447 if ((mask & 0x7) == 0)
5a01bb1d
MGD
12448 {
12449 /* No conversion needed. */
5ee91343 12450 now_pred.block_length = 1;
5a01bb1d 12451 }
c19d1205 12452 else if ((mask & 0x3) == 0)
5a01bb1d
MGD
12453 {
12454 mask ^= 0x8;
5ee91343 12455 now_pred.block_length = 2;
5a01bb1d 12456 }
e27ec89e 12457 else if ((mask & 0x1) == 0)
5a01bb1d
MGD
12458 {
12459 mask ^= 0xC;
5ee91343 12460 now_pred.block_length = 3;
5a01bb1d 12461 }
c19d1205 12462 else
5a01bb1d
MGD
12463 {
12464 mask ^= 0xE;
5ee91343 12465 now_pred.block_length = 4;
5a01bb1d 12466 }
90e4755a 12467
e27ec89e
PB
12468 inst.instruction &= 0xfff0;
12469 inst.instruction |= mask;
c19d1205 12470 }
90e4755a 12471
c19d1205
ZW
12472 inst.instruction |= cond << 4;
12473}
90e4755a 12474
3c707909
PB
12475/* Helper function used for both push/pop and ldm/stm. */
12476static void
4b5a202f
AV
12477encode_thumb2_multi (bfd_boolean do_io, int base, unsigned mask,
12478 bfd_boolean writeback)
3c707909 12479{
4b5a202f 12480 bfd_boolean load, store;
3c707909 12481
4b5a202f
AV
12482 gas_assert (base != -1 || !do_io);
12483 load = do_io && ((inst.instruction & (1 << 20)) != 0);
12484 store = do_io && !load;
3c707909
PB
12485
12486 if (mask & (1 << 13))
12487 inst.error = _("SP not allowed in register list");
1e5b0379 12488
4b5a202f 12489 if (do_io && (mask & (1 << base)) != 0
1e5b0379
NC
12490 && writeback)
12491 inst.error = _("having the base register in the register list when "
12492 "using write back is UNPREDICTABLE");
12493
3c707909
PB
12494 if (load)
12495 {
e07e6e58 12496 if (mask & (1 << 15))
477330fc
RM
12497 {
12498 if (mask & (1 << 14))
12499 inst.error = _("LR and PC should not both be in register list");
12500 else
5ee91343 12501 set_pred_insn_type_last ();
477330fc 12502 }
3c707909 12503 }
4b5a202f 12504 else if (store)
3c707909
PB
12505 {
12506 if (mask & (1 << 15))
12507 inst.error = _("PC not allowed in register list");
3c707909
PB
12508 }
12509
4b5a202f 12510 if (do_io && ((mask & (mask - 1)) == 0))
3c707909
PB
12511 {
12512 /* Single register transfers implemented as str/ldr. */
12513 if (writeback)
12514 {
12515 if (inst.instruction & (1 << 23))
12516 inst.instruction = 0x00000b04; /* ia! -> [base], #4 */
12517 else
12518 inst.instruction = 0x00000d04; /* db! -> [base, #-4]! */
12519 }
12520 else
12521 {
12522 if (inst.instruction & (1 << 23))
12523 inst.instruction = 0x00800000; /* ia -> [base] */
12524 else
12525 inst.instruction = 0x00000c04; /* db -> [base, #-4] */
12526 }
12527
12528 inst.instruction |= 0xf8400000;
12529 if (load)
12530 inst.instruction |= 0x00100000;
12531
5f4273c7 12532 mask = ffs (mask) - 1;
3c707909
PB
12533 mask <<= 12;
12534 }
12535 else if (writeback)
12536 inst.instruction |= WRITE_BACK;
12537
12538 inst.instruction |= mask;
4b5a202f
AV
12539 if (do_io)
12540 inst.instruction |= base << 16;
3c707909
PB
12541}
12542
c19d1205
ZW
12543static void
12544do_t_ldmstm (void)
12545{
12546 /* This really doesn't seem worth it. */
e2b0ab59 12547 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205
ZW
12548 _("expression too complex"));
12549 constraint (inst.operands[1].writeback,
12550 _("Thumb load/store multiple does not support {reglist}^"));
90e4755a 12551
c19d1205
ZW
12552 if (unified_syntax)
12553 {
3c707909
PB
12554 bfd_boolean narrow;
12555 unsigned mask;
12556
12557 narrow = FALSE;
c19d1205
ZW
12558 /* See if we can use a 16-bit instruction. */
12559 if (inst.instruction < 0xffff /* not ldmdb/stmdb */
12560 && inst.size_req != 4
3c707909 12561 && !(inst.operands[1].imm & ~0xff))
90e4755a 12562 {
3c707909 12563 mask = 1 << inst.operands[0].reg;
90e4755a 12564
eab4f823 12565 if (inst.operands[0].reg <= 7)
90e4755a 12566 {
3c707909 12567 if (inst.instruction == T_MNEM_stmia
eab4f823
MGD
12568 ? inst.operands[0].writeback
12569 : (inst.operands[0].writeback
12570 == !(inst.operands[1].imm & mask)))
477330fc 12571 {
eab4f823
MGD
12572 if (inst.instruction == T_MNEM_stmia
12573 && (inst.operands[1].imm & mask)
12574 && (inst.operands[1].imm & (mask - 1)))
12575 as_warn (_("value stored for r%d is UNKNOWN"),
12576 inst.operands[0].reg);
3c707909 12577
eab4f823
MGD
12578 inst.instruction = THUMB_OP16 (inst.instruction);
12579 inst.instruction |= inst.operands[0].reg << 8;
12580 inst.instruction |= inst.operands[1].imm;
12581 narrow = TRUE;
12582 }
12583 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12584 {
12585 /* This means 1 register in reg list one of 3 situations:
12586 1. Instruction is stmia, but without writeback.
12587 2. lmdia without writeback, but with Rn not in
477330fc 12588 reglist.
eab4f823
MGD
12589 3. ldmia with writeback, but with Rn in reglist.
12590 Case 3 is UNPREDICTABLE behaviour, so we handle
12591 case 1 and 2 which can be converted into a 16-bit
12592 str or ldr. The SP cases are handled below. */
12593 unsigned long opcode;
12594 /* First, record an error for Case 3. */
12595 if (inst.operands[1].imm & mask
12596 && inst.operands[0].writeback)
fa94de6b 12597 inst.error =
eab4f823
MGD
12598 _("having the base register in the register list when "
12599 "using write back is UNPREDICTABLE");
fa94de6b
RM
12600
12601 opcode = (inst.instruction == T_MNEM_stmia ? T_MNEM_str
eab4f823
MGD
12602 : T_MNEM_ldr);
12603 inst.instruction = THUMB_OP16 (opcode);
12604 inst.instruction |= inst.operands[0].reg << 3;
12605 inst.instruction |= (ffs (inst.operands[1].imm)-1);
12606 narrow = TRUE;
12607 }
90e4755a 12608 }
eab4f823 12609 else if (inst.operands[0] .reg == REG_SP)
90e4755a 12610 {
eab4f823
MGD
12611 if (inst.operands[0].writeback)
12612 {
fa94de6b 12613 inst.instruction =
eab4f823 12614 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12615 ? T_MNEM_push : T_MNEM_pop);
eab4f823 12616 inst.instruction |= inst.operands[1].imm;
477330fc 12617 narrow = TRUE;
eab4f823
MGD
12618 }
12619 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12620 {
fa94de6b 12621 inst.instruction =
eab4f823 12622 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12623 ? T_MNEM_str_sp : T_MNEM_ldr_sp);
eab4f823 12624 inst.instruction |= ((ffs (inst.operands[1].imm)-1) << 8);
477330fc 12625 narrow = TRUE;
eab4f823 12626 }
90e4755a 12627 }
3c707909
PB
12628 }
12629
12630 if (!narrow)
12631 {
c19d1205
ZW
12632 if (inst.instruction < 0xffff)
12633 inst.instruction = THUMB_OP32 (inst.instruction);
3c707909 12634
4b5a202f
AV
12635 encode_thumb2_multi (TRUE /* do_io */, inst.operands[0].reg,
12636 inst.operands[1].imm,
12637 inst.operands[0].writeback);
90e4755a
RE
12638 }
12639 }
c19d1205 12640 else
90e4755a 12641 {
c19d1205
ZW
12642 constraint (inst.operands[0].reg > 7
12643 || (inst.operands[1].imm & ~0xff), BAD_HIREG);
1198ca51
PB
12644 constraint (inst.instruction != T_MNEM_ldmia
12645 && inst.instruction != T_MNEM_stmia,
12646 _("Thumb-2 instruction only valid in unified syntax"));
c19d1205 12647 if (inst.instruction == T_MNEM_stmia)
f03698e6 12648 {
c19d1205
ZW
12649 if (!inst.operands[0].writeback)
12650 as_warn (_("this instruction will write back the base register"));
12651 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
12652 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
1e5b0379 12653 as_warn (_("value stored for r%d is UNKNOWN"),
c19d1205 12654 inst.operands[0].reg);
f03698e6 12655 }
c19d1205 12656 else
90e4755a 12657 {
c19d1205
ZW
12658 if (!inst.operands[0].writeback
12659 && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
12660 as_warn (_("this instruction will write back the base register"));
12661 else if (inst.operands[0].writeback
12662 && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
12663 as_warn (_("this instruction will not write back the base register"));
90e4755a
RE
12664 }
12665
c19d1205
ZW
12666 inst.instruction = THUMB_OP16 (inst.instruction);
12667 inst.instruction |= inst.operands[0].reg << 8;
12668 inst.instruction |= inst.operands[1].imm;
12669 }
12670}
e28cd48c 12671
c19d1205
ZW
12672static void
12673do_t_ldrex (void)
12674{
12675 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
12676 || inst.operands[1].postind || inst.operands[1].writeback
12677 || inst.operands[1].immisreg || inst.operands[1].shifted
12678 || inst.operands[1].negative,
01cfc07f 12679 BAD_ADDR_MODE);
e28cd48c 12680
5be8be5d
DG
12681 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
12682
c19d1205
ZW
12683 inst.instruction |= inst.operands[0].reg << 12;
12684 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 12685 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
c19d1205 12686}
e28cd48c 12687
c19d1205
ZW
12688static void
12689do_t_ldrexd (void)
12690{
12691 if (!inst.operands[1].present)
1cac9012 12692 {
c19d1205
ZW
12693 constraint (inst.operands[0].reg == REG_LR,
12694 _("r14 not allowed as first register "
12695 "when second register is omitted"));
12696 inst.operands[1].reg = inst.operands[0].reg + 1;
b99bd4ef 12697 }
c19d1205
ZW
12698 constraint (inst.operands[0].reg == inst.operands[1].reg,
12699 BAD_OVERLAP);
b99bd4ef 12700
c19d1205
ZW
12701 inst.instruction |= inst.operands[0].reg << 12;
12702 inst.instruction |= inst.operands[1].reg << 8;
12703 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
12704}
12705
12706static void
c19d1205 12707do_t_ldst (void)
b99bd4ef 12708{
0110f2b8
PB
12709 unsigned long opcode;
12710 int Rn;
12711
e07e6e58
NC
12712 if (inst.operands[0].isreg
12713 && !inst.operands[0].preind
12714 && inst.operands[0].reg == REG_PC)
5ee91343 12715 set_pred_insn_type_last ();
e07e6e58 12716
0110f2b8 12717 opcode = inst.instruction;
c19d1205 12718 if (unified_syntax)
b99bd4ef 12719 {
53365c0d
PB
12720 if (!inst.operands[1].isreg)
12721 {
12722 if (opcode <= 0xffff)
12723 inst.instruction = THUMB_OP32 (opcode);
8335d6aa 12724 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
53365c0d
PB
12725 return;
12726 }
0110f2b8
PB
12727 if (inst.operands[1].isreg
12728 && !inst.operands[1].writeback
c19d1205
ZW
12729 && !inst.operands[1].shifted && !inst.operands[1].postind
12730 && !inst.operands[1].negative && inst.operands[0].reg <= 7
0110f2b8
PB
12731 && opcode <= 0xffff
12732 && inst.size_req != 4)
c19d1205 12733 {
0110f2b8
PB
12734 /* Insn may have a 16-bit form. */
12735 Rn = inst.operands[1].reg;
12736 if (inst.operands[1].immisreg)
12737 {
12738 inst.instruction = THUMB_OP16 (opcode);
5f4273c7 12739 /* [Rn, Rik] */
0110f2b8
PB
12740 if (Rn <= 7 && inst.operands[1].imm <= 7)
12741 goto op16;
5be8be5d
DG
12742 else if (opcode != T_MNEM_ldr && opcode != T_MNEM_str)
12743 reject_bad_reg (inst.operands[1].imm);
0110f2b8
PB
12744 }
12745 else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
12746 && opcode != T_MNEM_ldrsb)
12747 || ((Rn == REG_PC || Rn == REG_SP) && opcode == T_MNEM_ldr)
12748 || (Rn == REG_SP && opcode == T_MNEM_str))
12749 {
12750 /* [Rn, #const] */
12751 if (Rn > 7)
12752 {
12753 if (Rn == REG_PC)
12754 {
e2b0ab59 12755 if (inst.relocs[0].pc_rel)
0110f2b8
PB
12756 opcode = T_MNEM_ldr_pc2;
12757 else
12758 opcode = T_MNEM_ldr_pc;
12759 }
12760 else
12761 {
12762 if (opcode == T_MNEM_ldr)
12763 opcode = T_MNEM_ldr_sp;
12764 else
12765 opcode = T_MNEM_str_sp;
12766 }
12767 inst.instruction = inst.operands[0].reg << 8;
12768 }
12769 else
12770 {
12771 inst.instruction = inst.operands[0].reg;
12772 inst.instruction |= inst.operands[1].reg << 3;
12773 }
12774 inst.instruction |= THUMB_OP16 (opcode);
12775 if (inst.size_req == 2)
e2b0ab59 12776 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
0110f2b8
PB
12777 else
12778 inst.relax = opcode;
12779 return;
12780 }
c19d1205 12781 }
0110f2b8 12782 /* Definitely a 32-bit variant. */
5be8be5d 12783
8d67f500
NC
12784 /* Warning for Erratum 752419. */
12785 if (opcode == T_MNEM_ldr
12786 && inst.operands[0].reg == REG_SP
12787 && inst.operands[1].writeback == 1
12788 && !inst.operands[1].immisreg)
12789 {
12790 if (no_cpu_selected ()
12791 || (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7)
477330fc
RM
12792 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a)
12793 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7r)))
8d67f500
NC
12794 as_warn (_("This instruction may be unpredictable "
12795 "if executed on M-profile cores "
12796 "with interrupts enabled."));
12797 }
12798
5be8be5d 12799 /* Do some validations regarding addressing modes. */
1be5fd2e 12800 if (inst.operands[1].immisreg)
5be8be5d
DG
12801 reject_bad_reg (inst.operands[1].imm);
12802
1be5fd2e
NC
12803 constraint (inst.operands[1].writeback == 1
12804 && inst.operands[0].reg == inst.operands[1].reg,
12805 BAD_OVERLAP);
12806
0110f2b8 12807 inst.instruction = THUMB_OP32 (opcode);
c19d1205
ZW
12808 inst.instruction |= inst.operands[0].reg << 12;
12809 encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
1be5fd2e 12810 check_ldr_r15_aligned ();
b99bd4ef
NC
12811 return;
12812 }
12813
c19d1205
ZW
12814 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12815
12816 if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
b99bd4ef 12817 {
c19d1205
ZW
12818 /* Only [Rn,Rm] is acceptable. */
12819 constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
12820 constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
12821 || inst.operands[1].postind || inst.operands[1].shifted
12822 || inst.operands[1].negative,
12823 _("Thumb does not support this addressing mode"));
12824 inst.instruction = THUMB_OP16 (inst.instruction);
12825 goto op16;
b99bd4ef 12826 }
5f4273c7 12827
c19d1205
ZW
12828 inst.instruction = THUMB_OP16 (inst.instruction);
12829 if (!inst.operands[1].isreg)
8335d6aa 12830 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
c19d1205 12831 return;
b99bd4ef 12832
c19d1205
ZW
12833 constraint (!inst.operands[1].preind
12834 || inst.operands[1].shifted
12835 || inst.operands[1].writeback,
12836 _("Thumb does not support this addressing mode"));
12837 if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
90e4755a 12838 {
c19d1205
ZW
12839 constraint (inst.instruction & 0x0600,
12840 _("byte or halfword not valid for base register"));
12841 constraint (inst.operands[1].reg == REG_PC
12842 && !(inst.instruction & THUMB_LOAD_BIT),
12843 _("r15 based store not allowed"));
12844 constraint (inst.operands[1].immisreg,
12845 _("invalid base register for register offset"));
b99bd4ef 12846
c19d1205
ZW
12847 if (inst.operands[1].reg == REG_PC)
12848 inst.instruction = T_OPCODE_LDR_PC;
12849 else if (inst.instruction & THUMB_LOAD_BIT)
12850 inst.instruction = T_OPCODE_LDR_SP;
12851 else
12852 inst.instruction = T_OPCODE_STR_SP;
b99bd4ef 12853
c19d1205 12854 inst.instruction |= inst.operands[0].reg << 8;
e2b0ab59 12855 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12856 return;
12857 }
90e4755a 12858
c19d1205
ZW
12859 constraint (inst.operands[1].reg > 7, BAD_HIREG);
12860 if (!inst.operands[1].immisreg)
12861 {
12862 /* Immediate offset. */
12863 inst.instruction |= inst.operands[0].reg;
12864 inst.instruction |= inst.operands[1].reg << 3;
e2b0ab59 12865 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12866 return;
12867 }
90e4755a 12868
c19d1205
ZW
12869 /* Register offset. */
12870 constraint (inst.operands[1].imm > 7, BAD_HIREG);
12871 constraint (inst.operands[1].negative,
12872 _("Thumb does not support this addressing mode"));
90e4755a 12873
c19d1205
ZW
12874 op16:
12875 switch (inst.instruction)
12876 {
12877 case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
12878 case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
12879 case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
12880 case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
12881 case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
12882 case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
12883 case 0x5600 /* ldrsb */:
12884 case 0x5e00 /* ldrsh */: break;
12885 default: abort ();
12886 }
90e4755a 12887
c19d1205
ZW
12888 inst.instruction |= inst.operands[0].reg;
12889 inst.instruction |= inst.operands[1].reg << 3;
12890 inst.instruction |= inst.operands[1].imm << 6;
12891}
90e4755a 12892
c19d1205
ZW
12893static void
12894do_t_ldstd (void)
12895{
12896 if (!inst.operands[1].present)
b99bd4ef 12897 {
c19d1205
ZW
12898 inst.operands[1].reg = inst.operands[0].reg + 1;
12899 constraint (inst.operands[0].reg == REG_LR,
12900 _("r14 not allowed here"));
bd340a04 12901 constraint (inst.operands[0].reg == REG_R12,
477330fc 12902 _("r12 not allowed here"));
b99bd4ef 12903 }
bd340a04
MGD
12904
12905 if (inst.operands[2].writeback
12906 && (inst.operands[0].reg == inst.operands[2].reg
12907 || inst.operands[1].reg == inst.operands[2].reg))
12908 as_warn (_("base register written back, and overlaps "
477330fc 12909 "one of transfer registers"));
bd340a04 12910
c19d1205
ZW
12911 inst.instruction |= inst.operands[0].reg << 12;
12912 inst.instruction |= inst.operands[1].reg << 8;
12913 encode_thumb32_addr_mode (2, /*is_t=*/FALSE, /*is_d=*/TRUE);
b99bd4ef
NC
12914}
12915
c19d1205
ZW
12916static void
12917do_t_ldstt (void)
12918{
12919 inst.instruction |= inst.operands[0].reg << 12;
12920 encode_thumb32_addr_mode (1, /*is_t=*/TRUE, /*is_d=*/FALSE);
12921}
a737bd4d 12922
b99bd4ef 12923static void
c19d1205 12924do_t_mla (void)
b99bd4ef 12925{
fdfde340 12926 unsigned Rd, Rn, Rm, Ra;
c921be7d 12927
fdfde340
JM
12928 Rd = inst.operands[0].reg;
12929 Rn = inst.operands[1].reg;
12930 Rm = inst.operands[2].reg;
12931 Ra = inst.operands[3].reg;
12932
12933 reject_bad_reg (Rd);
12934 reject_bad_reg (Rn);
12935 reject_bad_reg (Rm);
12936 reject_bad_reg (Ra);
12937
12938 inst.instruction |= Rd << 8;
12939 inst.instruction |= Rn << 16;
12940 inst.instruction |= Rm;
12941 inst.instruction |= Ra << 12;
c19d1205 12942}
b99bd4ef 12943
c19d1205
ZW
12944static void
12945do_t_mlal (void)
12946{
fdfde340
JM
12947 unsigned RdLo, RdHi, Rn, Rm;
12948
12949 RdLo = inst.operands[0].reg;
12950 RdHi = inst.operands[1].reg;
12951 Rn = inst.operands[2].reg;
12952 Rm = inst.operands[3].reg;
12953
12954 reject_bad_reg (RdLo);
12955 reject_bad_reg (RdHi);
12956 reject_bad_reg (Rn);
12957 reject_bad_reg (Rm);
12958
12959 inst.instruction |= RdLo << 12;
12960 inst.instruction |= RdHi << 8;
12961 inst.instruction |= Rn << 16;
12962 inst.instruction |= Rm;
c19d1205 12963}
b99bd4ef 12964
c19d1205
ZW
12965static void
12966do_t_mov_cmp (void)
12967{
fdfde340
JM
12968 unsigned Rn, Rm;
12969
12970 Rn = inst.operands[0].reg;
12971 Rm = inst.operands[1].reg;
12972
e07e6e58 12973 if (Rn == REG_PC)
5ee91343 12974 set_pred_insn_type_last ();
e07e6e58 12975
c19d1205 12976 if (unified_syntax)
b99bd4ef 12977 {
c19d1205
ZW
12978 int r0off = (inst.instruction == T_MNEM_mov
12979 || inst.instruction == T_MNEM_movs) ? 8 : 16;
0110f2b8 12980 unsigned long opcode;
3d388997
PB
12981 bfd_boolean narrow;
12982 bfd_boolean low_regs;
12983
fdfde340 12984 low_regs = (Rn <= 7 && Rm <= 7);
0110f2b8 12985 opcode = inst.instruction;
5ee91343 12986 if (in_pred_block ())
0110f2b8 12987 narrow = opcode != T_MNEM_movs;
3d388997 12988 else
0110f2b8 12989 narrow = opcode != T_MNEM_movs || low_regs;
3d388997
PB
12990 if (inst.size_req == 4
12991 || inst.operands[1].shifted)
12992 narrow = FALSE;
12993
efd81785
PB
12994 /* MOVS PC, LR is encoded as SUBS PC, LR, #0. */
12995 if (opcode == T_MNEM_movs && inst.operands[1].isreg
12996 && !inst.operands[1].shifted
fdfde340
JM
12997 && Rn == REG_PC
12998 && Rm == REG_LR)
efd81785
PB
12999 {
13000 inst.instruction = T2_SUBS_PC_LR;
13001 return;
13002 }
13003
fdfde340
JM
13004 if (opcode == T_MNEM_cmp)
13005 {
13006 constraint (Rn == REG_PC, BAD_PC);
94206790
MM
13007 if (narrow)
13008 {
13009 /* In the Thumb-2 ISA, use of R13 as Rm is deprecated,
13010 but valid. */
13011 warn_deprecated_sp (Rm);
13012 /* R15 was documented as a valid choice for Rm in ARMv6,
13013 but as UNPREDICTABLE in ARMv7. ARM's proprietary
13014 tools reject R15, so we do too. */
13015 constraint (Rm == REG_PC, BAD_PC);
13016 }
13017 else
13018 reject_bad_reg (Rm);
fdfde340
JM
13019 }
13020 else if (opcode == T_MNEM_mov
13021 || opcode == T_MNEM_movs)
13022 {
13023 if (inst.operands[1].isreg)
13024 {
13025 if (opcode == T_MNEM_movs)
13026 {
13027 reject_bad_reg (Rn);
13028 reject_bad_reg (Rm);
13029 }
76fa04a4
MGD
13030 else if (narrow)
13031 {
13032 /* This is mov.n. */
13033 if ((Rn == REG_SP || Rn == REG_PC)
13034 && (Rm == REG_SP || Rm == REG_PC))
13035 {
5c3696f8 13036 as_tsktsk (_("Use of r%u as a source register is "
76fa04a4
MGD
13037 "deprecated when r%u is the destination "
13038 "register."), Rm, Rn);
13039 }
13040 }
13041 else
13042 {
13043 /* This is mov.w. */
13044 constraint (Rn == REG_PC, BAD_PC);
13045 constraint (Rm == REG_PC, BAD_PC);
5c8ed6a4
JW
13046 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
13047 constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
76fa04a4 13048 }
fdfde340
JM
13049 }
13050 else
13051 reject_bad_reg (Rn);
13052 }
13053
c19d1205
ZW
13054 if (!inst.operands[1].isreg)
13055 {
0110f2b8 13056 /* Immediate operand. */
5ee91343 13057 if (!in_pred_block () && opcode == T_MNEM_mov)
0110f2b8
PB
13058 narrow = 0;
13059 if (low_regs && narrow)
13060 {
13061 inst.instruction = THUMB_OP16 (opcode);
fdfde340 13062 inst.instruction |= Rn << 8;
e2b0ab59
AV
13063 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
13064 || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
72d98d16 13065 {
a9f02af8 13066 if (inst.size_req == 2)
e2b0ab59 13067 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
a9f02af8
MG
13068 else
13069 inst.relax = opcode;
72d98d16 13070 }
0110f2b8
PB
13071 }
13072 else
13073 {
e2b0ab59
AV
13074 constraint ((inst.relocs[0].type
13075 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
13076 && (inst.relocs[0].type
13077 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8
MG
13078 THUMB1_RELOC_ONLY);
13079
0110f2b8
PB
13080 inst.instruction = THUMB_OP32 (inst.instruction);
13081 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 13082 inst.instruction |= Rn << r0off;
e2b0ab59 13083 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8 13084 }
c19d1205 13085 }
728ca7c9
PB
13086 else if (inst.operands[1].shifted && inst.operands[1].immisreg
13087 && (inst.instruction == T_MNEM_mov
13088 || inst.instruction == T_MNEM_movs))
13089 {
13090 /* Register shifts are encoded as separate shift instructions. */
13091 bfd_boolean flags = (inst.instruction == T_MNEM_movs);
13092
5ee91343 13093 if (in_pred_block ())
728ca7c9
PB
13094 narrow = !flags;
13095 else
13096 narrow = flags;
13097
13098 if (inst.size_req == 4)
13099 narrow = FALSE;
13100
13101 if (!low_regs || inst.operands[1].imm > 7)
13102 narrow = FALSE;
13103
fdfde340 13104 if (Rn != Rm)
728ca7c9
PB
13105 narrow = FALSE;
13106
13107 switch (inst.operands[1].shift_kind)
13108 {
13109 case SHIFT_LSL:
13110 opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl);
13111 break;
13112 case SHIFT_ASR:
13113 opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr);
13114 break;
13115 case SHIFT_LSR:
13116 opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr);
13117 break;
13118 case SHIFT_ROR:
13119 opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror);
13120 break;
13121 default:
5f4273c7 13122 abort ();
728ca7c9
PB
13123 }
13124
13125 inst.instruction = opcode;
13126 if (narrow)
13127 {
fdfde340 13128 inst.instruction |= Rn;
728ca7c9
PB
13129 inst.instruction |= inst.operands[1].imm << 3;
13130 }
13131 else
13132 {
13133 if (flags)
13134 inst.instruction |= CONDS_BIT;
13135
fdfde340
JM
13136 inst.instruction |= Rn << 8;
13137 inst.instruction |= Rm << 16;
728ca7c9
PB
13138 inst.instruction |= inst.operands[1].imm;
13139 }
13140 }
3d388997 13141 else if (!narrow)
c19d1205 13142 {
728ca7c9
PB
13143 /* Some mov with immediate shift have narrow variants.
13144 Register shifts are handled above. */
13145 if (low_regs && inst.operands[1].shifted
13146 && (inst.instruction == T_MNEM_mov
13147 || inst.instruction == T_MNEM_movs))
13148 {
5ee91343 13149 if (in_pred_block ())
728ca7c9
PB
13150 narrow = (inst.instruction == T_MNEM_mov);
13151 else
13152 narrow = (inst.instruction == T_MNEM_movs);
13153 }
13154
13155 if (narrow)
13156 {
13157 switch (inst.operands[1].shift_kind)
13158 {
13159 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
13160 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
13161 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
13162 default: narrow = FALSE; break;
13163 }
13164 }
13165
13166 if (narrow)
13167 {
fdfde340
JM
13168 inst.instruction |= Rn;
13169 inst.instruction |= Rm << 3;
e2b0ab59 13170 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
728ca7c9
PB
13171 }
13172 else
13173 {
13174 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 13175 inst.instruction |= Rn << r0off;
728ca7c9
PB
13176 encode_thumb32_shifted_operand (1);
13177 }
c19d1205
ZW
13178 }
13179 else
13180 switch (inst.instruction)
13181 {
13182 case T_MNEM_mov:
837b3435 13183 /* In v4t or v5t a move of two lowregs produces unpredictable
c6400f8a
MGD
13184 results. Don't allow this. */
13185 if (low_regs)
13186 {
13187 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
13188 "MOV Rd, Rs with two low registers is not "
13189 "permitted on this architecture");
fa94de6b 13190 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
c6400f8a
MGD
13191 arm_ext_v6);
13192 }
13193
c19d1205 13194 inst.instruction = T_OPCODE_MOV_HR;
fdfde340
JM
13195 inst.instruction |= (Rn & 0x8) << 4;
13196 inst.instruction |= (Rn & 0x7);
13197 inst.instruction |= Rm << 3;
c19d1205 13198 break;
b99bd4ef 13199
c19d1205
ZW
13200 case T_MNEM_movs:
13201 /* We know we have low registers at this point.
941a8a52
MGD
13202 Generate LSLS Rd, Rs, #0. */
13203 inst.instruction = T_OPCODE_LSL_I;
fdfde340
JM
13204 inst.instruction |= Rn;
13205 inst.instruction |= Rm << 3;
c19d1205
ZW
13206 break;
13207
13208 case T_MNEM_cmp:
3d388997 13209 if (low_regs)
c19d1205
ZW
13210 {
13211 inst.instruction = T_OPCODE_CMP_LR;
fdfde340
JM
13212 inst.instruction |= Rn;
13213 inst.instruction |= Rm << 3;
c19d1205
ZW
13214 }
13215 else
13216 {
13217 inst.instruction = T_OPCODE_CMP_HR;
fdfde340
JM
13218 inst.instruction |= (Rn & 0x8) << 4;
13219 inst.instruction |= (Rn & 0x7);
13220 inst.instruction |= Rm << 3;
c19d1205
ZW
13221 }
13222 break;
13223 }
b99bd4ef
NC
13224 return;
13225 }
13226
c19d1205 13227 inst.instruction = THUMB_OP16 (inst.instruction);
539d4391
NC
13228
13229 /* PR 10443: Do not silently ignore shifted operands. */
13230 constraint (inst.operands[1].shifted,
13231 _("shifts in CMP/MOV instructions are only supported in unified syntax"));
13232
c19d1205 13233 if (inst.operands[1].isreg)
b99bd4ef 13234 {
fdfde340 13235 if (Rn < 8 && Rm < 8)
b99bd4ef 13236 {
c19d1205
ZW
13237 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
13238 since a MOV instruction produces unpredictable results. */
13239 if (inst.instruction == T_OPCODE_MOV_I8)
13240 inst.instruction = T_OPCODE_ADD_I3;
b99bd4ef 13241 else
c19d1205 13242 inst.instruction = T_OPCODE_CMP_LR;
b99bd4ef 13243
fdfde340
JM
13244 inst.instruction |= Rn;
13245 inst.instruction |= Rm << 3;
b99bd4ef
NC
13246 }
13247 else
13248 {
c19d1205
ZW
13249 if (inst.instruction == T_OPCODE_MOV_I8)
13250 inst.instruction = T_OPCODE_MOV_HR;
13251 else
13252 inst.instruction = T_OPCODE_CMP_HR;
13253 do_t_cpy ();
b99bd4ef
NC
13254 }
13255 }
c19d1205 13256 else
b99bd4ef 13257 {
fdfde340 13258 constraint (Rn > 7,
c19d1205 13259 _("only lo regs allowed with immediate"));
fdfde340 13260 inst.instruction |= Rn << 8;
e2b0ab59 13261 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
c19d1205
ZW
13262 }
13263}
b99bd4ef 13264
c19d1205
ZW
13265static void
13266do_t_mov16 (void)
13267{
fdfde340 13268 unsigned Rd;
b6895b4f
PB
13269 bfd_vma imm;
13270 bfd_boolean top;
13271
13272 top = (inst.instruction & 0x00800000) != 0;
e2b0ab59 13273 if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
b6895b4f 13274 {
33eaf5de 13275 constraint (top, _(":lower16: not allowed in this instruction"));
e2b0ab59 13276 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
b6895b4f 13277 }
e2b0ab59 13278 else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
b6895b4f 13279 {
33eaf5de 13280 constraint (!top, _(":upper16: not allowed in this instruction"));
e2b0ab59 13281 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
b6895b4f
PB
13282 }
13283
fdfde340
JM
13284 Rd = inst.operands[0].reg;
13285 reject_bad_reg (Rd);
13286
13287 inst.instruction |= Rd << 8;
e2b0ab59 13288 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 13289 {
e2b0ab59 13290 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
13291 inst.instruction |= (imm & 0xf000) << 4;
13292 inst.instruction |= (imm & 0x0800) << 15;
13293 inst.instruction |= (imm & 0x0700) << 4;
13294 inst.instruction |= (imm & 0x00ff);
13295 }
c19d1205 13296}
b99bd4ef 13297
c19d1205
ZW
13298static void
13299do_t_mvn_tst (void)
13300{
fdfde340 13301 unsigned Rn, Rm;
c921be7d 13302
fdfde340
JM
13303 Rn = inst.operands[0].reg;
13304 Rm = inst.operands[1].reg;
13305
13306 if (inst.instruction == T_MNEM_cmp
13307 || inst.instruction == T_MNEM_cmn)
13308 constraint (Rn == REG_PC, BAD_PC);
13309 else
13310 reject_bad_reg (Rn);
13311 reject_bad_reg (Rm);
13312
c19d1205
ZW
13313 if (unified_syntax)
13314 {
13315 int r0off = (inst.instruction == T_MNEM_mvn
13316 || inst.instruction == T_MNEM_mvns) ? 8 : 16;
3d388997
PB
13317 bfd_boolean narrow;
13318
13319 if (inst.size_req == 4
13320 || inst.instruction > 0xffff
13321 || inst.operands[1].shifted
fdfde340 13322 || Rn > 7 || Rm > 7)
3d388997 13323 narrow = FALSE;
fe8b4cc3
KT
13324 else if (inst.instruction == T_MNEM_cmn
13325 || inst.instruction == T_MNEM_tst)
3d388997
PB
13326 narrow = TRUE;
13327 else if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13328 narrow = !in_pred_block ();
3d388997 13329 else
5ee91343 13330 narrow = in_pred_block ();
3d388997 13331
c19d1205 13332 if (!inst.operands[1].isreg)
b99bd4ef 13333 {
c19d1205
ZW
13334 /* For an immediate, we always generate a 32-bit opcode;
13335 section relaxation will shrink it later if possible. */
13336 if (inst.instruction < 0xffff)
13337 inst.instruction = THUMB_OP32 (inst.instruction);
13338 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 13339 inst.instruction |= Rn << r0off;
e2b0ab59 13340 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 13341 }
c19d1205 13342 else
b99bd4ef 13343 {
c19d1205 13344 /* See if we can do this with a 16-bit instruction. */
3d388997 13345 if (narrow)
b99bd4ef 13346 {
c19d1205 13347 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13348 inst.instruction |= Rn;
13349 inst.instruction |= Rm << 3;
b99bd4ef 13350 }
c19d1205 13351 else
b99bd4ef 13352 {
c19d1205
ZW
13353 constraint (inst.operands[1].shifted
13354 && inst.operands[1].immisreg,
13355 _("shift must be constant"));
13356 if (inst.instruction < 0xffff)
13357 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 13358 inst.instruction |= Rn << r0off;
c19d1205 13359 encode_thumb32_shifted_operand (1);
b99bd4ef 13360 }
b99bd4ef
NC
13361 }
13362 }
13363 else
13364 {
c19d1205
ZW
13365 constraint (inst.instruction > 0xffff
13366 || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
13367 constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
13368 _("unshifted register required"));
fdfde340 13369 constraint (Rn > 7 || Rm > 7,
c19d1205 13370 BAD_HIREG);
b99bd4ef 13371
c19d1205 13372 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13373 inst.instruction |= Rn;
13374 inst.instruction |= Rm << 3;
b99bd4ef 13375 }
b99bd4ef
NC
13376}
13377
b05fe5cf 13378static void
c19d1205 13379do_t_mrs (void)
b05fe5cf 13380{
fdfde340 13381 unsigned Rd;
037e8744
JB
13382
13383 if (do_vfp_nsyn_mrs () == SUCCESS)
13384 return;
13385
90ec0d68
MGD
13386 Rd = inst.operands[0].reg;
13387 reject_bad_reg (Rd);
13388 inst.instruction |= Rd << 8;
13389
13390 if (inst.operands[1].isreg)
62b3e311 13391 {
90ec0d68
MGD
13392 unsigned br = inst.operands[1].reg;
13393 if (((br & 0x200) == 0) && ((br & 0xf000) != 0xf000))
13394 as_bad (_("bad register for mrs"));
13395
13396 inst.instruction |= br & (0xf << 16);
13397 inst.instruction |= (br & 0x300) >> 4;
13398 inst.instruction |= (br & SPSR_BIT) >> 2;
62b3e311
PB
13399 }
13400 else
13401 {
90ec0d68 13402 int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
5f4273c7 13403
d2cd1205 13404 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
1a43faaf
NC
13405 {
13406 /* PR gas/12698: The constraint is only applied for m_profile.
13407 If the user has specified -march=all, we want to ignore it as
13408 we are building for any CPU type, including non-m variants. */
823d2571
TG
13409 bfd_boolean m_profile =
13410 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf
NC
13411 constraint ((flags != 0) && m_profile, _("selected processor does "
13412 "not support requested special purpose register"));
13413 }
90ec0d68 13414 else
d2cd1205
JB
13415 /* mrs only accepts APSR/CPSR/SPSR/CPSR_all/SPSR_all (for non-M profile
13416 devices). */
13417 constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
13418 _("'APSR', 'CPSR' or 'SPSR' expected"));
fdfde340 13419
90ec0d68
MGD
13420 inst.instruction |= (flags & SPSR_BIT) >> 2;
13421 inst.instruction |= inst.operands[1].imm & 0xff;
13422 inst.instruction |= 0xf0000;
13423 }
c19d1205 13424}
b05fe5cf 13425
c19d1205
ZW
13426static void
13427do_t_msr (void)
13428{
62b3e311 13429 int flags;
fdfde340 13430 unsigned Rn;
62b3e311 13431
037e8744
JB
13432 if (do_vfp_nsyn_msr () == SUCCESS)
13433 return;
13434
c19d1205
ZW
13435 constraint (!inst.operands[1].isreg,
13436 _("Thumb encoding does not support an immediate here"));
90ec0d68
MGD
13437
13438 if (inst.operands[0].isreg)
13439 flags = (int)(inst.operands[0].reg);
13440 else
13441 flags = inst.operands[0].imm;
13442
d2cd1205 13443 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
62b3e311 13444 {
d2cd1205
JB
13445 int bits = inst.operands[0].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
13446
1a43faaf 13447 /* PR gas/12698: The constraint is only applied for m_profile.
477330fc
RM
13448 If the user has specified -march=all, we want to ignore it as
13449 we are building for any CPU type, including non-m variants. */
823d2571
TG
13450 bfd_boolean m_profile =
13451 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf 13452 constraint (((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
477330fc
RM
13453 && (bits & ~(PSR_s | PSR_f)) != 0)
13454 || (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
13455 && bits != PSR_f)) && m_profile,
13456 _("selected processor does not support requested special "
13457 "purpose register"));
62b3e311
PB
13458 }
13459 else
d2cd1205
JB
13460 constraint ((flags & 0xff) != 0, _("selected processor does not support "
13461 "requested special purpose register"));
c921be7d 13462
fdfde340
JM
13463 Rn = inst.operands[1].reg;
13464 reject_bad_reg (Rn);
13465
62b3e311 13466 inst.instruction |= (flags & SPSR_BIT) >> 2;
90ec0d68
MGD
13467 inst.instruction |= (flags & 0xf0000) >> 8;
13468 inst.instruction |= (flags & 0x300) >> 4;
62b3e311 13469 inst.instruction |= (flags & 0xff);
fdfde340 13470 inst.instruction |= Rn << 16;
c19d1205 13471}
b05fe5cf 13472
c19d1205
ZW
13473static void
13474do_t_mul (void)
13475{
17828f45 13476 bfd_boolean narrow;
fdfde340 13477 unsigned Rd, Rn, Rm;
17828f45 13478
c19d1205
ZW
13479 if (!inst.operands[2].present)
13480 inst.operands[2].reg = inst.operands[0].reg;
b05fe5cf 13481
fdfde340
JM
13482 Rd = inst.operands[0].reg;
13483 Rn = inst.operands[1].reg;
13484 Rm = inst.operands[2].reg;
13485
17828f45 13486 if (unified_syntax)
b05fe5cf 13487 {
17828f45 13488 if (inst.size_req == 4
fdfde340
JM
13489 || (Rd != Rn
13490 && Rd != Rm)
13491 || Rn > 7
13492 || Rm > 7)
17828f45
JM
13493 narrow = FALSE;
13494 else if (inst.instruction == T_MNEM_muls)
5ee91343 13495 narrow = !in_pred_block ();
17828f45 13496 else
5ee91343 13497 narrow = in_pred_block ();
b05fe5cf 13498 }
c19d1205 13499 else
b05fe5cf 13500 {
17828f45 13501 constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32);
fdfde340 13502 constraint (Rn > 7 || Rm > 7,
c19d1205 13503 BAD_HIREG);
17828f45
JM
13504 narrow = TRUE;
13505 }
b05fe5cf 13506
17828f45
JM
13507 if (narrow)
13508 {
13509 /* 16-bit MULS/Conditional MUL. */
c19d1205 13510 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 13511 inst.instruction |= Rd;
b05fe5cf 13512
fdfde340
JM
13513 if (Rd == Rn)
13514 inst.instruction |= Rm << 3;
13515 else if (Rd == Rm)
13516 inst.instruction |= Rn << 3;
c19d1205
ZW
13517 else
13518 constraint (1, _("dest must overlap one source register"));
13519 }
17828f45
JM
13520 else
13521 {
e07e6e58
NC
13522 constraint (inst.instruction != T_MNEM_mul,
13523 _("Thumb-2 MUL must not set flags"));
17828f45
JM
13524 /* 32-bit MUL. */
13525 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13526 inst.instruction |= Rd << 8;
13527 inst.instruction |= Rn << 16;
13528 inst.instruction |= Rm << 0;
13529
13530 reject_bad_reg (Rd);
13531 reject_bad_reg (Rn);
13532 reject_bad_reg (Rm);
17828f45 13533 }
c19d1205 13534}
b05fe5cf 13535
c19d1205
ZW
13536static void
13537do_t_mull (void)
13538{
fdfde340 13539 unsigned RdLo, RdHi, Rn, Rm;
b05fe5cf 13540
fdfde340
JM
13541 RdLo = inst.operands[0].reg;
13542 RdHi = inst.operands[1].reg;
13543 Rn = inst.operands[2].reg;
13544 Rm = inst.operands[3].reg;
13545
13546 reject_bad_reg (RdLo);
13547 reject_bad_reg (RdHi);
13548 reject_bad_reg (Rn);
13549 reject_bad_reg (Rm);
13550
13551 inst.instruction |= RdLo << 12;
13552 inst.instruction |= RdHi << 8;
13553 inst.instruction |= Rn << 16;
13554 inst.instruction |= Rm;
13555
13556 if (RdLo == RdHi)
c19d1205
ZW
13557 as_tsktsk (_("rdhi and rdlo must be different"));
13558}
b05fe5cf 13559
c19d1205
ZW
13560static void
13561do_t_nop (void)
13562{
5ee91343 13563 set_pred_insn_type (NEUTRAL_IT_INSN);
e07e6e58 13564
c19d1205
ZW
13565 if (unified_syntax)
13566 {
13567 if (inst.size_req == 4 || inst.operands[0].imm > 15)
b05fe5cf 13568 {
c19d1205
ZW
13569 inst.instruction = THUMB_OP32 (inst.instruction);
13570 inst.instruction |= inst.operands[0].imm;
13571 }
13572 else
13573 {
bc2d1808
NC
13574 /* PR9722: Check for Thumb2 availability before
13575 generating a thumb2 nop instruction. */
afa62d5e 13576 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
bc2d1808
NC
13577 {
13578 inst.instruction = THUMB_OP16 (inst.instruction);
13579 inst.instruction |= inst.operands[0].imm << 4;
13580 }
13581 else
13582 inst.instruction = 0x46c0;
c19d1205
ZW
13583 }
13584 }
13585 else
13586 {
13587 constraint (inst.operands[0].present,
13588 _("Thumb does not support NOP with hints"));
13589 inst.instruction = 0x46c0;
13590 }
13591}
b05fe5cf 13592
c19d1205
ZW
13593static void
13594do_t_neg (void)
13595{
13596 if (unified_syntax)
13597 {
3d388997
PB
13598 bfd_boolean narrow;
13599
13600 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13601 narrow = !in_pred_block ();
3d388997 13602 else
5ee91343 13603 narrow = in_pred_block ();
3d388997
PB
13604 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
13605 narrow = FALSE;
13606 if (inst.size_req == 4)
13607 narrow = FALSE;
13608
13609 if (!narrow)
c19d1205
ZW
13610 {
13611 inst.instruction = THUMB_OP32 (inst.instruction);
13612 inst.instruction |= inst.operands[0].reg << 8;
13613 inst.instruction |= inst.operands[1].reg << 16;
b05fe5cf
ZW
13614 }
13615 else
13616 {
c19d1205
ZW
13617 inst.instruction = THUMB_OP16 (inst.instruction);
13618 inst.instruction |= inst.operands[0].reg;
13619 inst.instruction |= inst.operands[1].reg << 3;
b05fe5cf
ZW
13620 }
13621 }
13622 else
13623 {
c19d1205
ZW
13624 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
13625 BAD_HIREG);
13626 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
13627
13628 inst.instruction = THUMB_OP16 (inst.instruction);
13629 inst.instruction |= inst.operands[0].reg;
13630 inst.instruction |= inst.operands[1].reg << 3;
13631 }
13632}
13633
1c444d06
JM
13634static void
13635do_t_orn (void)
13636{
13637 unsigned Rd, Rn;
13638
13639 Rd = inst.operands[0].reg;
13640 Rn = inst.operands[1].present ? inst.operands[1].reg : Rd;
13641
fdfde340
JM
13642 reject_bad_reg (Rd);
13643 /* Rn == REG_SP is unpredictable; Rn == REG_PC is MVN. */
13644 reject_bad_reg (Rn);
13645
1c444d06
JM
13646 inst.instruction |= Rd << 8;
13647 inst.instruction |= Rn << 16;
13648
13649 if (!inst.operands[2].isreg)
13650 {
13651 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13652 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
1c444d06
JM
13653 }
13654 else
13655 {
13656 unsigned Rm;
13657
13658 Rm = inst.operands[2].reg;
fdfde340 13659 reject_bad_reg (Rm);
1c444d06
JM
13660
13661 constraint (inst.operands[2].shifted
13662 && inst.operands[2].immisreg,
13663 _("shift must be constant"));
13664 encode_thumb32_shifted_operand (2);
13665 }
13666}
13667
c19d1205
ZW
13668static void
13669do_t_pkhbt (void)
13670{
fdfde340
JM
13671 unsigned Rd, Rn, Rm;
13672
13673 Rd = inst.operands[0].reg;
13674 Rn = inst.operands[1].reg;
13675 Rm = inst.operands[2].reg;
13676
13677 reject_bad_reg (Rd);
13678 reject_bad_reg (Rn);
13679 reject_bad_reg (Rm);
13680
13681 inst.instruction |= Rd << 8;
13682 inst.instruction |= Rn << 16;
13683 inst.instruction |= Rm;
c19d1205
ZW
13684 if (inst.operands[3].present)
13685 {
e2b0ab59
AV
13686 unsigned int val = inst.relocs[0].exp.X_add_number;
13687 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
13688 _("expression too complex"));
13689 inst.instruction |= (val & 0x1c) << 10;
13690 inst.instruction |= (val & 0x03) << 6;
b05fe5cf 13691 }
c19d1205 13692}
b05fe5cf 13693
c19d1205
ZW
13694static void
13695do_t_pkhtb (void)
13696{
13697 if (!inst.operands[3].present)
1ef52f49
NC
13698 {
13699 unsigned Rtmp;
13700
13701 inst.instruction &= ~0x00000020;
13702
13703 /* PR 10168. Swap the Rm and Rn registers. */
13704 Rtmp = inst.operands[1].reg;
13705 inst.operands[1].reg = inst.operands[2].reg;
13706 inst.operands[2].reg = Rtmp;
13707 }
c19d1205 13708 do_t_pkhbt ();
b05fe5cf
ZW
13709}
13710
c19d1205
ZW
13711static void
13712do_t_pld (void)
13713{
fdfde340
JM
13714 if (inst.operands[0].immisreg)
13715 reject_bad_reg (inst.operands[0].imm);
13716
c19d1205
ZW
13717 encode_thumb32_addr_mode (0, /*is_t=*/FALSE, /*is_d=*/FALSE);
13718}
b05fe5cf 13719
c19d1205
ZW
13720static void
13721do_t_push_pop (void)
b99bd4ef 13722{
e9f89963 13723 unsigned mask;
5f4273c7 13724
c19d1205
ZW
13725 constraint (inst.operands[0].writeback,
13726 _("push/pop do not support {reglist}^"));
e2b0ab59 13727 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205 13728 _("expression too complex"));
b99bd4ef 13729
e9f89963 13730 mask = inst.operands[0].imm;
d3bfe16e 13731 if (inst.size_req != 4 && (mask & ~0xff) == 0)
3c707909 13732 inst.instruction = THUMB_OP16 (inst.instruction) | mask;
d3bfe16e 13733 else if (inst.size_req != 4
c6025a80 13734 && (mask & ~0xff) == (1U << (inst.instruction == T_MNEM_push
d3bfe16e 13735 ? REG_LR : REG_PC)))
b99bd4ef 13736 {
c19d1205
ZW
13737 inst.instruction = THUMB_OP16 (inst.instruction);
13738 inst.instruction |= THUMB_PP_PC_LR;
3c707909 13739 inst.instruction |= mask & 0xff;
c19d1205
ZW
13740 }
13741 else if (unified_syntax)
13742 {
3c707909 13743 inst.instruction = THUMB_OP32 (inst.instruction);
4b5a202f
AV
13744 encode_thumb2_multi (TRUE /* do_io */, 13, mask, TRUE);
13745 }
13746 else
13747 {
13748 inst.error = _("invalid register list to push/pop instruction");
13749 return;
c19d1205 13750 }
4b5a202f
AV
13751}
13752
13753static void
13754do_t_clrm (void)
13755{
13756 if (unified_syntax)
13757 encode_thumb2_multi (FALSE /* do_io */, -1, inst.operands[0].imm, FALSE);
c19d1205
ZW
13758 else
13759 {
13760 inst.error = _("invalid register list to push/pop instruction");
13761 return;
13762 }
c19d1205 13763}
b99bd4ef 13764
efd6b359
AV
13765static void
13766do_t_vscclrm (void)
13767{
13768 if (inst.operands[0].issingle)
13769 {
13770 inst.instruction |= (inst.operands[0].reg & 0x1) << 22;
13771 inst.instruction |= (inst.operands[0].reg & 0x1e) << 11;
13772 inst.instruction |= inst.operands[0].imm;
13773 }
13774 else
13775 {
13776 inst.instruction |= (inst.operands[0].reg & 0x10) << 18;
13777 inst.instruction |= (inst.operands[0].reg & 0xf) << 12;
13778 inst.instruction |= 1 << 8;
13779 inst.instruction |= inst.operands[0].imm << 1;
13780 }
13781}
13782
c19d1205
ZW
13783static void
13784do_t_rbit (void)
13785{
fdfde340
JM
13786 unsigned Rd, Rm;
13787
13788 Rd = inst.operands[0].reg;
13789 Rm = inst.operands[1].reg;
13790
13791 reject_bad_reg (Rd);
13792 reject_bad_reg (Rm);
13793
13794 inst.instruction |= Rd << 8;
13795 inst.instruction |= Rm << 16;
13796 inst.instruction |= Rm;
c19d1205 13797}
b99bd4ef 13798
c19d1205
ZW
13799static void
13800do_t_rev (void)
13801{
fdfde340
JM
13802 unsigned Rd, Rm;
13803
13804 Rd = inst.operands[0].reg;
13805 Rm = inst.operands[1].reg;
13806
13807 reject_bad_reg (Rd);
13808 reject_bad_reg (Rm);
13809
13810 if (Rd <= 7 && Rm <= 7
c19d1205
ZW
13811 && inst.size_req != 4)
13812 {
13813 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13814 inst.instruction |= Rd;
13815 inst.instruction |= Rm << 3;
c19d1205
ZW
13816 }
13817 else if (unified_syntax)
13818 {
13819 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13820 inst.instruction |= Rd << 8;
13821 inst.instruction |= Rm << 16;
13822 inst.instruction |= Rm;
c19d1205
ZW
13823 }
13824 else
13825 inst.error = BAD_HIREG;
13826}
b99bd4ef 13827
1c444d06
JM
13828static void
13829do_t_rrx (void)
13830{
13831 unsigned Rd, Rm;
13832
13833 Rd = inst.operands[0].reg;
13834 Rm = inst.operands[1].reg;
13835
fdfde340
JM
13836 reject_bad_reg (Rd);
13837 reject_bad_reg (Rm);
c921be7d 13838
1c444d06
JM
13839 inst.instruction |= Rd << 8;
13840 inst.instruction |= Rm;
13841}
13842
c19d1205
ZW
13843static void
13844do_t_rsb (void)
13845{
fdfde340 13846 unsigned Rd, Rs;
b99bd4ef 13847
c19d1205
ZW
13848 Rd = inst.operands[0].reg;
13849 Rs = (inst.operands[1].present
13850 ? inst.operands[1].reg /* Rd, Rs, foo */
13851 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
b99bd4ef 13852
fdfde340
JM
13853 reject_bad_reg (Rd);
13854 reject_bad_reg (Rs);
13855 if (inst.operands[2].isreg)
13856 reject_bad_reg (inst.operands[2].reg);
13857
c19d1205
ZW
13858 inst.instruction |= Rd << 8;
13859 inst.instruction |= Rs << 16;
13860 if (!inst.operands[2].isreg)
13861 {
026d3abb
PB
13862 bfd_boolean narrow;
13863
13864 if ((inst.instruction & 0x00100000) != 0)
5ee91343 13865 narrow = !in_pred_block ();
026d3abb 13866 else
5ee91343 13867 narrow = in_pred_block ();
026d3abb
PB
13868
13869 if (Rd > 7 || Rs > 7)
13870 narrow = FALSE;
13871
13872 if (inst.size_req == 4 || !unified_syntax)
13873 narrow = FALSE;
13874
e2b0ab59
AV
13875 if (inst.relocs[0].exp.X_op != O_constant
13876 || inst.relocs[0].exp.X_add_number != 0)
026d3abb
PB
13877 narrow = FALSE;
13878
13879 /* Turn rsb #0 into 16-bit neg. We should probably do this via
477330fc 13880 relaxation, but it doesn't seem worth the hassle. */
026d3abb
PB
13881 if (narrow)
13882 {
e2b0ab59 13883 inst.relocs[0].type = BFD_RELOC_UNUSED;
026d3abb
PB
13884 inst.instruction = THUMB_OP16 (T_MNEM_negs);
13885 inst.instruction |= Rs << 3;
13886 inst.instruction |= Rd;
13887 }
13888 else
13889 {
13890 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13891 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
026d3abb 13892 }
c19d1205
ZW
13893 }
13894 else
13895 encode_thumb32_shifted_operand (2);
13896}
b99bd4ef 13897
c19d1205
ZW
13898static void
13899do_t_setend (void)
13900{
12e37cbc
MGD
13901 if (warn_on_deprecated
13902 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 13903 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 13904
5ee91343 13905 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
13906 if (inst.operands[0].imm)
13907 inst.instruction |= 0x8;
13908}
b99bd4ef 13909
c19d1205
ZW
13910static void
13911do_t_shift (void)
13912{
13913 if (!inst.operands[1].present)
13914 inst.operands[1].reg = inst.operands[0].reg;
13915
13916 if (unified_syntax)
13917 {
3d388997
PB
13918 bfd_boolean narrow;
13919 int shift_kind;
13920
13921 switch (inst.instruction)
13922 {
13923 case T_MNEM_asr:
13924 case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
13925 case T_MNEM_lsl:
13926 case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
13927 case T_MNEM_lsr:
13928 case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
13929 case T_MNEM_ror:
13930 case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
13931 default: abort ();
13932 }
13933
13934 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13935 narrow = !in_pred_block ();
3d388997 13936 else
5ee91343 13937 narrow = in_pred_block ();
3d388997
PB
13938 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
13939 narrow = FALSE;
13940 if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
13941 narrow = FALSE;
13942 if (inst.operands[2].isreg
13943 && (inst.operands[1].reg != inst.operands[0].reg
13944 || inst.operands[2].reg > 7))
13945 narrow = FALSE;
13946 if (inst.size_req == 4)
13947 narrow = FALSE;
13948
fdfde340
JM
13949 reject_bad_reg (inst.operands[0].reg);
13950 reject_bad_reg (inst.operands[1].reg);
c921be7d 13951
3d388997 13952 if (!narrow)
c19d1205
ZW
13953 {
13954 if (inst.operands[2].isreg)
b99bd4ef 13955 {
fdfde340 13956 reject_bad_reg (inst.operands[2].reg);
c19d1205
ZW
13957 inst.instruction = THUMB_OP32 (inst.instruction);
13958 inst.instruction |= inst.operands[0].reg << 8;
13959 inst.instruction |= inst.operands[1].reg << 16;
13960 inst.instruction |= inst.operands[2].reg;
94342ec3
NC
13961
13962 /* PR 12854: Error on extraneous shifts. */
13963 constraint (inst.operands[2].shifted,
13964 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13965 }
13966 else
13967 {
13968 inst.operands[1].shifted = 1;
3d388997 13969 inst.operands[1].shift_kind = shift_kind;
c19d1205
ZW
13970 inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
13971 ? T_MNEM_movs : T_MNEM_mov);
13972 inst.instruction |= inst.operands[0].reg << 8;
13973 encode_thumb32_shifted_operand (1);
13974 /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
e2b0ab59 13975 inst.relocs[0].type = BFD_RELOC_UNUSED;
b99bd4ef
NC
13976 }
13977 }
13978 else
13979 {
c19d1205 13980 if (inst.operands[2].isreg)
b99bd4ef 13981 {
3d388997 13982 switch (shift_kind)
b99bd4ef 13983 {
3d388997
PB
13984 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
13985 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
13986 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
13987 case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
c19d1205 13988 default: abort ();
b99bd4ef 13989 }
5f4273c7 13990
c19d1205
ZW
13991 inst.instruction |= inst.operands[0].reg;
13992 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13993
13994 /* PR 12854: Error on extraneous shifts. */
13995 constraint (inst.operands[2].shifted,
13996 _("extraneous shift as part of operand to shift insn"));
b99bd4ef
NC
13997 }
13998 else
13999 {
3d388997 14000 switch (shift_kind)
b99bd4ef 14001 {
3d388997
PB
14002 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
14003 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
14004 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
c19d1205 14005 default: abort ();
b99bd4ef 14006 }
e2b0ab59 14007 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
14008 inst.instruction |= inst.operands[0].reg;
14009 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
14010 }
14011 }
c19d1205
ZW
14012 }
14013 else
14014 {
14015 constraint (inst.operands[0].reg > 7
14016 || inst.operands[1].reg > 7, BAD_HIREG);
14017 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
b99bd4ef 14018
c19d1205
ZW
14019 if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
14020 {
14021 constraint (inst.operands[2].reg > 7, BAD_HIREG);
14022 constraint (inst.operands[0].reg != inst.operands[1].reg,
14023 _("source1 and dest must be same register"));
b99bd4ef 14024
c19d1205
ZW
14025 switch (inst.instruction)
14026 {
14027 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
14028 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
14029 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
14030 case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
14031 default: abort ();
14032 }
5f4273c7 14033
c19d1205
ZW
14034 inst.instruction |= inst.operands[0].reg;
14035 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
14036
14037 /* PR 12854: Error on extraneous shifts. */
14038 constraint (inst.operands[2].shifted,
14039 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
14040 }
14041 else
b99bd4ef 14042 {
c19d1205
ZW
14043 switch (inst.instruction)
14044 {
14045 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
14046 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
14047 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
14048 case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
14049 default: abort ();
14050 }
e2b0ab59 14051 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
14052 inst.instruction |= inst.operands[0].reg;
14053 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
14054 }
14055 }
b99bd4ef
NC
14056}
14057
14058static void
c19d1205 14059do_t_simd (void)
b99bd4ef 14060{
fdfde340
JM
14061 unsigned Rd, Rn, Rm;
14062
14063 Rd = inst.operands[0].reg;
14064 Rn = inst.operands[1].reg;
14065 Rm = inst.operands[2].reg;
14066
14067 reject_bad_reg (Rd);
14068 reject_bad_reg (Rn);
14069 reject_bad_reg (Rm);
14070
14071 inst.instruction |= Rd << 8;
14072 inst.instruction |= Rn << 16;
14073 inst.instruction |= Rm;
c19d1205 14074}
b99bd4ef 14075
03ee1b7f
NC
14076static void
14077do_t_simd2 (void)
14078{
14079 unsigned Rd, Rn, Rm;
14080
14081 Rd = inst.operands[0].reg;
14082 Rm = inst.operands[1].reg;
14083 Rn = inst.operands[2].reg;
14084
14085 reject_bad_reg (Rd);
14086 reject_bad_reg (Rn);
14087 reject_bad_reg (Rm);
14088
14089 inst.instruction |= Rd << 8;
14090 inst.instruction |= Rn << 16;
14091 inst.instruction |= Rm;
14092}
14093
c19d1205 14094static void
3eb17e6b 14095do_t_smc (void)
c19d1205 14096{
e2b0ab59 14097 unsigned int value = inst.relocs[0].exp.X_add_number;
f4c65163
MGD
14098 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
14099 _("SMC is not permitted on this architecture"));
e2b0ab59 14100 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 14101 _("expression too complex"));
ba85f98c
BW
14102 constraint (value > 0xf, _("immediate too large (bigger than 0xF)"));
14103
e2b0ab59 14104 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205 14105 inst.instruction |= (value & 0x000f) << 16;
ba85f98c 14106
24382199 14107 /* PR gas/15623: SMC instructions must be last in an IT block. */
5ee91343 14108 set_pred_insn_type_last ();
c19d1205 14109}
b99bd4ef 14110
90ec0d68
MGD
14111static void
14112do_t_hvc (void)
14113{
e2b0ab59 14114 unsigned int value = inst.relocs[0].exp.X_add_number;
90ec0d68 14115
e2b0ab59 14116 inst.relocs[0].type = BFD_RELOC_UNUSED;
90ec0d68
MGD
14117 inst.instruction |= (value & 0x0fff);
14118 inst.instruction |= (value & 0xf000) << 4;
14119}
14120
c19d1205 14121static void
3a21c15a 14122do_t_ssat_usat (int bias)
c19d1205 14123{
fdfde340
JM
14124 unsigned Rd, Rn;
14125
14126 Rd = inst.operands[0].reg;
14127 Rn = inst.operands[2].reg;
14128
14129 reject_bad_reg (Rd);
14130 reject_bad_reg (Rn);
14131
14132 inst.instruction |= Rd << 8;
3a21c15a 14133 inst.instruction |= inst.operands[1].imm - bias;
fdfde340 14134 inst.instruction |= Rn << 16;
b99bd4ef 14135
c19d1205 14136 if (inst.operands[3].present)
b99bd4ef 14137 {
e2b0ab59 14138 offsetT shift_amount = inst.relocs[0].exp.X_add_number;
3a21c15a 14139
e2b0ab59 14140 inst.relocs[0].type = BFD_RELOC_UNUSED;
3a21c15a 14141
e2b0ab59 14142 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 14143 _("expression too complex"));
b99bd4ef 14144
3a21c15a 14145 if (shift_amount != 0)
6189168b 14146 {
3a21c15a
NC
14147 constraint (shift_amount > 31,
14148 _("shift expression is too large"));
14149
c19d1205 14150 if (inst.operands[3].shift_kind == SHIFT_ASR)
3a21c15a
NC
14151 inst.instruction |= 0x00200000; /* sh bit. */
14152
14153 inst.instruction |= (shift_amount & 0x1c) << 10;
14154 inst.instruction |= (shift_amount & 0x03) << 6;
6189168b
NC
14155 }
14156 }
b99bd4ef 14157}
c921be7d 14158
3a21c15a
NC
14159static void
14160do_t_ssat (void)
14161{
14162 do_t_ssat_usat (1);
14163}
b99bd4ef 14164
0dd132b6 14165static void
c19d1205 14166do_t_ssat16 (void)
0dd132b6 14167{
fdfde340
JM
14168 unsigned Rd, Rn;
14169
14170 Rd = inst.operands[0].reg;
14171 Rn = inst.operands[2].reg;
14172
14173 reject_bad_reg (Rd);
14174 reject_bad_reg (Rn);
14175
14176 inst.instruction |= Rd << 8;
c19d1205 14177 inst.instruction |= inst.operands[1].imm - 1;
fdfde340 14178 inst.instruction |= Rn << 16;
c19d1205 14179}
0dd132b6 14180
c19d1205
ZW
14181static void
14182do_t_strex (void)
14183{
14184 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
14185 || inst.operands[2].postind || inst.operands[2].writeback
14186 || inst.operands[2].immisreg || inst.operands[2].shifted
14187 || inst.operands[2].negative,
01cfc07f 14188 BAD_ADDR_MODE);
0dd132b6 14189
5be8be5d
DG
14190 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
14191
c19d1205
ZW
14192 inst.instruction |= inst.operands[0].reg << 8;
14193 inst.instruction |= inst.operands[1].reg << 12;
14194 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 14195 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
0dd132b6
NC
14196}
14197
b99bd4ef 14198static void
c19d1205 14199do_t_strexd (void)
b99bd4ef 14200{
c19d1205
ZW
14201 if (!inst.operands[2].present)
14202 inst.operands[2].reg = inst.operands[1].reg + 1;
b99bd4ef 14203
c19d1205
ZW
14204 constraint (inst.operands[0].reg == inst.operands[1].reg
14205 || inst.operands[0].reg == inst.operands[2].reg
f8a8e9d6 14206 || inst.operands[0].reg == inst.operands[3].reg,
c19d1205 14207 BAD_OVERLAP);
b99bd4ef 14208
c19d1205
ZW
14209 inst.instruction |= inst.operands[0].reg;
14210 inst.instruction |= inst.operands[1].reg << 12;
14211 inst.instruction |= inst.operands[2].reg << 8;
14212 inst.instruction |= inst.operands[3].reg << 16;
b99bd4ef
NC
14213}
14214
14215static void
c19d1205 14216do_t_sxtah (void)
b99bd4ef 14217{
fdfde340
JM
14218 unsigned Rd, Rn, Rm;
14219
14220 Rd = inst.operands[0].reg;
14221 Rn = inst.operands[1].reg;
14222 Rm = inst.operands[2].reg;
14223
14224 reject_bad_reg (Rd);
14225 reject_bad_reg (Rn);
14226 reject_bad_reg (Rm);
14227
14228 inst.instruction |= Rd << 8;
14229 inst.instruction |= Rn << 16;
14230 inst.instruction |= Rm;
c19d1205
ZW
14231 inst.instruction |= inst.operands[3].imm << 4;
14232}
b99bd4ef 14233
c19d1205
ZW
14234static void
14235do_t_sxth (void)
14236{
fdfde340
JM
14237 unsigned Rd, Rm;
14238
14239 Rd = inst.operands[0].reg;
14240 Rm = inst.operands[1].reg;
14241
14242 reject_bad_reg (Rd);
14243 reject_bad_reg (Rm);
c921be7d
NC
14244
14245 if (inst.instruction <= 0xffff
14246 && inst.size_req != 4
fdfde340 14247 && Rd <= 7 && Rm <= 7
c19d1205 14248 && (!inst.operands[2].present || inst.operands[2].imm == 0))
b99bd4ef 14249 {
c19d1205 14250 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
14251 inst.instruction |= Rd;
14252 inst.instruction |= Rm << 3;
b99bd4ef 14253 }
c19d1205 14254 else if (unified_syntax)
b99bd4ef 14255 {
c19d1205
ZW
14256 if (inst.instruction <= 0xffff)
14257 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
14258 inst.instruction |= Rd << 8;
14259 inst.instruction |= Rm;
c19d1205 14260 inst.instruction |= inst.operands[2].imm << 4;
b99bd4ef 14261 }
c19d1205 14262 else
b99bd4ef 14263 {
c19d1205
ZW
14264 constraint (inst.operands[2].present && inst.operands[2].imm != 0,
14265 _("Thumb encoding does not support rotation"));
14266 constraint (1, BAD_HIREG);
b99bd4ef 14267 }
c19d1205 14268}
b99bd4ef 14269
c19d1205
ZW
14270static void
14271do_t_swi (void)
14272{
e2b0ab59 14273 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
c19d1205 14274}
b99bd4ef 14275
92e90b6e
PB
14276static void
14277do_t_tb (void)
14278{
fdfde340 14279 unsigned Rn, Rm;
92e90b6e
PB
14280 int half;
14281
14282 half = (inst.instruction & 0x10) != 0;
5ee91343 14283 set_pred_insn_type_last ();
dfa9f0d5
PB
14284 constraint (inst.operands[0].immisreg,
14285 _("instruction requires register index"));
fdfde340
JM
14286
14287 Rn = inst.operands[0].reg;
14288 Rm = inst.operands[0].imm;
c921be7d 14289
5c8ed6a4
JW
14290 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
14291 constraint (Rn == REG_SP, BAD_SP);
fdfde340
JM
14292 reject_bad_reg (Rm);
14293
92e90b6e
PB
14294 constraint (!half && inst.operands[0].shifted,
14295 _("instruction does not allow shifted index"));
fdfde340 14296 inst.instruction |= (Rn << 16) | Rm;
92e90b6e
PB
14297}
14298
74db7efb
NC
14299static void
14300do_t_udf (void)
14301{
14302 if (!inst.operands[0].present)
14303 inst.operands[0].imm = 0;
14304
14305 if ((unsigned int) inst.operands[0].imm > 255 || inst.size_req == 4)
14306 {
14307 constraint (inst.size_req == 2,
14308 _("immediate value out of range"));
14309 inst.instruction = THUMB_OP32 (inst.instruction);
14310 inst.instruction |= (inst.operands[0].imm & 0xf000u) << 4;
14311 inst.instruction |= (inst.operands[0].imm & 0x0fffu) << 0;
14312 }
14313 else
14314 {
14315 inst.instruction = THUMB_OP16 (inst.instruction);
14316 inst.instruction |= inst.operands[0].imm;
14317 }
14318
5ee91343 14319 set_pred_insn_type (NEUTRAL_IT_INSN);
74db7efb
NC
14320}
14321
14322
c19d1205
ZW
14323static void
14324do_t_usat (void)
14325{
3a21c15a 14326 do_t_ssat_usat (0);
b99bd4ef
NC
14327}
14328
14329static void
c19d1205 14330do_t_usat16 (void)
b99bd4ef 14331{
fdfde340
JM
14332 unsigned Rd, Rn;
14333
14334 Rd = inst.operands[0].reg;
14335 Rn = inst.operands[2].reg;
14336
14337 reject_bad_reg (Rd);
14338 reject_bad_reg (Rn);
14339
14340 inst.instruction |= Rd << 8;
c19d1205 14341 inst.instruction |= inst.operands[1].imm;
fdfde340 14342 inst.instruction |= Rn << 16;
b99bd4ef 14343}
c19d1205 14344
e12437dc
AV
14345/* Checking the range of the branch offset (VAL) with NBITS bits
14346 and IS_SIGNED signedness. Also checks the LSB to be 0. */
14347static int
14348v8_1_branch_value_check (int val, int nbits, int is_signed)
14349{
14350 gas_assert (nbits > 0 && nbits <= 32);
14351 if (is_signed)
14352 {
14353 int cmp = (1 << (nbits - 1));
14354 if ((val < -cmp) || (val >= cmp) || (val & 0x01))
14355 return FAIL;
14356 }
14357 else
14358 {
14359 if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
14360 return FAIL;
14361 }
14362 return SUCCESS;
14363}
14364
4389b29a
AV
14365/* For branches in Armv8.1-M Mainline. */
14366static void
14367do_t_branch_future (void)
14368{
14369 unsigned long insn = inst.instruction;
14370
14371 inst.instruction = THUMB_OP32 (inst.instruction);
14372 if (inst.operands[0].hasreloc == 0)
14373 {
14374 if (v8_1_branch_value_check (inst.operands[0].imm, 5, FALSE) == FAIL)
14375 as_bad (BAD_BRANCH_OFF);
14376
14377 inst.instruction |= ((inst.operands[0].imm & 0x1f) >> 1) << 23;
14378 }
14379 else
14380 {
14381 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH5;
14382 inst.relocs[0].pc_rel = 1;
14383 }
14384
14385 switch (insn)
14386 {
14387 case T_MNEM_bf:
14388 if (inst.operands[1].hasreloc == 0)
14389 {
14390 int val = inst.operands[1].imm;
14391 if (v8_1_branch_value_check (inst.operands[1].imm, 17, TRUE) == FAIL)
14392 as_bad (BAD_BRANCH_OFF);
14393
14394 int immA = (val & 0x0001f000) >> 12;
14395 int immB = (val & 0x00000ffc) >> 2;
14396 int immC = (val & 0x00000002) >> 1;
14397 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14398 }
14399 else
14400 {
14401 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF17;
14402 inst.relocs[1].pc_rel = 1;
14403 }
14404 break;
14405
65d1bc05
AV
14406 case T_MNEM_bfl:
14407 if (inst.operands[1].hasreloc == 0)
14408 {
14409 int val = inst.operands[1].imm;
14410 if (v8_1_branch_value_check (inst.operands[1].imm, 19, TRUE) == FAIL)
14411 as_bad (BAD_BRANCH_OFF);
14412
14413 int immA = (val & 0x0007f000) >> 12;
14414 int immB = (val & 0x00000ffc) >> 2;
14415 int immC = (val & 0x00000002) >> 1;
14416 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14417 }
14418 else
14419 {
14420 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
14421 inst.relocs[1].pc_rel = 1;
14422 }
14423 break;
14424
f6b2b12d
AV
14425 case T_MNEM_bfcsel:
14426 /* Operand 1. */
14427 if (inst.operands[1].hasreloc == 0)
14428 {
14429 int val = inst.operands[1].imm;
14430 int immA = (val & 0x00001000) >> 12;
14431 int immB = (val & 0x00000ffc) >> 2;
14432 int immC = (val & 0x00000002) >> 1;
14433 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14434 }
14435 else
14436 {
14437 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF13;
14438 inst.relocs[1].pc_rel = 1;
14439 }
14440
14441 /* Operand 2. */
14442 if (inst.operands[2].hasreloc == 0)
14443 {
14444 constraint ((inst.operands[0].hasreloc != 0), BAD_ARGS);
14445 int val2 = inst.operands[2].imm;
14446 int val0 = inst.operands[0].imm & 0x1f;
14447 int diff = val2 - val0;
14448 if (diff == 4)
14449 inst.instruction |= 1 << 17; /* T bit. */
14450 else if (diff != 2)
14451 as_bad (_("out of range label-relative fixup value"));
14452 }
14453 else
14454 {
14455 constraint ((inst.operands[0].hasreloc == 0), BAD_ARGS);
14456 inst.relocs[2].type = BFD_RELOC_THUMB_PCREL_BFCSEL;
14457 inst.relocs[2].pc_rel = 1;
14458 }
14459
14460 /* Operand 3. */
14461 constraint (inst.cond != COND_ALWAYS, BAD_COND);
14462 inst.instruction |= (inst.operands[3].imm & 0xf) << 18;
14463 break;
14464
f1c7f421
AV
14465 case T_MNEM_bfx:
14466 case T_MNEM_bflx:
14467 inst.instruction |= inst.operands[1].reg << 16;
14468 break;
14469
4389b29a
AV
14470 default: abort ();
14471 }
14472}
14473
60f993ce
AV
14474/* Helper function for do_t_loloop to handle relocations. */
14475static void
14476v8_1_loop_reloc (int is_le)
14477{
14478 if (inst.relocs[0].exp.X_op == O_constant)
14479 {
14480 int value = inst.relocs[0].exp.X_add_number;
14481 value = (is_le) ? -value : value;
14482
14483 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
14484 as_bad (BAD_BRANCH_OFF);
14485
14486 int imml, immh;
14487
14488 immh = (value & 0x00000ffc) >> 2;
14489 imml = (value & 0x00000002) >> 1;
14490
14491 inst.instruction |= (imml << 11) | (immh << 1);
14492 }
14493 else
14494 {
14495 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_LOOP12;
14496 inst.relocs[0].pc_rel = 1;
14497 }
14498}
14499
08132bdd
SP
14500/* For shifts with four operands in MVE. */
14501static void
14502do_mve_scalar_shift1 (void)
14503{
14504 unsigned int value = inst.operands[2].imm;
14505
14506 inst.instruction |= inst.operands[0].reg << 16;
14507 inst.instruction |= inst.operands[1].reg << 8;
14508
14509 /* Setting the bit for saturation. */
14510 inst.instruction |= ((value == 64) ? 0: 1) << 7;
14511
14512 /* Assuming Rm is already checked not to be 11x1. */
14513 constraint (inst.operands[3].reg == inst.operands[0].reg, BAD_OVERLAP);
14514 constraint (inst.operands[3].reg == inst.operands[1].reg, BAD_OVERLAP);
14515 inst.instruction |= inst.operands[3].reg << 12;
14516}
14517
23d00a41
SD
14518/* For shifts in MVE. */
14519static void
14520do_mve_scalar_shift (void)
14521{
14522 if (!inst.operands[2].present)
14523 {
14524 inst.operands[2] = inst.operands[1];
14525 inst.operands[1].reg = 0xf;
14526 }
14527
14528 inst.instruction |= inst.operands[0].reg << 16;
14529 inst.instruction |= inst.operands[1].reg << 8;
14530
14531 if (inst.operands[2].isreg)
14532 {
14533 /* Assuming Rm is already checked not to be 11x1. */
14534 constraint (inst.operands[2].reg == inst.operands[0].reg, BAD_OVERLAP);
14535 constraint (inst.operands[2].reg == inst.operands[1].reg, BAD_OVERLAP);
14536 inst.instruction |= inst.operands[2].reg << 12;
14537 }
14538 else
14539 {
14540 /* Assuming imm is already checked as [1,32]. */
14541 unsigned int value = inst.operands[2].imm;
14542 inst.instruction |= (value & 0x1c) << 10;
14543 inst.instruction |= (value & 0x03) << 6;
14544 /* Change last 4 bits from 0xd to 0xf. */
14545 inst.instruction |= 0x2;
14546 }
14547}
14548
a302e574
AV
14549/* MVE instruction encoder helpers. */
14550#define M_MNEM_vabav 0xee800f01
14551#define M_MNEM_vmladav 0xeef00e00
14552#define M_MNEM_vmladava 0xeef00e20
14553#define M_MNEM_vmladavx 0xeef01e00
14554#define M_MNEM_vmladavax 0xeef01e20
14555#define M_MNEM_vmlsdav 0xeef00e01
14556#define M_MNEM_vmlsdava 0xeef00e21
14557#define M_MNEM_vmlsdavx 0xeef01e01
14558#define M_MNEM_vmlsdavax 0xeef01e21
886e1c73
AV
14559#define M_MNEM_vmullt 0xee011e00
14560#define M_MNEM_vmullb 0xee010e00
efd0b310 14561#define M_MNEM_vctp 0xf000e801
35c228db
AV
14562#define M_MNEM_vst20 0xfc801e00
14563#define M_MNEM_vst21 0xfc801e20
14564#define M_MNEM_vst40 0xfc801e01
14565#define M_MNEM_vst41 0xfc801e21
14566#define M_MNEM_vst42 0xfc801e41
14567#define M_MNEM_vst43 0xfc801e61
14568#define M_MNEM_vld20 0xfc901e00
14569#define M_MNEM_vld21 0xfc901e20
14570#define M_MNEM_vld40 0xfc901e01
14571#define M_MNEM_vld41 0xfc901e21
14572#define M_MNEM_vld42 0xfc901e41
14573#define M_MNEM_vld43 0xfc901e61
f5f10c66
AV
14574#define M_MNEM_vstrb 0xec000e00
14575#define M_MNEM_vstrh 0xec000e10
14576#define M_MNEM_vstrw 0xec000e40
14577#define M_MNEM_vstrd 0xec000e50
14578#define M_MNEM_vldrb 0xec100e00
14579#define M_MNEM_vldrh 0xec100e10
14580#define M_MNEM_vldrw 0xec100e40
14581#define M_MNEM_vldrd 0xec100e50
57785aa2
AV
14582#define M_MNEM_vmovlt 0xeea01f40
14583#define M_MNEM_vmovlb 0xeea00f40
14584#define M_MNEM_vmovnt 0xfe311e81
14585#define M_MNEM_vmovnb 0xfe310e81
c2dafc2a
AV
14586#define M_MNEM_vadc 0xee300f00
14587#define M_MNEM_vadci 0xee301f00
14588#define M_MNEM_vbrsr 0xfe011e60
26c1e780
AV
14589#define M_MNEM_vaddlv 0xee890f00
14590#define M_MNEM_vaddlva 0xee890f20
14591#define M_MNEM_vaddv 0xeef10f00
14592#define M_MNEM_vaddva 0xeef10f20
b409bdb6
AV
14593#define M_MNEM_vddup 0xee011f6e
14594#define M_MNEM_vdwdup 0xee011f60
14595#define M_MNEM_vidup 0xee010f6e
14596#define M_MNEM_viwdup 0xee010f60
13ccd4c0
AV
14597#define M_MNEM_vmaxv 0xeee20f00
14598#define M_MNEM_vmaxav 0xeee00f00
14599#define M_MNEM_vminv 0xeee20f80
14600#define M_MNEM_vminav 0xeee00f80
93925576
AV
14601#define M_MNEM_vmlaldav 0xee800e00
14602#define M_MNEM_vmlaldava 0xee800e20
14603#define M_MNEM_vmlaldavx 0xee801e00
14604#define M_MNEM_vmlaldavax 0xee801e20
14605#define M_MNEM_vmlsldav 0xee800e01
14606#define M_MNEM_vmlsldava 0xee800e21
14607#define M_MNEM_vmlsldavx 0xee801e01
14608#define M_MNEM_vmlsldavax 0xee801e21
14609#define M_MNEM_vrmlaldavhx 0xee801f00
14610#define M_MNEM_vrmlaldavhax 0xee801f20
14611#define M_MNEM_vrmlsldavh 0xfe800e01
14612#define M_MNEM_vrmlsldavha 0xfe800e21
14613#define M_MNEM_vrmlsldavhx 0xfe801e01
14614#define M_MNEM_vrmlsldavhax 0xfe801e21
1be7aba3
AV
14615#define M_MNEM_vqmovnt 0xee331e01
14616#define M_MNEM_vqmovnb 0xee330e01
14617#define M_MNEM_vqmovunt 0xee311e81
14618#define M_MNEM_vqmovunb 0xee310e81
4aa88b50
AV
14619#define M_MNEM_vshrnt 0xee801fc1
14620#define M_MNEM_vshrnb 0xee800fc1
14621#define M_MNEM_vrshrnt 0xfe801fc1
14622#define M_MNEM_vqshrnt 0xee801f40
14623#define M_MNEM_vqshrnb 0xee800f40
14624#define M_MNEM_vqshrunt 0xee801fc0
14625#define M_MNEM_vqshrunb 0xee800fc0
14626#define M_MNEM_vrshrnb 0xfe800fc1
14627#define M_MNEM_vqrshrnt 0xee801f41
14628#define M_MNEM_vqrshrnb 0xee800f41
14629#define M_MNEM_vqrshrunt 0xfe801fc0
14630#define M_MNEM_vqrshrunb 0xfe800fc0
a302e574 14631
aab2c27d
MM
14632/* Bfloat16 instruction encoder helpers. */
14633#define B_MNEM_vfmat 0xfc300850
14634#define B_MNEM_vfmab 0xfc300810
14635
5287ad62 14636/* Neon instruction encoder helpers. */
5f4273c7 14637
5287ad62 14638/* Encodings for the different types for various Neon opcodes. */
b99bd4ef 14639
5287ad62
JB
14640/* An "invalid" code for the following tables. */
14641#define N_INV -1u
14642
14643struct neon_tab_entry
b99bd4ef 14644{
5287ad62
JB
14645 unsigned integer;
14646 unsigned float_or_poly;
14647 unsigned scalar_or_imm;
14648};
5f4273c7 14649
5287ad62
JB
14650/* Map overloaded Neon opcodes to their respective encodings. */
14651#define NEON_ENC_TAB \
14652 X(vabd, 0x0000700, 0x1200d00, N_INV), \
5ee91343 14653 X(vabdl, 0x0800700, N_INV, N_INV), \
5287ad62
JB
14654 X(vmax, 0x0000600, 0x0000f00, N_INV), \
14655 X(vmin, 0x0000610, 0x0200f00, N_INV), \
14656 X(vpadd, 0x0000b10, 0x1000d00, N_INV), \
14657 X(vpmax, 0x0000a00, 0x1000f00, N_INV), \
14658 X(vpmin, 0x0000a10, 0x1200f00, N_INV), \
14659 X(vadd, 0x0000800, 0x0000d00, N_INV), \
5ee91343 14660 X(vaddl, 0x0800000, N_INV, N_INV), \
5287ad62 14661 X(vsub, 0x1000800, 0x0200d00, N_INV), \
5ee91343 14662 X(vsubl, 0x0800200, N_INV, N_INV), \
5287ad62
JB
14663 X(vceq, 0x1000810, 0x0000e00, 0x1b10100), \
14664 X(vcge, 0x0000310, 0x1000e00, 0x1b10080), \
14665 X(vcgt, 0x0000300, 0x1200e00, 0x1b10000), \
14666 /* Register variants of the following two instructions are encoded as
e07e6e58 14667 vcge / vcgt with the operands reversed. */ \
92559b5b
PB
14668 X(vclt, 0x0000300, 0x1200e00, 0x1b10200), \
14669 X(vcle, 0x0000310, 0x1000e00, 0x1b10180), \
62f3b8c8
PB
14670 X(vfma, N_INV, 0x0000c10, N_INV), \
14671 X(vfms, N_INV, 0x0200c10, N_INV), \
5287ad62
JB
14672 X(vmla, 0x0000900, 0x0000d10, 0x0800040), \
14673 X(vmls, 0x1000900, 0x0200d10, 0x0800440), \
14674 X(vmul, 0x0000910, 0x1000d10, 0x0800840), \
14675 X(vmull, 0x0800c00, 0x0800e00, 0x0800a40), /* polynomial not float. */ \
14676 X(vmlal, 0x0800800, N_INV, 0x0800240), \
14677 X(vmlsl, 0x0800a00, N_INV, 0x0800640), \
14678 X(vqdmlal, 0x0800900, N_INV, 0x0800340), \
14679 X(vqdmlsl, 0x0800b00, N_INV, 0x0800740), \
14680 X(vqdmull, 0x0800d00, N_INV, 0x0800b40), \
14681 X(vqdmulh, 0x0000b00, N_INV, 0x0800c40), \
14682 X(vqrdmulh, 0x1000b00, N_INV, 0x0800d40), \
d6b4b13e
MW
14683 X(vqrdmlah, 0x3000b10, N_INV, 0x0800e40), \
14684 X(vqrdmlsh, 0x3000c10, N_INV, 0x0800f40), \
5287ad62
JB
14685 X(vshl, 0x0000400, N_INV, 0x0800510), \
14686 X(vqshl, 0x0000410, N_INV, 0x0800710), \
14687 X(vand, 0x0000110, N_INV, 0x0800030), \
14688 X(vbic, 0x0100110, N_INV, 0x0800030), \
14689 X(veor, 0x1000110, N_INV, N_INV), \
14690 X(vorn, 0x0300110, N_INV, 0x0800010), \
14691 X(vorr, 0x0200110, N_INV, 0x0800010), \
14692 X(vmvn, 0x1b00580, N_INV, 0x0800030), \
14693 X(vshll, 0x1b20300, N_INV, 0x0800a10), /* max shift, immediate. */ \
14694 X(vcvt, 0x1b30600, N_INV, 0x0800e10), /* integer, fixed-point. */ \
14695 X(vdup, 0xe800b10, N_INV, 0x1b00c00), /* arm, scalar. */ \
14696 X(vld1, 0x0200000, 0x0a00000, 0x0a00c00), /* interlv, lane, dup. */ \
14697 X(vst1, 0x0000000, 0x0800000, N_INV), \
14698 X(vld2, 0x0200100, 0x0a00100, 0x0a00d00), \
14699 X(vst2, 0x0000100, 0x0800100, N_INV), \
14700 X(vld3, 0x0200200, 0x0a00200, 0x0a00e00), \
14701 X(vst3, 0x0000200, 0x0800200, N_INV), \
14702 X(vld4, 0x0200300, 0x0a00300, 0x0a00f00), \
14703 X(vst4, 0x0000300, 0x0800300, N_INV), \
14704 X(vmovn, 0x1b20200, N_INV, N_INV), \
14705 X(vtrn, 0x1b20080, N_INV, N_INV), \
14706 X(vqmovn, 0x1b20200, N_INV, N_INV), \
037e8744
JB
14707 X(vqmovun, 0x1b20240, N_INV, N_INV), \
14708 X(vnmul, 0xe200a40, 0xe200b40, N_INV), \
e6655fda
PB
14709 X(vnmla, 0xe100a40, 0xe100b40, N_INV), \
14710 X(vnmls, 0xe100a00, 0xe100b00, N_INV), \
62f3b8c8
PB
14711 X(vfnma, 0xe900a40, 0xe900b40, N_INV), \
14712 X(vfnms, 0xe900a00, 0xe900b00, N_INV), \
037e8744
JB
14713 X(vcmp, 0xeb40a40, 0xeb40b40, N_INV), \
14714 X(vcmpz, 0xeb50a40, 0xeb50b40, N_INV), \
14715 X(vcmpe, 0xeb40ac0, 0xeb40bc0, N_INV), \
33399f07
MGD
14716 X(vcmpez, 0xeb50ac0, 0xeb50bc0, N_INV), \
14717 X(vseleq, 0xe000a00, N_INV, N_INV), \
14718 X(vselvs, 0xe100a00, N_INV, N_INV), \
14719 X(vselge, 0xe200a00, N_INV, N_INV), \
73924fbc
MGD
14720 X(vselgt, 0xe300a00, N_INV, N_INV), \
14721 X(vmaxnm, 0xe800a00, 0x3000f10, N_INV), \
7e8e6784 14722 X(vminnm, 0xe800a40, 0x3200f10, N_INV), \
30bdf752
MGD
14723 X(vcvta, 0xebc0a40, 0x3bb0000, N_INV), \
14724 X(vrintr, 0xeb60a40, 0x3ba0400, N_INV), \
91ff7894 14725 X(vrinta, 0xeb80a40, 0x3ba0400, N_INV), \
48adcd8e 14726 X(aes, 0x3b00300, N_INV, N_INV), \
3c9017d2
MGD
14727 X(sha3op, 0x2000c00, N_INV, N_INV), \
14728 X(sha1h, 0x3b902c0, N_INV, N_INV), \
14729 X(sha2op, 0x3ba0380, N_INV, N_INV)
5287ad62
JB
14730
14731enum neon_opc
14732{
14733#define X(OPC,I,F,S) N_MNEM_##OPC
14734NEON_ENC_TAB
14735#undef X
14736};
b99bd4ef 14737
5287ad62
JB
14738static const struct neon_tab_entry neon_enc_tab[] =
14739{
14740#define X(OPC,I,F,S) { (I), (F), (S) }
14741NEON_ENC_TAB
14742#undef X
14743};
b99bd4ef 14744
88714cb8
DG
14745/* Do not use these macros; instead, use NEON_ENCODE defined below. */
14746#define NEON_ENC_INTEGER_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14747#define NEON_ENC_ARMREG_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14748#define NEON_ENC_POLY_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14749#define NEON_ENC_FLOAT_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14750#define NEON_ENC_SCALAR_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14751#define NEON_ENC_IMMED_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14752#define NEON_ENC_INTERLV_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14753#define NEON_ENC_LANE_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14754#define NEON_ENC_DUP_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14755#define NEON_ENC_SINGLE_(X) \
037e8744 14756 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf0000000))
88714cb8 14757#define NEON_ENC_DOUBLE_(X) \
037e8744 14758 ((neon_enc_tab[(X) & 0x0fffffff].float_or_poly) | ((X) & 0xf0000000))
33399f07
MGD
14759#define NEON_ENC_FPV8_(X) \
14760 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf000000))
5287ad62 14761
88714cb8
DG
14762#define NEON_ENCODE(type, inst) \
14763 do \
14764 { \
14765 inst.instruction = NEON_ENC_##type##_ (inst.instruction); \
14766 inst.is_neon = 1; \
14767 } \
14768 while (0)
14769
14770#define check_neon_suffixes \
14771 do \
14772 { \
14773 if (!inst.error && inst.vectype.elems > 0 && !inst.is_neon) \
14774 { \
14775 as_bad (_("invalid neon suffix for non neon instruction")); \
14776 return; \
14777 } \
14778 } \
14779 while (0)
14780
037e8744
JB
14781/* Define shapes for instruction operands. The following mnemonic characters
14782 are used in this table:
5287ad62 14783
037e8744 14784 F - VFP S<n> register
5287ad62
JB
14785 D - Neon D<n> register
14786 Q - Neon Q<n> register
14787 I - Immediate
14788 S - Scalar
14789 R - ARM register
14790 L - D<n> register list
5f4273c7 14791
037e8744
JB
14792 This table is used to generate various data:
14793 - enumerations of the form NS_DDR to be used as arguments to
14794 neon_select_shape.
14795 - a table classifying shapes into single, double, quad, mixed.
5f4273c7 14796 - a table used to drive neon_select_shape. */
b99bd4ef 14797
037e8744 14798#define NEON_SHAPE_DEF \
93925576 14799 X(4, (R, R, Q, Q), QUAD), \
b409bdb6 14800 X(4, (Q, R, R, I), QUAD), \
57785aa2
AV
14801 X(4, (R, R, S, S), QUAD), \
14802 X(4, (S, S, R, R), QUAD), \
b409bdb6 14803 X(3, (Q, R, I), QUAD), \
1b883319
AV
14804 X(3, (I, Q, Q), QUAD), \
14805 X(3, (I, Q, R), QUAD), \
a302e574 14806 X(3, (R, Q, Q), QUAD), \
037e8744
JB
14807 X(3, (D, D, D), DOUBLE), \
14808 X(3, (Q, Q, Q), QUAD), \
14809 X(3, (D, D, I), DOUBLE), \
14810 X(3, (Q, Q, I), QUAD), \
14811 X(3, (D, D, S), DOUBLE), \
14812 X(3, (Q, Q, S), QUAD), \
5ee91343 14813 X(3, (Q, Q, R), QUAD), \
26c1e780
AV
14814 X(3, (R, R, Q), QUAD), \
14815 X(2, (R, Q), QUAD), \
037e8744
JB
14816 X(2, (D, D), DOUBLE), \
14817 X(2, (Q, Q), QUAD), \
14818 X(2, (D, S), DOUBLE), \
14819 X(2, (Q, S), QUAD), \
14820 X(2, (D, R), DOUBLE), \
14821 X(2, (Q, R), QUAD), \
14822 X(2, (D, I), DOUBLE), \
14823 X(2, (Q, I), QUAD), \
5aae9ae9
MM
14824 X(3, (P, F, I), SINGLE), \
14825 X(3, (P, D, I), DOUBLE), \
14826 X(3, (P, Q, I), QUAD), \
14827 X(4, (P, F, F, I), SINGLE), \
14828 X(4, (P, D, D, I), DOUBLE), \
14829 X(4, (P, Q, Q, I), QUAD), \
14830 X(5, (P, F, F, F, I), SINGLE), \
14831 X(5, (P, D, D, D, I), DOUBLE), \
14832 X(5, (P, Q, Q, Q, I), QUAD), \
037e8744
JB
14833 X(3, (D, L, D), DOUBLE), \
14834 X(2, (D, Q), MIXED), \
14835 X(2, (Q, D), MIXED), \
14836 X(3, (D, Q, I), MIXED), \
14837 X(3, (Q, D, I), MIXED), \
14838 X(3, (Q, D, D), MIXED), \
14839 X(3, (D, Q, Q), MIXED), \
14840 X(3, (Q, Q, D), MIXED), \
14841 X(3, (Q, D, S), MIXED), \
14842 X(3, (D, Q, S), MIXED), \
14843 X(4, (D, D, D, I), DOUBLE), \
14844 X(4, (Q, Q, Q, I), QUAD), \
c28eeff2
SN
14845 X(4, (D, D, S, I), DOUBLE), \
14846 X(4, (Q, Q, S, I), QUAD), \
037e8744
JB
14847 X(2, (F, F), SINGLE), \
14848 X(3, (F, F, F), SINGLE), \
14849 X(2, (F, I), SINGLE), \
14850 X(2, (F, D), MIXED), \
14851 X(2, (D, F), MIXED), \
14852 X(3, (F, F, I), MIXED), \
14853 X(4, (R, R, F, F), SINGLE), \
14854 X(4, (F, F, R, R), SINGLE), \
14855 X(3, (D, R, R), DOUBLE), \
14856 X(3, (R, R, D), DOUBLE), \
14857 X(2, (S, R), SINGLE), \
14858 X(2, (R, S), SINGLE), \
14859 X(2, (F, R), SINGLE), \
d54af2d0 14860 X(2, (R, F), SINGLE), \
1f6234a3
AV
14861/* Used for MVE tail predicated loop instructions. */\
14862 X(2, (R, R), QUAD), \
d54af2d0
RL
14863/* Half float shape supported so far. */\
14864 X (2, (H, D), MIXED), \
14865 X (2, (D, H), MIXED), \
14866 X (2, (H, F), MIXED), \
14867 X (2, (F, H), MIXED), \
14868 X (2, (H, H), HALF), \
14869 X (2, (H, R), HALF), \
14870 X (2, (R, H), HALF), \
14871 X (2, (H, I), HALF), \
14872 X (3, (H, H, H), HALF), \
14873 X (3, (H, F, I), MIXED), \
dec41383
JW
14874 X (3, (F, H, I), MIXED), \
14875 X (3, (D, H, H), MIXED), \
14876 X (3, (D, H, S), MIXED)
037e8744
JB
14877
14878#define S2(A,B) NS_##A##B
14879#define S3(A,B,C) NS_##A##B##C
14880#define S4(A,B,C,D) NS_##A##B##C##D
5aae9ae9 14881#define S5(A,B,C,D,E) NS_##A##B##C##D##E
037e8744
JB
14882
14883#define X(N, L, C) S##N L
14884
5287ad62
JB
14885enum neon_shape
14886{
037e8744
JB
14887 NEON_SHAPE_DEF,
14888 NS_NULL
5287ad62 14889};
b99bd4ef 14890
037e8744
JB
14891#undef X
14892#undef S2
14893#undef S3
14894#undef S4
5aae9ae9 14895#undef S5
037e8744
JB
14896
14897enum neon_shape_class
14898{
d54af2d0 14899 SC_HALF,
037e8744
JB
14900 SC_SINGLE,
14901 SC_DOUBLE,
14902 SC_QUAD,
14903 SC_MIXED
14904};
14905
14906#define X(N, L, C) SC_##C
14907
14908static enum neon_shape_class neon_shape_class[] =
14909{
14910 NEON_SHAPE_DEF
14911};
14912
14913#undef X
14914
14915enum neon_shape_el
14916{
d54af2d0 14917 SE_H,
037e8744
JB
14918 SE_F,
14919 SE_D,
14920 SE_Q,
14921 SE_I,
14922 SE_S,
14923 SE_R,
5aae9ae9
MM
14924 SE_L,
14925 SE_P
037e8744
JB
14926};
14927
14928/* Register widths of above. */
14929static unsigned neon_shape_el_size[] =
14930{
d54af2d0 14931 16,
037e8744
JB
14932 32,
14933 64,
14934 128,
14935 0,
14936 32,
14937 32,
5aae9ae9 14938 0,
037e8744
JB
14939 0
14940};
14941
14942struct neon_shape_info
14943{
14944 unsigned els;
14945 enum neon_shape_el el[NEON_MAX_TYPE_ELS];
14946};
14947
14948#define S2(A,B) { SE_##A, SE_##B }
14949#define S3(A,B,C) { SE_##A, SE_##B, SE_##C }
14950#define S4(A,B,C,D) { SE_##A, SE_##B, SE_##C, SE_##D }
5aae9ae9 14951#define S5(A,B,C,D,E) { SE_##A, SE_##B, SE_##C, SE_##D, SE_##E }
037e8744
JB
14952
14953#define X(N, L, C) { N, S##N L }
14954
14955static struct neon_shape_info neon_shape_tab[] =
14956{
14957 NEON_SHAPE_DEF
14958};
14959
14960#undef X
14961#undef S2
14962#undef S3
14963#undef S4
5aae9ae9 14964#undef S5
037e8744 14965
5287ad62
JB
14966/* Bit masks used in type checking given instructions.
14967 'N_EQK' means the type must be the same as (or based on in some way) the key
14968 type, which itself is marked with the 'N_KEY' bit. If the 'N_EQK' bit is
14969 set, various other bits can be set as well in order to modify the meaning of
14970 the type constraint. */
14971
14972enum neon_type_mask
14973{
8e79c3df
CM
14974 N_S8 = 0x0000001,
14975 N_S16 = 0x0000002,
14976 N_S32 = 0x0000004,
14977 N_S64 = 0x0000008,
14978 N_U8 = 0x0000010,
14979 N_U16 = 0x0000020,
14980 N_U32 = 0x0000040,
14981 N_U64 = 0x0000080,
14982 N_I8 = 0x0000100,
14983 N_I16 = 0x0000200,
14984 N_I32 = 0x0000400,
14985 N_I64 = 0x0000800,
14986 N_8 = 0x0001000,
14987 N_16 = 0x0002000,
14988 N_32 = 0x0004000,
14989 N_64 = 0x0008000,
14990 N_P8 = 0x0010000,
14991 N_P16 = 0x0020000,
14992 N_F16 = 0x0040000,
14993 N_F32 = 0x0080000,
14994 N_F64 = 0x0100000,
4f51b4bd 14995 N_P64 = 0x0200000,
aab2c27d 14996 N_BF16 = 0x0400000,
c921be7d
NC
14997 N_KEY = 0x1000000, /* Key element (main type specifier). */
14998 N_EQK = 0x2000000, /* Given operand has the same type & size as the key. */
8e79c3df 14999 N_VFP = 0x4000000, /* VFP mode: operand size must match register width. */
91ff7894 15000 N_UNT = 0x8000000, /* Must be explicitly untyped. */
c921be7d
NC
15001 N_DBL = 0x0000001, /* If N_EQK, this operand is twice the size. */
15002 N_HLF = 0x0000002, /* If N_EQK, this operand is half the size. */
15003 N_SGN = 0x0000004, /* If N_EQK, this operand is forced to be signed. */
15004 N_UNS = 0x0000008, /* If N_EQK, this operand is forced to be unsigned. */
15005 N_INT = 0x0000010, /* If N_EQK, this operand is forced to be integer. */
15006 N_FLT = 0x0000020, /* If N_EQK, this operand is forced to be float. */
15007 N_SIZ = 0x0000040, /* If N_EQK, this operand is forced to be size-only. */
5287ad62 15008 N_UTYP = 0,
4f51b4bd 15009 N_MAX_NONSPECIAL = N_P64
5287ad62
JB
15010};
15011
dcbf9037
JB
15012#define N_ALLMODS (N_DBL | N_HLF | N_SGN | N_UNS | N_INT | N_FLT | N_SIZ)
15013
5287ad62
JB
15014#define N_SU_ALL (N_S8 | N_S16 | N_S32 | N_S64 | N_U8 | N_U16 | N_U32 | N_U64)
15015#define N_SU_32 (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
15016#define N_SU_16_64 (N_S16 | N_S32 | N_S64 | N_U16 | N_U32 | N_U64)
cc933301
JW
15017#define N_S_32 (N_S8 | N_S16 | N_S32)
15018#define N_F_16_32 (N_F16 | N_F32)
15019#define N_SUF_32 (N_SU_32 | N_F_16_32)
5287ad62 15020#define N_I_ALL (N_I8 | N_I16 | N_I32 | N_I64)
cc933301 15021#define N_IF_32 (N_I8 | N_I16 | N_I32 | N_F16 | N_F32)
d54af2d0 15022#define N_F_ALL (N_F16 | N_F32 | N_F64)
5ee91343
AV
15023#define N_I_MVE (N_I8 | N_I16 | N_I32)
15024#define N_F_MVE (N_F16 | N_F32)
15025#define N_SU_MVE (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
5287ad62
JB
15026
15027/* Pass this as the first type argument to neon_check_type to ignore types
15028 altogether. */
15029#define N_IGNORE_TYPE (N_KEY | N_EQK)
15030
037e8744
JB
15031/* Select a "shape" for the current instruction (describing register types or
15032 sizes) from a list of alternatives. Return NS_NULL if the current instruction
15033 doesn't fit. For non-polymorphic shapes, checking is usually done as a
15034 function of operand parsing, so this function doesn't need to be called.
15035 Shapes should be listed in order of decreasing length. */
5287ad62
JB
15036
15037static enum neon_shape
037e8744 15038neon_select_shape (enum neon_shape shape, ...)
5287ad62 15039{
037e8744
JB
15040 va_list ap;
15041 enum neon_shape first_shape = shape;
5287ad62
JB
15042
15043 /* Fix missing optional operands. FIXME: we don't know at this point how
15044 many arguments we should have, so this makes the assumption that we have
15045 > 1. This is true of all current Neon opcodes, I think, but may not be
15046 true in the future. */
15047 if (!inst.operands[1].present)
15048 inst.operands[1] = inst.operands[0];
15049
037e8744 15050 va_start (ap, shape);
5f4273c7 15051
21d799b5 15052 for (; shape != NS_NULL; shape = (enum neon_shape) va_arg (ap, int))
037e8744
JB
15053 {
15054 unsigned j;
15055 int matches = 1;
15056
15057 for (j = 0; j < neon_shape_tab[shape].els; j++)
477330fc
RM
15058 {
15059 if (!inst.operands[j].present)
15060 {
15061 matches = 0;
15062 break;
15063 }
15064
15065 switch (neon_shape_tab[shape].el[j])
15066 {
d54af2d0
RL
15067 /* If a .f16, .16, .u16, .s16 type specifier is given over
15068 a VFP single precision register operand, it's essentially
15069 means only half of the register is used.
15070
15071 If the type specifier is given after the mnemonics, the
15072 information is stored in inst.vectype. If the type specifier
15073 is given after register operand, the information is stored
15074 in inst.operands[].vectype.
15075
15076 When there is only one type specifier, and all the register
15077 operands are the same type of hardware register, the type
15078 specifier applies to all register operands.
15079
15080 If no type specifier is given, the shape is inferred from
15081 operand information.
15082
15083 for example:
15084 vadd.f16 s0, s1, s2: NS_HHH
15085 vabs.f16 s0, s1: NS_HH
15086 vmov.f16 s0, r1: NS_HR
15087 vmov.f16 r0, s1: NS_RH
15088 vcvt.f16 r0, s1: NS_RH
15089 vcvt.f16.s32 s2, s2, #29: NS_HFI
15090 vcvt.f16.s32 s2, s2: NS_HF
15091 */
15092 case SE_H:
15093 if (!(inst.operands[j].isreg
15094 && inst.operands[j].isvec
15095 && inst.operands[j].issingle
15096 && !inst.operands[j].isquad
15097 && ((inst.vectype.elems == 1
15098 && inst.vectype.el[0].size == 16)
15099 || (inst.vectype.elems > 1
15100 && inst.vectype.el[j].size == 16)
15101 || (inst.vectype.elems == 0
15102 && inst.operands[j].vectype.type != NT_invtype
15103 && inst.operands[j].vectype.size == 16))))
15104 matches = 0;
15105 break;
15106
477330fc
RM
15107 case SE_F:
15108 if (!(inst.operands[j].isreg
15109 && inst.operands[j].isvec
15110 && inst.operands[j].issingle
d54af2d0
RL
15111 && !inst.operands[j].isquad
15112 && ((inst.vectype.elems == 1 && inst.vectype.el[0].size == 32)
15113 || (inst.vectype.elems > 1 && inst.vectype.el[j].size == 32)
15114 || (inst.vectype.elems == 0
15115 && (inst.operands[j].vectype.size == 32
15116 || inst.operands[j].vectype.type == NT_invtype)))))
477330fc
RM
15117 matches = 0;
15118 break;
15119
15120 case SE_D:
15121 if (!(inst.operands[j].isreg
15122 && inst.operands[j].isvec
15123 && !inst.operands[j].isquad
15124 && !inst.operands[j].issingle))
15125 matches = 0;
15126 break;
15127
15128 case SE_R:
15129 if (!(inst.operands[j].isreg
15130 && !inst.operands[j].isvec))
15131 matches = 0;
15132 break;
15133
15134 case SE_Q:
15135 if (!(inst.operands[j].isreg
15136 && inst.operands[j].isvec
15137 && inst.operands[j].isquad
15138 && !inst.operands[j].issingle))
15139 matches = 0;
15140 break;
15141
15142 case SE_I:
15143 if (!(!inst.operands[j].isreg
15144 && !inst.operands[j].isscalar))
15145 matches = 0;
15146 break;
15147
15148 case SE_S:
15149 if (!(!inst.operands[j].isreg
15150 && inst.operands[j].isscalar))
15151 matches = 0;
15152 break;
15153
5aae9ae9 15154 case SE_P:
477330fc
RM
15155 case SE_L:
15156 break;
15157 }
3fde54a2
JZ
15158 if (!matches)
15159 break;
477330fc 15160 }
ad6cec43
MGD
15161 if (matches && (j >= ARM_IT_MAX_OPERANDS || !inst.operands[j].present))
15162 /* We've matched all the entries in the shape table, and we don't
15163 have any left over operands which have not been matched. */
477330fc 15164 break;
037e8744 15165 }
5f4273c7 15166
037e8744 15167 va_end (ap);
5287ad62 15168
037e8744
JB
15169 if (shape == NS_NULL && first_shape != NS_NULL)
15170 first_error (_("invalid instruction shape"));
5287ad62 15171
037e8744
JB
15172 return shape;
15173}
5287ad62 15174
037e8744
JB
15175/* True if SHAPE is predominantly a quadword operation (most of the time, this
15176 means the Q bit should be set). */
15177
15178static int
15179neon_quad (enum neon_shape shape)
15180{
15181 return neon_shape_class[shape] == SC_QUAD;
5287ad62 15182}
037e8744 15183
5287ad62
JB
15184static void
15185neon_modify_type_size (unsigned typebits, enum neon_el_type *g_type,
477330fc 15186 unsigned *g_size)
5287ad62
JB
15187{
15188 /* Allow modification to be made to types which are constrained to be
15189 based on the key element, based on bits set alongside N_EQK. */
15190 if ((typebits & N_EQK) != 0)
15191 {
15192 if ((typebits & N_HLF) != 0)
15193 *g_size /= 2;
15194 else if ((typebits & N_DBL) != 0)
15195 *g_size *= 2;
15196 if ((typebits & N_SGN) != 0)
15197 *g_type = NT_signed;
15198 else if ((typebits & N_UNS) != 0)
477330fc 15199 *g_type = NT_unsigned;
5287ad62 15200 else if ((typebits & N_INT) != 0)
477330fc 15201 *g_type = NT_integer;
5287ad62 15202 else if ((typebits & N_FLT) != 0)
477330fc 15203 *g_type = NT_float;
dcbf9037 15204 else if ((typebits & N_SIZ) != 0)
477330fc 15205 *g_type = NT_untyped;
5287ad62
JB
15206 }
15207}
5f4273c7 15208
5287ad62
JB
15209/* Return operand OPNO promoted by bits set in THISARG. KEY should be the "key"
15210 operand type, i.e. the single type specified in a Neon instruction when it
15211 is the only one given. */
15212
15213static struct neon_type_el
15214neon_type_promote (struct neon_type_el *key, unsigned thisarg)
15215{
15216 struct neon_type_el dest = *key;
5f4273c7 15217
9c2799c2 15218 gas_assert ((thisarg & N_EQK) != 0);
5f4273c7 15219
5287ad62
JB
15220 neon_modify_type_size (thisarg, &dest.type, &dest.size);
15221
15222 return dest;
15223}
15224
15225/* Convert Neon type and size into compact bitmask representation. */
15226
15227static enum neon_type_mask
15228type_chk_of_el_type (enum neon_el_type type, unsigned size)
15229{
15230 switch (type)
15231 {
15232 case NT_untyped:
15233 switch (size)
477330fc
RM
15234 {
15235 case 8: return N_8;
15236 case 16: return N_16;
15237 case 32: return N_32;
15238 case 64: return N_64;
15239 default: ;
15240 }
5287ad62
JB
15241 break;
15242
15243 case NT_integer:
15244 switch (size)
477330fc
RM
15245 {
15246 case 8: return N_I8;
15247 case 16: return N_I16;
15248 case 32: return N_I32;
15249 case 64: return N_I64;
15250 default: ;
15251 }
5287ad62
JB
15252 break;
15253
15254 case NT_float:
037e8744 15255 switch (size)
477330fc 15256 {
8e79c3df 15257 case 16: return N_F16;
477330fc
RM
15258 case 32: return N_F32;
15259 case 64: return N_F64;
15260 default: ;
15261 }
5287ad62
JB
15262 break;
15263
15264 case NT_poly:
15265 switch (size)
477330fc
RM
15266 {
15267 case 8: return N_P8;
15268 case 16: return N_P16;
4f51b4bd 15269 case 64: return N_P64;
477330fc
RM
15270 default: ;
15271 }
5287ad62
JB
15272 break;
15273
15274 case NT_signed:
15275 switch (size)
477330fc
RM
15276 {
15277 case 8: return N_S8;
15278 case 16: return N_S16;
15279 case 32: return N_S32;
15280 case 64: return N_S64;
15281 default: ;
15282 }
5287ad62
JB
15283 break;
15284
15285 case NT_unsigned:
15286 switch (size)
477330fc
RM
15287 {
15288 case 8: return N_U8;
15289 case 16: return N_U16;
15290 case 32: return N_U32;
15291 case 64: return N_U64;
15292 default: ;
15293 }
5287ad62
JB
15294 break;
15295
aab2c27d
MM
15296 case NT_bfloat:
15297 if (size == 16) return N_BF16;
15298 break;
15299
5287ad62
JB
15300 default: ;
15301 }
5f4273c7 15302
5287ad62
JB
15303 return N_UTYP;
15304}
15305
15306/* Convert compact Neon bitmask type representation to a type and size. Only
15307 handles the case where a single bit is set in the mask. */
15308
dcbf9037 15309static int
5287ad62 15310el_type_of_type_chk (enum neon_el_type *type, unsigned *size,
477330fc 15311 enum neon_type_mask mask)
5287ad62 15312{
dcbf9037
JB
15313 if ((mask & N_EQK) != 0)
15314 return FAIL;
15315
5287ad62
JB
15316 if ((mask & (N_S8 | N_U8 | N_I8 | N_8 | N_P8)) != 0)
15317 *size = 8;
aab2c27d
MM
15318 else if ((mask & (N_S16 | N_U16 | N_I16 | N_16 | N_F16 | N_P16 | N_BF16))
15319 != 0)
5287ad62 15320 *size = 16;
dcbf9037 15321 else if ((mask & (N_S32 | N_U32 | N_I32 | N_32 | N_F32)) != 0)
5287ad62 15322 *size = 32;
4f51b4bd 15323 else if ((mask & (N_S64 | N_U64 | N_I64 | N_64 | N_F64 | N_P64)) != 0)
5287ad62 15324 *size = 64;
dcbf9037
JB
15325 else
15326 return FAIL;
15327
5287ad62
JB
15328 if ((mask & (N_S8 | N_S16 | N_S32 | N_S64)) != 0)
15329 *type = NT_signed;
dcbf9037 15330 else if ((mask & (N_U8 | N_U16 | N_U32 | N_U64)) != 0)
5287ad62 15331 *type = NT_unsigned;
dcbf9037 15332 else if ((mask & (N_I8 | N_I16 | N_I32 | N_I64)) != 0)
5287ad62 15333 *type = NT_integer;
dcbf9037 15334 else if ((mask & (N_8 | N_16 | N_32 | N_64)) != 0)
5287ad62 15335 *type = NT_untyped;
4f51b4bd 15336 else if ((mask & (N_P8 | N_P16 | N_P64)) != 0)
5287ad62 15337 *type = NT_poly;
d54af2d0 15338 else if ((mask & (N_F_ALL)) != 0)
5287ad62 15339 *type = NT_float;
aab2c27d
MM
15340 else if ((mask & (N_BF16)) != 0)
15341 *type = NT_bfloat;
dcbf9037
JB
15342 else
15343 return FAIL;
5f4273c7 15344
dcbf9037 15345 return SUCCESS;
5287ad62
JB
15346}
15347
15348/* Modify a bitmask of allowed types. This is only needed for type
15349 relaxation. */
15350
15351static unsigned
15352modify_types_allowed (unsigned allowed, unsigned mods)
15353{
15354 unsigned size;
15355 enum neon_el_type type;
15356 unsigned destmask;
15357 int i;
5f4273c7 15358
5287ad62 15359 destmask = 0;
5f4273c7 15360
5287ad62
JB
15361 for (i = 1; i <= N_MAX_NONSPECIAL; i <<= 1)
15362 {
21d799b5 15363 if (el_type_of_type_chk (&type, &size,
477330fc
RM
15364 (enum neon_type_mask) (allowed & i)) == SUCCESS)
15365 {
15366 neon_modify_type_size (mods, &type, &size);
15367 destmask |= type_chk_of_el_type (type, size);
15368 }
5287ad62 15369 }
5f4273c7 15370
5287ad62
JB
15371 return destmask;
15372}
15373
15374/* Check type and return type classification.
15375 The manual states (paraphrase): If one datatype is given, it indicates the
15376 type given in:
15377 - the second operand, if there is one
15378 - the operand, if there is no second operand
15379 - the result, if there are no operands.
15380 This isn't quite good enough though, so we use a concept of a "key" datatype
15381 which is set on a per-instruction basis, which is the one which matters when
15382 only one data type is written.
15383 Note: this function has side-effects (e.g. filling in missing operands). All
037e8744 15384 Neon instructions should call it before performing bit encoding. */
5287ad62
JB
15385
15386static struct neon_type_el
15387neon_check_type (unsigned els, enum neon_shape ns, ...)
15388{
15389 va_list ap;
15390 unsigned i, pass, key_el = 0;
15391 unsigned types[NEON_MAX_TYPE_ELS];
15392 enum neon_el_type k_type = NT_invtype;
15393 unsigned k_size = -1u;
15394 struct neon_type_el badtype = {NT_invtype, -1};
15395 unsigned key_allowed = 0;
15396
15397 /* Optional registers in Neon instructions are always (not) in operand 1.
15398 Fill in the missing operand here, if it was omitted. */
15399 if (els > 1 && !inst.operands[1].present)
15400 inst.operands[1] = inst.operands[0];
15401
15402 /* Suck up all the varargs. */
15403 va_start (ap, ns);
15404 for (i = 0; i < els; i++)
15405 {
15406 unsigned thisarg = va_arg (ap, unsigned);
15407 if (thisarg == N_IGNORE_TYPE)
477330fc
RM
15408 {
15409 va_end (ap);
15410 return badtype;
15411 }
5287ad62
JB
15412 types[i] = thisarg;
15413 if ((thisarg & N_KEY) != 0)
477330fc 15414 key_el = i;
5287ad62
JB
15415 }
15416 va_end (ap);
15417
dcbf9037
JB
15418 if (inst.vectype.elems > 0)
15419 for (i = 0; i < els; i++)
15420 if (inst.operands[i].vectype.type != NT_invtype)
477330fc
RM
15421 {
15422 first_error (_("types specified in both the mnemonic and operands"));
15423 return badtype;
15424 }
dcbf9037 15425
5287ad62
JB
15426 /* Duplicate inst.vectype elements here as necessary.
15427 FIXME: No idea if this is exactly the same as the ARM assembler,
15428 particularly when an insn takes one register and one non-register
15429 operand. */
15430 if (inst.vectype.elems == 1 && els > 1)
15431 {
15432 unsigned j;
15433 inst.vectype.elems = els;
15434 inst.vectype.el[key_el] = inst.vectype.el[0];
15435 for (j = 0; j < els; j++)
477330fc
RM
15436 if (j != key_el)
15437 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
15438 types[j]);
dcbf9037
JB
15439 }
15440 else if (inst.vectype.elems == 0 && els > 0)
15441 {
15442 unsigned j;
15443 /* No types were given after the mnemonic, so look for types specified
477330fc
RM
15444 after each operand. We allow some flexibility here; as long as the
15445 "key" operand has a type, we can infer the others. */
dcbf9037 15446 for (j = 0; j < els; j++)
477330fc
RM
15447 if (inst.operands[j].vectype.type != NT_invtype)
15448 inst.vectype.el[j] = inst.operands[j].vectype;
dcbf9037
JB
15449
15450 if (inst.operands[key_el].vectype.type != NT_invtype)
477330fc
RM
15451 {
15452 for (j = 0; j < els; j++)
15453 if (inst.operands[j].vectype.type == NT_invtype)
15454 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
15455 types[j]);
15456 }
dcbf9037 15457 else
477330fc
RM
15458 {
15459 first_error (_("operand types can't be inferred"));
15460 return badtype;
15461 }
5287ad62
JB
15462 }
15463 else if (inst.vectype.elems != els)
15464 {
dcbf9037 15465 first_error (_("type specifier has the wrong number of parts"));
5287ad62
JB
15466 return badtype;
15467 }
15468
15469 for (pass = 0; pass < 2; pass++)
15470 {
15471 for (i = 0; i < els; i++)
477330fc
RM
15472 {
15473 unsigned thisarg = types[i];
15474 unsigned types_allowed = ((thisarg & N_EQK) != 0 && pass != 0)
15475 ? modify_types_allowed (key_allowed, thisarg) : thisarg;
15476 enum neon_el_type g_type = inst.vectype.el[i].type;
15477 unsigned g_size = inst.vectype.el[i].size;
15478
15479 /* Decay more-specific signed & unsigned types to sign-insensitive
5287ad62 15480 integer types if sign-specific variants are unavailable. */
477330fc 15481 if ((g_type == NT_signed || g_type == NT_unsigned)
5287ad62
JB
15482 && (types_allowed & N_SU_ALL) == 0)
15483 g_type = NT_integer;
15484
477330fc 15485 /* If only untyped args are allowed, decay any more specific types to
5287ad62
JB
15486 them. Some instructions only care about signs for some element
15487 sizes, so handle that properly. */
477330fc 15488 if (((types_allowed & N_UNT) == 0)
91ff7894
MGD
15489 && ((g_size == 8 && (types_allowed & N_8) != 0)
15490 || (g_size == 16 && (types_allowed & N_16) != 0)
15491 || (g_size == 32 && (types_allowed & N_32) != 0)
15492 || (g_size == 64 && (types_allowed & N_64) != 0)))
5287ad62
JB
15493 g_type = NT_untyped;
15494
477330fc
RM
15495 if (pass == 0)
15496 {
15497 if ((thisarg & N_KEY) != 0)
15498 {
15499 k_type = g_type;
15500 k_size = g_size;
15501 key_allowed = thisarg & ~N_KEY;
cc933301
JW
15502
15503 /* Check architecture constraint on FP16 extension. */
15504 if (k_size == 16
15505 && k_type == NT_float
15506 && ! ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15507 {
15508 inst.error = _(BAD_FP16);
15509 return badtype;
15510 }
477330fc
RM
15511 }
15512 }
15513 else
15514 {
15515 if ((thisarg & N_VFP) != 0)
15516 {
15517 enum neon_shape_el regshape;
15518 unsigned regwidth, match;
99b253c5
NC
15519
15520 /* PR 11136: Catch the case where we are passed a shape of NS_NULL. */
15521 if (ns == NS_NULL)
15522 {
15523 first_error (_("invalid instruction shape"));
15524 return badtype;
15525 }
477330fc
RM
15526 regshape = neon_shape_tab[ns].el[i];
15527 regwidth = neon_shape_el_size[regshape];
15528
15529 /* In VFP mode, operands must match register widths. If we
15530 have a key operand, use its width, else use the width of
15531 the current operand. */
15532 if (k_size != -1u)
15533 match = k_size;
15534 else
15535 match = g_size;
15536
9db2f6b4
RL
15537 /* FP16 will use a single precision register. */
15538 if (regwidth == 32 && match == 16)
15539 {
15540 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15541 match = regwidth;
15542 else
15543 {
15544 inst.error = _(BAD_FP16);
15545 return badtype;
15546 }
15547 }
15548
477330fc
RM
15549 if (regwidth != match)
15550 {
15551 first_error (_("operand size must match register width"));
15552 return badtype;
15553 }
15554 }
15555
15556 if ((thisarg & N_EQK) == 0)
15557 {
15558 unsigned given_type = type_chk_of_el_type (g_type, g_size);
15559
15560 if ((given_type & types_allowed) == 0)
15561 {
a302e574 15562 first_error (BAD_SIMD_TYPE);
477330fc
RM
15563 return badtype;
15564 }
15565 }
15566 else
15567 {
15568 enum neon_el_type mod_k_type = k_type;
15569 unsigned mod_k_size = k_size;
15570 neon_modify_type_size (thisarg, &mod_k_type, &mod_k_size);
15571 if (g_type != mod_k_type || g_size != mod_k_size)
15572 {
15573 first_error (_("inconsistent types in Neon instruction"));
15574 return badtype;
15575 }
15576 }
15577 }
15578 }
5287ad62
JB
15579 }
15580
15581 return inst.vectype.el[key_el];
15582}
15583
037e8744 15584/* Neon-style VFP instruction forwarding. */
5287ad62 15585
037e8744
JB
15586/* Thumb VFP instructions have 0xE in the condition field. */
15587
15588static void
15589do_vfp_cond_or_thumb (void)
5287ad62 15590{
88714cb8
DG
15591 inst.is_neon = 1;
15592
5287ad62 15593 if (thumb_mode)
037e8744 15594 inst.instruction |= 0xe0000000;
5287ad62 15595 else
037e8744 15596 inst.instruction |= inst.cond << 28;
5287ad62
JB
15597}
15598
037e8744
JB
15599/* Look up and encode a simple mnemonic, for use as a helper function for the
15600 Neon-style VFP syntax. This avoids duplication of bits of the insns table,
15601 etc. It is assumed that operand parsing has already been done, and that the
15602 operands are in the form expected by the given opcode (this isn't necessarily
15603 the same as the form in which they were parsed, hence some massaging must
15604 take place before this function is called).
15605 Checks current arch version against that in the looked-up opcode. */
5287ad62 15606
037e8744
JB
15607static void
15608do_vfp_nsyn_opcode (const char *opname)
5287ad62 15609{
037e8744 15610 const struct asm_opcode *opcode;
5f4273c7 15611
21d799b5 15612 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, opname);
5287ad62 15613
037e8744
JB
15614 if (!opcode)
15615 abort ();
5287ad62 15616
037e8744 15617 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant,
477330fc
RM
15618 thumb_mode ? *opcode->tvariant : *opcode->avariant),
15619 _(BAD_FPU));
5287ad62 15620
88714cb8
DG
15621 inst.is_neon = 1;
15622
037e8744
JB
15623 if (thumb_mode)
15624 {
15625 inst.instruction = opcode->tvalue;
15626 opcode->tencode ();
15627 }
15628 else
15629 {
15630 inst.instruction = (inst.cond << 28) | opcode->avalue;
15631 opcode->aencode ();
15632 }
15633}
5287ad62
JB
15634
15635static void
037e8744 15636do_vfp_nsyn_add_sub (enum neon_shape rs)
5287ad62 15637{
037e8744
JB
15638 int is_add = (inst.instruction & 0x0fffffff) == N_MNEM_vadd;
15639
9db2f6b4 15640 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15641 {
15642 if (is_add)
477330fc 15643 do_vfp_nsyn_opcode ("fadds");
037e8744 15644 else
477330fc 15645 do_vfp_nsyn_opcode ("fsubs");
9db2f6b4
RL
15646
15647 /* ARMv8.2 fp16 instruction. */
15648 if (rs == NS_HHH)
15649 do_scalar_fp16_v82_encode ();
037e8744
JB
15650 }
15651 else
15652 {
15653 if (is_add)
477330fc 15654 do_vfp_nsyn_opcode ("faddd");
037e8744 15655 else
477330fc 15656 do_vfp_nsyn_opcode ("fsubd");
037e8744
JB
15657 }
15658}
15659
15660/* Check operand types to see if this is a VFP instruction, and if so call
15661 PFN (). */
15662
15663static int
15664try_vfp_nsyn (int args, void (*pfn) (enum neon_shape))
15665{
15666 enum neon_shape rs;
15667 struct neon_type_el et;
15668
15669 switch (args)
15670 {
15671 case 2:
9db2f6b4
RL
15672 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15673 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
037e8744 15674 break;
5f4273c7 15675
037e8744 15676 case 3:
9db2f6b4
RL
15677 rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
15678 et = neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
15679 N_F_ALL | N_KEY | N_VFP);
037e8744
JB
15680 break;
15681
15682 default:
15683 abort ();
15684 }
15685
15686 if (et.type != NT_invtype)
15687 {
15688 pfn (rs);
15689 return SUCCESS;
15690 }
037e8744 15691
99b253c5 15692 inst.error = NULL;
037e8744
JB
15693 return FAIL;
15694}
15695
15696static void
15697do_vfp_nsyn_mla_mls (enum neon_shape rs)
15698{
15699 int is_mla = (inst.instruction & 0x0fffffff) == N_MNEM_vmla;
5f4273c7 15700
9db2f6b4 15701 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15702 {
15703 if (is_mla)
477330fc 15704 do_vfp_nsyn_opcode ("fmacs");
037e8744 15705 else
477330fc 15706 do_vfp_nsyn_opcode ("fnmacs");
9db2f6b4
RL
15707
15708 /* ARMv8.2 fp16 instruction. */
15709 if (rs == NS_HHH)
15710 do_scalar_fp16_v82_encode ();
037e8744
JB
15711 }
15712 else
15713 {
15714 if (is_mla)
477330fc 15715 do_vfp_nsyn_opcode ("fmacd");
037e8744 15716 else
477330fc 15717 do_vfp_nsyn_opcode ("fnmacd");
037e8744
JB
15718 }
15719}
15720
62f3b8c8
PB
15721static void
15722do_vfp_nsyn_fma_fms (enum neon_shape rs)
15723{
15724 int is_fma = (inst.instruction & 0x0fffffff) == N_MNEM_vfma;
15725
9db2f6b4 15726 if (rs == NS_FFF || rs == NS_HHH)
62f3b8c8
PB
15727 {
15728 if (is_fma)
477330fc 15729 do_vfp_nsyn_opcode ("ffmas");
62f3b8c8 15730 else
477330fc 15731 do_vfp_nsyn_opcode ("ffnmas");
9db2f6b4
RL
15732
15733 /* ARMv8.2 fp16 instruction. */
15734 if (rs == NS_HHH)
15735 do_scalar_fp16_v82_encode ();
62f3b8c8
PB
15736 }
15737 else
15738 {
15739 if (is_fma)
477330fc 15740 do_vfp_nsyn_opcode ("ffmad");
62f3b8c8 15741 else
477330fc 15742 do_vfp_nsyn_opcode ("ffnmad");
62f3b8c8
PB
15743 }
15744}
15745
037e8744
JB
15746static void
15747do_vfp_nsyn_mul (enum neon_shape rs)
15748{
9db2f6b4
RL
15749 if (rs == NS_FFF || rs == NS_HHH)
15750 {
15751 do_vfp_nsyn_opcode ("fmuls");
15752
15753 /* ARMv8.2 fp16 instruction. */
15754 if (rs == NS_HHH)
15755 do_scalar_fp16_v82_encode ();
15756 }
037e8744
JB
15757 else
15758 do_vfp_nsyn_opcode ("fmuld");
15759}
15760
15761static void
15762do_vfp_nsyn_abs_neg (enum neon_shape rs)
15763{
15764 int is_neg = (inst.instruction & 0x80) != 0;
9db2f6b4 15765 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_VFP | N_KEY);
037e8744 15766
9db2f6b4 15767 if (rs == NS_FF || rs == NS_HH)
037e8744
JB
15768 {
15769 if (is_neg)
477330fc 15770 do_vfp_nsyn_opcode ("fnegs");
037e8744 15771 else
477330fc 15772 do_vfp_nsyn_opcode ("fabss");
9db2f6b4
RL
15773
15774 /* ARMv8.2 fp16 instruction. */
15775 if (rs == NS_HH)
15776 do_scalar_fp16_v82_encode ();
037e8744
JB
15777 }
15778 else
15779 {
15780 if (is_neg)
477330fc 15781 do_vfp_nsyn_opcode ("fnegd");
037e8744 15782 else
477330fc 15783 do_vfp_nsyn_opcode ("fabsd");
037e8744
JB
15784 }
15785}
15786
15787/* Encode single-precision (only!) VFP fldm/fstm instructions. Double precision
15788 insns belong to Neon, and are handled elsewhere. */
15789
15790static void
15791do_vfp_nsyn_ldm_stm (int is_dbmode)
15792{
15793 int is_ldm = (inst.instruction & (1 << 20)) != 0;
15794 if (is_ldm)
15795 {
15796 if (is_dbmode)
477330fc 15797 do_vfp_nsyn_opcode ("fldmdbs");
037e8744 15798 else
477330fc 15799 do_vfp_nsyn_opcode ("fldmias");
037e8744
JB
15800 }
15801 else
15802 {
15803 if (is_dbmode)
477330fc 15804 do_vfp_nsyn_opcode ("fstmdbs");
037e8744 15805 else
477330fc 15806 do_vfp_nsyn_opcode ("fstmias");
037e8744
JB
15807 }
15808}
15809
037e8744
JB
15810static void
15811do_vfp_nsyn_sqrt (void)
15812{
9db2f6b4
RL
15813 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15814 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 15815
9db2f6b4
RL
15816 if (rs == NS_FF || rs == NS_HH)
15817 {
15818 do_vfp_nsyn_opcode ("fsqrts");
15819
15820 /* ARMv8.2 fp16 instruction. */
15821 if (rs == NS_HH)
15822 do_scalar_fp16_v82_encode ();
15823 }
037e8744
JB
15824 else
15825 do_vfp_nsyn_opcode ("fsqrtd");
15826}
15827
15828static void
15829do_vfp_nsyn_div (void)
15830{
9db2f6b4 15831 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15832 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15833 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15834
9db2f6b4
RL
15835 if (rs == NS_FFF || rs == NS_HHH)
15836 {
15837 do_vfp_nsyn_opcode ("fdivs");
15838
15839 /* ARMv8.2 fp16 instruction. */
15840 if (rs == NS_HHH)
15841 do_scalar_fp16_v82_encode ();
15842 }
037e8744
JB
15843 else
15844 do_vfp_nsyn_opcode ("fdivd");
15845}
15846
15847static void
15848do_vfp_nsyn_nmul (void)
15849{
9db2f6b4 15850 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15851 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15852 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15853
9db2f6b4 15854 if (rs == NS_FFF || rs == NS_HHH)
037e8744 15855 {
88714cb8 15856 NEON_ENCODE (SINGLE, inst);
037e8744 15857 do_vfp_sp_dyadic ();
9db2f6b4
RL
15858
15859 /* ARMv8.2 fp16 instruction. */
15860 if (rs == NS_HHH)
15861 do_scalar_fp16_v82_encode ();
037e8744
JB
15862 }
15863 else
15864 {
88714cb8 15865 NEON_ENCODE (DOUBLE, inst);
037e8744
JB
15866 do_vfp_dp_rd_rn_rm ();
15867 }
15868 do_vfp_cond_or_thumb ();
9db2f6b4 15869
037e8744
JB
15870}
15871
1b883319
AV
15872/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
15873 (0, 1, 2, 3). */
15874
15875static unsigned
15876neon_logbits (unsigned x)
15877{
15878 return ffs (x) - 4;
15879}
15880
15881#define LOW4(R) ((R) & 0xf)
15882#define HI1(R) (((R) >> 4) & 1)
5aae9ae9
MM
15883#define LOW1(R) ((R) & 0x1)
15884#define HI4(R) (((R) >> 1) & 0xf)
1b883319
AV
15885
15886static unsigned
15887mve_get_vcmp_vpt_cond (struct neon_type_el et)
15888{
15889 switch (et.type)
15890 {
15891 default:
15892 first_error (BAD_EL_TYPE);
15893 return 0;
15894 case NT_float:
15895 switch (inst.operands[0].imm)
15896 {
15897 default:
15898 first_error (_("invalid condition"));
15899 return 0;
15900 case 0x0:
15901 /* eq. */
15902 return 0;
15903 case 0x1:
15904 /* ne. */
15905 return 1;
15906 case 0xa:
15907 /* ge/ */
15908 return 4;
15909 case 0xb:
15910 /* lt. */
15911 return 5;
15912 case 0xc:
15913 /* gt. */
15914 return 6;
15915 case 0xd:
15916 /* le. */
15917 return 7;
15918 }
15919 case NT_integer:
15920 /* only accept eq and ne. */
15921 if (inst.operands[0].imm > 1)
15922 {
15923 first_error (_("invalid condition"));
15924 return 0;
15925 }
15926 return inst.operands[0].imm;
15927 case NT_unsigned:
15928 if (inst.operands[0].imm == 0x2)
15929 return 2;
15930 else if (inst.operands[0].imm == 0x8)
15931 return 3;
15932 else
15933 {
15934 first_error (_("invalid condition"));
15935 return 0;
15936 }
15937 case NT_signed:
15938 switch (inst.operands[0].imm)
15939 {
15940 default:
15941 first_error (_("invalid condition"));
15942 return 0;
15943 case 0xa:
15944 /* ge. */
15945 return 4;
15946 case 0xb:
15947 /* lt. */
15948 return 5;
15949 case 0xc:
15950 /* gt. */
15951 return 6;
15952 case 0xd:
15953 /* le. */
15954 return 7;
15955 }
15956 }
15957 /* Should be unreachable. */
15958 abort ();
15959}
15960
efd0b310
SP
15961/* For VCTP (create vector tail predicate) in MVE. */
15962static void
15963do_mve_vctp (void)
15964{
15965 int dt = 0;
15966 unsigned size = 0x0;
15967
15968 if (inst.cond > COND_ALWAYS)
15969 inst.pred_insn_type = INSIDE_VPT_INSN;
15970 else
15971 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15972
15973 /* This is a typical MVE instruction which has no type but have size 8, 16,
15974 32 and 64. For instructions with no type, inst.vectype.el[j].type is set
15975 to NT_untyped and size is updated in inst.vectype.el[j].size. */
15976 if ((inst.operands[0].present) && (inst.vectype.el[0].type == NT_untyped))
15977 dt = inst.vectype.el[0].size;
15978
15979 /* Setting this does not indicate an actual NEON instruction, but only
15980 indicates that the mnemonic accepts neon-style type suffixes. */
15981 inst.is_neon = 1;
15982
15983 switch (dt)
15984 {
15985 case 8:
15986 break;
15987 case 16:
15988 size = 0x1; break;
15989 case 32:
15990 size = 0x2; break;
15991 case 64:
15992 size = 0x3; break;
15993 default:
15994 first_error (_("Type is not allowed for this instruction"));
15995 }
15996 inst.instruction |= size << 20;
15997 inst.instruction |= inst.operands[0].reg << 16;
15998}
15999
1b883319
AV
16000static void
16001do_mve_vpt (void)
16002{
16003 /* We are dealing with a vector predicated block. */
16004 if (inst.operands[0].present)
16005 {
16006 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
16007 struct neon_type_el et
16008 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
16009 N_EQK);
16010
16011 unsigned fcond = mve_get_vcmp_vpt_cond (et);
16012
16013 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
16014
16015 if (et.type == NT_invtype)
16016 return;
16017
16018 if (et.type == NT_float)
16019 {
16020 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
16021 BAD_FPU);
16022 constraint (et.size != 16 && et.size != 32, BAD_EL_TYPE);
16023 inst.instruction |= (et.size == 16) << 28;
16024 inst.instruction |= 0x3 << 20;
16025 }
16026 else
16027 {
16028 constraint (et.size != 8 && et.size != 16 && et.size != 32,
16029 BAD_EL_TYPE);
16030 inst.instruction |= 1 << 28;
16031 inst.instruction |= neon_logbits (et.size) << 20;
16032 }
16033
16034 if (inst.operands[2].isquad)
16035 {
16036 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16037 inst.instruction |= LOW4 (inst.operands[2].reg);
16038 inst.instruction |= (fcond & 0x2) >> 1;
16039 }
16040 else
16041 {
16042 if (inst.operands[2].reg == REG_SP)
16043 as_tsktsk (MVE_BAD_SP);
16044 inst.instruction |= 1 << 6;
16045 inst.instruction |= (fcond & 0x2) << 4;
16046 inst.instruction |= inst.operands[2].reg;
16047 }
16048 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16049 inst.instruction |= (fcond & 0x4) << 10;
16050 inst.instruction |= (fcond & 0x1) << 7;
16051
16052 }
16053 set_pred_insn_type (VPT_INSN);
16054 now_pred.cc = 0;
16055 now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
16056 | ((inst.instruction & 0xe000) >> 13);
16057 now_pred.warn_deprecated = FALSE;
16058 now_pred.type = VECTOR_PRED;
16059 inst.is_neon = 1;
16060}
16061
16062static void
16063do_mve_vcmp (void)
16064{
16065 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
16066 if (!inst.operands[1].isreg || !inst.operands[1].isquad)
16067 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
16068 if (!inst.operands[2].present)
16069 first_error (_("MVE vector or ARM register expected"));
16070 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
16071
16072 /* Deal with 'else' conditional MVE's vcmp, it will be parsed as vcmpe. */
16073 if ((inst.instruction & 0xffffffff) == N_MNEM_vcmpe
16074 && inst.operands[1].isquad)
16075 {
16076 inst.instruction = N_MNEM_vcmp;
16077 inst.cond = 0x10;
16078 }
16079
16080 if (inst.cond > COND_ALWAYS)
16081 inst.pred_insn_type = INSIDE_VPT_INSN;
16082 else
16083 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16084
16085 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
16086 struct neon_type_el et
16087 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
16088 N_EQK);
16089
16090 constraint (rs == NS_IQR && inst.operands[2].reg == REG_PC
16091 && !inst.operands[2].iszr, BAD_PC);
16092
16093 unsigned fcond = mve_get_vcmp_vpt_cond (et);
16094
16095 inst.instruction = 0xee010f00;
16096 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16097 inst.instruction |= (fcond & 0x4) << 10;
16098 inst.instruction |= (fcond & 0x1) << 7;
16099 if (et.type == NT_float)
16100 {
16101 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
16102 BAD_FPU);
16103 inst.instruction |= (et.size == 16) << 28;
16104 inst.instruction |= 0x3 << 20;
16105 }
16106 else
16107 {
16108 inst.instruction |= 1 << 28;
16109 inst.instruction |= neon_logbits (et.size) << 20;
16110 }
16111 if (inst.operands[2].isquad)
16112 {
16113 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16114 inst.instruction |= (fcond & 0x2) >> 1;
16115 inst.instruction |= LOW4 (inst.operands[2].reg);
16116 }
16117 else
16118 {
16119 if (inst.operands[2].reg == REG_SP)
16120 as_tsktsk (MVE_BAD_SP);
16121 inst.instruction |= 1 << 6;
16122 inst.instruction |= (fcond & 0x2) << 4;
16123 inst.instruction |= inst.operands[2].reg;
16124 }
16125
16126 inst.is_neon = 1;
16127 return;
16128}
16129
935295b5
AV
16130static void
16131do_mve_vmaxa_vmina (void)
16132{
16133 if (inst.cond > COND_ALWAYS)
16134 inst.pred_insn_type = INSIDE_VPT_INSN;
16135 else
16136 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16137
16138 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
16139 struct neon_type_el et
16140 = neon_check_type (2, rs, N_EQK, N_KEY | N_S8 | N_S16 | N_S32);
16141
16142 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16143 inst.instruction |= neon_logbits (et.size) << 18;
16144 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16145 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16146 inst.instruction |= LOW4 (inst.operands[1].reg);
16147 inst.is_neon = 1;
16148}
16149
f30ee27c
AV
16150static void
16151do_mve_vfmas (void)
16152{
16153 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
16154 struct neon_type_el et
16155 = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK, N_EQK);
16156
16157 if (inst.cond > COND_ALWAYS)
16158 inst.pred_insn_type = INSIDE_VPT_INSN;
16159 else
16160 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16161
16162 if (inst.operands[2].reg == REG_SP)
16163 as_tsktsk (MVE_BAD_SP);
16164 else if (inst.operands[2].reg == REG_PC)
16165 as_tsktsk (MVE_BAD_PC);
16166
16167 inst.instruction |= (et.size == 16) << 28;
16168 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16169 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16170 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16171 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16172 inst.instruction |= inst.operands[2].reg;
16173 inst.is_neon = 1;
16174}
16175
b409bdb6
AV
16176static void
16177do_mve_viddup (void)
16178{
16179 if (inst.cond > COND_ALWAYS)
16180 inst.pred_insn_type = INSIDE_VPT_INSN;
16181 else
16182 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16183
16184 unsigned imm = inst.relocs[0].exp.X_add_number;
16185 constraint (imm != 1 && imm != 2 && imm != 4 && imm != 8,
16186 _("immediate must be either 1, 2, 4 or 8"));
16187
16188 enum neon_shape rs;
16189 struct neon_type_el et;
16190 unsigned Rm;
16191 if (inst.instruction == M_MNEM_vddup || inst.instruction == M_MNEM_vidup)
16192 {
16193 rs = neon_select_shape (NS_QRI, NS_NULL);
16194 et = neon_check_type (2, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK);
16195 Rm = 7;
16196 }
16197 else
16198 {
16199 constraint ((inst.operands[2].reg % 2) != 1, BAD_EVEN);
16200 if (inst.operands[2].reg == REG_SP)
16201 as_tsktsk (MVE_BAD_SP);
16202 else if (inst.operands[2].reg == REG_PC)
16203 first_error (BAD_PC);
16204
16205 rs = neon_select_shape (NS_QRRI, NS_NULL);
16206 et = neon_check_type (3, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK, N_EQK);
16207 Rm = inst.operands[2].reg >> 1;
16208 }
16209 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16210 inst.instruction |= neon_logbits (et.size) << 20;
16211 inst.instruction |= inst.operands[1].reg << 16;
16212 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16213 inst.instruction |= (imm > 2) << 7;
16214 inst.instruction |= Rm << 1;
16215 inst.instruction |= (imm == 2 || imm == 8);
16216 inst.is_neon = 1;
16217}
16218
2d78f95b
AV
16219static void
16220do_mve_vmlas (void)
16221{
16222 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
16223 struct neon_type_el et
16224 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
16225
16226 if (inst.operands[2].reg == REG_PC)
16227 as_tsktsk (MVE_BAD_PC);
16228 else if (inst.operands[2].reg == REG_SP)
16229 as_tsktsk (MVE_BAD_SP);
16230
16231 if (inst.cond > COND_ALWAYS)
16232 inst.pred_insn_type = INSIDE_VPT_INSN;
16233 else
16234 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16235
16236 inst.instruction |= (et.type == NT_unsigned) << 28;
16237 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16238 inst.instruction |= neon_logbits (et.size) << 20;
16239 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16240 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16241 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16242 inst.instruction |= inst.operands[2].reg;
16243 inst.is_neon = 1;
16244}
16245
acca5630
AV
16246static void
16247do_mve_vshll (void)
16248{
16249 struct neon_type_el et
16250 = neon_check_type (2, NS_QQI, N_EQK, N_S8 | N_U8 | N_S16 | N_U16 | N_KEY);
16251
16252 if (inst.cond > COND_ALWAYS)
16253 inst.pred_insn_type = INSIDE_VPT_INSN;
16254 else
16255 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16256
16257 int imm = inst.operands[2].imm;
16258 constraint (imm < 1 || (unsigned)imm > et.size,
16259 _("immediate value out of range"));
16260
16261 if ((unsigned)imm == et.size)
16262 {
16263 inst.instruction |= neon_logbits (et.size) << 18;
16264 inst.instruction |= 0x110001;
16265 }
16266 else
16267 {
16268 inst.instruction |= (et.size + imm) << 16;
16269 inst.instruction |= 0x800140;
16270 }
16271
16272 inst.instruction |= (et.type == NT_unsigned) << 28;
16273 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16274 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16275 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16276 inst.instruction |= LOW4 (inst.operands[1].reg);
16277 inst.is_neon = 1;
16278}
16279
16280static void
16281do_mve_vshlc (void)
16282{
16283 if (inst.cond > COND_ALWAYS)
16284 inst.pred_insn_type = INSIDE_VPT_INSN;
16285 else
16286 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16287
16288 if (inst.operands[1].reg == REG_PC)
16289 as_tsktsk (MVE_BAD_PC);
16290 else if (inst.operands[1].reg == REG_SP)
16291 as_tsktsk (MVE_BAD_SP);
16292
16293 int imm = inst.operands[2].imm;
16294 constraint (imm < 1 || imm > 32, _("immediate value out of range"));
16295
16296 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16297 inst.instruction |= (imm & 0x1f) << 16;
16298 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16299 inst.instruction |= inst.operands[1].reg;
16300 inst.is_neon = 1;
16301}
16302
4aa88b50
AV
16303static void
16304do_mve_vshrn (void)
16305{
16306 unsigned types;
16307 switch (inst.instruction)
16308 {
16309 case M_MNEM_vshrnt:
16310 case M_MNEM_vshrnb:
16311 case M_MNEM_vrshrnt:
16312 case M_MNEM_vrshrnb:
16313 types = N_I16 | N_I32;
16314 break;
16315 case M_MNEM_vqshrnt:
16316 case M_MNEM_vqshrnb:
16317 case M_MNEM_vqrshrnt:
16318 case M_MNEM_vqrshrnb:
16319 types = N_U16 | N_U32 | N_S16 | N_S32;
16320 break;
16321 case M_MNEM_vqshrunt:
16322 case M_MNEM_vqshrunb:
16323 case M_MNEM_vqrshrunt:
16324 case M_MNEM_vqrshrunb:
16325 types = N_S16 | N_S32;
16326 break;
16327 default:
16328 abort ();
16329 }
16330
16331 struct neon_type_el et = neon_check_type (2, NS_QQI, N_EQK, types | N_KEY);
16332
16333 if (inst.cond > COND_ALWAYS)
16334 inst.pred_insn_type = INSIDE_VPT_INSN;
16335 else
16336 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16337
16338 unsigned Qd = inst.operands[0].reg;
16339 unsigned Qm = inst.operands[1].reg;
16340 unsigned imm = inst.operands[2].imm;
16341 constraint (imm < 1 || ((unsigned) imm) > (et.size / 2),
16342 et.size == 16
16343 ? _("immediate operand expected in the range [1,8]")
16344 : _("immediate operand expected in the range [1,16]"));
16345
16346 inst.instruction |= (et.type == NT_unsigned) << 28;
16347 inst.instruction |= HI1 (Qd) << 22;
16348 inst.instruction |= (et.size - imm) << 16;
16349 inst.instruction |= LOW4 (Qd) << 12;
16350 inst.instruction |= HI1 (Qm) << 5;
16351 inst.instruction |= LOW4 (Qm);
16352 inst.is_neon = 1;
16353}
16354
1be7aba3
AV
16355static void
16356do_mve_vqmovn (void)
16357{
16358 struct neon_type_el et;
16359 if (inst.instruction == M_MNEM_vqmovnt
16360 || inst.instruction == M_MNEM_vqmovnb)
16361 et = neon_check_type (2, NS_QQ, N_EQK,
16362 N_U16 | N_U32 | N_S16 | N_S32 | N_KEY);
16363 else
16364 et = neon_check_type (2, NS_QQ, N_EQK, N_S16 | N_S32 | N_KEY);
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 inst.instruction |= (et.type == NT_unsigned) << 28;
16372 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16373 inst.instruction |= (et.size == 32) << 18;
16374 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16375 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16376 inst.instruction |= LOW4 (inst.operands[1].reg);
16377 inst.is_neon = 1;
16378}
16379
3063888e
AV
16380static void
16381do_mve_vpsel (void)
16382{
16383 neon_select_shape (NS_QQQ, NS_NULL);
16384
16385 if (inst.cond > COND_ALWAYS)
16386 inst.pred_insn_type = INSIDE_VPT_INSN;
16387 else
16388 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16389
16390 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16391 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16392 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16393 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16394 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16395 inst.instruction |= LOW4 (inst.operands[2].reg);
16396 inst.is_neon = 1;
16397}
16398
16399static void
16400do_mve_vpnot (void)
16401{
16402 if (inst.cond > COND_ALWAYS)
16403 inst.pred_insn_type = INSIDE_VPT_INSN;
16404 else
16405 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16406}
16407
935295b5
AV
16408static void
16409do_mve_vmaxnma_vminnma (void)
16410{
16411 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
16412 struct neon_type_el et
16413 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
16414
16415 if (inst.cond > COND_ALWAYS)
16416 inst.pred_insn_type = INSIDE_VPT_INSN;
16417 else
16418 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16419
16420 inst.instruction |= (et.size == 16) << 28;
16421 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16422 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16423 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16424 inst.instruction |= LOW4 (inst.operands[1].reg);
16425 inst.is_neon = 1;
16426}
16427
5d281bf0
AV
16428static void
16429do_mve_vcmul (void)
16430{
16431 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
16432 struct neon_type_el et
16433 = neon_check_type (3, rs, N_EQK, N_EQK, N_F_MVE | N_KEY);
16434
16435 if (inst.cond > COND_ALWAYS)
16436 inst.pred_insn_type = INSIDE_VPT_INSN;
16437 else
16438 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16439
16440 unsigned rot = inst.relocs[0].exp.X_add_number;
16441 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
16442 _("immediate out of range"));
16443
16444 if (et.size == 32 && (inst.operands[0].reg == inst.operands[1].reg
16445 || inst.operands[0].reg == inst.operands[2].reg))
16446 as_tsktsk (BAD_MVE_SRCDEST);
16447
16448 inst.instruction |= (et.size == 32) << 28;
16449 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16450 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16451 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16452 inst.instruction |= (rot > 90) << 12;
16453 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16454 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16455 inst.instruction |= LOW4 (inst.operands[2].reg);
16456 inst.instruction |= (rot == 90 || rot == 270);
16457 inst.is_neon = 1;
16458}
16459
1f6234a3
AV
16460/* To handle the Low Overhead Loop instructions
16461 in Armv8.1-M Mainline and MVE. */
16462static void
16463do_t_loloop (void)
16464{
16465 unsigned long insn = inst.instruction;
16466
16467 inst.instruction = THUMB_OP32 (inst.instruction);
16468
16469 if (insn == T_MNEM_lctp)
16470 return;
16471
16472 set_pred_insn_type (MVE_OUTSIDE_PRED_INSN);
16473
16474 if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
16475 {
16476 struct neon_type_el et
16477 = neon_check_type (2, NS_RR, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
16478 inst.instruction |= neon_logbits (et.size) << 20;
16479 inst.is_neon = 1;
16480 }
16481
16482 switch (insn)
16483 {
16484 case T_MNEM_letp:
16485 constraint (!inst.operands[0].present,
16486 _("expected LR"));
16487 /* fall through. */
16488 case T_MNEM_le:
16489 /* le <label>. */
16490 if (!inst.operands[0].present)
16491 inst.instruction |= 1 << 21;
16492
16493 v8_1_loop_reloc (TRUE);
16494 break;
16495
16496 case T_MNEM_wls:
16497 case T_MNEM_wlstp:
16498 v8_1_loop_reloc (FALSE);
16499 /* fall through. */
16500 case T_MNEM_dlstp:
16501 case T_MNEM_dls:
16502 constraint (inst.operands[1].isreg != 1, BAD_ARGS);
16503
16504 if (insn == T_MNEM_wlstp || insn == T_MNEM_dlstp)
16505 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
16506 else if (inst.operands[1].reg == REG_PC)
16507 as_tsktsk (MVE_BAD_PC);
16508 if (inst.operands[1].reg == REG_SP)
16509 as_tsktsk (MVE_BAD_SP);
16510
16511 inst.instruction |= (inst.operands[1].reg << 16);
16512 break;
16513
16514 default:
16515 abort ();
16516 }
16517}
16518
16519
037e8744
JB
16520static void
16521do_vfp_nsyn_cmp (void)
16522{
9db2f6b4 16523 enum neon_shape rs;
1b883319
AV
16524 if (!inst.operands[0].isreg)
16525 {
16526 do_mve_vcmp ();
16527 return;
16528 }
16529 else
16530 {
16531 constraint (inst.operands[2].present, BAD_SYNTAX);
16532 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd),
16533 BAD_FPU);
16534 }
16535
037e8744
JB
16536 if (inst.operands[1].isreg)
16537 {
9db2f6b4
RL
16538 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
16539 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 16540
9db2f6b4 16541 if (rs == NS_FF || rs == NS_HH)
477330fc
RM
16542 {
16543 NEON_ENCODE (SINGLE, inst);
16544 do_vfp_sp_monadic ();
16545 }
037e8744 16546 else
477330fc
RM
16547 {
16548 NEON_ENCODE (DOUBLE, inst);
16549 do_vfp_dp_rd_rm ();
16550 }
037e8744
JB
16551 }
16552 else
16553 {
9db2f6b4
RL
16554 rs = neon_select_shape (NS_HI, NS_FI, NS_DI, NS_NULL);
16555 neon_check_type (2, rs, N_F_ALL | N_KEY | N_VFP, N_EQK);
037e8744
JB
16556
16557 switch (inst.instruction & 0x0fffffff)
477330fc
RM
16558 {
16559 case N_MNEM_vcmp:
16560 inst.instruction += N_MNEM_vcmpz - N_MNEM_vcmp;
16561 break;
16562 case N_MNEM_vcmpe:
16563 inst.instruction += N_MNEM_vcmpez - N_MNEM_vcmpe;
16564 break;
16565 default:
16566 abort ();
16567 }
5f4273c7 16568
9db2f6b4 16569 if (rs == NS_FI || rs == NS_HI)
477330fc
RM
16570 {
16571 NEON_ENCODE (SINGLE, inst);
16572 do_vfp_sp_compare_z ();
16573 }
037e8744 16574 else
477330fc
RM
16575 {
16576 NEON_ENCODE (DOUBLE, inst);
16577 do_vfp_dp_rd ();
16578 }
037e8744
JB
16579 }
16580 do_vfp_cond_or_thumb ();
9db2f6b4
RL
16581
16582 /* ARMv8.2 fp16 instruction. */
16583 if (rs == NS_HI || rs == NS_HH)
16584 do_scalar_fp16_v82_encode ();
037e8744
JB
16585}
16586
16587static void
16588nsyn_insert_sp (void)
16589{
16590 inst.operands[1] = inst.operands[0];
16591 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
fdfde340 16592 inst.operands[0].reg = REG_SP;
037e8744
JB
16593 inst.operands[0].isreg = 1;
16594 inst.operands[0].writeback = 1;
16595 inst.operands[0].present = 1;
16596}
16597
037e8744
JB
16598/* Fix up Neon data-processing instructions, ORing in the correct bits for
16599 ARM mode or Thumb mode and moving the encoded bit 24 to bit 28. */
16600
88714cb8
DG
16601static void
16602neon_dp_fixup (struct arm_it* insn)
037e8744 16603{
88714cb8
DG
16604 unsigned int i = insn->instruction;
16605 insn->is_neon = 1;
16606
037e8744
JB
16607 if (thumb_mode)
16608 {
16609 /* The U bit is at bit 24 by default. Move to bit 28 in Thumb mode. */
16610 if (i & (1 << 24))
477330fc 16611 i |= 1 << 28;
5f4273c7 16612
037e8744 16613 i &= ~(1 << 24);
5f4273c7 16614
037e8744
JB
16615 i |= 0xef000000;
16616 }
16617 else
16618 i |= 0xf2000000;
5f4273c7 16619
88714cb8 16620 insn->instruction = i;
037e8744
JB
16621}
16622
5ee91343 16623static void
7df54120 16624mve_encode_qqr (int size, int U, int fp)
5ee91343
AV
16625{
16626 if (inst.operands[2].reg == REG_SP)
16627 as_tsktsk (MVE_BAD_SP);
16628 else if (inst.operands[2].reg == REG_PC)
16629 as_tsktsk (MVE_BAD_PC);
16630
16631 if (fp)
16632 {
16633 /* vadd. */
16634 if (((unsigned)inst.instruction) == 0xd00)
16635 inst.instruction = 0xee300f40;
16636 /* vsub. */
16637 else if (((unsigned)inst.instruction) == 0x200d00)
16638 inst.instruction = 0xee301f40;
a8465a06
AV
16639 /* vmul. */
16640 else if (((unsigned)inst.instruction) == 0x1000d10)
16641 inst.instruction = 0xee310e60;
5ee91343
AV
16642
16643 /* Setting size which is 1 for F16 and 0 for F32. */
16644 inst.instruction |= (size == 16) << 28;
16645 }
16646 else
16647 {
16648 /* vadd. */
16649 if (((unsigned)inst.instruction) == 0x800)
16650 inst.instruction = 0xee010f40;
16651 /* vsub. */
16652 else if (((unsigned)inst.instruction) == 0x1000800)
16653 inst.instruction = 0xee011f40;
7df54120
AV
16654 /* vhadd. */
16655 else if (((unsigned)inst.instruction) == 0)
16656 inst.instruction = 0xee000f40;
16657 /* vhsub. */
16658 else if (((unsigned)inst.instruction) == 0x200)
16659 inst.instruction = 0xee001f40;
a8465a06
AV
16660 /* vmla. */
16661 else if (((unsigned)inst.instruction) == 0x900)
16662 inst.instruction = 0xee010e40;
16663 /* vmul. */
16664 else if (((unsigned)inst.instruction) == 0x910)
16665 inst.instruction = 0xee011e60;
16666 /* vqadd. */
16667 else if (((unsigned)inst.instruction) == 0x10)
16668 inst.instruction = 0xee000f60;
16669 /* vqsub. */
16670 else if (((unsigned)inst.instruction) == 0x210)
16671 inst.instruction = 0xee001f60;
42b16635
AV
16672 /* vqrdmlah. */
16673 else if (((unsigned)inst.instruction) == 0x3000b10)
16674 inst.instruction = 0xee000e40;
16675 /* vqdmulh. */
16676 else if (((unsigned)inst.instruction) == 0x0000b00)
16677 inst.instruction = 0xee010e60;
16678 /* vqrdmulh. */
16679 else if (((unsigned)inst.instruction) == 0x1000b00)
16680 inst.instruction = 0xfe010e60;
7df54120
AV
16681
16682 /* Set U-bit. */
16683 inst.instruction |= U << 28;
16684
5ee91343
AV
16685 /* Setting bits for size. */
16686 inst.instruction |= neon_logbits (size) << 20;
16687 }
16688 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16689 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16690 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16691 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16692 inst.instruction |= inst.operands[2].reg;
16693 inst.is_neon = 1;
16694}
16695
a302e574
AV
16696static void
16697mve_encode_rqq (unsigned bit28, unsigned size)
16698{
16699 inst.instruction |= bit28 << 28;
16700 inst.instruction |= neon_logbits (size) << 20;
16701 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16702 inst.instruction |= inst.operands[0].reg << 12;
16703 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16704 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16705 inst.instruction |= LOW4 (inst.operands[2].reg);
16706 inst.is_neon = 1;
16707}
16708
886e1c73
AV
16709static void
16710mve_encode_qqq (int ubit, int size)
16711{
16712
16713 inst.instruction |= (ubit != 0) << 28;
16714 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16715 inst.instruction |= neon_logbits (size) << 20;
16716 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16717 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16718 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16719 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16720 inst.instruction |= LOW4 (inst.operands[2].reg);
16721
16722 inst.is_neon = 1;
16723}
16724
26c1e780
AV
16725static void
16726mve_encode_rq (unsigned bit28, unsigned size)
16727{
16728 inst.instruction |= bit28 << 28;
16729 inst.instruction |= neon_logbits (size) << 18;
16730 inst.instruction |= inst.operands[0].reg << 12;
16731 inst.instruction |= LOW4 (inst.operands[1].reg);
16732 inst.is_neon = 1;
16733}
886e1c73 16734
93925576
AV
16735static void
16736mve_encode_rrqq (unsigned U, unsigned size)
16737{
16738 constraint (inst.operands[3].reg > 14, MVE_BAD_QREG);
16739
16740 inst.instruction |= U << 28;
16741 inst.instruction |= (inst.operands[1].reg >> 1) << 20;
16742 inst.instruction |= LOW4 (inst.operands[2].reg) << 16;
16743 inst.instruction |= (size == 32) << 16;
16744 inst.instruction |= inst.operands[0].reg << 12;
16745 inst.instruction |= HI1 (inst.operands[2].reg) << 7;
16746 inst.instruction |= inst.operands[3].reg;
16747 inst.is_neon = 1;
16748}
16749
aab2c27d
MM
16750/* Helper function for neon_three_same handling the operands. */
16751static void
16752neon_three_args (int isquad)
16753{
16754 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16755 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16756 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16757 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16758 inst.instruction |= LOW4 (inst.operands[2].reg);
16759 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16760 inst.instruction |= (isquad != 0) << 6;
16761 inst.is_neon = 1;
16762}
16763
037e8744
JB
16764/* Encode insns with bit pattern:
16765
16766 |28/24|23|22 |21 20|19 16|15 12|11 8|7|6|5|4|3 0|
16767 | U |x |D |size | Rn | Rd |x x x x|N|Q|M|x| Rm |
5f4273c7 16768
037e8744
JB
16769 SIZE is passed in bits. -1 means size field isn't changed, in case it has a
16770 different meaning for some instruction. */
16771
16772static void
16773neon_three_same (int isquad, int ubit, int size)
16774{
aab2c27d 16775 neon_three_args (isquad);
037e8744
JB
16776 inst.instruction |= (ubit != 0) << 24;
16777 if (size != -1)
16778 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 16779
88714cb8 16780 neon_dp_fixup (&inst);
037e8744
JB
16781}
16782
16783/* Encode instructions of the form:
16784
16785 |28/24|23|22|21 20|19 18|17 16|15 12|11 7|6|5|4|3 0|
16786 | U |x |D |x x |size |x x | Rd |x x x x x|Q|M|x| Rm |
5287ad62
JB
16787
16788 Don't write size if SIZE == -1. */
16789
16790static void
16791neon_two_same (int qbit, int ubit, int size)
16792{
16793 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16794 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16795 inst.instruction |= LOW4 (inst.operands[1].reg);
16796 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16797 inst.instruction |= (qbit != 0) << 6;
16798 inst.instruction |= (ubit != 0) << 24;
16799
16800 if (size != -1)
16801 inst.instruction |= neon_logbits (size) << 18;
16802
88714cb8 16803 neon_dp_fixup (&inst);
5287ad62
JB
16804}
16805
7df54120
AV
16806enum vfp_or_neon_is_neon_bits
16807{
16808NEON_CHECK_CC = 1,
16809NEON_CHECK_ARCH = 2,
16810NEON_CHECK_ARCH8 = 4
16811};
16812
16813/* Call this function if an instruction which may have belonged to the VFP or
16814 Neon instruction sets, but turned out to be a Neon instruction (due to the
16815 operand types involved, etc.). We have to check and/or fix-up a couple of
16816 things:
16817
16818 - Make sure the user hasn't attempted to make a Neon instruction
16819 conditional.
16820 - Alter the value in the condition code field if necessary.
16821 - Make sure that the arch supports Neon instructions.
16822
16823 Which of these operations take place depends on bits from enum
16824 vfp_or_neon_is_neon_bits.
16825
16826 WARNING: This function has side effects! If NEON_CHECK_CC is used and the
16827 current instruction's condition is COND_ALWAYS, the condition field is
16828 changed to inst.uncond_value. This is necessary because instructions shared
16829 between VFP and Neon may be conditional for the VFP variants only, and the
16830 unconditional Neon version must have, e.g., 0xF in the condition field. */
16831
16832static int
16833vfp_or_neon_is_neon (unsigned check)
16834{
16835/* Conditions are always legal in Thumb mode (IT blocks). */
16836if (!thumb_mode && (check & NEON_CHECK_CC))
16837 {
16838 if (inst.cond != COND_ALWAYS)
16839 {
16840 first_error (_(BAD_COND));
16841 return FAIL;
16842 }
16843 if (inst.uncond_value != -1)
16844 inst.instruction |= inst.uncond_value << 28;
16845 }
16846
16847
16848 if (((check & NEON_CHECK_ARCH) && !mark_feature_used (&fpu_neon_ext_v1))
16849 || ((check & NEON_CHECK_ARCH8)
16850 && !mark_feature_used (&fpu_neon_ext_armv8)))
16851 {
16852 first_error (_(BAD_FPU));
16853 return FAIL;
16854 }
16855
16856return SUCCESS;
16857}
16858
64c350f2
AV
16859
16860/* Return TRUE if the SIMD instruction is available for the current
16861 cpu_variant. FP is set to TRUE if this is a SIMD floating-point
16862 instruction. CHECK contains th. CHECK contains the set of bits to pass to
16863 vfp_or_neon_is_neon for the NEON specific checks. */
16864
16865static bfd_boolean
7df54120
AV
16866check_simd_pred_availability (int fp, unsigned check)
16867{
16868if (inst.cond > COND_ALWAYS)
16869 {
16870 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16871 {
16872 inst.error = BAD_FPU;
64c350f2 16873 return FALSE;
7df54120
AV
16874 }
16875 inst.pred_insn_type = INSIDE_VPT_INSN;
16876 }
16877else if (inst.cond < COND_ALWAYS)
16878 {
16879 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16880 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16881 else if (vfp_or_neon_is_neon (check) == FAIL)
64c350f2 16882 return FALSE;
7df54120
AV
16883 }
16884else
16885 {
16886 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fp ? mve_fp_ext : mve_ext)
16887 && vfp_or_neon_is_neon (check) == FAIL)
64c350f2 16888 return FALSE;
7df54120
AV
16889
16890 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16891 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16892 }
64c350f2 16893return TRUE;
7df54120
AV
16894}
16895
5287ad62
JB
16896/* Neon instruction encoders, in approximate order of appearance. */
16897
16898static void
16899do_neon_dyadic_i_su (void)
16900{
64c350f2 16901 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
7df54120
AV
16902 return;
16903
16904 enum neon_shape rs;
16905 struct neon_type_el et;
16906 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16907 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
16908 else
16909 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16910
16911 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_32 | N_KEY);
16912
16913
16914 if (rs != NS_QQR)
16915 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
16916 else
16917 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
5287ad62
JB
16918}
16919
16920static void
16921do_neon_dyadic_i64_su (void)
16922{
64c350f2 16923 if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
a8465a06
AV
16924 return;
16925 enum neon_shape rs;
16926 struct neon_type_el et;
16927 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16928 {
16929 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
16930 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
16931 }
16932 else
16933 {
16934 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16935 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
16936 }
16937 if (rs == NS_QQR)
16938 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
16939 else
16940 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
16941}
16942
16943static void
16944neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
477330fc 16945 unsigned immbits)
5287ad62
JB
16946{
16947 unsigned size = et.size >> 3;
16948 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16949 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16950 inst.instruction |= LOW4 (inst.operands[1].reg);
16951 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16952 inst.instruction |= (isquad != 0) << 6;
16953 inst.instruction |= immbits << 16;
16954 inst.instruction |= (size >> 3) << 7;
16955 inst.instruction |= (size & 0x7) << 19;
16956 if (write_ubit)
16957 inst.instruction |= (uval != 0) << 24;
16958
88714cb8 16959 neon_dp_fixup (&inst);
5287ad62
JB
16960}
16961
16962static void
5150f0d8 16963do_neon_shl (void)
5287ad62 16964{
64c350f2 16965 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
16966 return;
16967
5287ad62
JB
16968 if (!inst.operands[2].isreg)
16969 {
5150f0d8
AV
16970 enum neon_shape rs;
16971 struct neon_type_el et;
16972 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16973 {
16974 rs = neon_select_shape (NS_QQI, NS_NULL);
16975 et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_MVE);
16976 }
16977 else
16978 {
16979 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
16980 et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
16981 }
cb3b1e65
JB
16982 int imm = inst.operands[2].imm;
16983
16984 constraint (imm < 0 || (unsigned)imm >= et.size,
16985 _("immediate out of range for shift"));
88714cb8 16986 NEON_ENCODE (IMMED, inst);
cb3b1e65 16987 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
16988 }
16989 else
16990 {
5150f0d8
AV
16991 enum neon_shape rs;
16992 struct neon_type_el et;
16993 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16994 {
16995 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
16996 et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
16997 }
16998 else
16999 {
17000 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17001 et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
17002 }
17003
17004
17005 if (rs == NS_QQR)
17006 {
17007 constraint (inst.operands[0].reg != inst.operands[1].reg,
17008 _("invalid instruction shape"));
17009 if (inst.operands[2].reg == REG_SP)
17010 as_tsktsk (MVE_BAD_SP);
17011 else if (inst.operands[2].reg == REG_PC)
17012 as_tsktsk (MVE_BAD_PC);
17013
17014 inst.instruction = 0xee311e60;
17015 inst.instruction |= (et.type == NT_unsigned) << 28;
17016 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17017 inst.instruction |= neon_logbits (et.size) << 18;
17018 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17019 inst.instruction |= inst.operands[2].reg;
17020 inst.is_neon = 1;
17021 }
17022 else
17023 {
17024 unsigned int tmp;
17025
17026 /* VSHL/VQSHL 3-register variants have syntax such as:
17027 vshl.xx Dd, Dm, Dn
17028 whereas other 3-register operations encoded by neon_three_same have
17029 syntax like:
17030 vadd.xx Dd, Dn, Dm
17031 (i.e. with Dn & Dm reversed). Swap operands[1].reg and
17032 operands[2].reg here. */
17033 tmp = inst.operands[2].reg;
17034 inst.operands[2].reg = inst.operands[1].reg;
17035 inst.operands[1].reg = tmp;
17036 NEON_ENCODE (INTEGER, inst);
17037 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17038 }
5287ad62
JB
17039 }
17040}
17041
17042static void
5150f0d8 17043do_neon_qshl (void)
5287ad62 17044{
64c350f2 17045 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
17046 return;
17047
5287ad62
JB
17048 if (!inst.operands[2].isreg)
17049 {
5150f0d8
AV
17050 enum neon_shape rs;
17051 struct neon_type_el et;
17052 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17053 {
17054 rs = neon_select_shape (NS_QQI, NS_NULL);
17055 et = neon_check_type (2, rs, N_EQK, N_KEY | N_SU_MVE);
17056 }
17057 else
17058 {
17059 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
17060 et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
17061 }
cb3b1e65 17062 int imm = inst.operands[2].imm;
627907b7 17063
cb3b1e65
JB
17064 constraint (imm < 0 || (unsigned)imm >= et.size,
17065 _("immediate out of range for shift"));
88714cb8 17066 NEON_ENCODE (IMMED, inst);
cb3b1e65 17067 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et, imm);
5287ad62
JB
17068 }
17069 else
17070 {
5150f0d8
AV
17071 enum neon_shape rs;
17072 struct neon_type_el et;
627907b7 17073
5150f0d8
AV
17074 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17075 {
17076 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17077 et = neon_check_type (3, rs, N_EQK, N_SU_MVE | N_KEY, N_EQK | N_EQK);
17078 }
17079 else
17080 {
17081 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17082 et = neon_check_type (3, rs, N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
17083 }
17084
17085 if (rs == NS_QQR)
17086 {
17087 constraint (inst.operands[0].reg != inst.operands[1].reg,
17088 _("invalid instruction shape"));
17089 if (inst.operands[2].reg == REG_SP)
17090 as_tsktsk (MVE_BAD_SP);
17091 else if (inst.operands[2].reg == REG_PC)
17092 as_tsktsk (MVE_BAD_PC);
17093
17094 inst.instruction = 0xee311ee0;
17095 inst.instruction |= (et.type == NT_unsigned) << 28;
17096 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17097 inst.instruction |= neon_logbits (et.size) << 18;
17098 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17099 inst.instruction |= inst.operands[2].reg;
17100 inst.is_neon = 1;
17101 }
17102 else
17103 {
17104 unsigned int tmp;
17105
17106 /* See note in do_neon_shl. */
17107 tmp = inst.operands[2].reg;
17108 inst.operands[2].reg = inst.operands[1].reg;
17109 inst.operands[1].reg = tmp;
17110 NEON_ENCODE (INTEGER, inst);
17111 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17112 }
5287ad62
JB
17113 }
17114}
17115
627907b7
JB
17116static void
17117do_neon_rshl (void)
17118{
64c350f2 17119 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
1be7aba3
AV
17120 return;
17121
17122 enum neon_shape rs;
17123 struct neon_type_el et;
17124 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17125 {
17126 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
17127 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17128 }
17129 else
17130 {
17131 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17132 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_ALL | N_KEY);
17133 }
17134
627907b7
JB
17135 unsigned int tmp;
17136
1be7aba3
AV
17137 if (rs == NS_QQR)
17138 {
17139 if (inst.operands[2].reg == REG_PC)
17140 as_tsktsk (MVE_BAD_PC);
17141 else if (inst.operands[2].reg == REG_SP)
17142 as_tsktsk (MVE_BAD_SP);
17143
17144 constraint (inst.operands[0].reg != inst.operands[1].reg,
17145 _("invalid instruction shape"));
17146
17147 if (inst.instruction == 0x0000510)
17148 /* We are dealing with vqrshl. */
17149 inst.instruction = 0xee331ee0;
17150 else
17151 /* We are dealing with vrshl. */
17152 inst.instruction = 0xee331e60;
17153
17154 inst.instruction |= (et.type == NT_unsigned) << 28;
17155 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17156 inst.instruction |= neon_logbits (et.size) << 18;
17157 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17158 inst.instruction |= inst.operands[2].reg;
17159 inst.is_neon = 1;
17160 }
17161 else
17162 {
17163 tmp = inst.operands[2].reg;
17164 inst.operands[2].reg = inst.operands[1].reg;
17165 inst.operands[1].reg = tmp;
17166 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
17167 }
627907b7
JB
17168}
17169
5287ad62
JB
17170static int
17171neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
17172{
036dc3f7
PB
17173 /* Handle .I8 pseudo-instructions. */
17174 if (size == 8)
5287ad62 17175 {
5287ad62 17176 /* Unfortunately, this will make everything apart from zero out-of-range.
477330fc
RM
17177 FIXME is this the intended semantics? There doesn't seem much point in
17178 accepting .I8 if so. */
5287ad62
JB
17179 immediate |= immediate << 8;
17180 size = 16;
036dc3f7
PB
17181 }
17182
17183 if (size >= 32)
17184 {
17185 if (immediate == (immediate & 0x000000ff))
17186 {
17187 *immbits = immediate;
17188 return 0x1;
17189 }
17190 else if (immediate == (immediate & 0x0000ff00))
17191 {
17192 *immbits = immediate >> 8;
17193 return 0x3;
17194 }
17195 else if (immediate == (immediate & 0x00ff0000))
17196 {
17197 *immbits = immediate >> 16;
17198 return 0x5;
17199 }
17200 else if (immediate == (immediate & 0xff000000))
17201 {
17202 *immbits = immediate >> 24;
17203 return 0x7;
17204 }
17205 if ((immediate & 0xffff) != (immediate >> 16))
17206 goto bad_immediate;
17207 immediate &= 0xffff;
5287ad62
JB
17208 }
17209
17210 if (immediate == (immediate & 0x000000ff))
17211 {
17212 *immbits = immediate;
036dc3f7 17213 return 0x9;
5287ad62
JB
17214 }
17215 else if (immediate == (immediate & 0x0000ff00))
17216 {
17217 *immbits = immediate >> 8;
036dc3f7 17218 return 0xb;
5287ad62
JB
17219 }
17220
17221 bad_immediate:
dcbf9037 17222 first_error (_("immediate value out of range"));
5287ad62
JB
17223 return FAIL;
17224}
17225
5287ad62
JB
17226static void
17227do_neon_logic (void)
17228{
17229 if (inst.operands[2].present && inst.operands[2].isreg)
17230 {
037e8744 17231 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
f601a00c 17232 if (rs == NS_QQQ
64c350f2
AV
17233 && !check_simd_pred_availability (FALSE,
17234 NEON_CHECK_ARCH | NEON_CHECK_CC))
f601a00c
AV
17235 return;
17236 else if (rs != NS_QQQ
17237 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
17238 first_error (BAD_FPU);
17239
5287ad62
JB
17240 neon_check_type (3, rs, N_IGNORE_TYPE);
17241 /* U bit and size field were set as part of the bitmask. */
88714cb8 17242 NEON_ENCODE (INTEGER, inst);
037e8744 17243 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
17244 }
17245 else
17246 {
4316f0d2
DG
17247 const int three_ops_form = (inst.operands[2].present
17248 && !inst.operands[2].isreg);
17249 const int immoperand = (three_ops_form ? 2 : 1);
17250 enum neon_shape rs = (three_ops_form
17251 ? neon_select_shape (NS_DDI, NS_QQI, NS_NULL)
17252 : neon_select_shape (NS_DI, NS_QI, NS_NULL));
f601a00c
AV
17253 /* Because neon_select_shape makes the second operand a copy of the first
17254 if the second operand is not present. */
17255 if (rs == NS_QQI
64c350f2
AV
17256 && !check_simd_pred_availability (FALSE,
17257 NEON_CHECK_ARCH | NEON_CHECK_CC))
f601a00c
AV
17258 return;
17259 else if (rs != NS_QQI
17260 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
17261 first_error (BAD_FPU);
17262
17263 struct neon_type_el et;
17264 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17265 et = neon_check_type (2, rs, N_I32 | N_I16 | N_KEY, N_EQK);
17266 else
17267 et = neon_check_type (2, rs, N_I8 | N_I16 | N_I32 | N_I64 | N_F32
17268 | N_KEY, N_EQK);
17269
17270 if (et.type == NT_invtype)
17271 return;
21d799b5 17272 enum neon_opc opcode = (enum neon_opc) inst.instruction & 0x0fffffff;
5287ad62
JB
17273 unsigned immbits;
17274 int cmode;
5f4273c7 17275
5f4273c7 17276
4316f0d2
DG
17277 if (three_ops_form)
17278 constraint (inst.operands[0].reg != inst.operands[1].reg,
17279 _("first and second operands shall be the same register"));
17280
88714cb8 17281 NEON_ENCODE (IMMED, inst);
5287ad62 17282
4316f0d2 17283 immbits = inst.operands[immoperand].imm;
036dc3f7
PB
17284 if (et.size == 64)
17285 {
17286 /* .i64 is a pseudo-op, so the immediate must be a repeating
17287 pattern. */
4316f0d2
DG
17288 if (immbits != (inst.operands[immoperand].regisimm ?
17289 inst.operands[immoperand].reg : 0))
036dc3f7
PB
17290 {
17291 /* Set immbits to an invalid constant. */
17292 immbits = 0xdeadbeef;
17293 }
17294 }
17295
5287ad62 17296 switch (opcode)
477330fc
RM
17297 {
17298 case N_MNEM_vbic:
17299 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17300 break;
17301
17302 case N_MNEM_vorr:
17303 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17304 break;
17305
17306 case N_MNEM_vand:
17307 /* Pseudo-instruction for VBIC. */
17308 neon_invert_size (&immbits, 0, et.size);
17309 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17310 break;
17311
17312 case N_MNEM_vorn:
17313 /* Pseudo-instruction for VORR. */
17314 neon_invert_size (&immbits, 0, et.size);
17315 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
17316 break;
17317
17318 default:
17319 abort ();
17320 }
5287ad62
JB
17321
17322 if (cmode == FAIL)
477330fc 17323 return;
5287ad62 17324
037e8744 17325 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
17326 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17327 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17328 inst.instruction |= cmode << 8;
17329 neon_write_immbits (immbits);
5f4273c7 17330
88714cb8 17331 neon_dp_fixup (&inst);
5287ad62
JB
17332 }
17333}
17334
17335static void
17336do_neon_bitfield (void)
17337{
037e8744 17338 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 17339 neon_check_type (3, rs, N_IGNORE_TYPE);
037e8744 17340 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
17341}
17342
17343static void
dcbf9037 17344neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types,
477330fc 17345 unsigned destbits)
5287ad62 17346{
5ee91343 17347 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
dcbf9037 17348 struct neon_type_el et = neon_check_type (3, rs, N_EQK | destbits, N_EQK,
477330fc 17349 types | N_KEY);
5287ad62
JB
17350 if (et.type == NT_float)
17351 {
88714cb8 17352 NEON_ENCODE (FLOAT, inst);
5ee91343 17353 if (rs == NS_QQR)
7df54120 17354 mve_encode_qqr (et.size, 0, 1);
5ee91343
AV
17355 else
17356 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
17357 }
17358 else
17359 {
88714cb8 17360 NEON_ENCODE (INTEGER, inst);
5ee91343 17361 if (rs == NS_QQR)
a8465a06 17362 mve_encode_qqr (et.size, et.type == ubit_meaning, 0);
5ee91343
AV
17363 else
17364 neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
5287ad62
JB
17365 }
17366}
17367
5287ad62
JB
17368
17369static void
17370do_neon_dyadic_if_su_d (void)
17371{
17372 /* This version only allow D registers, but that constraint is enforced during
17373 operand parsing so we don't need to do anything extra here. */
dcbf9037 17374 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
17375}
17376
5287ad62
JB
17377static void
17378do_neon_dyadic_if_i_d (void)
17379{
428e3f1f
PB
17380 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17381 affected if we specify unsigned args. */
17382 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
5287ad62
JB
17383}
17384
f5f10c66
AV
17385static void
17386do_mve_vstr_vldr_QI (int size, int elsize, int load)
17387{
17388 constraint (size < 32, BAD_ADDR_MODE);
17389 constraint (size != elsize, BAD_EL_TYPE);
17390 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
17391 constraint (!inst.operands[1].preind, BAD_ADDR_MODE);
17392 constraint (load && inst.operands[0].reg == inst.operands[1].reg,
17393 _("destination register and offset register may not be the"
17394 " same"));
17395
17396 int imm = inst.relocs[0].exp.X_add_number;
17397 int add = 1;
17398 if (imm < 0)
17399 {
17400 add = 0;
17401 imm = -imm;
17402 }
17403 constraint ((imm % (size / 8) != 0)
17404 || imm > (0x7f << neon_logbits (size)),
17405 (size == 32) ? _("immediate must be a multiple of 4 in the"
17406 " range of +/-[0,508]")
17407 : _("immediate must be a multiple of 8 in the"
17408 " range of +/-[0,1016]"));
17409 inst.instruction |= 0x11 << 24;
17410 inst.instruction |= add << 23;
17411 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17412 inst.instruction |= inst.operands[1].writeback << 21;
17413 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17414 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17415 inst.instruction |= 1 << 12;
17416 inst.instruction |= (size == 64) << 8;
17417 inst.instruction &= 0xffffff00;
17418 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17419 inst.instruction |= imm >> neon_logbits (size);
17420}
17421
17422static void
17423do_mve_vstr_vldr_RQ (int size, int elsize, int load)
17424{
17425 unsigned os = inst.operands[1].imm >> 5;
e449ea97 17426 unsigned type = inst.vectype.el[0].type;
f5f10c66
AV
17427 constraint (os != 0 && size == 8,
17428 _("can not shift offsets when accessing less than half-word"));
17429 constraint (os && os != neon_logbits (size),
17430 _("shift immediate must be 1, 2 or 3 for half-word, word"
17431 " or double-word accesses respectively"));
17432 if (inst.operands[1].reg == REG_PC)
17433 as_tsktsk (MVE_BAD_PC);
17434
17435 switch (size)
17436 {
17437 case 8:
17438 constraint (elsize >= 64, BAD_EL_TYPE);
17439 break;
17440 case 16:
17441 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
17442 break;
17443 case 32:
17444 case 64:
17445 constraint (elsize != size, BAD_EL_TYPE);
17446 break;
17447 default:
17448 break;
17449 }
17450 constraint (inst.operands[1].writeback || !inst.operands[1].preind,
17451 BAD_ADDR_MODE);
17452 if (load)
17453 {
17454 constraint (inst.operands[0].reg == (inst.operands[1].imm & 0x1f),
17455 _("destination register and offset register may not be"
17456 " the same"));
e449ea97
SP
17457 constraint (size == elsize && type == NT_signed, BAD_EL_TYPE);
17458 constraint (size != elsize && type != NT_unsigned && type != NT_signed,
f5f10c66 17459 BAD_EL_TYPE);
e449ea97 17460 inst.instruction |= ((size == elsize) || (type == NT_unsigned)) << 28;
f5f10c66
AV
17461 }
17462 else
17463 {
e449ea97 17464 constraint (type != NT_untyped, BAD_EL_TYPE);
f5f10c66
AV
17465 }
17466
17467 inst.instruction |= 1 << 23;
17468 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17469 inst.instruction |= inst.operands[1].reg << 16;
17470 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17471 inst.instruction |= neon_logbits (elsize) << 7;
17472 inst.instruction |= HI1 (inst.operands[1].imm) << 5;
17473 inst.instruction |= LOW4 (inst.operands[1].imm);
17474 inst.instruction |= !!os;
17475}
17476
17477static void
17478do_mve_vstr_vldr_RI (int size, int elsize, int load)
17479{
17480 enum neon_el_type type = inst.vectype.el[0].type;
17481
17482 constraint (size >= 64, BAD_ADDR_MODE);
17483 switch (size)
17484 {
17485 case 16:
17486 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
17487 break;
17488 case 32:
17489 constraint (elsize != size, BAD_EL_TYPE);
17490 break;
17491 default:
17492 break;
17493 }
17494 if (load)
17495 {
17496 constraint (elsize != size && type != NT_unsigned
17497 && type != NT_signed, BAD_EL_TYPE);
17498 }
17499 else
17500 {
17501 constraint (elsize != size && type != NT_untyped, BAD_EL_TYPE);
17502 }
17503
17504 int imm = inst.relocs[0].exp.X_add_number;
17505 int add = 1;
17506 if (imm < 0)
17507 {
17508 add = 0;
17509 imm = -imm;
17510 }
17511
17512 if ((imm % (size / 8) != 0) || imm > (0x7f << neon_logbits (size)))
17513 {
17514 switch (size)
17515 {
17516 case 8:
17517 constraint (1, _("immediate must be in the range of +/-[0,127]"));
17518 break;
17519 case 16:
17520 constraint (1, _("immediate must be a multiple of 2 in the"
17521 " range of +/-[0,254]"));
17522 break;
17523 case 32:
17524 constraint (1, _("immediate must be a multiple of 4 in the"
17525 " range of +/-[0,508]"));
17526 break;
17527 }
17528 }
17529
17530 if (size != elsize)
17531 {
17532 constraint (inst.operands[1].reg > 7, BAD_HIREG);
17533 constraint (inst.operands[0].reg > 14,
17534 _("MVE vector register in the range [Q0..Q7] expected"));
17535 inst.instruction |= (load && type == NT_unsigned) << 28;
17536 inst.instruction |= (size == 16) << 19;
17537 inst.instruction |= neon_logbits (elsize) << 7;
17538 }
17539 else
17540 {
17541 if (inst.operands[1].reg == REG_PC)
17542 as_tsktsk (MVE_BAD_PC);
17543 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
17544 as_tsktsk (MVE_BAD_SP);
17545 inst.instruction |= 1 << 12;
17546 inst.instruction |= neon_logbits (size) << 7;
17547 }
17548 inst.instruction |= inst.operands[1].preind << 24;
17549 inst.instruction |= add << 23;
17550 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17551 inst.instruction |= inst.operands[1].writeback << 21;
17552 inst.instruction |= inst.operands[1].reg << 16;
17553 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17554 inst.instruction &= 0xffffff80;
17555 inst.instruction |= imm >> neon_logbits (size);
17556
17557}
17558
17559static void
17560do_mve_vstr_vldr (void)
17561{
17562 unsigned size;
17563 int load = 0;
17564
17565 if (inst.cond > COND_ALWAYS)
17566 inst.pred_insn_type = INSIDE_VPT_INSN;
17567 else
17568 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17569
17570 switch (inst.instruction)
17571 {
17572 default:
17573 gas_assert (0);
17574 break;
17575 case M_MNEM_vldrb:
17576 load = 1;
17577 /* fall through. */
17578 case M_MNEM_vstrb:
17579 size = 8;
17580 break;
17581 case M_MNEM_vldrh:
17582 load = 1;
17583 /* fall through. */
17584 case M_MNEM_vstrh:
17585 size = 16;
17586 break;
17587 case M_MNEM_vldrw:
17588 load = 1;
17589 /* fall through. */
17590 case M_MNEM_vstrw:
17591 size = 32;
17592 break;
17593 case M_MNEM_vldrd:
17594 load = 1;
17595 /* fall through. */
17596 case M_MNEM_vstrd:
17597 size = 64;
17598 break;
17599 }
17600 unsigned elsize = inst.vectype.el[0].size;
17601
17602 if (inst.operands[1].isquad)
17603 {
17604 /* We are dealing with [Q, imm]{!} cases. */
17605 do_mve_vstr_vldr_QI (size, elsize, load);
17606 }
17607 else
17608 {
17609 if (inst.operands[1].immisreg == 2)
17610 {
17611 /* We are dealing with [R, Q, {UXTW #os}] cases. */
17612 do_mve_vstr_vldr_RQ (size, elsize, load);
17613 }
17614 else if (!inst.operands[1].immisreg)
17615 {
17616 /* We are dealing with [R, Imm]{!}/[R], Imm cases. */
17617 do_mve_vstr_vldr_RI (size, elsize, load);
17618 }
17619 else
17620 constraint (1, BAD_ADDR_MODE);
17621 }
17622
17623 inst.is_neon = 1;
17624}
17625
35c228db
AV
17626static void
17627do_mve_vst_vld (void)
17628{
17629 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17630 return;
17631
17632 constraint (!inst.operands[1].preind || inst.relocs[0].exp.X_add_symbol != 0
17633 || inst.relocs[0].exp.X_add_number != 0
17634 || inst.operands[1].immisreg != 0,
17635 BAD_ADDR_MODE);
17636 constraint (inst.vectype.el[0].size > 32, BAD_EL_TYPE);
17637 if (inst.operands[1].reg == REG_PC)
17638 as_tsktsk (MVE_BAD_PC);
17639 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
17640 as_tsktsk (MVE_BAD_SP);
17641
17642
17643 /* These instructions are one of the "exceptions" mentioned in
17644 handle_pred_state. They are MVE instructions that are not VPT compatible
17645 and do not accept a VPT code, thus appending such a code is a syntax
17646 error. */
17647 if (inst.cond > COND_ALWAYS)
17648 first_error (BAD_SYNTAX);
17649 /* If we append a scalar condition code we can set this to
17650 MVE_OUTSIDE_PRED_INSN as it will also lead to a syntax error. */
17651 else if (inst.cond < COND_ALWAYS)
17652 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17653 else
17654 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
17655
17656 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17657 inst.instruction |= inst.operands[1].writeback << 21;
17658 inst.instruction |= inst.operands[1].reg << 16;
17659 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17660 inst.instruction |= neon_logbits (inst.vectype.el[0].size) << 7;
17661 inst.is_neon = 1;
17662}
17663
26c1e780
AV
17664static void
17665do_mve_vaddlv (void)
17666{
17667 enum neon_shape rs = neon_select_shape (NS_RRQ, NS_NULL);
17668 struct neon_type_el et
17669 = neon_check_type (3, rs, N_EQK, N_EQK, N_S32 | N_U32 | N_KEY);
17670
17671 if (et.type == NT_invtype)
17672 first_error (BAD_EL_TYPE);
17673
17674 if (inst.cond > COND_ALWAYS)
17675 inst.pred_insn_type = INSIDE_VPT_INSN;
17676 else
17677 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17678
17679 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
17680
17681 inst.instruction |= (et.type == NT_unsigned) << 28;
17682 inst.instruction |= inst.operands[1].reg << 19;
17683 inst.instruction |= inst.operands[0].reg << 12;
17684 inst.instruction |= inst.operands[2].reg;
17685 inst.is_neon = 1;
17686}
17687
5287ad62 17688static void
5ee91343 17689do_neon_dyadic_if_su (void)
5287ad62 17690{
5ee91343
AV
17691 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
17692 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
17693 N_SUF_32 | N_KEY);
17694
935295b5
AV
17695 constraint ((inst.instruction == ((unsigned) N_MNEM_vmax)
17696 || inst.instruction == ((unsigned) N_MNEM_vmin))
17697 && et.type == NT_float
17698 && !ARM_CPU_HAS_FEATURE (cpu_variant,fpu_neon_ext_v1), BAD_FPU);
17699
64c350f2
AV
17700 if (!check_simd_pred_availability (et.type == NT_float,
17701 NEON_CHECK_ARCH | NEON_CHECK_CC))
037e8744
JB
17702 return;
17703
5ee91343
AV
17704 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
17705}
17706
17707static void
17708do_neon_addsub_if_i (void)
17709{
17710 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
17711 && try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
037e8744
JB
17712 return;
17713
5ee91343
AV
17714 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
17715 struct neon_type_el et = neon_check_type (3, rs, N_EQK,
17716 N_EQK, N_IF_32 | N_I64 | N_KEY);
17717
17718 constraint (rs == NS_QQR && et.size == 64, BAD_FPU);
17719 /* If we are parsing Q registers and the element types match MVE, which NEON
17720 also supports, then we must check whether this is an instruction that can
17721 be used by both MVE/NEON. This distinction can be made based on whether
17722 they are predicated or not. */
17723 if ((rs == NS_QQQ || rs == NS_QQR) && et.size != 64)
17724 {
64c350f2
AV
17725 if (!check_simd_pred_availability (et.type == NT_float,
17726 NEON_CHECK_ARCH | NEON_CHECK_CC))
5ee91343
AV
17727 return;
17728 }
17729 else
17730 {
17731 /* If they are either in a D register or are using an unsupported. */
17732 if (rs != NS_QQR
17733 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
17734 return;
17735 }
17736
5287ad62
JB
17737 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17738 affected if we specify unsigned args. */
dcbf9037 17739 neon_dyadic_misc (NT_untyped, N_IF_32 | N_I64, 0);
5287ad62
JB
17740}
17741
17742/* Swaps operands 1 and 2. If operand 1 (optional arg) was omitted, we want the
17743 result to be:
17744 V<op> A,B (A is operand 0, B is operand 2)
17745 to mean:
17746 V<op> A,B,A
17747 not:
17748 V<op> A,B,B
17749 so handle that case specially. */
17750
17751static void
17752neon_exchange_operands (void)
17753{
5287ad62
JB
17754 if (inst.operands[1].present)
17755 {
e1fa0163
NC
17756 void *scratch = xmalloc (sizeof (inst.operands[0]));
17757
5287ad62
JB
17758 /* Swap operands[1] and operands[2]. */
17759 memcpy (scratch, &inst.operands[1], sizeof (inst.operands[0]));
17760 inst.operands[1] = inst.operands[2];
17761 memcpy (&inst.operands[2], scratch, sizeof (inst.operands[0]));
e1fa0163 17762 free (scratch);
5287ad62
JB
17763 }
17764 else
17765 {
17766 inst.operands[1] = inst.operands[2];
17767 inst.operands[2] = inst.operands[0];
17768 }
17769}
17770
17771static void
17772neon_compare (unsigned regtypes, unsigned immtypes, int invert)
17773{
17774 if (inst.operands[2].isreg)
17775 {
17776 if (invert)
477330fc 17777 neon_exchange_operands ();
dcbf9037 17778 neon_dyadic_misc (NT_unsigned, regtypes, N_SIZ);
5287ad62
JB
17779 }
17780 else
17781 {
037e8744 17782 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
dcbf9037 17783 struct neon_type_el et = neon_check_type (2, rs,
477330fc 17784 N_EQK | N_SIZ, immtypes | N_KEY);
5287ad62 17785
88714cb8 17786 NEON_ENCODE (IMMED, inst);
5287ad62
JB
17787 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17788 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17789 inst.instruction |= LOW4 (inst.operands[1].reg);
17790 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 17791 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
17792 inst.instruction |= (et.type == NT_float) << 10;
17793 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 17794
88714cb8 17795 neon_dp_fixup (&inst);
5287ad62
JB
17796 }
17797}
17798
17799static void
17800do_neon_cmp (void)
17801{
cc933301 17802 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, FALSE);
5287ad62
JB
17803}
17804
17805static void
17806do_neon_cmp_inv (void)
17807{
cc933301 17808 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, TRUE);
5287ad62
JB
17809}
17810
17811static void
17812do_neon_ceq (void)
17813{
17814 neon_compare (N_IF_32, N_IF_32, FALSE);
17815}
17816
17817/* For multiply instructions, we have the possibility of 16-bit or 32-bit
17818 scalars, which are encoded in 5 bits, M : Rm.
17819 For 16-bit scalars, the register is encoded in Rm[2:0] and the index in
17820 M:Rm[3], and for 32-bit scalars, the register is encoded in Rm[3:0] and the
c604a79a
JW
17821 index in M.
17822
17823 Dot Product instructions are similar to multiply instructions except elsize
17824 should always be 32.
17825
17826 This function translates SCALAR, which is GAS's internal encoding of indexed
17827 scalar register, to raw encoding. There is also register and index range
17828 check based on ELSIZE. */
5287ad62
JB
17829
17830static unsigned
17831neon_scalar_for_mul (unsigned scalar, unsigned elsize)
17832{
dcbf9037
JB
17833 unsigned regno = NEON_SCALAR_REG (scalar);
17834 unsigned elno = NEON_SCALAR_INDEX (scalar);
5287ad62
JB
17835
17836 switch (elsize)
17837 {
17838 case 16:
17839 if (regno > 7 || elno > 3)
477330fc 17840 goto bad_scalar;
5287ad62 17841 return regno | (elno << 3);
5f4273c7 17842
5287ad62
JB
17843 case 32:
17844 if (regno > 15 || elno > 1)
477330fc 17845 goto bad_scalar;
5287ad62
JB
17846 return regno | (elno << 4);
17847
17848 default:
17849 bad_scalar:
dcbf9037 17850 first_error (_("scalar out of range for multiply instruction"));
5287ad62
JB
17851 }
17852
17853 return 0;
17854}
17855
17856/* Encode multiply / multiply-accumulate scalar instructions. */
17857
17858static void
17859neon_mul_mac (struct neon_type_el et, int ubit)
17860{
dcbf9037
JB
17861 unsigned scalar;
17862
17863 /* Give a more helpful error message if we have an invalid type. */
17864 if (et.type == NT_invtype)
17865 return;
5f4273c7 17866
dcbf9037 17867 scalar = neon_scalar_for_mul (inst.operands[2].reg, et.size);
5287ad62
JB
17868 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17869 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17870 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17871 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17872 inst.instruction |= LOW4 (scalar);
17873 inst.instruction |= HI1 (scalar) << 5;
17874 inst.instruction |= (et.type == NT_float) << 8;
17875 inst.instruction |= neon_logbits (et.size) << 20;
17876 inst.instruction |= (ubit != 0) << 24;
17877
88714cb8 17878 neon_dp_fixup (&inst);
5287ad62
JB
17879}
17880
17881static void
17882do_neon_mac_maybe_scalar (void)
17883{
037e8744
JB
17884 if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
17885 return;
17886
64c350f2 17887 if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
17888 return;
17889
5287ad62
JB
17890 if (inst.operands[2].isscalar)
17891 {
a8465a06 17892 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 17893 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 17894 struct neon_type_el et = neon_check_type (3, rs,
589a7d88 17895 N_EQK, N_EQK, N_I16 | N_I32 | N_F_16_32 | N_KEY);
88714cb8 17896 NEON_ENCODE (SCALAR, inst);
037e8744 17897 neon_mul_mac (et, neon_quad (rs));
5287ad62 17898 }
a8465a06
AV
17899 else if (!inst.operands[2].isvec)
17900 {
17901 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
17902
17903 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
17904 neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
17905
17906 neon_dyadic_misc (NT_unsigned, N_SU_MVE, 0);
17907 }
5287ad62 17908 else
428e3f1f 17909 {
a8465a06 17910 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
428e3f1f
PB
17911 /* The "untyped" case can't happen. Do this to stop the "U" bit being
17912 affected if we specify unsigned args. */
17913 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
17914 }
5287ad62
JB
17915}
17916
aab2c27d
MM
17917static void
17918do_bfloat_vfma (void)
17919{
17920 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
17921 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
17922 enum neon_shape rs;
17923 int t_bit = 0;
17924
17925 if (inst.instruction != B_MNEM_vfmab)
17926 {
17927 t_bit = 1;
17928 inst.instruction = B_MNEM_vfmat;
17929 }
17930
17931 if (inst.operands[2].isscalar)
17932 {
17933 rs = neon_select_shape (NS_QQS, NS_NULL);
17934 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
17935
17936 inst.instruction |= (1 << 25);
17937 int index = inst.operands[2].reg & 0xf;
17938 constraint (!(index < 4), _("index must be in the range 0 to 3"));
17939 inst.operands[2].reg >>= 4;
17940 constraint (!(inst.operands[2].reg < 8),
17941 _("indexed register must be less than 8"));
17942 neon_three_args (t_bit);
17943 inst.instruction |= ((index & 1) << 3);
17944 inst.instruction |= ((index & 2) << 4);
17945 }
17946 else
17947 {
17948 rs = neon_select_shape (NS_QQQ, NS_NULL);
17949 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
17950 neon_three_args (t_bit);
17951 }
17952
17953}
17954
62f3b8c8
PB
17955static void
17956do_neon_fmac (void)
17957{
d58196e0
AV
17958 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_fma)
17959 && try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS)
62f3b8c8
PB
17960 return;
17961
64c350f2 17962 if (!check_simd_pred_availability (TRUE, NEON_CHECK_CC | NEON_CHECK_ARCH))
62f3b8c8
PB
17963 return;
17964
d58196e0
AV
17965 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
17966 {
17967 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17968 struct neon_type_el et = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK,
17969 N_EQK);
17970
17971 if (rs == NS_QQR)
17972 {
aab2c27d 17973
d58196e0
AV
17974 if (inst.operands[2].reg == REG_SP)
17975 as_tsktsk (MVE_BAD_SP);
17976 else if (inst.operands[2].reg == REG_PC)
17977 as_tsktsk (MVE_BAD_PC);
17978
17979 inst.instruction = 0xee310e40;
17980 inst.instruction |= (et.size == 16) << 28;
17981 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17982 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17983 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17984 inst.instruction |= HI1 (inst.operands[1].reg) << 6;
17985 inst.instruction |= inst.operands[2].reg;
17986 inst.is_neon = 1;
17987 return;
17988 }
17989 }
17990 else
17991 {
17992 constraint (!inst.operands[2].isvec, BAD_FPU);
17993 }
17994
62f3b8c8
PB
17995 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
17996}
17997
aab2c27d
MM
17998static void
17999do_mve_vfma (void)
18000{
18001 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_bf16) &&
18002 inst.cond == COND_ALWAYS)
18003 {
18004 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
18005 inst.instruction = N_MNEM_vfma;
18006 inst.pred_insn_type = INSIDE_VPT_INSN;
18007 inst.cond = 0xf;
18008 return do_neon_fmac();
18009 }
18010 else
18011 {
18012 do_bfloat_vfma();
18013 }
18014}
18015
5287ad62
JB
18016static void
18017do_neon_tst (void)
18018{
037e8744 18019 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
18020 struct neon_type_el et = neon_check_type (3, rs,
18021 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
037e8744 18022 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
18023}
18024
18025/* VMUL with 3 registers allows the P8 type. The scalar version supports the
18026 same types as the MAC equivalents. The polynomial type for this instruction
18027 is encoded the same as the integer type. */
18028
18029static void
18030do_neon_mul (void)
18031{
037e8744
JB
18032 if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
18033 return;
18034
64c350f2 18035 if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
037e8744
JB
18036 return;
18037
5287ad62 18038 if (inst.operands[2].isscalar)
a8465a06
AV
18039 {
18040 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
18041 do_neon_mac_maybe_scalar ();
18042 }
5287ad62 18043 else
a8465a06
AV
18044 {
18045 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18046 {
18047 enum neon_shape rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
18048 struct neon_type_el et
18049 = neon_check_type (3, rs, N_EQK, N_EQK, N_I_MVE | N_F_MVE | N_KEY);
18050 if (et.type == NT_float)
18051 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
18052 BAD_FPU);
18053
18054 neon_dyadic_misc (NT_float, N_I_MVE | N_F_MVE, 0);
18055 }
18056 else
18057 {
18058 constraint (!inst.operands[2].isvec, BAD_FPU);
18059 neon_dyadic_misc (NT_poly,
18060 N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
18061 }
18062 }
5287ad62
JB
18063}
18064
18065static void
18066do_neon_qdmulh (void)
18067{
64c350f2 18068 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
42b16635
AV
18069 return;
18070
5287ad62
JB
18071 if (inst.operands[2].isscalar)
18072 {
42b16635 18073 constraint (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
037e8744 18074 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 18075 struct neon_type_el et = neon_check_type (3, rs,
477330fc 18076 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 18077 NEON_ENCODE (SCALAR, inst);
037e8744 18078 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
18079 }
18080 else
18081 {
42b16635
AV
18082 enum neon_shape rs;
18083 struct neon_type_el et;
18084 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18085 {
18086 rs = neon_select_shape (NS_QQR, NS_QQQ, NS_NULL);
18087 et = neon_check_type (3, rs,
18088 N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18089 }
18090 else
18091 {
18092 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
18093 et = neon_check_type (3, rs,
18094 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18095 }
18096
88714cb8 18097 NEON_ENCODE (INTEGER, inst);
42b16635
AV
18098 if (rs == NS_QQR)
18099 mve_encode_qqr (et.size, 0, 0);
18100 else
18101 /* The U bit (rounding) comes from bit mask. */
18102 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
18103 }
18104}
18105
26c1e780
AV
18106static void
18107do_mve_vaddv (void)
18108{
18109 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18110 struct neon_type_el et
18111 = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
18112
18113 if (et.type == NT_invtype)
18114 first_error (BAD_EL_TYPE);
18115
18116 if (inst.cond > COND_ALWAYS)
18117 inst.pred_insn_type = INSIDE_VPT_INSN;
18118 else
18119 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18120
18121 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
18122
18123 mve_encode_rq (et.type == NT_unsigned, et.size);
18124}
18125
7df54120
AV
18126static void
18127do_mve_vhcadd (void)
18128{
18129 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
18130 struct neon_type_el et
18131 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18132
18133 if (inst.cond > COND_ALWAYS)
18134 inst.pred_insn_type = INSIDE_VPT_INSN;
18135 else
18136 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18137
18138 unsigned rot = inst.relocs[0].exp.X_add_number;
18139 constraint (rot != 90 && rot != 270, _("immediate out of range"));
18140
18141 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
18142 as_tsktsk (_("Warning: 32-bit element size and same first and third "
18143 "operand makes instruction UNPREDICTABLE"));
18144
18145 mve_encode_qqq (0, et.size);
18146 inst.instruction |= (rot == 270) << 12;
18147 inst.is_neon = 1;
18148}
18149
35d1cfc2
AV
18150static void
18151do_mve_vqdmull (void)
18152{
18153 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
18154 struct neon_type_el et
18155 = neon_check_type (3, rs, N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18156
18157 if (et.size == 32
18158 && (inst.operands[0].reg == inst.operands[1].reg
18159 || (rs == NS_QQQ && inst.operands[0].reg == inst.operands[2].reg)))
18160 as_tsktsk (BAD_MVE_SRCDEST);
18161
18162 if (inst.cond > COND_ALWAYS)
18163 inst.pred_insn_type = INSIDE_VPT_INSN;
18164 else
18165 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18166
18167 if (rs == NS_QQQ)
18168 {
18169 mve_encode_qqq (et.size == 32, 64);
18170 inst.instruction |= 1;
18171 }
18172 else
18173 {
18174 mve_encode_qqr (64, et.size == 32, 0);
18175 inst.instruction |= 0x3 << 5;
18176 }
18177}
18178
c2dafc2a
AV
18179static void
18180do_mve_vadc (void)
18181{
18182 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
18183 struct neon_type_el et
18184 = neon_check_type (3, rs, N_KEY | N_I32, N_EQK, N_EQK);
18185
18186 if (et.type == NT_invtype)
18187 first_error (BAD_EL_TYPE);
18188
18189 if (inst.cond > COND_ALWAYS)
18190 inst.pred_insn_type = INSIDE_VPT_INSN;
18191 else
18192 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18193
18194 mve_encode_qqq (0, 64);
18195}
18196
18197static void
18198do_mve_vbrsr (void)
18199{
18200 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18201 struct neon_type_el et
18202 = neon_check_type (3, rs, N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18203
18204 if (inst.cond > COND_ALWAYS)
18205 inst.pred_insn_type = INSIDE_VPT_INSN;
18206 else
18207 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18208
7df54120 18209 mve_encode_qqr (et.size, 0, 0);
c2dafc2a
AV
18210}
18211
18212static void
18213do_mve_vsbc (void)
18214{
18215 neon_check_type (3, NS_QQQ, N_EQK, N_EQK, N_I32 | N_KEY);
18216
18217 if (inst.cond > COND_ALWAYS)
18218 inst.pred_insn_type = INSIDE_VPT_INSN;
18219 else
18220 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18221
18222 mve_encode_qqq (1, 64);
18223}
18224
2d78f95b
AV
18225static void
18226do_mve_vmulh (void)
18227{
18228 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
18229 struct neon_type_el et
18230 = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_MVE | N_KEY);
18231
18232 if (inst.cond > COND_ALWAYS)
18233 inst.pred_insn_type = INSIDE_VPT_INSN;
18234 else
18235 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18236
18237 mve_encode_qqq (et.type == NT_unsigned, et.size);
18238}
18239
42b16635
AV
18240static void
18241do_mve_vqdmlah (void)
18242{
18243 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18244 struct neon_type_el et
23d188c7 18245 = neon_check_type (3, rs, N_EQK, N_EQK, N_S_32 | N_KEY);
42b16635
AV
18246
18247 if (inst.cond > COND_ALWAYS)
18248 inst.pred_insn_type = INSIDE_VPT_INSN;
18249 else
18250 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18251
18252 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
18253}
8b8b22a4
AV
18254
18255static void
18256do_mve_vqdmladh (void)
18257{
18258 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
18259 struct neon_type_el et
18260 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18261
18262 if (inst.cond > COND_ALWAYS)
18263 inst.pred_insn_type = INSIDE_VPT_INSN;
18264 else
18265 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18266
8b8b22a4
AV
18267 mve_encode_qqq (0, et.size);
18268}
18269
18270
886e1c73
AV
18271static void
18272do_mve_vmull (void)
18273{
18274
18275 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_DDS,
18276 NS_QQS, NS_QQQ, NS_QQR, NS_NULL);
fe05f369 18277 if (inst.cond == COND_ALWAYS
886e1c73
AV
18278 && ((unsigned)inst.instruction) == M_MNEM_vmullt)
18279 {
fe05f369 18280
886e1c73
AV
18281 if (rs == NS_QQQ)
18282 {
fe05f369 18283 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
886e1c73
AV
18284 goto neon_vmul;
18285 }
18286 else
18287 goto neon_vmul;
18288 }
18289
18290 constraint (rs != NS_QQQ, BAD_FPU);
18291 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
18292 N_SU_32 | N_P8 | N_P16 | N_KEY);
18293
18294 /* We are dealing with MVE's vmullt. */
18295 if (et.size == 32
18296 && (inst.operands[0].reg == inst.operands[1].reg
18297 || inst.operands[0].reg == inst.operands[2].reg))
18298 as_tsktsk (BAD_MVE_SRCDEST);
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 if (et.type == NT_poly)
18306 mve_encode_qqq (neon_logbits (et.size), 64);
18307 else
18308 mve_encode_qqq (et.type == NT_unsigned, et.size);
18309
18310 return;
18311
dc1e8a47 18312 neon_vmul:
886e1c73
AV
18313 inst.instruction = N_MNEM_vmul;
18314 inst.cond = 0xb;
18315 if (thumb_mode)
18316 inst.pred_insn_type = INSIDE_IT_INSN;
18317 do_neon_mul ();
18318}
18319
a302e574
AV
18320static void
18321do_mve_vabav (void)
18322{
18323 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
18324
18325 if (rs == NS_NULL)
18326 return;
18327
18328 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18329 return;
18330
18331 struct neon_type_el et = neon_check_type (2, NS_NULL, N_EQK, N_KEY | N_S8
18332 | N_S16 | N_S32 | N_U8 | N_U16
18333 | N_U32);
18334
18335 if (inst.cond > COND_ALWAYS)
18336 inst.pred_insn_type = INSIDE_VPT_INSN;
18337 else
18338 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18339
18340 mve_encode_rqq (et.type == NT_unsigned, et.size);
18341}
18342
18343static void
18344do_mve_vmladav (void)
18345{
18346 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
18347 struct neon_type_el et = neon_check_type (3, rs,
18348 N_EQK, N_EQK, N_SU_MVE | N_KEY);
18349
18350 if (et.type == NT_unsigned
18351 && (inst.instruction == M_MNEM_vmladavx
18352 || inst.instruction == M_MNEM_vmladavax
18353 || inst.instruction == M_MNEM_vmlsdav
18354 || inst.instruction == M_MNEM_vmlsdava
18355 || inst.instruction == M_MNEM_vmlsdavx
18356 || inst.instruction == M_MNEM_vmlsdavax))
18357 first_error (BAD_SIMD_TYPE);
18358
18359 constraint (inst.operands[2].reg > 14,
18360 _("MVE vector register in the range [Q0..Q7] expected"));
18361
18362 if (inst.cond > COND_ALWAYS)
18363 inst.pred_insn_type = INSIDE_VPT_INSN;
18364 else
18365 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18366
18367 if (inst.instruction == M_MNEM_vmlsdav
18368 || inst.instruction == M_MNEM_vmlsdava
18369 || inst.instruction == M_MNEM_vmlsdavx
18370 || inst.instruction == M_MNEM_vmlsdavax)
18371 inst.instruction |= (et.size == 8) << 28;
18372 else
18373 inst.instruction |= (et.size == 8) << 8;
18374
18375 mve_encode_rqq (et.type == NT_unsigned, 64);
18376 inst.instruction |= (et.size == 32) << 16;
18377}
18378
93925576
AV
18379static void
18380do_mve_vmlaldav (void)
18381{
18382 enum neon_shape rs = neon_select_shape (NS_RRQQ, NS_NULL);
18383 struct neon_type_el et
18384 = neon_check_type (4, rs, N_EQK, N_EQK, N_EQK,
18385 N_S16 | N_S32 | N_U16 | N_U32 | N_KEY);
18386
18387 if (et.type == NT_unsigned
18388 && (inst.instruction == M_MNEM_vmlsldav
18389 || inst.instruction == M_MNEM_vmlsldava
18390 || inst.instruction == M_MNEM_vmlsldavx
18391 || inst.instruction == M_MNEM_vmlsldavax))
18392 first_error (BAD_SIMD_TYPE);
18393
18394 if (inst.cond > COND_ALWAYS)
18395 inst.pred_insn_type = INSIDE_VPT_INSN;
18396 else
18397 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18398
18399 mve_encode_rrqq (et.type == NT_unsigned, et.size);
18400}
18401
18402static void
18403do_mve_vrmlaldavh (void)
18404{
18405 struct neon_type_el et;
18406 if (inst.instruction == M_MNEM_vrmlsldavh
18407 || inst.instruction == M_MNEM_vrmlsldavha
18408 || inst.instruction == M_MNEM_vrmlsldavhx
18409 || inst.instruction == M_MNEM_vrmlsldavhax)
18410 {
18411 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
18412 if (inst.operands[1].reg == REG_SP)
18413 as_tsktsk (MVE_BAD_SP);
18414 }
18415 else
18416 {
18417 if (inst.instruction == M_MNEM_vrmlaldavhx
18418 || inst.instruction == M_MNEM_vrmlaldavhax)
18419 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
18420 else
18421 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK,
18422 N_U32 | N_S32 | N_KEY);
18423 /* vrmlaldavh's encoding with SP as the second, odd, GPR operand may alias
18424 with vmax/min instructions, making the use of SP in assembly really
18425 nonsensical, so instead of issuing a warning like we do for other uses
18426 of SP for the odd register operand we error out. */
18427 constraint (inst.operands[1].reg == REG_SP, BAD_SP);
18428 }
18429
18430 /* Make sure we still check the second operand is an odd one and that PC is
18431 disallowed. This because we are parsing for any GPR operand, to be able
18432 to distinguish between giving a warning or an error for SP as described
18433 above. */
18434 constraint ((inst.operands[1].reg % 2) != 1, BAD_EVEN);
18435 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
18436
18437 if (inst.cond > COND_ALWAYS)
18438 inst.pred_insn_type = INSIDE_VPT_INSN;
18439 else
18440 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18441
18442 mve_encode_rrqq (et.type == NT_unsigned, 0);
18443}
18444
18445
8cd78170
AV
18446static void
18447do_mve_vmaxnmv (void)
18448{
18449 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18450 struct neon_type_el et
18451 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
18452
18453 if (inst.cond > COND_ALWAYS)
18454 inst.pred_insn_type = INSIDE_VPT_INSN;
18455 else
18456 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18457
18458 if (inst.operands[0].reg == REG_SP)
18459 as_tsktsk (MVE_BAD_SP);
18460 else if (inst.operands[0].reg == REG_PC)
18461 as_tsktsk (MVE_BAD_PC);
18462
18463 mve_encode_rq (et.size == 16, 64);
18464}
18465
13ccd4c0
AV
18466static void
18467do_mve_vmaxv (void)
18468{
18469 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
18470 struct neon_type_el et;
18471
18472 if (inst.instruction == M_MNEM_vmaxv || inst.instruction == M_MNEM_vminv)
18473 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
18474 else
18475 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
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 if (inst.operands[0].reg == REG_SP)
18483 as_tsktsk (MVE_BAD_SP);
18484 else if (inst.operands[0].reg == REG_PC)
18485 as_tsktsk (MVE_BAD_PC);
18486
18487 mve_encode_rq (et.type == NT_unsigned, et.size);
18488}
18489
18490
643afb90
MW
18491static void
18492do_neon_qrdmlah (void)
18493{
64c350f2 18494 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
42b16635
AV
18495 return;
18496 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
643afb90 18497 {
42b16635
AV
18498 /* Check we're on the correct architecture. */
18499 if (!mark_feature_used (&fpu_neon_ext_armv8))
18500 inst.error
18501 = _("instruction form not available on this architecture.");
18502 else if (!mark_feature_used (&fpu_neon_ext_v8_1))
18503 {
18504 as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
18505 record_feature_use (&fpu_neon_ext_v8_1);
18506 }
18507 if (inst.operands[2].isscalar)
18508 {
18509 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
18510 struct neon_type_el et = neon_check_type (3, rs,
18511 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18512 NEON_ENCODE (SCALAR, inst);
18513 neon_mul_mac (et, neon_quad (rs));
18514 }
18515 else
18516 {
18517 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
18518 struct neon_type_el et = neon_check_type (3, rs,
18519 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
18520 NEON_ENCODE (INTEGER, inst);
18521 /* The U bit (rounding) comes from bit mask. */
18522 neon_three_same (neon_quad (rs), 0, et.size);
18523 }
643afb90
MW
18524 }
18525 else
18526 {
42b16635
AV
18527 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
18528 struct neon_type_el et
23d188c7 18529 = neon_check_type (3, rs, N_EQK, N_EQK, N_S_32 | N_KEY);
42b16635 18530
643afb90 18531 NEON_ENCODE (INTEGER, inst);
42b16635 18532 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
643afb90
MW
18533 }
18534}
18535
5287ad62
JB
18536static void
18537do_neon_fcmp_absolute (void)
18538{
037e8744 18539 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
18540 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
18541 N_F_16_32 | N_KEY);
5287ad62 18542 /* Size field comes from bit mask. */
cc933301 18543 neon_three_same (neon_quad (rs), 1, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
18544}
18545
18546static void
18547do_neon_fcmp_absolute_inv (void)
18548{
18549 neon_exchange_operands ();
18550 do_neon_fcmp_absolute ();
18551}
18552
18553static void
18554do_neon_step (void)
18555{
037e8744 18556 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
18557 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
18558 N_F_16_32 | N_KEY);
18559 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
18560}
18561
18562static void
18563do_neon_abs_neg (void)
18564{
037e8744
JB
18565 enum neon_shape rs;
18566 struct neon_type_el et;
5f4273c7 18567
037e8744
JB
18568 if (try_vfp_nsyn (2, do_vfp_nsyn_abs_neg) == SUCCESS)
18569 return;
18570
037e8744 18571 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
cc933301 18572 et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
5f4273c7 18573
64c350f2
AV
18574 if (!check_simd_pred_availability (et.type == NT_float,
18575 NEON_CHECK_ARCH | NEON_CHECK_CC))
485dee97
AV
18576 return;
18577
5287ad62
JB
18578 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18579 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18580 inst.instruction |= LOW4 (inst.operands[1].reg);
18581 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 18582 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18583 inst.instruction |= (et.type == NT_float) << 10;
18584 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 18585
88714cb8 18586 neon_dp_fixup (&inst);
5287ad62
JB
18587}
18588
18589static void
18590do_neon_sli (void)
18591{
64c350f2 18592 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
18593 return;
18594
18595 enum neon_shape rs;
18596 struct neon_type_el et;
18597 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18598 {
18599 rs = neon_select_shape (NS_QQI, NS_NULL);
18600 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18601 }
18602 else
18603 {
18604 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18605 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18606 }
18607
18608
5287ad62
JB
18609 int imm = inst.operands[2].imm;
18610 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 18611 _("immediate out of range for insert"));
037e8744 18612 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
18613}
18614
18615static void
18616do_neon_sri (void)
18617{
64c350f2 18618 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
18619 return;
18620
18621 enum neon_shape rs;
18622 struct neon_type_el et;
18623 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18624 {
18625 rs = neon_select_shape (NS_QQI, NS_NULL);
18626 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_KEY);
18627 }
18628 else
18629 {
18630 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18631 et = neon_check_type (2, rs, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18632 }
18633
5287ad62
JB
18634 int imm = inst.operands[2].imm;
18635 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18636 _("immediate out of range for insert"));
037e8744 18637 neon_imm_shift (FALSE, 0, neon_quad (rs), et, et.size - imm);
5287ad62
JB
18638}
18639
18640static void
18641do_neon_qshlu_imm (void)
18642{
64c350f2 18643 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
5150f0d8
AV
18644 return;
18645
18646 enum neon_shape rs;
18647 struct neon_type_el et;
18648 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18649 {
18650 rs = neon_select_shape (NS_QQI, NS_NULL);
18651 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
18652 }
18653 else
18654 {
18655 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
18656 et = neon_check_type (2, rs, N_EQK | N_UNS,
18657 N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
18658 }
18659
5287ad62
JB
18660 int imm = inst.operands[2].imm;
18661 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 18662 _("immediate out of range for shift"));
5287ad62
JB
18663 /* Only encodes the 'U present' variant of the instruction.
18664 In this case, signed types have OP (bit 8) set to 0.
18665 Unsigned types have OP set to 1. */
18666 inst.instruction |= (et.type == NT_unsigned) << 8;
18667 /* The rest of the bits are the same as other immediate shifts. */
037e8744 18668 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
18669}
18670
18671static void
18672do_neon_qmovn (void)
18673{
18674 struct neon_type_el et = neon_check_type (2, NS_DQ,
18675 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
18676 /* Saturating move where operands can be signed or unsigned, and the
18677 destination has the same signedness. */
88714cb8 18678 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18679 if (et.type == NT_unsigned)
18680 inst.instruction |= 0xc0;
18681 else
18682 inst.instruction |= 0x80;
18683 neon_two_same (0, 1, et.size / 2);
18684}
18685
18686static void
18687do_neon_qmovun (void)
18688{
18689 struct neon_type_el et = neon_check_type (2, NS_DQ,
18690 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
18691 /* Saturating move with unsigned results. Operands must be signed. */
88714cb8 18692 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18693 neon_two_same (0, 1, et.size / 2);
18694}
18695
18696static void
18697do_neon_rshift_sat_narrow (void)
18698{
18699 /* FIXME: Types for narrowing. If operands are signed, results can be signed
18700 or unsigned. If operands are unsigned, results must also be unsigned. */
18701 struct neon_type_el et = neon_check_type (2, NS_DQI,
18702 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
18703 int imm = inst.operands[2].imm;
18704 /* This gets the bounds check, size encoding and immediate bits calculation
18705 right. */
18706 et.size /= 2;
5f4273c7 18707
5287ad62
JB
18708 /* VQ{R}SHRN.I<size> <Dd>, <Qm>, #0 is a synonym for
18709 VQMOVN.I<size> <Dd>, <Qm>. */
18710 if (imm == 0)
18711 {
18712 inst.operands[2].present = 0;
18713 inst.instruction = N_MNEM_vqmovn;
18714 do_neon_qmovn ();
18715 return;
18716 }
5f4273c7 18717
5287ad62 18718 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18719 _("immediate out of range"));
5287ad62
JB
18720 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, et.size - imm);
18721}
18722
18723static void
18724do_neon_rshift_sat_narrow_u (void)
18725{
18726 /* FIXME: Types for narrowing. If operands are signed, results can be signed
18727 or unsigned. If operands are unsigned, results must also be unsigned. */
18728 struct neon_type_el et = neon_check_type (2, NS_DQI,
18729 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
18730 int imm = inst.operands[2].imm;
18731 /* This gets the bounds check, size encoding and immediate bits calculation
18732 right. */
18733 et.size /= 2;
18734
18735 /* VQSHRUN.I<size> <Dd>, <Qm>, #0 is a synonym for
18736 VQMOVUN.I<size> <Dd>, <Qm>. */
18737 if (imm == 0)
18738 {
18739 inst.operands[2].present = 0;
18740 inst.instruction = N_MNEM_vqmovun;
18741 do_neon_qmovun ();
18742 return;
18743 }
18744
18745 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18746 _("immediate out of range"));
5287ad62
JB
18747 /* FIXME: The manual is kind of unclear about what value U should have in
18748 VQ{R}SHRUN instructions, but U=0, op=0 definitely encodes VRSHR, so it
18749 must be 1. */
18750 neon_imm_shift (TRUE, 1, 0, et, et.size - imm);
18751}
18752
18753static void
18754do_neon_movn (void)
18755{
18756 struct neon_type_el et = neon_check_type (2, NS_DQ,
18757 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
88714cb8 18758 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18759 neon_two_same (0, 1, et.size / 2);
18760}
18761
18762static void
18763do_neon_rshift_narrow (void)
18764{
18765 struct neon_type_el et = neon_check_type (2, NS_DQI,
18766 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
18767 int imm = inst.operands[2].imm;
18768 /* This gets the bounds check, size encoding and immediate bits calculation
18769 right. */
18770 et.size /= 2;
5f4273c7 18771
5287ad62
JB
18772 /* If immediate is zero then we are a pseudo-instruction for
18773 VMOVN.I<size> <Dd>, <Qm> */
18774 if (imm == 0)
18775 {
18776 inst.operands[2].present = 0;
18777 inst.instruction = N_MNEM_vmovn;
18778 do_neon_movn ();
18779 return;
18780 }
5f4273c7 18781
5287ad62 18782 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 18783 _("immediate out of range for narrowing operation"));
5287ad62
JB
18784 neon_imm_shift (FALSE, 0, 0, et, et.size - imm);
18785}
18786
18787static void
18788do_neon_shll (void)
18789{
18790 /* FIXME: Type checking when lengthening. */
18791 struct neon_type_el et = neon_check_type (2, NS_QDI,
18792 N_EQK | N_DBL, N_I8 | N_I16 | N_I32 | N_KEY);
18793 unsigned imm = inst.operands[2].imm;
18794
18795 if (imm == et.size)
18796 {
18797 /* Maximum shift variant. */
88714cb8 18798 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18799 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18800 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18801 inst.instruction |= LOW4 (inst.operands[1].reg);
18802 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18803 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 18804
88714cb8 18805 neon_dp_fixup (&inst);
5287ad62
JB
18806 }
18807 else
18808 {
18809 /* A more-specific type check for non-max versions. */
18810 et = neon_check_type (2, NS_QDI,
477330fc 18811 N_EQK | N_DBL, N_SU_32 | N_KEY);
88714cb8 18812 NEON_ENCODE (IMMED, inst);
5287ad62
JB
18813 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, imm);
18814 }
18815}
18816
037e8744 18817/* Check the various types for the VCVT instruction, and return which version
5287ad62
JB
18818 the current instruction is. */
18819
6b9a8b67
MGD
18820#define CVT_FLAVOUR_VAR \
18821 CVT_VAR (s32_f32, N_S32, N_F32, whole_reg, "ftosls", "ftosis", "ftosizs") \
18822 CVT_VAR (u32_f32, N_U32, N_F32, whole_reg, "ftouls", "ftouis", "ftouizs") \
18823 CVT_VAR (f32_s32, N_F32, N_S32, whole_reg, "fsltos", "fsitos", NULL) \
18824 CVT_VAR (f32_u32, N_F32, N_U32, whole_reg, "fultos", "fuitos", NULL) \
18825 /* Half-precision conversions. */ \
cc933301
JW
18826 CVT_VAR (s16_f16, N_S16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
18827 CVT_VAR (u16_f16, N_U16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
18828 CVT_VAR (f16_s16, N_F16 | N_KEY, N_S16, whole_reg, NULL, NULL, NULL) \
18829 CVT_VAR (f16_u16, N_F16 | N_KEY, N_U16, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
18830 CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
18831 CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
9db2f6b4
RL
18832 /* New VCVT instructions introduced by ARMv8.2 fp16 extension. \
18833 Compared with single/double precision variants, only the co-processor \
18834 field is different, so the encoding flow is reused here. */ \
18835 CVT_VAR (f16_s32, N_F16 | N_KEY, N_S32, N_VFP, "fsltos", "fsitos", NULL) \
18836 CVT_VAR (f16_u32, N_F16 | N_KEY, N_U32, N_VFP, "fultos", "fuitos", NULL) \
18837 CVT_VAR (u32_f16, N_U32, N_F16 | N_KEY, N_VFP, "ftouls", "ftouis", "ftouizs")\
18838 CVT_VAR (s32_f16, N_S32, N_F16 | N_KEY, N_VFP, "ftosls", "ftosis", "ftosizs")\
aab2c27d 18839 CVT_VAR (bf16_f32, N_BF16, N_F32, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
18840 /* VFP instructions. */ \
18841 CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
18842 CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
18843 CVT_VAR (s32_f64, N_S32, N_F64 | key, N_VFP, "ftosld", "ftosid", "ftosizd") \
18844 CVT_VAR (u32_f64, N_U32, N_F64 | key, N_VFP, "ftould", "ftouid", "ftouizd") \
18845 CVT_VAR (f64_s32, N_F64 | key, N_S32, N_VFP, "fsltod", "fsitod", NULL) \
18846 CVT_VAR (f64_u32, N_F64 | key, N_U32, N_VFP, "fultod", "fuitod", NULL) \
18847 /* VFP instructions with bitshift. */ \
18848 CVT_VAR (f32_s16, N_F32 | key, N_S16, N_VFP, "fshtos", NULL, NULL) \
18849 CVT_VAR (f32_u16, N_F32 | key, N_U16, N_VFP, "fuhtos", NULL, NULL) \
18850 CVT_VAR (f64_s16, N_F64 | key, N_S16, N_VFP, "fshtod", NULL, NULL) \
18851 CVT_VAR (f64_u16, N_F64 | key, N_U16, N_VFP, "fuhtod", NULL, NULL) \
18852 CVT_VAR (s16_f32, N_S16, N_F32 | key, N_VFP, "ftoshs", NULL, NULL) \
18853 CVT_VAR (u16_f32, N_U16, N_F32 | key, N_VFP, "ftouhs", NULL, NULL) \
18854 CVT_VAR (s16_f64, N_S16, N_F64 | key, N_VFP, "ftoshd", NULL, NULL) \
18855 CVT_VAR (u16_f64, N_U16, N_F64 | key, N_VFP, "ftouhd", NULL, NULL)
18856
18857#define CVT_VAR(C, X, Y, R, BSN, CN, ZN) \
18858 neon_cvt_flavour_##C,
18859
18860/* The different types of conversions we can do. */
18861enum neon_cvt_flavour
18862{
18863 CVT_FLAVOUR_VAR
18864 neon_cvt_flavour_invalid,
18865 neon_cvt_flavour_first_fp = neon_cvt_flavour_f32_f64
18866};
18867
18868#undef CVT_VAR
18869
18870static enum neon_cvt_flavour
18871get_neon_cvt_flavour (enum neon_shape rs)
5287ad62 18872{
6b9a8b67
MGD
18873#define CVT_VAR(C,X,Y,R,BSN,CN,ZN) \
18874 et = neon_check_type (2, rs, (R) | (X), (R) | (Y)); \
18875 if (et.type != NT_invtype) \
18876 { \
18877 inst.error = NULL; \
18878 return (neon_cvt_flavour_##C); \
5287ad62 18879 }
6b9a8b67 18880
5287ad62 18881 struct neon_type_el et;
037e8744 18882 unsigned whole_reg = (rs == NS_FFI || rs == NS_FD || rs == NS_DF
477330fc 18883 || rs == NS_FF) ? N_VFP : 0;
037e8744
JB
18884 /* The instruction versions which take an immediate take one register
18885 argument, which is extended to the width of the full register. Thus the
18886 "source" and "destination" registers must have the same width. Hack that
18887 here by making the size equal to the key (wider, in this case) operand. */
18888 unsigned key = (rs == NS_QQI || rs == NS_DDI || rs == NS_FFI) ? N_KEY : 0;
5f4273c7 18889
6b9a8b67
MGD
18890 CVT_FLAVOUR_VAR;
18891
18892 return neon_cvt_flavour_invalid;
5287ad62
JB
18893#undef CVT_VAR
18894}
18895
7e8e6784
MGD
18896enum neon_cvt_mode
18897{
18898 neon_cvt_mode_a,
18899 neon_cvt_mode_n,
18900 neon_cvt_mode_p,
18901 neon_cvt_mode_m,
18902 neon_cvt_mode_z,
30bdf752
MGD
18903 neon_cvt_mode_x,
18904 neon_cvt_mode_r
7e8e6784
MGD
18905};
18906
037e8744
JB
18907/* Neon-syntax VFP conversions. */
18908
5287ad62 18909static void
6b9a8b67 18910do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
5287ad62 18911{
037e8744 18912 const char *opname = 0;
5f4273c7 18913
d54af2d0
RL
18914 if (rs == NS_DDI || rs == NS_QQI || rs == NS_FFI
18915 || rs == NS_FHI || rs == NS_HFI)
5287ad62 18916 {
037e8744
JB
18917 /* Conversions with immediate bitshift. */
18918 const char *enc[] =
477330fc 18919 {
6b9a8b67
MGD
18920#define CVT_VAR(C,A,B,R,BSN,CN,ZN) BSN,
18921 CVT_FLAVOUR_VAR
18922 NULL
18923#undef CVT_VAR
477330fc 18924 };
037e8744 18925
6b9a8b67 18926 if (flavour < (int) ARRAY_SIZE (enc))
477330fc
RM
18927 {
18928 opname = enc[flavour];
18929 constraint (inst.operands[0].reg != inst.operands[1].reg,
18930 _("operands 0 and 1 must be the same register"));
18931 inst.operands[1] = inst.operands[2];
18932 memset (&inst.operands[2], '\0', sizeof (inst.operands[2]));
18933 }
5287ad62
JB
18934 }
18935 else
18936 {
037e8744
JB
18937 /* Conversions without bitshift. */
18938 const char *enc[] =
477330fc 18939 {
6b9a8b67
MGD
18940#define CVT_VAR(C,A,B,R,BSN,CN,ZN) CN,
18941 CVT_FLAVOUR_VAR
18942 NULL
18943#undef CVT_VAR
477330fc 18944 };
037e8744 18945
6b9a8b67 18946 if (flavour < (int) ARRAY_SIZE (enc))
477330fc 18947 opname = enc[flavour];
037e8744
JB
18948 }
18949
18950 if (opname)
18951 do_vfp_nsyn_opcode (opname);
9db2f6b4
RL
18952
18953 /* ARMv8.2 fp16 VCVT instruction. */
18954 if (flavour == neon_cvt_flavour_s32_f16
18955 || flavour == neon_cvt_flavour_u32_f16
18956 || flavour == neon_cvt_flavour_f16_u32
18957 || flavour == neon_cvt_flavour_f16_s32)
18958 do_scalar_fp16_v82_encode ();
037e8744
JB
18959}
18960
18961static void
18962do_vfp_nsyn_cvtz (void)
18963{
d54af2d0 18964 enum neon_shape rs = neon_select_shape (NS_FH, NS_FF, NS_FD, NS_NULL);
6b9a8b67 18965 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744
JB
18966 const char *enc[] =
18967 {
6b9a8b67
MGD
18968#define CVT_VAR(C,A,B,R,BSN,CN,ZN) ZN,
18969 CVT_FLAVOUR_VAR
18970 NULL
18971#undef CVT_VAR
037e8744
JB
18972 };
18973
6b9a8b67 18974 if (flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
037e8744
JB
18975 do_vfp_nsyn_opcode (enc[flavour]);
18976}
f31fef98 18977
037e8744 18978static void
bacebabc 18979do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
7e8e6784
MGD
18980 enum neon_cvt_mode mode)
18981{
18982 int sz, op;
18983 int rm;
18984
a715796b
TG
18985 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
18986 D register operands. */
18987 if (flavour == neon_cvt_flavour_s32_f64
18988 || flavour == neon_cvt_flavour_u32_f64)
18989 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18990 _(BAD_FPU));
18991
9db2f6b4
RL
18992 if (flavour == neon_cvt_flavour_s32_f16
18993 || flavour == neon_cvt_flavour_u32_f16)
18994 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
18995 _(BAD_FP16));
18996
5ee91343 18997 set_pred_insn_type (OUTSIDE_PRED_INSN);
7e8e6784
MGD
18998
18999 switch (flavour)
19000 {
19001 case neon_cvt_flavour_s32_f64:
19002 sz = 1;
827f64ff 19003 op = 1;
7e8e6784
MGD
19004 break;
19005 case neon_cvt_flavour_s32_f32:
19006 sz = 0;
19007 op = 1;
19008 break;
9db2f6b4
RL
19009 case neon_cvt_flavour_s32_f16:
19010 sz = 0;
19011 op = 1;
19012 break;
7e8e6784
MGD
19013 case neon_cvt_flavour_u32_f64:
19014 sz = 1;
19015 op = 0;
19016 break;
19017 case neon_cvt_flavour_u32_f32:
19018 sz = 0;
19019 op = 0;
19020 break;
9db2f6b4
RL
19021 case neon_cvt_flavour_u32_f16:
19022 sz = 0;
19023 op = 0;
19024 break;
7e8e6784
MGD
19025 default:
19026 first_error (_("invalid instruction shape"));
19027 return;
19028 }
19029
19030 switch (mode)
19031 {
19032 case neon_cvt_mode_a: rm = 0; break;
19033 case neon_cvt_mode_n: rm = 1; break;
19034 case neon_cvt_mode_p: rm = 2; break;
19035 case neon_cvt_mode_m: rm = 3; break;
19036 default: first_error (_("invalid rounding mode")); return;
19037 }
19038
19039 NEON_ENCODE (FPV8, inst);
19040 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
19041 encode_arm_vfp_reg (inst.operands[1].reg, sz == 1 ? VFP_REG_Dm : VFP_REG_Sm);
19042 inst.instruction |= sz << 8;
9db2f6b4
RL
19043
19044 /* ARMv8.2 fp16 VCVT instruction. */
19045 if (flavour == neon_cvt_flavour_s32_f16
19046 ||flavour == neon_cvt_flavour_u32_f16)
19047 do_scalar_fp16_v82_encode ();
7e8e6784
MGD
19048 inst.instruction |= op << 7;
19049 inst.instruction |= rm << 16;
19050 inst.instruction |= 0xf0000000;
19051 inst.is_neon = TRUE;
19052}
19053
19054static void
19055do_neon_cvt_1 (enum neon_cvt_mode mode)
037e8744
JB
19056{
19057 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
d54af2d0
RL
19058 NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ,
19059 NS_FH, NS_HF, NS_FHI, NS_HFI,
19060 NS_NULL);
6b9a8b67 19061 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744 19062
cc933301
JW
19063 if (flavour == neon_cvt_flavour_invalid)
19064 return;
19065
e3e535bc 19066 /* PR11109: Handle round-to-zero for VCVT conversions. */
7e8e6784 19067 if (mode == neon_cvt_mode_z
e3e535bc 19068 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
cc933301
JW
19069 && (flavour == neon_cvt_flavour_s16_f16
19070 || flavour == neon_cvt_flavour_u16_f16
19071 || flavour == neon_cvt_flavour_s32_f32
bacebabc
RM
19072 || flavour == neon_cvt_flavour_u32_f32
19073 || flavour == neon_cvt_flavour_s32_f64
6b9a8b67 19074 || flavour == neon_cvt_flavour_u32_f64)
e3e535bc
NC
19075 && (rs == NS_FD || rs == NS_FF))
19076 {
19077 do_vfp_nsyn_cvtz ();
19078 return;
19079 }
19080
9db2f6b4
RL
19081 /* ARMv8.2 fp16 VCVT conversions. */
19082 if (mode == neon_cvt_mode_z
19083 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16)
19084 && (flavour == neon_cvt_flavour_s32_f16
19085 || flavour == neon_cvt_flavour_u32_f16)
19086 && (rs == NS_FH))
19087 {
19088 do_vfp_nsyn_cvtz ();
19089 do_scalar_fp16_v82_encode ();
19090 return;
19091 }
19092
037e8744 19093 /* VFP rather than Neon conversions. */
6b9a8b67 19094 if (flavour >= neon_cvt_flavour_first_fp)
037e8744 19095 {
7e8e6784
MGD
19096 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
19097 do_vfp_nsyn_cvt (rs, flavour);
19098 else
19099 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
19100
037e8744
JB
19101 return;
19102 }
19103
19104 switch (rs)
19105 {
037e8744 19106 case NS_QQI:
dd9634d9
AV
19107 if (mode == neon_cvt_mode_z
19108 && (flavour == neon_cvt_flavour_f16_s16
19109 || flavour == neon_cvt_flavour_f16_u16
19110 || flavour == neon_cvt_flavour_s16_f16
19111 || flavour == neon_cvt_flavour_u16_f16
19112 || flavour == neon_cvt_flavour_f32_u32
19113 || flavour == neon_cvt_flavour_f32_s32
19114 || flavour == neon_cvt_flavour_s32_f32
19115 || flavour == neon_cvt_flavour_u32_f32))
19116 {
64c350f2
AV
19117 if (!check_simd_pred_availability (TRUE,
19118 NEON_CHECK_CC | NEON_CHECK_ARCH))
dd9634d9
AV
19119 return;
19120 }
19121 else if (mode == neon_cvt_mode_n)
19122 {
19123 /* We are dealing with vcvt with the 'ne' condition. */
19124 inst.cond = 0x1;
19125 inst.instruction = N_MNEM_vcvt;
19126 do_neon_cvt_1 (neon_cvt_mode_z);
19127 return;
19128 }
19129 /* fall through. */
19130 case NS_DDI:
037e8744 19131 {
477330fc 19132 unsigned immbits;
cc933301
JW
19133 unsigned enctab[] = {0x0000100, 0x1000100, 0x0, 0x1000000,
19134 0x0000100, 0x1000100, 0x0, 0x1000000};
35997600 19135
dd9634d9
AV
19136 if ((rs != NS_QQI || !ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19137 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19138 return;
19139
19140 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19141 {
19142 constraint (inst.operands[2].present && inst.operands[2].imm == 0,
19143 _("immediate value out of range"));
19144 switch (flavour)
19145 {
19146 case neon_cvt_flavour_f16_s16:
19147 case neon_cvt_flavour_f16_u16:
19148 case neon_cvt_flavour_s16_f16:
19149 case neon_cvt_flavour_u16_f16:
19150 constraint (inst.operands[2].imm > 16,
19151 _("immediate value out of range"));
19152 break;
19153 case neon_cvt_flavour_f32_u32:
19154 case neon_cvt_flavour_f32_s32:
19155 case neon_cvt_flavour_s32_f32:
19156 case neon_cvt_flavour_u32_f32:
19157 constraint (inst.operands[2].imm > 32,
19158 _("immediate value out of range"));
19159 break;
19160 default:
19161 inst.error = BAD_FPU;
19162 return;
19163 }
19164 }
037e8744 19165
477330fc
RM
19166 /* Fixed-point conversion with #0 immediate is encoded as an
19167 integer conversion. */
19168 if (inst.operands[2].present && inst.operands[2].imm == 0)
19169 goto int_encode;
477330fc
RM
19170 NEON_ENCODE (IMMED, inst);
19171 if (flavour != neon_cvt_flavour_invalid)
19172 inst.instruction |= enctab[flavour];
19173 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19174 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19175 inst.instruction |= LOW4 (inst.operands[1].reg);
19176 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19177 inst.instruction |= neon_quad (rs) << 6;
19178 inst.instruction |= 1 << 21;
cc933301
JW
19179 if (flavour < neon_cvt_flavour_s16_f16)
19180 {
19181 inst.instruction |= 1 << 21;
19182 immbits = 32 - inst.operands[2].imm;
19183 inst.instruction |= immbits << 16;
19184 }
19185 else
19186 {
19187 inst.instruction |= 3 << 20;
19188 immbits = 16 - inst.operands[2].imm;
19189 inst.instruction |= immbits << 16;
19190 inst.instruction &= ~(1 << 9);
19191 }
477330fc
RM
19192
19193 neon_dp_fixup (&inst);
037e8744
JB
19194 }
19195 break;
19196
037e8744 19197 case NS_QQ:
dd9634d9
AV
19198 if ((mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
19199 || mode == neon_cvt_mode_m || mode == neon_cvt_mode_p)
19200 && (flavour == neon_cvt_flavour_s16_f16
19201 || flavour == neon_cvt_flavour_u16_f16
19202 || flavour == neon_cvt_flavour_s32_f32
19203 || flavour == neon_cvt_flavour_u32_f32))
19204 {
64c350f2
AV
19205 if (!check_simd_pred_availability (TRUE,
19206 NEON_CHECK_CC | NEON_CHECK_ARCH8))
dd9634d9
AV
19207 return;
19208 }
19209 else if (mode == neon_cvt_mode_z
19210 && (flavour == neon_cvt_flavour_f16_s16
19211 || flavour == neon_cvt_flavour_f16_u16
19212 || flavour == neon_cvt_flavour_s16_f16
19213 || flavour == neon_cvt_flavour_u16_f16
19214 || flavour == neon_cvt_flavour_f32_u32
19215 || flavour == neon_cvt_flavour_f32_s32
19216 || flavour == neon_cvt_flavour_s32_f32
19217 || flavour == neon_cvt_flavour_u32_f32))
19218 {
64c350f2
AV
19219 if (!check_simd_pred_availability (TRUE,
19220 NEON_CHECK_CC | NEON_CHECK_ARCH))
dd9634d9
AV
19221 return;
19222 }
19223 /* fall through. */
19224 case NS_DD:
7e8e6784
MGD
19225 if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
19226 {
7e8e6784 19227
dd9634d9 19228 NEON_ENCODE (FLOAT, inst);
64c350f2
AV
19229 if (!check_simd_pred_availability (TRUE,
19230 NEON_CHECK_CC | NEON_CHECK_ARCH8))
7e8e6784
MGD
19231 return;
19232
19233 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19234 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19235 inst.instruction |= LOW4 (inst.operands[1].reg);
19236 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19237 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
19238 inst.instruction |= (flavour == neon_cvt_flavour_u16_f16
19239 || flavour == neon_cvt_flavour_u32_f32) << 7;
7e8e6784 19240 inst.instruction |= mode << 8;
cc933301
JW
19241 if (flavour == neon_cvt_flavour_u16_f16
19242 || flavour == neon_cvt_flavour_s16_f16)
19243 /* Mask off the original size bits and reencode them. */
19244 inst.instruction = ((inst.instruction & 0xfff3ffff) | (1 << 18));
19245
7e8e6784
MGD
19246 if (thumb_mode)
19247 inst.instruction |= 0xfc000000;
19248 else
19249 inst.instruction |= 0xf0000000;
19250 }
19251 else
19252 {
037e8744 19253 int_encode:
7e8e6784 19254 {
cc933301
JW
19255 unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080,
19256 0x100, 0x180, 0x0, 0x080};
037e8744 19257
7e8e6784 19258 NEON_ENCODE (INTEGER, inst);
037e8744 19259
dd9634d9
AV
19260 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
19261 {
19262 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19263 return;
19264 }
037e8744 19265
7e8e6784
MGD
19266 if (flavour != neon_cvt_flavour_invalid)
19267 inst.instruction |= enctab[flavour];
037e8744 19268
7e8e6784
MGD
19269 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19270 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19271 inst.instruction |= LOW4 (inst.operands[1].reg);
19272 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19273 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
19274 if (flavour >= neon_cvt_flavour_s16_f16
19275 && flavour <= neon_cvt_flavour_f16_u16)
19276 /* Half precision. */
19277 inst.instruction |= 1 << 18;
19278 else
19279 inst.instruction |= 2 << 18;
037e8744 19280
7e8e6784
MGD
19281 neon_dp_fixup (&inst);
19282 }
19283 }
19284 break;
037e8744 19285
8e79c3df
CM
19286 /* Half-precision conversions for Advanced SIMD -- neon. */
19287 case NS_QD:
19288 case NS_DQ:
bc52d49c
MM
19289 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
19290 return;
8e79c3df
CM
19291
19292 if ((rs == NS_DQ)
19293 && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
19294 {
19295 as_bad (_("operand size must match register width"));
19296 break;
19297 }
19298
19299 if ((rs == NS_QD)
19300 && ((inst.vectype.el[0].size != 32 || inst.vectype.el[1].size != 16)))
19301 {
19302 as_bad (_("operand size must match register width"));
19303 break;
19304 }
19305
19306 if (rs == NS_DQ)
aab2c27d
MM
19307 {
19308 if (flavour == neon_cvt_flavour_bf16_f32)
19309 {
19310 if (vfp_or_neon_is_neon (NEON_CHECK_ARCH8) == FAIL)
19311 return;
19312 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
19313 /* VCVT.bf16.f32. */
19314 inst.instruction = 0x11b60640;
19315 }
19316 else
19317 /* VCVT.f16.f32. */
19318 inst.instruction = 0x3b60600;
19319 }
8e79c3df 19320 else
aab2c27d 19321 /* VCVT.f32.f16. */
8e79c3df
CM
19322 inst.instruction = 0x3b60700;
19323
19324 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19325 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19326 inst.instruction |= LOW4 (inst.operands[1].reg);
19327 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
88714cb8 19328 neon_dp_fixup (&inst);
8e79c3df
CM
19329 break;
19330
037e8744
JB
19331 default:
19332 /* Some VFP conversions go here (s32 <-> f32, u32 <-> f32). */
7e8e6784
MGD
19333 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
19334 do_vfp_nsyn_cvt (rs, flavour);
19335 else
19336 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
5287ad62 19337 }
5287ad62
JB
19338}
19339
e3e535bc
NC
19340static void
19341do_neon_cvtr (void)
19342{
7e8e6784 19343 do_neon_cvt_1 (neon_cvt_mode_x);
e3e535bc
NC
19344}
19345
19346static void
19347do_neon_cvt (void)
19348{
7e8e6784
MGD
19349 do_neon_cvt_1 (neon_cvt_mode_z);
19350}
19351
19352static void
19353do_neon_cvta (void)
19354{
19355 do_neon_cvt_1 (neon_cvt_mode_a);
19356}
19357
19358static void
19359do_neon_cvtn (void)
19360{
19361 do_neon_cvt_1 (neon_cvt_mode_n);
19362}
19363
19364static void
19365do_neon_cvtp (void)
19366{
19367 do_neon_cvt_1 (neon_cvt_mode_p);
19368}
19369
19370static void
19371do_neon_cvtm (void)
19372{
19373 do_neon_cvt_1 (neon_cvt_mode_m);
e3e535bc
NC
19374}
19375
8e79c3df 19376static void
c70a8987 19377do_neon_cvttb_2 (bfd_boolean t, bfd_boolean to, bfd_boolean is_double)
8e79c3df 19378{
c70a8987
MGD
19379 if (is_double)
19380 mark_feature_used (&fpu_vfp_ext_armv8);
8e79c3df 19381
c70a8987
MGD
19382 encode_arm_vfp_reg (inst.operands[0].reg,
19383 (is_double && !to) ? VFP_REG_Dd : VFP_REG_Sd);
19384 encode_arm_vfp_reg (inst.operands[1].reg,
19385 (is_double && to) ? VFP_REG_Dm : VFP_REG_Sm);
19386 inst.instruction |= to ? 0x10000 : 0;
19387 inst.instruction |= t ? 0x80 : 0;
19388 inst.instruction |= is_double ? 0x100 : 0;
19389 do_vfp_cond_or_thumb ();
19390}
8e79c3df 19391
c70a8987
MGD
19392static void
19393do_neon_cvttb_1 (bfd_boolean t)
19394{
d54af2d0 19395 enum neon_shape rs = neon_select_shape (NS_HF, NS_HD, NS_FH, NS_FF, NS_FD,
dd9634d9 19396 NS_DF, NS_DH, NS_QQ, NS_QQI, NS_NULL);
8e79c3df 19397
c70a8987
MGD
19398 if (rs == NS_NULL)
19399 return;
dd9634d9
AV
19400 else if (rs == NS_QQ || rs == NS_QQI)
19401 {
19402 int single_to_half = 0;
64c350f2 19403 if (!check_simd_pred_availability (TRUE, NEON_CHECK_ARCH))
dd9634d9
AV
19404 return;
19405
19406 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
19407
19408 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19409 && (flavour == neon_cvt_flavour_u16_f16
19410 || flavour == neon_cvt_flavour_s16_f16
19411 || flavour == neon_cvt_flavour_f16_s16
19412 || flavour == neon_cvt_flavour_f16_u16
19413 || flavour == neon_cvt_flavour_u32_f32
19414 || flavour == neon_cvt_flavour_s32_f32
19415 || flavour == neon_cvt_flavour_f32_s32
19416 || flavour == neon_cvt_flavour_f32_u32))
19417 {
19418 inst.cond = 0xf;
19419 inst.instruction = N_MNEM_vcvt;
19420 set_pred_insn_type (INSIDE_VPT_INSN);
19421 do_neon_cvt_1 (neon_cvt_mode_z);
19422 return;
19423 }
19424 else if (rs == NS_QQ && flavour == neon_cvt_flavour_f32_f16)
19425 single_to_half = 1;
19426 else if (rs == NS_QQ && flavour != neon_cvt_flavour_f16_f32)
19427 {
19428 first_error (BAD_FPU);
19429 return;
19430 }
19431
19432 inst.instruction = 0xee3f0e01;
19433 inst.instruction |= single_to_half << 28;
19434 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19435 inst.instruction |= LOW4 (inst.operands[0].reg) << 13;
19436 inst.instruction |= t << 12;
19437 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19438 inst.instruction |= LOW4 (inst.operands[1].reg) << 1;
19439 inst.is_neon = 1;
19440 }
c70a8987
MGD
19441 else if (neon_check_type (2, rs, N_F16, N_F32 | N_VFP).type != NT_invtype)
19442 {
19443 inst.error = NULL;
19444 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/FALSE);
19445 }
19446 else if (neon_check_type (2, rs, N_F32 | N_VFP, N_F16).type != NT_invtype)
19447 {
19448 inst.error = NULL;
19449 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/FALSE);
19450 }
19451 else if (neon_check_type (2, rs, N_F16, N_F64 | N_VFP).type != NT_invtype)
19452 {
a715796b
TG
19453 /* The VCVTB and VCVTT instructions with D-register operands
19454 don't work for SP only targets. */
19455 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19456 _(BAD_FPU));
19457
c70a8987
MGD
19458 inst.error = NULL;
19459 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/TRUE);
19460 }
19461 else if (neon_check_type (2, rs, N_F64 | N_VFP, N_F16).type != NT_invtype)
19462 {
a715796b
TG
19463 /* The VCVTB and VCVTT instructions with D-register operands
19464 don't work for SP only targets. */
19465 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19466 _(BAD_FPU));
19467
c70a8987
MGD
19468 inst.error = NULL;
19469 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/TRUE);
19470 }
aab2c27d
MM
19471 else if (neon_check_type (2, rs, N_BF16 | N_VFP, N_F32).type != NT_invtype)
19472 {
19473 constraint (!mark_feature_used (&arm_ext_bf16), _(BAD_BF16));
19474 inst.error = NULL;
19475 inst.instruction |= (1 << 8);
19476 inst.instruction &= ~(1 << 9);
19477 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/FALSE);
19478 }
c70a8987
MGD
19479 else
19480 return;
19481}
19482
19483static void
19484do_neon_cvtb (void)
19485{
19486 do_neon_cvttb_1 (FALSE);
8e79c3df
CM
19487}
19488
19489
19490static void
19491do_neon_cvtt (void)
19492{
c70a8987 19493 do_neon_cvttb_1 (TRUE);
8e79c3df
CM
19494}
19495
5287ad62
JB
19496static void
19497neon_move_immediate (void)
19498{
037e8744
JB
19499 enum neon_shape rs = neon_select_shape (NS_DI, NS_QI, NS_NULL);
19500 struct neon_type_el et = neon_check_type (2, rs,
19501 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
5287ad62 19502 unsigned immlo, immhi = 0, immbits;
c96612cc 19503 int op, cmode, float_p;
5287ad62 19504
037e8744 19505 constraint (et.type == NT_invtype,
477330fc 19506 _("operand size must be specified for immediate VMOV"));
037e8744 19507
5287ad62
JB
19508 /* We start out as an MVN instruction if OP = 1, MOV otherwise. */
19509 op = (inst.instruction & (1 << 5)) != 0;
19510
19511 immlo = inst.operands[1].imm;
19512 if (inst.operands[1].regisimm)
19513 immhi = inst.operands[1].reg;
19514
19515 constraint (et.size < 32 && (immlo & ~((1 << et.size) - 1)) != 0,
477330fc 19516 _("immediate has bits set outside the operand size"));
5287ad62 19517
c96612cc
JB
19518 float_p = inst.operands[1].immisfloat;
19519
19520 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits, &op,
477330fc 19521 et.size, et.type)) == FAIL)
5287ad62
JB
19522 {
19523 /* Invert relevant bits only. */
19524 neon_invert_size (&immlo, &immhi, et.size);
19525 /* Flip from VMOV/VMVN to VMVN/VMOV. Some immediate types are unavailable
477330fc
RM
19526 with one or the other; those cases are caught by
19527 neon_cmode_for_move_imm. */
5287ad62 19528 op = !op;
c96612cc
JB
19529 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits,
19530 &op, et.size, et.type)) == FAIL)
477330fc
RM
19531 {
19532 first_error (_("immediate out of range"));
19533 return;
19534 }
5287ad62
JB
19535 }
19536
19537 inst.instruction &= ~(1 << 5);
19538 inst.instruction |= op << 5;
19539
19540 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19541 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
037e8744 19542 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
19543 inst.instruction |= cmode << 8;
19544
19545 neon_write_immbits (immbits);
19546}
19547
19548static void
19549do_neon_mvn (void)
19550{
64c350f2 19551 if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
1a186d29
AV
19552 return;
19553
5287ad62
JB
19554 if (inst.operands[1].isreg)
19555 {
1a186d29
AV
19556 enum neon_shape rs;
19557 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19558 rs = neon_select_shape (NS_QQ, NS_NULL);
19559 else
19560 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5f4273c7 19561
88714cb8 19562 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
19563 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19564 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19565 inst.instruction |= LOW4 (inst.operands[1].reg);
19566 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 19567 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
19568 }
19569 else
19570 {
88714cb8 19571 NEON_ENCODE (IMMED, inst);
5287ad62
JB
19572 neon_move_immediate ();
19573 }
19574
88714cb8 19575 neon_dp_fixup (&inst);
1a186d29
AV
19576
19577 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19578 {
19579 constraint (!inst.operands[1].isreg && !inst.operands[0].isquad, BAD_FPU);
1a186d29 19580 }
5287ad62
JB
19581}
19582
19583/* Encode instructions of form:
19584
19585 |28/24|23|22|21 20|19 16|15 12|11 8|7|6|5|4|3 0|
5f4273c7 19586 | U |x |D |size | Rn | Rd |x x x x|N|x|M|x| Rm | */
5287ad62
JB
19587
19588static void
19589neon_mixed_length (struct neon_type_el et, unsigned size)
19590{
19591 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19592 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19593 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19594 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19595 inst.instruction |= LOW4 (inst.operands[2].reg);
19596 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
19597 inst.instruction |= (et.type == NT_unsigned) << 24;
19598 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 19599
88714cb8 19600 neon_dp_fixup (&inst);
5287ad62
JB
19601}
19602
19603static void
19604do_neon_dyadic_long (void)
19605{
66d1f7cc 19606 enum neon_shape rs = neon_select_shape (NS_QDD, NS_HHH, NS_FFF, NS_DDD, NS_NULL);
5ee91343
AV
19607 if (rs == NS_QDD)
19608 {
19609 if (vfp_or_neon_is_neon (NEON_CHECK_ARCH | NEON_CHECK_CC) == FAIL)
19610 return;
19611
19612 NEON_ENCODE (INTEGER, inst);
19613 /* FIXME: Type checking for lengthening op. */
19614 struct neon_type_el et = neon_check_type (3, NS_QDD,
19615 N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
19616 neon_mixed_length (et, et.size);
19617 }
19618 else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19619 && (inst.cond == 0xf || inst.cond == 0x10))
19620 {
19621 /* If parsing for MVE, vaddl/vsubl/vabdl{e,t} can only be vadd/vsub/vabd
19622 in an IT block with le/lt conditions. */
19623
19624 if (inst.cond == 0xf)
19625 inst.cond = 0xb;
19626 else if (inst.cond == 0x10)
19627 inst.cond = 0xd;
19628
19629 inst.pred_insn_type = INSIDE_IT_INSN;
19630
19631 if (inst.instruction == N_MNEM_vaddl)
19632 {
19633 inst.instruction = N_MNEM_vadd;
19634 do_neon_addsub_if_i ();
19635 }
19636 else if (inst.instruction == N_MNEM_vsubl)
19637 {
19638 inst.instruction = N_MNEM_vsub;
19639 do_neon_addsub_if_i ();
19640 }
19641 else if (inst.instruction == N_MNEM_vabdl)
19642 {
19643 inst.instruction = N_MNEM_vabd;
19644 do_neon_dyadic_if_su ();
19645 }
19646 }
19647 else
19648 first_error (BAD_FPU);
5287ad62
JB
19649}
19650
19651static void
19652do_neon_abal (void)
19653{
19654 struct neon_type_el et = neon_check_type (3, NS_QDD,
19655 N_EQK | N_INT | N_DBL, N_EQK, N_SU_32 | N_KEY);
19656 neon_mixed_length (et, et.size);
19657}
19658
19659static void
19660neon_mac_reg_scalar_long (unsigned regtypes, unsigned scalartypes)
19661{
19662 if (inst.operands[2].isscalar)
19663 {
dcbf9037 19664 struct neon_type_el et = neon_check_type (3, NS_QDS,
477330fc 19665 N_EQK | N_DBL, N_EQK, regtypes | N_KEY);
88714cb8 19666 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
19667 neon_mul_mac (et, et.type == NT_unsigned);
19668 }
19669 else
19670 {
19671 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 19672 N_EQK | N_DBL, N_EQK, scalartypes | N_KEY);
88714cb8 19673 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
19674 neon_mixed_length (et, et.size);
19675 }
19676}
19677
19678static void
19679do_neon_mac_maybe_scalar_long (void)
19680{
19681 neon_mac_reg_scalar_long (N_S16 | N_S32 | N_U16 | N_U32, N_SU_32);
19682}
19683
dec41383
JW
19684/* Like neon_scalar_for_mul, this function generate Rm encoding from GAS's
19685 internal SCALAR. QUAD_P is 1 if it's for Q format, otherwise it's 0. */
19686
19687static unsigned
19688neon_scalar_for_fmac_fp16_long (unsigned scalar, unsigned quad_p)
19689{
19690 unsigned regno = NEON_SCALAR_REG (scalar);
19691 unsigned elno = NEON_SCALAR_INDEX (scalar);
19692
19693 if (quad_p)
19694 {
19695 if (regno > 7 || elno > 3)
19696 goto bad_scalar;
19697
19698 return ((regno & 0x7)
19699 | ((elno & 0x1) << 3)
19700 | (((elno >> 1) & 0x1) << 5));
19701 }
19702 else
19703 {
19704 if (regno > 15 || elno > 1)
19705 goto bad_scalar;
19706
19707 return (((regno & 0x1) << 5)
19708 | ((regno >> 1) & 0x7)
19709 | ((elno & 0x1) << 3));
19710 }
19711
dc1e8a47 19712 bad_scalar:
dec41383
JW
19713 first_error (_("scalar out of range for multiply instruction"));
19714 return 0;
19715}
19716
19717static void
19718do_neon_fmac_maybe_scalar_long (int subtype)
19719{
19720 enum neon_shape rs;
19721 int high8;
19722 /* NOTE: vfmal/vfmsl use slightly different NEON three-same encoding. 'size"
19723 field (bits[21:20]) has different meaning. For scalar index variant, it's
19724 used to differentiate add and subtract, otherwise it's with fixed value
19725 0x2. */
19726 int size = -1;
19727
dec41383
JW
19728 /* vfmal/vfmsl are in three-same D/Q register format or the third operand can
19729 be a scalar index register. */
19730 if (inst.operands[2].isscalar)
19731 {
19732 high8 = 0xfe000000;
19733 if (subtype)
19734 size = 16;
19735 rs = neon_select_shape (NS_DHS, NS_QDS, NS_NULL);
19736 }
19737 else
19738 {
19739 high8 = 0xfc000000;
19740 size = 32;
19741 if (subtype)
19742 inst.instruction |= (0x1 << 23);
19743 rs = neon_select_shape (NS_DHH, NS_QDD, NS_NULL);
19744 }
19745
aab2c27d
MM
19746
19747 if (inst.cond != COND_ALWAYS)
19748 as_warn (_("vfmal/vfmsl with FP16 type cannot be conditional, the "
19749 "behaviour is UNPREDICTABLE"));
19750
19751 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16_fml),
19752 _(BAD_FP16));
19753
19754 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
19755 _(BAD_FPU));
dec41383
JW
19756
19757 /* "opcode" from template has included "ubit", so simply pass 0 here. Also,
19758 the "S" bit in size field has been reused to differentiate vfmal and vfmsl,
19759 so we simply pass -1 as size. */
19760 unsigned quad_p = (rs == NS_QDD || rs == NS_QDS);
19761 neon_three_same (quad_p, 0, size);
19762
19763 /* Undo neon_dp_fixup. Redo the high eight bits. */
19764 inst.instruction &= 0x00ffffff;
19765 inst.instruction |= high8;
19766
dec41383
JW
19767 /* Unlike usually NEON three-same, encoding for Vn and Vm will depend on
19768 whether the instruction is in Q form and whether Vm is a scalar indexed
19769 operand. */
19770 if (inst.operands[2].isscalar)
19771 {
19772 unsigned rm
19773 = neon_scalar_for_fmac_fp16_long (inst.operands[2].reg, quad_p);
19774 inst.instruction &= 0xffffffd0;
19775 inst.instruction |= rm;
19776
19777 if (!quad_p)
19778 {
19779 /* Redo Rn as well. */
19780 inst.instruction &= 0xfff0ff7f;
19781 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
19782 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
19783 }
19784 }
19785 else if (!quad_p)
19786 {
19787 /* Redo Rn and Rm. */
19788 inst.instruction &= 0xfff0ff50;
19789 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
19790 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
19791 inst.instruction |= HI4 (inst.operands[2].reg);
19792 inst.instruction |= LOW1 (inst.operands[2].reg) << 5;
19793 }
19794}
19795
19796static void
19797do_neon_vfmal (void)
19798{
19799 return do_neon_fmac_maybe_scalar_long (0);
19800}
19801
19802static void
19803do_neon_vfmsl (void)
19804{
19805 return do_neon_fmac_maybe_scalar_long (1);
19806}
19807
5287ad62
JB
19808static void
19809do_neon_dyadic_wide (void)
19810{
19811 struct neon_type_el et = neon_check_type (3, NS_QQD,
19812 N_EQK | N_DBL, N_EQK | N_DBL, N_SU_32 | N_KEY);
19813 neon_mixed_length (et, et.size);
19814}
19815
19816static void
19817do_neon_dyadic_narrow (void)
19818{
19819 struct neon_type_el et = neon_check_type (3, NS_QDD,
19820 N_EQK | N_DBL, N_EQK, N_I16 | N_I32 | N_I64 | N_KEY);
428e3f1f
PB
19821 /* Operand sign is unimportant, and the U bit is part of the opcode,
19822 so force the operand type to integer. */
19823 et.type = NT_integer;
5287ad62
JB
19824 neon_mixed_length (et, et.size / 2);
19825}
19826
19827static void
19828do_neon_mul_sat_scalar_long (void)
19829{
19830 neon_mac_reg_scalar_long (N_S16 | N_S32, N_S16 | N_S32);
19831}
19832
19833static void
19834do_neon_vmull (void)
19835{
19836 if (inst.operands[2].isscalar)
19837 do_neon_mac_maybe_scalar_long ();
19838 else
19839 {
19840 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 19841 N_EQK | N_DBL, N_EQK, N_SU_32 | N_P8 | N_P64 | N_KEY);
4f51b4bd 19842
5287ad62 19843 if (et.type == NT_poly)
477330fc 19844 NEON_ENCODE (POLY, inst);
5287ad62 19845 else
477330fc 19846 NEON_ENCODE (INTEGER, inst);
4f51b4bd
MGD
19847
19848 /* For polynomial encoding the U bit must be zero, and the size must
19849 be 8 (encoded as 0b00) or, on ARMv8 or later 64 (encoded, non
19850 obviously, as 0b10). */
19851 if (et.size == 64)
19852 {
19853 /* Check we're on the correct architecture. */
19854 if (!mark_feature_used (&fpu_crypto_ext_armv8))
19855 inst.error =
19856 _("Instruction form not available on this architecture.");
19857
19858 et.size = 32;
19859 }
19860
5287ad62
JB
19861 neon_mixed_length (et, et.size);
19862 }
19863}
19864
19865static void
19866do_neon_ext (void)
19867{
037e8744 19868 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
5287ad62
JB
19869 struct neon_type_el et = neon_check_type (3, rs,
19870 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
19871 unsigned imm = (inst.operands[3].imm * et.size) / 8;
35997600
NC
19872
19873 constraint (imm >= (unsigned) (neon_quad (rs) ? 16 : 8),
19874 _("shift out of range"));
5287ad62
JB
19875 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19876 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19877 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19878 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19879 inst.instruction |= LOW4 (inst.operands[2].reg);
19880 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
037e8744 19881 inst.instruction |= neon_quad (rs) << 6;
5287ad62 19882 inst.instruction |= imm << 8;
5f4273c7 19883
88714cb8 19884 neon_dp_fixup (&inst);
5287ad62
JB
19885}
19886
19887static void
19888do_neon_rev (void)
19889{
64c350f2 19890 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
19891 return;
19892
19893 enum neon_shape rs;
19894 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19895 rs = neon_select_shape (NS_QQ, NS_NULL);
19896 else
19897 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
19898
5287ad62
JB
19899 struct neon_type_el et = neon_check_type (2, rs,
19900 N_EQK, N_8 | N_16 | N_32 | N_KEY);
4401c241 19901
5287ad62
JB
19902 unsigned op = (inst.instruction >> 7) & 3;
19903 /* N (width of reversed regions) is encoded as part of the bitmask. We
19904 extract it here to check the elements to be reversed are smaller.
19905 Otherwise we'd get a reserved instruction. */
19906 unsigned elsize = (op == 2) ? 16 : (op == 1) ? 32 : (op == 0) ? 64 : 0;
4401c241
AV
19907
19908 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext) && elsize == 64
19909 && inst.operands[0].reg == inst.operands[1].reg)
19910 as_tsktsk (_("Warning: 64-bit element size and same destination and source"
19911 " operands makes instruction UNPREDICTABLE"));
19912
9c2799c2 19913 gas_assert (elsize != 0);
5287ad62 19914 constraint (et.size >= elsize,
477330fc 19915 _("elements must be smaller than reversal region"));
037e8744 19916 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19917}
19918
19919static void
19920do_neon_dup (void)
19921{
19922 if (inst.operands[1].isscalar)
19923 {
b409bdb6
AV
19924 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
19925 BAD_FPU);
037e8744 19926 enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
dcbf9037 19927 struct neon_type_el et = neon_check_type (2, rs,
477330fc 19928 N_EQK, N_8 | N_16 | N_32 | N_KEY);
5287ad62 19929 unsigned sizebits = et.size >> 3;
dcbf9037 19930 unsigned dm = NEON_SCALAR_REG (inst.operands[1].reg);
5287ad62 19931 int logsize = neon_logbits (et.size);
dcbf9037 19932 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg) << logsize;
037e8744
JB
19933
19934 if (vfp_or_neon_is_neon (NEON_CHECK_CC) == FAIL)
477330fc 19935 return;
037e8744 19936
88714cb8 19937 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
19938 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19939 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19940 inst.instruction |= LOW4 (dm);
19941 inst.instruction |= HI1 (dm) << 5;
037e8744 19942 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
19943 inst.instruction |= x << 17;
19944 inst.instruction |= sizebits << 16;
5f4273c7 19945
88714cb8 19946 neon_dp_fixup (&inst);
5287ad62
JB
19947 }
19948 else
19949 {
037e8744
JB
19950 enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
19951 struct neon_type_el et = neon_check_type (2, rs,
477330fc 19952 N_8 | N_16 | N_32 | N_KEY, N_EQK);
b409bdb6
AV
19953 if (rs == NS_QR)
19954 {
64c350f2 19955 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH))
b409bdb6
AV
19956 return;
19957 }
19958 else
19959 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
19960 BAD_FPU);
19961
19962 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19963 {
19964 if (inst.operands[1].reg == REG_SP)
19965 as_tsktsk (MVE_BAD_SP);
19966 else if (inst.operands[1].reg == REG_PC)
19967 as_tsktsk (MVE_BAD_PC);
19968 }
19969
5287ad62 19970 /* Duplicate ARM register to lanes of vector. */
88714cb8 19971 NEON_ENCODE (ARMREG, inst);
5287ad62 19972 switch (et.size)
477330fc
RM
19973 {
19974 case 8: inst.instruction |= 0x400000; break;
19975 case 16: inst.instruction |= 0x000020; break;
19976 case 32: inst.instruction |= 0x000000; break;
19977 default: break;
19978 }
5287ad62
JB
19979 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
19980 inst.instruction |= LOW4 (inst.operands[0].reg) << 16;
19981 inst.instruction |= HI1 (inst.operands[0].reg) << 7;
037e8744 19982 inst.instruction |= neon_quad (rs) << 21;
5287ad62 19983 /* The encoding for this instruction is identical for the ARM and Thumb
477330fc 19984 variants, except for the condition field. */
037e8744 19985 do_vfp_cond_or_thumb ();
5287ad62
JB
19986 }
19987}
19988
57785aa2
AV
19989static void
19990do_mve_mov (int toQ)
19991{
19992 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19993 return;
19994 if (inst.cond > COND_ALWAYS)
19995 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
19996
19997 unsigned Rt = 0, Rt2 = 1, Q0 = 2, Q1 = 3;
19998 if (toQ)
19999 {
20000 Q0 = 0;
20001 Q1 = 1;
20002 Rt = 2;
20003 Rt2 = 3;
20004 }
20005
20006 constraint (inst.operands[Q0].reg != inst.operands[Q1].reg + 2,
20007 _("Index one must be [2,3] and index two must be two less than"
20008 " index one."));
20009 constraint (inst.operands[Rt].reg == inst.operands[Rt2].reg,
20010 _("General purpose registers may not be the same"));
20011 constraint (inst.operands[Rt].reg == REG_SP
20012 || inst.operands[Rt2].reg == REG_SP,
20013 BAD_SP);
20014 constraint (inst.operands[Rt].reg == REG_PC
20015 || inst.operands[Rt2].reg == REG_PC,
20016 BAD_PC);
20017
20018 inst.instruction = 0xec000f00;
20019 inst.instruction |= HI1 (inst.operands[Q1].reg / 32) << 23;
20020 inst.instruction |= !!toQ << 20;
20021 inst.instruction |= inst.operands[Rt2].reg << 16;
20022 inst.instruction |= LOW4 (inst.operands[Q1].reg / 32) << 13;
20023 inst.instruction |= (inst.operands[Q1].reg % 4) << 4;
20024 inst.instruction |= inst.operands[Rt].reg;
20025}
20026
20027static void
20028do_mve_movn (void)
20029{
20030 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20031 return;
20032
20033 if (inst.cond > COND_ALWAYS)
20034 inst.pred_insn_type = INSIDE_VPT_INSN;
20035 else
20036 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
20037
20038 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_I16 | N_I32
20039 | N_KEY);
20040
20041 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20042 inst.instruction |= (neon_logbits (et.size) - 1) << 18;
20043 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20044 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20045 inst.instruction |= LOW4 (inst.operands[1].reg);
20046 inst.is_neon = 1;
20047
20048}
20049
5287ad62
JB
20050/* VMOV has particularly many variations. It can be one of:
20051 0. VMOV<c><q> <Qd>, <Qm>
20052 1. VMOV<c><q> <Dd>, <Dm>
20053 (Register operations, which are VORR with Rm = Rn.)
20054 2. VMOV<c><q>.<dt> <Qd>, #<imm>
20055 3. VMOV<c><q>.<dt> <Dd>, #<imm>
20056 (Immediate loads.)
20057 4. VMOV<c><q>.<size> <Dn[x]>, <Rd>
20058 (ARM register to scalar.)
20059 5. VMOV<c><q> <Dm>, <Rd>, <Rn>
20060 (Two ARM registers to vector.)
20061 6. VMOV<c><q>.<dt> <Rd>, <Dn[x]>
20062 (Scalar to ARM register.)
20063 7. VMOV<c><q> <Rd>, <Rn>, <Dm>
20064 (Vector to two ARM registers.)
037e8744
JB
20065 8. VMOV.F32 <Sd>, <Sm>
20066 9. VMOV.F64 <Dd>, <Dm>
20067 (VFP register moves.)
20068 10. VMOV.F32 <Sd>, #imm
20069 11. VMOV.F64 <Dd>, #imm
20070 (VFP float immediate load.)
20071 12. VMOV <Rd>, <Sm>
20072 (VFP single to ARM reg.)
20073 13. VMOV <Sd>, <Rm>
20074 (ARM reg to VFP single.)
20075 14. VMOV <Rd>, <Re>, <Sn>, <Sm>
20076 (Two ARM regs to two VFP singles.)
20077 15. VMOV <Sd>, <Se>, <Rn>, <Rm>
20078 (Two VFP singles to two ARM regs.)
57785aa2
AV
20079 16. VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]>
20080 17. VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2>
20081 18. VMOV<c>.<dt> <Rt>, <Qn[idx]>
20082 19. VMOV<c>.<dt> <Qd[idx]>, <Rt>
5f4273c7 20083
037e8744
JB
20084 These cases can be disambiguated using neon_select_shape, except cases 1/9
20085 and 3/11 which depend on the operand type too.
5f4273c7 20086
5287ad62 20087 All the encoded bits are hardcoded by this function.
5f4273c7 20088
b7fc2769
JB
20089 Cases 4, 6 may be used with VFPv1 and above (only 32-bit transfers!).
20090 Cases 5, 7 may be used with VFPv2 and above.
5f4273c7 20091
5287ad62 20092 FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
5f4273c7 20093 can specify a type where it doesn't make sense to, and is ignored). */
5287ad62
JB
20094
20095static void
20096do_neon_mov (void)
20097{
57785aa2
AV
20098 enum neon_shape rs = neon_select_shape (NS_RRSS, NS_SSRR, NS_RRFF, NS_FFRR,
20099 NS_DRR, NS_RRD, NS_QQ, NS_DD, NS_QI,
20100 NS_DI, NS_SR, NS_RS, NS_FF, NS_FI,
20101 NS_RF, NS_FR, NS_HR, NS_RH, NS_HI,
20102 NS_NULL);
037e8744
JB
20103 struct neon_type_el et;
20104 const char *ldconst = 0;
5287ad62 20105
037e8744 20106 switch (rs)
5287ad62 20107 {
037e8744
JB
20108 case NS_DD: /* case 1/9. */
20109 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
20110 /* It is not an error here if no type is given. */
20111 inst.error = NULL;
1c1e0fe5
SP
20112
20113 /* In MVE we interpret the following instructions as same, so ignoring
20114 the following type (float) and size (64) checks.
20115 a: VMOV<c><q> <Dd>, <Dm>
20116 b: VMOV<c><q>.F64 <Dd>, <Dm>. */
20117 if ((et.type == NT_float && et.size == 64)
20118 || (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)))
477330fc
RM
20119 {
20120 do_vfp_nsyn_opcode ("fcpyd");
20121 break;
20122 }
037e8744 20123 /* fall through. */
5287ad62 20124
037e8744
JB
20125 case NS_QQ: /* case 0/1. */
20126 {
64c350f2
AV
20127 if (!check_simd_pred_availability (FALSE,
20128 NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc
RM
20129 return;
20130 /* The architecture manual I have doesn't explicitly state which
20131 value the U bit should have for register->register moves, but
20132 the equivalent VORR instruction has U = 0, so do that. */
20133 inst.instruction = 0x0200110;
20134 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20135 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20136 inst.instruction |= LOW4 (inst.operands[1].reg);
20137 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20138 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20139 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20140 inst.instruction |= neon_quad (rs) << 6;
20141
20142 neon_dp_fixup (&inst);
037e8744
JB
20143 }
20144 break;
5f4273c7 20145
037e8744
JB
20146 case NS_DI: /* case 3/11. */
20147 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
20148 inst.error = NULL;
20149 if (et.type == NT_float && et.size == 64)
477330fc
RM
20150 {
20151 /* case 11 (fconstd). */
20152 ldconst = "fconstd";
20153 goto encode_fconstd;
20154 }
037e8744
JB
20155 /* fall through. */
20156
20157 case NS_QI: /* case 2/3. */
64c350f2
AV
20158 if (!check_simd_pred_availability (FALSE,
20159 NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc 20160 return;
037e8744
JB
20161 inst.instruction = 0x0800010;
20162 neon_move_immediate ();
88714cb8 20163 neon_dp_fixup (&inst);
5287ad62 20164 break;
5f4273c7 20165
037e8744
JB
20166 case NS_SR: /* case 4. */
20167 {
477330fc
RM
20168 unsigned bcdebits = 0;
20169 int logsize;
20170 unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
20171 unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
037e8744 20172
05ac0ffb
JB
20173 /* .<size> is optional here, defaulting to .32. */
20174 if (inst.vectype.elems == 0
20175 && inst.operands[0].vectype.type == NT_invtype
20176 && inst.operands[1].vectype.type == NT_invtype)
20177 {
20178 inst.vectype.el[0].type = NT_untyped;
20179 inst.vectype.el[0].size = 32;
20180 inst.vectype.elems = 1;
20181 }
20182
477330fc
RM
20183 et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
20184 logsize = neon_logbits (et.size);
20185
57785aa2
AV
20186 if (et.size != 32)
20187 {
20188 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
20189 && vfp_or_neon_is_neon (NEON_CHECK_ARCH) == FAIL)
20190 return;
20191 }
20192 else
20193 {
20194 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
20195 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20196 _(BAD_FPU));
20197 }
20198
20199 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20200 {
20201 if (inst.operands[1].reg == REG_SP)
20202 as_tsktsk (MVE_BAD_SP);
20203 else if (inst.operands[1].reg == REG_PC)
20204 as_tsktsk (MVE_BAD_PC);
20205 }
20206 unsigned size = inst.operands[0].isscalar == 1 ? 64 : 128;
20207
477330fc 20208 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2
AV
20209 constraint (x >= size / et.size, _("scalar index out of range"));
20210
477330fc
RM
20211
20212 switch (et.size)
20213 {
20214 case 8: bcdebits = 0x8; break;
20215 case 16: bcdebits = 0x1; break;
20216 case 32: bcdebits = 0x0; break;
20217 default: ;
20218 }
20219
57785aa2 20220 bcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
20221
20222 inst.instruction = 0xe000b10;
20223 do_vfp_cond_or_thumb ();
20224 inst.instruction |= LOW4 (dn) << 16;
20225 inst.instruction |= HI1 (dn) << 7;
20226 inst.instruction |= inst.operands[1].reg << 12;
20227 inst.instruction |= (bcdebits & 3) << 5;
57785aa2
AV
20228 inst.instruction |= ((bcdebits >> 2) & 3) << 21;
20229 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
20230 }
20231 break;
5f4273c7 20232
037e8744 20233 case NS_DRR: /* case 5 (fmdrr). */
57785aa2
AV
20234 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20235 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 20236 _(BAD_FPU));
b7fc2769 20237
037e8744
JB
20238 inst.instruction = 0xc400b10;
20239 do_vfp_cond_or_thumb ();
20240 inst.instruction |= LOW4 (inst.operands[0].reg);
20241 inst.instruction |= HI1 (inst.operands[0].reg) << 5;
20242 inst.instruction |= inst.operands[1].reg << 12;
20243 inst.instruction |= inst.operands[2].reg << 16;
20244 break;
5f4273c7 20245
037e8744
JB
20246 case NS_RS: /* case 6. */
20247 {
477330fc
RM
20248 unsigned logsize;
20249 unsigned dn = NEON_SCALAR_REG (inst.operands[1].reg);
20250 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
20251 unsigned abcdebits = 0;
037e8744 20252
05ac0ffb
JB
20253 /* .<dt> is optional here, defaulting to .32. */
20254 if (inst.vectype.elems == 0
20255 && inst.operands[0].vectype.type == NT_invtype
20256 && inst.operands[1].vectype.type == NT_invtype)
20257 {
20258 inst.vectype.el[0].type = NT_untyped;
20259 inst.vectype.el[0].size = 32;
20260 inst.vectype.elems = 1;
20261 }
20262
91d6fa6a
NC
20263 et = neon_check_type (2, NS_NULL,
20264 N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
477330fc
RM
20265 logsize = neon_logbits (et.size);
20266
57785aa2
AV
20267 if (et.size != 32)
20268 {
20269 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
20270 && vfp_or_neon_is_neon (NEON_CHECK_CC
20271 | NEON_CHECK_ARCH) == FAIL)
20272 return;
20273 }
20274 else
20275 {
20276 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
20277 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20278 _(BAD_FPU));
20279 }
20280
20281 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20282 {
20283 if (inst.operands[0].reg == REG_SP)
20284 as_tsktsk (MVE_BAD_SP);
20285 else if (inst.operands[0].reg == REG_PC)
20286 as_tsktsk (MVE_BAD_PC);
20287 }
20288
20289 unsigned size = inst.operands[1].isscalar == 1 ? 64 : 128;
20290
477330fc 20291 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2 20292 constraint (x >= size / et.size, _("scalar index out of range"));
477330fc
RM
20293
20294 switch (et.size)
20295 {
20296 case 8: abcdebits = (et.type == NT_signed) ? 0x08 : 0x18; break;
20297 case 16: abcdebits = (et.type == NT_signed) ? 0x01 : 0x11; break;
20298 case 32: abcdebits = 0x00; break;
20299 default: ;
20300 }
20301
57785aa2 20302 abcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
20303 inst.instruction = 0xe100b10;
20304 do_vfp_cond_or_thumb ();
20305 inst.instruction |= LOW4 (dn) << 16;
20306 inst.instruction |= HI1 (dn) << 7;
20307 inst.instruction |= inst.operands[0].reg << 12;
20308 inst.instruction |= (abcdebits & 3) << 5;
20309 inst.instruction |= (abcdebits >> 2) << 21;
57785aa2 20310 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
20311 }
20312 break;
5f4273c7 20313
037e8744 20314 case NS_RRD: /* case 7 (fmrrd). */
57785aa2
AV
20315 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20316 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 20317 _(BAD_FPU));
037e8744
JB
20318
20319 inst.instruction = 0xc500b10;
20320 do_vfp_cond_or_thumb ();
20321 inst.instruction |= inst.operands[0].reg << 12;
20322 inst.instruction |= inst.operands[1].reg << 16;
20323 inst.instruction |= LOW4 (inst.operands[2].reg);
20324 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20325 break;
5f4273c7 20326
037e8744
JB
20327 case NS_FF: /* case 8 (fcpys). */
20328 do_vfp_nsyn_opcode ("fcpys");
20329 break;
5f4273c7 20330
9db2f6b4 20331 case NS_HI:
037e8744
JB
20332 case NS_FI: /* case 10 (fconsts). */
20333 ldconst = "fconsts";
4ef4710f 20334 encode_fconstd:
58ed5c38
TC
20335 if (!inst.operands[1].immisfloat)
20336 {
4ef4710f 20337 unsigned new_imm;
58ed5c38 20338 /* Immediate has to fit in 8 bits so float is enough. */
4ef4710f
NC
20339 float imm = (float) inst.operands[1].imm;
20340 memcpy (&new_imm, &imm, sizeof (float));
20341 /* But the assembly may have been written to provide an integer
20342 bit pattern that equates to a float, so check that the
20343 conversion has worked. */
20344 if (is_quarter_float (new_imm))
20345 {
20346 if (is_quarter_float (inst.operands[1].imm))
20347 as_warn (_("immediate constant is valid both as a bit-pattern and a floating point value (using the fp value)"));
20348
20349 inst.operands[1].imm = new_imm;
20350 inst.operands[1].immisfloat = 1;
20351 }
58ed5c38
TC
20352 }
20353
037e8744 20354 if (is_quarter_float (inst.operands[1].imm))
477330fc
RM
20355 {
20356 inst.operands[1].imm = neon_qfloat_bits (inst.operands[1].imm);
20357 do_vfp_nsyn_opcode (ldconst);
9db2f6b4
RL
20358
20359 /* ARMv8.2 fp16 vmov.f16 instruction. */
20360 if (rs == NS_HI)
20361 do_scalar_fp16_v82_encode ();
477330fc 20362 }
5287ad62 20363 else
477330fc 20364 first_error (_("immediate out of range"));
037e8744 20365 break;
5f4273c7 20366
9db2f6b4 20367 case NS_RH:
037e8744
JB
20368 case NS_RF: /* case 12 (fmrs). */
20369 do_vfp_nsyn_opcode ("fmrs");
9db2f6b4
RL
20370 /* ARMv8.2 fp16 vmov.f16 instruction. */
20371 if (rs == NS_RH)
20372 do_scalar_fp16_v82_encode ();
037e8744 20373 break;
5f4273c7 20374
9db2f6b4 20375 case NS_HR:
037e8744
JB
20376 case NS_FR: /* case 13 (fmsr). */
20377 do_vfp_nsyn_opcode ("fmsr");
9db2f6b4
RL
20378 /* ARMv8.2 fp16 vmov.f16 instruction. */
20379 if (rs == NS_HR)
20380 do_scalar_fp16_v82_encode ();
037e8744 20381 break;
5f4273c7 20382
57785aa2
AV
20383 case NS_RRSS:
20384 do_mve_mov (0);
20385 break;
20386 case NS_SSRR:
20387 do_mve_mov (1);
20388 break;
20389
037e8744
JB
20390 /* The encoders for the fmrrs and fmsrr instructions expect three operands
20391 (one of which is a list), but we have parsed four. Do some fiddling to
20392 make the operands what do_vfp_reg2_from_sp2 and do_vfp_sp2_from_reg2
20393 expect. */
20394 case NS_RRFF: /* case 14 (fmrrs). */
57785aa2
AV
20395 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20396 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20397 _(BAD_FPU));
037e8744 20398 constraint (inst.operands[3].reg != inst.operands[2].reg + 1,
477330fc 20399 _("VFP registers must be adjacent"));
037e8744
JB
20400 inst.operands[2].imm = 2;
20401 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
20402 do_vfp_nsyn_opcode ("fmrrs");
20403 break;
5f4273c7 20404
037e8744 20405 case NS_FFRR: /* case 15 (fmsrr). */
57785aa2
AV
20406 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
20407 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20408 _(BAD_FPU));
037e8744 20409 constraint (inst.operands[1].reg != inst.operands[0].reg + 1,
477330fc 20410 _("VFP registers must be adjacent"));
037e8744
JB
20411 inst.operands[1] = inst.operands[2];
20412 inst.operands[2] = inst.operands[3];
20413 inst.operands[0].imm = 2;
20414 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
20415 do_vfp_nsyn_opcode ("fmsrr");
5287ad62 20416 break;
5f4273c7 20417
4c261dff
NC
20418 case NS_NULL:
20419 /* neon_select_shape has determined that the instruction
20420 shape is wrong and has already set the error message. */
20421 break;
20422
5287ad62
JB
20423 default:
20424 abort ();
20425 }
20426}
20427
57785aa2
AV
20428static void
20429do_mve_movl (void)
20430{
20431 if (!(inst.operands[0].present && inst.operands[0].isquad
20432 && inst.operands[1].present && inst.operands[1].isquad
20433 && !inst.operands[2].present))
20434 {
20435 inst.instruction = 0;
20436 inst.cond = 0xb;
20437 if (thumb_mode)
20438 set_pred_insn_type (INSIDE_IT_INSN);
20439 do_neon_mov ();
20440 return;
20441 }
20442
20443 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20444 return;
20445
20446 if (inst.cond != COND_ALWAYS)
20447 inst.pred_insn_type = INSIDE_VPT_INSN;
20448
20449 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_S8 | N_U8
20450 | N_S16 | N_U16 | N_KEY);
20451
20452 inst.instruction |= (et.type == NT_unsigned) << 28;
20453 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20454 inst.instruction |= (neon_logbits (et.size) + 1) << 19;
20455 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20456 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20457 inst.instruction |= LOW4 (inst.operands[1].reg);
20458 inst.is_neon = 1;
20459}
20460
5287ad62
JB
20461static void
20462do_neon_rshift_round_imm (void)
20463{
64c350f2 20464 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
4401c241
AV
20465 return;
20466
20467 enum neon_shape rs;
20468 struct neon_type_el et;
20469
20470 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20471 {
20472 rs = neon_select_shape (NS_QQI, NS_NULL);
20473 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
20474 }
20475 else
20476 {
20477 rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
20478 et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
20479 }
5287ad62
JB
20480 int imm = inst.operands[2].imm;
20481
20482 /* imm == 0 case is encoded as VMOV for V{R}SHR. */
20483 if (imm == 0)
20484 {
20485 inst.operands[2].present = 0;
20486 do_neon_mov ();
20487 return;
20488 }
20489
20490 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 20491 _("immediate out of range for shift"));
037e8744 20492 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et,
477330fc 20493 et.size - imm);
5287ad62
JB
20494}
20495
9db2f6b4
RL
20496static void
20497do_neon_movhf (void)
20498{
20499 enum neon_shape rs = neon_select_shape (NS_HH, NS_NULL);
20500 constraint (rs != NS_HH, _("invalid suffix"));
20501
7bdf778b
ASDV
20502 if (inst.cond != COND_ALWAYS)
20503 {
20504 if (thumb_mode)
20505 {
20506 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
20507 " the behaviour is UNPREDICTABLE"));
20508 }
20509 else
20510 {
20511 inst.error = BAD_COND;
20512 return;
20513 }
20514 }
20515
9db2f6b4
RL
20516 do_vfp_sp_monadic ();
20517
20518 inst.is_neon = 1;
20519 inst.instruction |= 0xf0000000;
20520}
20521
5287ad62
JB
20522static void
20523do_neon_movl (void)
20524{
20525 struct neon_type_el et = neon_check_type (2, NS_QD,
20526 N_EQK | N_DBL, N_SU_32 | N_KEY);
20527 unsigned sizebits = et.size >> 3;
20528 inst.instruction |= sizebits << 19;
20529 neon_two_same (0, et.type == NT_unsigned, -1);
20530}
20531
20532static void
20533do_neon_trn (void)
20534{
037e8744 20535 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20536 struct neon_type_el et = neon_check_type (2, rs,
20537 N_EQK, N_8 | N_16 | N_32 | N_KEY);
88714cb8 20538 NEON_ENCODE (INTEGER, inst);
037e8744 20539 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20540}
20541
20542static void
20543do_neon_zip_uzp (void)
20544{
037e8744 20545 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20546 struct neon_type_el et = neon_check_type (2, rs,
20547 N_EQK, N_8 | N_16 | N_32 | N_KEY);
20548 if (rs == NS_DD && et.size == 32)
20549 {
20550 /* Special case: encode as VTRN.32 <Dd>, <Dm>. */
20551 inst.instruction = N_MNEM_vtrn;
20552 do_neon_trn ();
20553 return;
20554 }
037e8744 20555 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20556}
20557
20558static void
20559do_neon_sat_abs_neg (void)
20560{
64c350f2 20561 if (!check_simd_pred_availability (FALSE, NEON_CHECK_CC | NEON_CHECK_ARCH))
1a186d29
AV
20562 return;
20563
20564 enum neon_shape rs;
20565 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20566 rs = neon_select_shape (NS_QQ, NS_NULL);
20567 else
20568 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20569 struct neon_type_el et = neon_check_type (2, rs,
20570 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 20571 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20572}
20573
20574static void
20575do_neon_pair_long (void)
20576{
037e8744 20577 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20578 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
20579 /* Unsigned is encoded in OP field (bit 7) for these instruction. */
20580 inst.instruction |= (et.type == NT_unsigned) << 7;
037e8744 20581 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20582}
20583
20584static void
20585do_neon_recip_est (void)
20586{
037e8744 20587 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62 20588 struct neon_type_el et = neon_check_type (2, rs,
cc933301 20589 N_EQK | N_FLT, N_F_16_32 | N_U32 | N_KEY);
5287ad62 20590 inst.instruction |= (et.type == NT_float) << 8;
037e8744 20591 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20592}
20593
20594static void
20595do_neon_cls (void)
20596{
64c350f2 20597 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
f30ee27c
AV
20598 return;
20599
20600 enum neon_shape rs;
20601 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20602 rs = neon_select_shape (NS_QQ, NS_NULL);
20603 else
20604 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20605
5287ad62
JB
20606 struct neon_type_el et = neon_check_type (2, rs,
20607 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 20608 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20609}
20610
20611static void
20612do_neon_clz (void)
20613{
64c350f2 20614 if (!check_simd_pred_availability (FALSE, NEON_CHECK_ARCH | NEON_CHECK_CC))
f30ee27c
AV
20615 return;
20616
20617 enum neon_shape rs;
20618 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20619 rs = neon_select_shape (NS_QQ, NS_NULL);
20620 else
20621 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20622
5287ad62
JB
20623 struct neon_type_el et = neon_check_type (2, rs,
20624 N_EQK, N_I8 | N_I16 | N_I32 | N_KEY);
037e8744 20625 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20626}
20627
20628static void
20629do_neon_cnt (void)
20630{
037e8744 20631 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
20632 struct neon_type_el et = neon_check_type (2, rs,
20633 N_EQK | N_INT, N_8 | N_KEY);
037e8744 20634 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
20635}
20636
20637static void
20638do_neon_swp (void)
20639{
037e8744
JB
20640 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
20641 neon_two_same (neon_quad (rs), 1, -1);
5287ad62
JB
20642}
20643
20644static void
20645do_neon_tbl_tbx (void)
20646{
20647 unsigned listlenbits;
dcbf9037 20648 neon_check_type (3, NS_DLD, N_EQK, N_EQK, N_8 | N_KEY);
5f4273c7 20649
5287ad62
JB
20650 if (inst.operands[1].imm < 1 || inst.operands[1].imm > 4)
20651 {
dcbf9037 20652 first_error (_("bad list length for table lookup"));
5287ad62
JB
20653 return;
20654 }
5f4273c7 20655
5287ad62
JB
20656 listlenbits = inst.operands[1].imm - 1;
20657 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20658 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20659 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20660 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20661 inst.instruction |= LOW4 (inst.operands[2].reg);
20662 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20663 inst.instruction |= listlenbits << 8;
5f4273c7 20664
88714cb8 20665 neon_dp_fixup (&inst);
5287ad62
JB
20666}
20667
20668static void
20669do_neon_ldm_stm (void)
20670{
ef8f595f
MI
20671 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
20672 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
20673 _(BAD_FPU));
5287ad62
JB
20674 /* P, U and L bits are part of bitmask. */
20675 int is_dbmode = (inst.instruction & (1 << 24)) != 0;
20676 unsigned offsetbits = inst.operands[1].imm * 2;
20677
037e8744
JB
20678 if (inst.operands[1].issingle)
20679 {
20680 do_vfp_nsyn_ldm_stm (is_dbmode);
20681 return;
20682 }
20683
5287ad62 20684 constraint (is_dbmode && !inst.operands[0].writeback,
477330fc 20685 _("writeback (!) must be used for VLDMDB and VSTMDB"));
5287ad62
JB
20686
20687 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
477330fc
RM
20688 _("register list must contain at least 1 and at most 16 "
20689 "registers"));
5287ad62
JB
20690
20691 inst.instruction |= inst.operands[0].reg << 16;
20692 inst.instruction |= inst.operands[0].writeback << 21;
20693 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
20694 inst.instruction |= HI1 (inst.operands[1].reg) << 22;
20695
20696 inst.instruction |= offsetbits;
5f4273c7 20697
037e8744 20698 do_vfp_cond_or_thumb ();
5287ad62
JB
20699}
20700
ef8f595f
MI
20701static void
20702do_vfp_nsyn_pop (void)
20703{
20704 nsyn_insert_sp ();
20705 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)) {
20706 return do_vfp_nsyn_opcode ("vldm");
20707 }
20708
20709 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd),
20710 _(BAD_FPU));
20711
20712 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
20713 _("register list must contain at least 1 and at most 16 "
20714 "registers"));
20715
20716 if (inst.operands[1].issingle)
20717 do_vfp_nsyn_opcode ("fldmias");
20718 else
20719 do_vfp_nsyn_opcode ("fldmiad");
20720}
20721
20722static void
20723do_vfp_nsyn_push (void)
20724{
20725 nsyn_insert_sp ();
20726 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)) {
20727 return do_vfp_nsyn_opcode ("vstmdb");
20728 }
20729
20730 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd),
20731 _(BAD_FPU));
20732
20733 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
20734 _("register list must contain at least 1 and at most 16 "
20735 "registers"));
20736
20737 if (inst.operands[1].issingle)
20738 do_vfp_nsyn_opcode ("fstmdbs");
20739 else
20740 do_vfp_nsyn_opcode ("fstmdbd");
20741}
20742
20743
5287ad62
JB
20744static void
20745do_neon_ldr_str (void)
20746{
5287ad62 20747 int is_ldr = (inst.instruction & (1 << 20)) != 0;
5f4273c7 20748
6844b2c2
MGD
20749 /* Use of PC in vstr in ARM mode is deprecated in ARMv7.
20750 And is UNPREDICTABLE in thumb mode. */
fa94de6b 20751 if (!is_ldr
6844b2c2 20752 && inst.operands[1].reg == REG_PC
ba86b375 20753 && (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7) || thumb_mode))
6844b2c2 20754 {
94dcf8bf 20755 if (thumb_mode)
6844b2c2 20756 inst.error = _("Use of PC here is UNPREDICTABLE");
94dcf8bf 20757 else if (warn_on_deprecated)
5c3696f8 20758 as_tsktsk (_("Use of PC here is deprecated"));
6844b2c2
MGD
20759 }
20760
037e8744
JB
20761 if (inst.operands[0].issingle)
20762 {
cd2f129f 20763 if (is_ldr)
477330fc 20764 do_vfp_nsyn_opcode ("flds");
cd2f129f 20765 else
477330fc 20766 do_vfp_nsyn_opcode ("fsts");
9db2f6b4
RL
20767
20768 /* ARMv8.2 vldr.16/vstr.16 instruction. */
20769 if (inst.vectype.el[0].size == 16)
20770 do_scalar_fp16_v82_encode ();
5287ad62
JB
20771 }
20772 else
5287ad62 20773 {
cd2f129f 20774 if (is_ldr)
477330fc 20775 do_vfp_nsyn_opcode ("fldd");
5287ad62 20776 else
477330fc 20777 do_vfp_nsyn_opcode ("fstd");
5287ad62 20778 }
5287ad62
JB
20779}
20780
32c36c3c
AV
20781static void
20782do_t_vldr_vstr_sysreg (void)
20783{
20784 int fp_vldr_bitno = 20, sysreg_vldr_bitno = 20;
20785 bfd_boolean is_vldr = ((inst.instruction & (1 << fp_vldr_bitno)) != 0);
20786
20787 /* Use of PC is UNPREDICTABLE. */
20788 if (inst.operands[1].reg == REG_PC)
20789 inst.error = _("Use of PC here is UNPREDICTABLE");
20790
20791 if (inst.operands[1].immisreg)
20792 inst.error = _("instruction does not accept register index");
20793
20794 if (!inst.operands[1].isreg)
20795 inst.error = _("instruction does not accept PC-relative addressing");
20796
20797 if (abs (inst.operands[1].imm) >= (1 << 7))
20798 inst.error = _("immediate value out of range");
20799
20800 inst.instruction = 0xec000f80;
20801 if (is_vldr)
20802 inst.instruction |= 1 << sysreg_vldr_bitno;
20803 encode_arm_cp_address (1, TRUE, FALSE, BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM);
20804 inst.instruction |= (inst.operands[0].imm & 0x7) << 13;
20805 inst.instruction |= (inst.operands[0].imm & 0x8) << 19;
20806}
20807
20808static void
20809do_vldr_vstr (void)
20810{
20811 bfd_boolean sysreg_op = !inst.operands[0].isreg;
20812
20813 /* VLDR/VSTR (System Register). */
20814 if (sysreg_op)
20815 {
20816 if (!mark_feature_used (&arm_ext_v8_1m_main))
20817 as_bad (_("Instruction not permitted on this architecture"));
20818
20819 do_t_vldr_vstr_sysreg ();
20820 }
20821 /* VLDR/VSTR. */
20822 else
20823 {
ef8f595f
MI
20824 if (!mark_feature_used (&fpu_vfp_ext_v1xd)
20825 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
32c36c3c
AV
20826 as_bad (_("Instruction not permitted on this architecture"));
20827 do_neon_ldr_str ();
20828 }
20829}
20830
5287ad62
JB
20831/* "interleave" version also handles non-interleaving register VLD1/VST1
20832 instructions. */
20833
20834static void
20835do_neon_ld_st_interleave (void)
20836{
037e8744 20837 struct neon_type_el et = neon_check_type (1, NS_NULL,
477330fc 20838 N_8 | N_16 | N_32 | N_64);
5287ad62
JB
20839 unsigned alignbits = 0;
20840 unsigned idx;
20841 /* The bits in this table go:
20842 0: register stride of one (0) or two (1)
20843 1,2: register list length, minus one (1, 2, 3, 4).
20844 3,4: <n> in instruction type, minus one (VLD<n> / VST<n>).
20845 We use -1 for invalid entries. */
20846 const int typetable[] =
20847 {
20848 0x7, -1, 0xa, -1, 0x6, -1, 0x2, -1, /* VLD1 / VST1. */
20849 -1, -1, 0x8, 0x9, -1, -1, 0x3, -1, /* VLD2 / VST2. */
20850 -1, -1, -1, -1, 0x4, 0x5, -1, -1, /* VLD3 / VST3. */
20851 -1, -1, -1, -1, -1, -1, 0x0, 0x1 /* VLD4 / VST4. */
20852 };
20853 int typebits;
20854
dcbf9037
JB
20855 if (et.type == NT_invtype)
20856 return;
20857
5287ad62
JB
20858 if (inst.operands[1].immisalign)
20859 switch (inst.operands[1].imm >> 8)
20860 {
20861 case 64: alignbits = 1; break;
20862 case 128:
477330fc 20863 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2
e23c0ad8 20864 && NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
477330fc
RM
20865 goto bad_alignment;
20866 alignbits = 2;
20867 break;
5287ad62 20868 case 256:
477330fc
RM
20869 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
20870 goto bad_alignment;
20871 alignbits = 3;
20872 break;
5287ad62
JB
20873 default:
20874 bad_alignment:
477330fc
RM
20875 first_error (_("bad alignment"));
20876 return;
5287ad62
JB
20877 }
20878
20879 inst.instruction |= alignbits << 4;
20880 inst.instruction |= neon_logbits (et.size) << 6;
20881
20882 /* Bits [4:6] of the immediate in a list specifier encode register stride
20883 (minus 1) in bit 4, and list length in bits [5:6]. We put the <n> of
20884 VLD<n>/VST<n> in bits [9:8] of the initial bitmask. Suck it out here, look
20885 up the right value for "type" in a table based on this value and the given
20886 list style, then stick it back. */
20887 idx = ((inst.operands[0].imm >> 4) & 7)
477330fc 20888 | (((inst.instruction >> 8) & 3) << 3);
5287ad62
JB
20889
20890 typebits = typetable[idx];
5f4273c7 20891
5287ad62 20892 constraint (typebits == -1, _("bad list type for instruction"));
1d50d57c 20893 constraint (((inst.instruction >> 8) & 3) && et.size == 64,
35c228db 20894 BAD_EL_TYPE);
5287ad62
JB
20895
20896 inst.instruction &= ~0xf00;
20897 inst.instruction |= typebits << 8;
20898}
20899
20900/* Check alignment is valid for do_neon_ld_st_lane and do_neon_ld_dup.
20901 *DO_ALIGN is set to 1 if the relevant alignment bit should be set, 0
20902 otherwise. The variable arguments are a list of pairs of legal (size, align)
20903 values, terminated with -1. */
20904
20905static int
aa8a0863 20906neon_alignment_bit (int size, int align, int *do_alignment, ...)
5287ad62
JB
20907{
20908 va_list ap;
20909 int result = FAIL, thissize, thisalign;
5f4273c7 20910
5287ad62
JB
20911 if (!inst.operands[1].immisalign)
20912 {
aa8a0863 20913 *do_alignment = 0;
5287ad62
JB
20914 return SUCCESS;
20915 }
5f4273c7 20916
aa8a0863 20917 va_start (ap, do_alignment);
5287ad62
JB
20918
20919 do
20920 {
20921 thissize = va_arg (ap, int);
20922 if (thissize == -1)
477330fc 20923 break;
5287ad62
JB
20924 thisalign = va_arg (ap, int);
20925
20926 if (size == thissize && align == thisalign)
477330fc 20927 result = SUCCESS;
5287ad62
JB
20928 }
20929 while (result != SUCCESS);
20930
20931 va_end (ap);
20932
20933 if (result == SUCCESS)
aa8a0863 20934 *do_alignment = 1;
5287ad62 20935 else
dcbf9037 20936 first_error (_("unsupported alignment for instruction"));
5f4273c7 20937
5287ad62
JB
20938 return result;
20939}
20940
20941static void
20942do_neon_ld_st_lane (void)
20943{
037e8744 20944 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 20945 int align_good, do_alignment = 0;
5287ad62
JB
20946 int logsize = neon_logbits (et.size);
20947 int align = inst.operands[1].imm >> 8;
20948 int n = (inst.instruction >> 8) & 3;
20949 int max_el = 64 / et.size;
5f4273c7 20950
dcbf9037
JB
20951 if (et.type == NT_invtype)
20952 return;
5f4273c7 20953
5287ad62 20954 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != n + 1,
477330fc 20955 _("bad list length"));
5287ad62 20956 constraint (NEON_LANE (inst.operands[0].imm) >= max_el,
477330fc 20957 _("scalar index out of range"));
5287ad62 20958 constraint (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2
477330fc
RM
20959 && et.size == 8,
20960 _("stride of 2 unavailable when element size is 8"));
5f4273c7 20961
5287ad62
JB
20962 switch (n)
20963 {
20964 case 0: /* VLD1 / VST1. */
aa8a0863 20965 align_good = neon_alignment_bit (et.size, align, &do_alignment, 16, 16,
477330fc 20966 32, 32, -1);
5287ad62 20967 if (align_good == FAIL)
477330fc 20968 return;
aa8a0863 20969 if (do_alignment)
477330fc
RM
20970 {
20971 unsigned alignbits = 0;
20972 switch (et.size)
20973 {
20974 case 16: alignbits = 0x1; break;
20975 case 32: alignbits = 0x3; break;
20976 default: ;
20977 }
20978 inst.instruction |= alignbits << 4;
20979 }
5287ad62
JB
20980 break;
20981
20982 case 1: /* VLD2 / VST2. */
aa8a0863
TS
20983 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 16,
20984 16, 32, 32, 64, -1);
5287ad62 20985 if (align_good == FAIL)
477330fc 20986 return;
aa8a0863 20987 if (do_alignment)
477330fc 20988 inst.instruction |= 1 << 4;
5287ad62
JB
20989 break;
20990
20991 case 2: /* VLD3 / VST3. */
20992 constraint (inst.operands[1].immisalign,
477330fc 20993 _("can't use alignment with this instruction"));
5287ad62
JB
20994 break;
20995
20996 case 3: /* VLD4 / VST4. */
aa8a0863 20997 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc 20998 16, 64, 32, 64, 32, 128, -1);
5287ad62 20999 if (align_good == FAIL)
477330fc 21000 return;
aa8a0863 21001 if (do_alignment)
477330fc
RM
21002 {
21003 unsigned alignbits = 0;
21004 switch (et.size)
21005 {
21006 case 8: alignbits = 0x1; break;
21007 case 16: alignbits = 0x1; break;
21008 case 32: alignbits = (align == 64) ? 0x1 : 0x2; break;
21009 default: ;
21010 }
21011 inst.instruction |= alignbits << 4;
21012 }
5287ad62
JB
21013 break;
21014
21015 default: ;
21016 }
21017
21018 /* Reg stride of 2 is encoded in bit 5 when size==16, bit 6 when size==32. */
21019 if (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2)
21020 inst.instruction |= 1 << (4 + logsize);
5f4273c7 21021
5287ad62
JB
21022 inst.instruction |= NEON_LANE (inst.operands[0].imm) << (logsize + 5);
21023 inst.instruction |= logsize << 10;
21024}
21025
21026/* Encode single n-element structure to all lanes VLD<n> instructions. */
21027
21028static void
21029do_neon_ld_dup (void)
21030{
037e8744 21031 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 21032 int align_good, do_alignment = 0;
5287ad62 21033
dcbf9037
JB
21034 if (et.type == NT_invtype)
21035 return;
21036
5287ad62
JB
21037 switch ((inst.instruction >> 8) & 3)
21038 {
21039 case 0: /* VLD1. */
9c2799c2 21040 gas_assert (NEON_REG_STRIDE (inst.operands[0].imm) != 2);
5287ad62 21041 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863 21042 &do_alignment, 16, 16, 32, 32, -1);
5287ad62 21043 if (align_good == FAIL)
477330fc 21044 return;
5287ad62 21045 switch (NEON_REGLIST_LENGTH (inst.operands[0].imm))
477330fc
RM
21046 {
21047 case 1: break;
21048 case 2: inst.instruction |= 1 << 5; break;
21049 default: first_error (_("bad list length")); return;
21050 }
5287ad62
JB
21051 inst.instruction |= neon_logbits (et.size) << 6;
21052 break;
21053
21054 case 1: /* VLD2. */
21055 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863
TS
21056 &do_alignment, 8, 16, 16, 32, 32, 64,
21057 -1);
5287ad62 21058 if (align_good == FAIL)
477330fc 21059 return;
5287ad62 21060 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2,
477330fc 21061 _("bad list length"));
5287ad62 21062 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 21063 inst.instruction |= 1 << 5;
5287ad62
JB
21064 inst.instruction |= neon_logbits (et.size) << 6;
21065 break;
21066
21067 case 2: /* VLD3. */
21068 constraint (inst.operands[1].immisalign,
477330fc 21069 _("can't use alignment with this instruction"));
5287ad62 21070 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 3,
477330fc 21071 _("bad list length"));
5287ad62 21072 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 21073 inst.instruction |= 1 << 5;
5287ad62
JB
21074 inst.instruction |= neon_logbits (et.size) << 6;
21075 break;
21076
21077 case 3: /* VLD4. */
21078 {
477330fc 21079 int align = inst.operands[1].imm >> 8;
aa8a0863 21080 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc
RM
21081 16, 64, 32, 64, 32, 128, -1);
21082 if (align_good == FAIL)
21083 return;
21084 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4,
21085 _("bad list length"));
21086 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
21087 inst.instruction |= 1 << 5;
21088 if (et.size == 32 && align == 128)
21089 inst.instruction |= 0x3 << 6;
21090 else
21091 inst.instruction |= neon_logbits (et.size) << 6;
5287ad62
JB
21092 }
21093 break;
21094
21095 default: ;
21096 }
21097
aa8a0863 21098 inst.instruction |= do_alignment << 4;
5287ad62
JB
21099}
21100
21101/* Disambiguate VLD<n> and VST<n> instructions, and fill in common bits (those
21102 apart from bits [11:4]. */
21103
21104static void
21105do_neon_ldx_stx (void)
21106{
b1a769ed
DG
21107 if (inst.operands[1].isreg)
21108 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
21109
5287ad62
JB
21110 switch (NEON_LANE (inst.operands[0].imm))
21111 {
21112 case NEON_INTERLEAVE_LANES:
88714cb8 21113 NEON_ENCODE (INTERLV, inst);
5287ad62
JB
21114 do_neon_ld_st_interleave ();
21115 break;
5f4273c7 21116
5287ad62 21117 case NEON_ALL_LANES:
88714cb8 21118 NEON_ENCODE (DUP, inst);
2d51fb74
JB
21119 if (inst.instruction == N_INV)
21120 {
21121 first_error ("only loads support such operands");
21122 break;
21123 }
5287ad62
JB
21124 do_neon_ld_dup ();
21125 break;
5f4273c7 21126
5287ad62 21127 default:
88714cb8 21128 NEON_ENCODE (LANE, inst);
5287ad62
JB
21129 do_neon_ld_st_lane ();
21130 }
21131
21132 /* L bit comes from bit mask. */
21133 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21134 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21135 inst.instruction |= inst.operands[1].reg << 16;
5f4273c7 21136
5287ad62
JB
21137 if (inst.operands[1].postind)
21138 {
21139 int postreg = inst.operands[1].imm & 0xf;
21140 constraint (!inst.operands[1].immisreg,
477330fc 21141 _("post-index must be a register"));
5287ad62 21142 constraint (postreg == 0xd || postreg == 0xf,
477330fc 21143 _("bad register for post-index"));
5287ad62
JB
21144 inst.instruction |= postreg;
21145 }
4f2374c7 21146 else
5287ad62 21147 {
4f2374c7 21148 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
e2b0ab59
AV
21149 constraint (inst.relocs[0].exp.X_op != O_constant
21150 || inst.relocs[0].exp.X_add_number != 0,
4f2374c7
WN
21151 BAD_ADDR_MODE);
21152
21153 if (inst.operands[1].writeback)
21154 {
21155 inst.instruction |= 0xd;
21156 }
21157 else
21158 inst.instruction |= 0xf;
5287ad62 21159 }
5f4273c7 21160
5287ad62
JB
21161 if (thumb_mode)
21162 inst.instruction |= 0xf9000000;
21163 else
21164 inst.instruction |= 0xf4000000;
21165}
33399f07
MGD
21166
21167/* FP v8. */
21168static void
21169do_vfp_nsyn_fpv8 (enum neon_shape rs)
21170{
a715796b
TG
21171 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
21172 D register operands. */
21173 if (neon_shape_class[rs] == SC_DOUBLE)
21174 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
21175 _(BAD_FPU));
21176
33399f07
MGD
21177 NEON_ENCODE (FPV8, inst);
21178
9db2f6b4
RL
21179 if (rs == NS_FFF || rs == NS_HHH)
21180 {
21181 do_vfp_sp_dyadic ();
21182
21183 /* ARMv8.2 fp16 instruction. */
21184 if (rs == NS_HHH)
21185 do_scalar_fp16_v82_encode ();
21186 }
33399f07
MGD
21187 else
21188 do_vfp_dp_rd_rn_rm ();
21189
21190 if (rs == NS_DDD)
21191 inst.instruction |= 0x100;
21192
21193 inst.instruction |= 0xf0000000;
21194}
21195
21196static void
21197do_vsel (void)
21198{
5ee91343 21199 set_pred_insn_type (OUTSIDE_PRED_INSN);
33399f07
MGD
21200
21201 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
21202 first_error (_("invalid instruction shape"));
21203}
21204
73924fbc
MGD
21205static void
21206do_vmaxnm (void)
21207{
935295b5
AV
21208 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
21209 set_pred_insn_type (OUTSIDE_PRED_INSN);
73924fbc
MGD
21210
21211 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
21212 return;
21213
64c350f2 21214 if (!check_simd_pred_availability (TRUE, NEON_CHECK_CC | NEON_CHECK_ARCH8))
73924fbc
MGD
21215 return;
21216
cc933301 21217 neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
73924fbc
MGD
21218}
21219
30bdf752
MGD
21220static void
21221do_vrint_1 (enum neon_cvt_mode mode)
21222{
9db2f6b4 21223 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_QQ, NS_NULL);
30bdf752
MGD
21224 struct neon_type_el et;
21225
21226 if (rs == NS_NULL)
21227 return;
21228
a715796b
TG
21229 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
21230 D register operands. */
21231 if (neon_shape_class[rs] == SC_DOUBLE)
21232 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
21233 _(BAD_FPU));
21234
9db2f6b4
RL
21235 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY
21236 | N_VFP);
30bdf752
MGD
21237 if (et.type != NT_invtype)
21238 {
21239 /* VFP encodings. */
21240 if (mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
21241 || mode == neon_cvt_mode_p || mode == neon_cvt_mode_m)
5ee91343 21242 set_pred_insn_type (OUTSIDE_PRED_INSN);
30bdf752
MGD
21243
21244 NEON_ENCODE (FPV8, inst);
9db2f6b4 21245 if (rs == NS_FF || rs == NS_HH)
30bdf752
MGD
21246 do_vfp_sp_monadic ();
21247 else
21248 do_vfp_dp_rd_rm ();
21249
21250 switch (mode)
21251 {
21252 case neon_cvt_mode_r: inst.instruction |= 0x00000000; break;
21253 case neon_cvt_mode_z: inst.instruction |= 0x00000080; break;
21254 case neon_cvt_mode_x: inst.instruction |= 0x00010000; break;
21255 case neon_cvt_mode_a: inst.instruction |= 0xf0000000; break;
21256 case neon_cvt_mode_n: inst.instruction |= 0xf0010000; break;
21257 case neon_cvt_mode_p: inst.instruction |= 0xf0020000; break;
21258 case neon_cvt_mode_m: inst.instruction |= 0xf0030000; break;
21259 default: abort ();
21260 }
21261
21262 inst.instruction |= (rs == NS_DD) << 8;
21263 do_vfp_cond_or_thumb ();
9db2f6b4
RL
21264
21265 /* ARMv8.2 fp16 vrint instruction. */
21266 if (rs == NS_HH)
21267 do_scalar_fp16_v82_encode ();
30bdf752
MGD
21268 }
21269 else
21270 {
21271 /* Neon encodings (or something broken...). */
21272 inst.error = NULL;
cc933301 21273 et = neon_check_type (2, rs, N_EQK, N_F_16_32 | N_KEY);
30bdf752
MGD
21274
21275 if (et.type == NT_invtype)
21276 return;
21277
64c350f2
AV
21278 if (!check_simd_pred_availability (TRUE,
21279 NEON_CHECK_CC | NEON_CHECK_ARCH8))
30bdf752
MGD
21280 return;
21281
a710b305
AV
21282 NEON_ENCODE (FLOAT, inst);
21283
30bdf752
MGD
21284 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21285 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21286 inst.instruction |= LOW4 (inst.operands[1].reg);
21287 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
21288 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
21289 /* Mask off the original size bits and reencode them. */
21290 inst.instruction = ((inst.instruction & 0xfff3ffff)
21291 | neon_logbits (et.size) << 18);
21292
30bdf752
MGD
21293 switch (mode)
21294 {
21295 case neon_cvt_mode_z: inst.instruction |= 3 << 7; break;
21296 case neon_cvt_mode_x: inst.instruction |= 1 << 7; break;
21297 case neon_cvt_mode_a: inst.instruction |= 2 << 7; break;
21298 case neon_cvt_mode_n: inst.instruction |= 0 << 7; break;
21299 case neon_cvt_mode_p: inst.instruction |= 7 << 7; break;
21300 case neon_cvt_mode_m: inst.instruction |= 5 << 7; break;
21301 case neon_cvt_mode_r: inst.error = _("invalid rounding mode"); break;
21302 default: abort ();
21303 }
21304
21305 if (thumb_mode)
21306 inst.instruction |= 0xfc000000;
21307 else
21308 inst.instruction |= 0xf0000000;
21309 }
21310}
21311
21312static void
21313do_vrintx (void)
21314{
21315 do_vrint_1 (neon_cvt_mode_x);
21316}
21317
21318static void
21319do_vrintz (void)
21320{
21321 do_vrint_1 (neon_cvt_mode_z);
21322}
21323
21324static void
21325do_vrintr (void)
21326{
21327 do_vrint_1 (neon_cvt_mode_r);
21328}
21329
21330static void
21331do_vrinta (void)
21332{
21333 do_vrint_1 (neon_cvt_mode_a);
21334}
21335
21336static void
21337do_vrintn (void)
21338{
21339 do_vrint_1 (neon_cvt_mode_n);
21340}
21341
21342static void
21343do_vrintp (void)
21344{
21345 do_vrint_1 (neon_cvt_mode_p);
21346}
21347
21348static void
21349do_vrintm (void)
21350{
21351 do_vrint_1 (neon_cvt_mode_m);
21352}
21353
c28eeff2
SN
21354static unsigned
21355neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
21356{
21357 unsigned regno = NEON_SCALAR_REG (opnd);
21358 unsigned elno = NEON_SCALAR_INDEX (opnd);
21359
21360 if (elsize == 16 && elno < 2 && regno < 16)
21361 return regno | (elno << 4);
21362 else if (elsize == 32 && elno == 0)
21363 return regno;
21364
21365 first_error (_("scalar out of range"));
21366 return 0;
21367}
21368
21369static void
21370do_vcmla (void)
21371{
5d281bf0
AV
21372 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext)
21373 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
21374 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
21375 constraint (inst.relocs[0].exp.X_op != O_constant,
21376 _("expression too complex"));
21377 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
21378 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
21379 _("immediate out of range"));
21380 rot /= 90;
5d281bf0 21381
64c350f2
AV
21382 if (!check_simd_pred_availability (TRUE,
21383 NEON_CHECK_ARCH8 | NEON_CHECK_CC))
5d281bf0
AV
21384 return;
21385
c28eeff2
SN
21386 if (inst.operands[2].isscalar)
21387 {
5d281bf0
AV
21388 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
21389 first_error (_("invalid instruction shape"));
c28eeff2
SN
21390 enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
21391 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
21392 N_KEY | N_F16 | N_F32).size;
21393 unsigned m = neon_scalar_for_vcmla (inst.operands[2].reg, size);
21394 inst.is_neon = 1;
21395 inst.instruction = 0xfe000800;
21396 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21397 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21398 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
21399 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
21400 inst.instruction |= LOW4 (m);
21401 inst.instruction |= HI1 (m) << 5;
21402 inst.instruction |= neon_quad (rs) << 6;
21403 inst.instruction |= rot << 20;
21404 inst.instruction |= (size == 32) << 23;
21405 }
21406 else
21407 {
5d281bf0
AV
21408 enum neon_shape rs;
21409 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
21410 rs = neon_select_shape (NS_QQQI, NS_NULL);
21411 else
21412 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
21413
c28eeff2
SN
21414 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
21415 N_KEY | N_F16 | N_F32).size;
5d281bf0
AV
21416 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext) && size == 32
21417 && (inst.operands[0].reg == inst.operands[1].reg
21418 || inst.operands[0].reg == inst.operands[2].reg))
21419 as_tsktsk (BAD_MVE_SRCDEST);
21420
c28eeff2
SN
21421 neon_three_same (neon_quad (rs), 0, -1);
21422 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
21423 inst.instruction |= 0xfc200800;
21424 inst.instruction |= rot << 23;
21425 inst.instruction |= (size == 32) << 20;
21426 }
21427}
21428
21429static void
21430do_vcadd (void)
21431{
5d281bf0
AV
21432 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
21433 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
21434 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
21435 constraint (inst.relocs[0].exp.X_op != O_constant,
21436 _("expression too complex"));
5d281bf0 21437
e2b0ab59 21438 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2 21439 constraint (rot != 90 && rot != 270, _("immediate out of range"));
5d281bf0
AV
21440 enum neon_shape rs;
21441 struct neon_type_el et;
21442 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
21443 {
21444 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
21445 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32);
21446 }
21447 else
21448 {
21449 rs = neon_select_shape (NS_QQQI, NS_NULL);
21450 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32 | N_I8
21451 | N_I16 | N_I32);
21452 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
21453 as_tsktsk (_("Warning: 32-bit element size and same first and third "
21454 "operand makes instruction UNPREDICTABLE"));
21455 }
21456
21457 if (et.type == NT_invtype)
21458 return;
21459
64c350f2
AV
21460 if (!check_simd_pred_availability (et.type == NT_float,
21461 NEON_CHECK_ARCH8 | NEON_CHECK_CC))
5d281bf0
AV
21462 return;
21463
21464 if (et.type == NT_float)
21465 {
21466 neon_three_same (neon_quad (rs), 0, -1);
21467 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
21468 inst.instruction |= 0xfc800800;
21469 inst.instruction |= (rot == 270) << 24;
21470 inst.instruction |= (et.size == 32) << 20;
21471 }
21472 else
21473 {
21474 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
21475 inst.instruction = 0xfe000f00;
21476 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
21477 inst.instruction |= neon_logbits (et.size) << 20;
21478 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
21479 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
21480 inst.instruction |= (rot == 270) << 12;
21481 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
21482 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
21483 inst.instruction |= LOW4 (inst.operands[2].reg);
21484 inst.is_neon = 1;
21485 }
c28eeff2
SN
21486}
21487
c604a79a
JW
21488/* Dot Product instructions encoding support. */
21489
21490static void
21491do_neon_dotproduct (int unsigned_p)
21492{
21493 enum neon_shape rs;
21494 unsigned scalar_oprd2 = 0;
21495 int high8;
21496
21497 if (inst.cond != COND_ALWAYS)
21498 as_warn (_("Dot Product instructions cannot be conditional, the behaviour "
21499 "is UNPREDICTABLE"));
21500
21501 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
21502 _(BAD_FPU));
21503
21504 /* Dot Product instructions are in three-same D/Q register format or the third
21505 operand can be a scalar index register. */
21506 if (inst.operands[2].isscalar)
21507 {
21508 scalar_oprd2 = neon_scalar_for_mul (inst.operands[2].reg, 32);
21509 high8 = 0xfe000000;
21510 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21511 }
21512 else
21513 {
21514 high8 = 0xfc000000;
21515 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
21516 }
21517
21518 if (unsigned_p)
21519 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_U8);
21520 else
21521 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_S8);
21522
21523 /* The "U" bit in traditional Three Same encoding is fixed to 0 for Dot
21524 Product instruction, so we pass 0 as the "ubit" parameter. And the
21525 "Size" field are fixed to 0x2, so we pass 32 as the "size" parameter. */
21526 neon_three_same (neon_quad (rs), 0, 32);
21527
21528 /* Undo neon_dp_fixup. Dot Product instructions are using a slightly
21529 different NEON three-same encoding. */
21530 inst.instruction &= 0x00ffffff;
21531 inst.instruction |= high8;
21532 /* Encode 'U' bit which indicates signedness. */
21533 inst.instruction |= (unsigned_p ? 1 : 0) << 4;
21534 /* Re-encode operand2 if it's indexed scalar operand. What has been encoded
21535 from inst.operand[2].reg in neon_three_same is GAS's internal encoding, not
21536 the instruction encoding. */
21537 if (inst.operands[2].isscalar)
21538 {
21539 inst.instruction &= 0xffffffd0;
21540 inst.instruction |= LOW4 (scalar_oprd2);
21541 inst.instruction |= HI1 (scalar_oprd2) << 5;
21542 }
21543}
21544
21545/* Dot Product instructions for signed integer. */
21546
21547static void
21548do_neon_dotproduct_s (void)
21549{
21550 return do_neon_dotproduct (0);
21551}
21552
21553/* Dot Product instructions for unsigned integer. */
21554
21555static void
21556do_neon_dotproduct_u (void)
21557{
21558 return do_neon_dotproduct (1);
21559}
21560
616ce08e
MM
21561static void
21562do_vusdot (void)
21563{
21564 enum neon_shape rs;
21565 set_pred_insn_type (OUTSIDE_PRED_INSN);
21566 if (inst.operands[2].isscalar)
21567 {
21568 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21569 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21570
21571 inst.instruction |= (1 << 25);
21572 int index = inst.operands[2].reg & 0xf;
21573 constraint ((index != 1 && index != 0), _("index must be 0 or 1"));
21574 inst.operands[2].reg >>= 4;
21575 constraint (!(inst.operands[2].reg < 16),
21576 _("indexed register must be less than 16"));
21577 neon_three_args (rs == NS_QQS);
21578 inst.instruction |= (index << 5);
21579 }
21580 else
21581 {
21582 inst.instruction |= (1 << 21);
21583 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
21584 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21585 neon_three_args (rs == NS_QQQ);
21586 }
21587}
21588
21589static void
21590do_vsudot (void)
21591{
21592 enum neon_shape rs;
21593 set_pred_insn_type (OUTSIDE_PRED_INSN);
21594 if (inst.operands[2].isscalar)
21595 {
21596 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
21597 neon_check_type (3, rs, N_EQK, N_EQK, N_U8 | N_KEY);
21598
21599 inst.instruction |= (1 << 25);
21600 int index = inst.operands[2].reg & 0xf;
21601 constraint ((index != 1 && index != 0), _("index must be 0 or 1"));
21602 inst.operands[2].reg >>= 4;
21603 constraint (!(inst.operands[2].reg < 16),
21604 _("indexed register must be less than 16"));
21605 neon_three_args (rs == NS_QQS);
21606 inst.instruction |= (index << 5);
21607 }
21608}
21609
21610static void
21611do_vsmmla (void)
21612{
21613 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
21614 neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_KEY);
21615
21616 set_pred_insn_type (OUTSIDE_PRED_INSN);
21617
21618 neon_three_args (1);
21619
21620}
21621
21622static void
21623do_vummla (void)
21624{
21625 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
21626 neon_check_type (3, rs, N_EQK, N_EQK, N_U8 | N_KEY);
21627
21628 set_pred_insn_type (OUTSIDE_PRED_INSN);
21629
21630 neon_three_args (1);
21631
21632}
21633
4934a27c
MM
21634static void
21635check_cde_operand (size_t index, int is_dual)
21636{
21637 unsigned Rx = inst.operands[index].reg;
21638 bfd_boolean isvec = inst.operands[index].isvec;
21639 if (is_dual == 0 && thumb_mode)
21640 constraint (
21641 !((Rx <= 14 && Rx != 13) || (Rx == REG_PC && isvec)),
21642 _("Register must be r0-r14 except r13, or APSR_nzcv."));
21643 else
21644 constraint ( !((Rx <= 10 && Rx % 2 == 0 )),
21645 _("Register must be an even register between r0-r10."));
21646}
21647
21648static bfd_boolean
21649cde_coproc_enabled (unsigned coproc)
21650{
21651 switch (coproc)
21652 {
21653 case 0: return mark_feature_used (&arm_ext_cde0);
21654 case 1: return mark_feature_used (&arm_ext_cde1);
21655 case 2: return mark_feature_used (&arm_ext_cde2);
21656 case 3: return mark_feature_used (&arm_ext_cde3);
21657 case 4: return mark_feature_used (&arm_ext_cde4);
21658 case 5: return mark_feature_used (&arm_ext_cde5);
21659 case 6: return mark_feature_used (&arm_ext_cde6);
21660 case 7: return mark_feature_used (&arm_ext_cde7);
21661 default: return FALSE;
21662 }
21663}
21664
21665#define cde_coproc_pos 8
21666static void
21667cde_handle_coproc (void)
21668{
21669 unsigned coproc = inst.operands[0].reg;
21670 constraint (coproc > 7, _("CDE Coprocessor must be in range 0-7"));
21671 constraint (!(cde_coproc_enabled (coproc)), BAD_CDE_COPROC);
21672 inst.instruction |= coproc << cde_coproc_pos;
21673}
21674#undef cde_coproc_pos
21675
21676static void
21677cxn_handle_predication (bfd_boolean is_accum)
21678{
cceb53b8
MM
21679 if (is_accum && conditional_insn ())
21680 set_pred_insn_type (INSIDE_IT_INSN);
21681 else if (conditional_insn ())
21682 /* conditional_insn essentially checks for a suffix, not whether the
21683 instruction is inside an IT block or not.
21684 The non-accumulator versions should not have suffixes. */
4934a27c 21685 inst.error = BAD_SYNTAX;
4934a27c
MM
21686 else
21687 set_pred_insn_type (OUTSIDE_PRED_INSN);
21688}
21689
21690static void
21691do_custom_instruction_1 (int is_dual, bfd_boolean is_accum)
21692{
21693
21694 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21695
21696 unsigned imm, Rd;
21697
21698 Rd = inst.operands[1].reg;
21699 check_cde_operand (1, is_dual);
21700
21701 if (is_dual == 1)
21702 {
21703 constraint (inst.operands[2].reg != Rd + 1,
21704 _("cx1d requires consecutive destination registers."));
21705 imm = inst.operands[3].imm;
21706 }
21707 else if (is_dual == 0)
21708 imm = inst.operands[2].imm;
21709 else
21710 abort ();
21711
21712 inst.instruction |= Rd << 12;
21713 inst.instruction |= (imm & 0x1F80) << 9;
21714 inst.instruction |= (imm & 0x0040) << 1;
21715 inst.instruction |= (imm & 0x003f);
21716
21717 cde_handle_coproc ();
21718 cxn_handle_predication (is_accum);
21719}
21720
21721static void
21722do_custom_instruction_2 (int is_dual, bfd_boolean is_accum)
21723{
21724
21725 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21726
21727 unsigned imm, Rd, Rn;
21728
21729 Rd = inst.operands[1].reg;
21730
21731 if (is_dual == 1)
21732 {
21733 constraint (inst.operands[2].reg != Rd + 1,
21734 _("cx2d requires consecutive destination registers."));
21735 imm = inst.operands[4].imm;
21736 Rn = inst.operands[3].reg;
21737 }
21738 else if (is_dual == 0)
21739 {
21740 imm = inst.operands[3].imm;
21741 Rn = inst.operands[2].reg;
21742 }
21743 else
21744 abort ();
21745
21746 check_cde_operand (2 + is_dual, /* is_dual = */0);
21747 check_cde_operand (1, is_dual);
21748
21749 inst.instruction |= Rd << 12;
21750 inst.instruction |= Rn << 16;
21751
21752 inst.instruction |= (imm & 0x0380) << 13;
21753 inst.instruction |= (imm & 0x0040) << 1;
21754 inst.instruction |= (imm & 0x003f);
21755
21756 cde_handle_coproc ();
21757 cxn_handle_predication (is_accum);
21758}
21759
21760static void
21761do_custom_instruction_3 (int is_dual, bfd_boolean is_accum)
21762{
21763
21764 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
21765
21766 unsigned imm, Rd, Rn, Rm;
21767
21768 Rd = inst.operands[1].reg;
21769
21770 if (is_dual == 1)
21771 {
21772 constraint (inst.operands[2].reg != Rd + 1,
21773 _("cx3d requires consecutive destination registers."));
21774 imm = inst.operands[5].imm;
21775 Rn = inst.operands[3].reg;
21776 Rm = inst.operands[4].reg;
21777 }
21778 else if (is_dual == 0)
21779 {
21780 imm = inst.operands[4].imm;
21781 Rn = inst.operands[2].reg;
21782 Rm = inst.operands[3].reg;
21783 }
21784 else
21785 abort ();
21786
21787 check_cde_operand (1, is_dual);
21788 check_cde_operand (2 + is_dual, /* is_dual = */0);
21789 check_cde_operand (3 + is_dual, /* is_dual = */0);
21790
21791 inst.instruction |= Rd;
21792 inst.instruction |= Rn << 16;
21793 inst.instruction |= Rm << 12;
21794
21795 inst.instruction |= (imm & 0x0038) << 17;
21796 inst.instruction |= (imm & 0x0004) << 5;
21797 inst.instruction |= (imm & 0x0003) << 4;
21798
21799 cde_handle_coproc ();
21800 cxn_handle_predication (is_accum);
21801}
21802
21803static void
21804do_cx1 (void)
21805{
21806 return do_custom_instruction_1 (0, 0);
21807}
21808
21809static void
21810do_cx1a (void)
21811{
21812 return do_custom_instruction_1 (0, 1);
21813}
21814
21815static void
21816do_cx1d (void)
21817{
21818 return do_custom_instruction_1 (1, 0);
21819}
21820
21821static void
21822do_cx1da (void)
21823{
21824 return do_custom_instruction_1 (1, 1);
21825}
21826
21827static void
21828do_cx2 (void)
21829{
21830 return do_custom_instruction_2 (0, 0);
21831}
21832
21833static void
21834do_cx2a (void)
21835{
21836 return do_custom_instruction_2 (0, 1);
21837}
21838
21839static void
21840do_cx2d (void)
21841{
21842 return do_custom_instruction_2 (1, 0);
21843}
21844
21845static void
21846do_cx2da (void)
21847{
21848 return do_custom_instruction_2 (1, 1);
21849}
21850
21851static void
21852do_cx3 (void)
21853{
21854 return do_custom_instruction_3 (0, 0);
21855}
21856
21857static void
21858do_cx3a (void)
21859{
21860 return do_custom_instruction_3 (0, 1);
21861}
21862
21863static void
21864do_cx3d (void)
21865{
21866 return do_custom_instruction_3 (1, 0);
21867}
21868
21869static void
21870do_cx3da (void)
21871{
21872 return do_custom_instruction_3 (1, 1);
21873}
21874
5aae9ae9
MM
21875static void
21876vcx_assign_vec_d (unsigned regnum)
21877{
21878 inst.instruction |= HI4 (regnum) << 12;
21879 inst.instruction |= LOW1 (regnum) << 22;
21880}
21881
21882static void
21883vcx_assign_vec_m (unsigned regnum)
21884{
21885 inst.instruction |= HI4 (regnum);
21886 inst.instruction |= LOW1 (regnum) << 5;
21887}
21888
21889static void
21890vcx_assign_vec_n (unsigned regnum)
21891{
21892 inst.instruction |= HI4 (regnum) << 16;
21893 inst.instruction |= LOW1 (regnum) << 7;
21894}
21895
21896enum vcx_reg_type {
21897 q_reg,
21898 d_reg,
21899 s_reg
21900};
21901
21902static enum vcx_reg_type
21903vcx_get_reg_type (enum neon_shape ns)
21904{
21905 gas_assert (ns == NS_PQI
21906 || ns == NS_PDI
21907 || ns == NS_PFI
21908 || ns == NS_PQQI
21909 || ns == NS_PDDI
21910 || ns == NS_PFFI
21911 || ns == NS_PQQQI
21912 || ns == NS_PDDDI
21913 || ns == NS_PFFFI);
21914 if (ns == NS_PQI || ns == NS_PQQI || ns == NS_PQQQI)
21915 return q_reg;
21916 if (ns == NS_PDI || ns == NS_PDDI || ns == NS_PDDDI)
21917 return d_reg;
21918 return s_reg;
21919}
21920
21921#define vcx_size_pos 24
21922#define vcx_vec_pos 6
21923static unsigned
21924vcx_handle_shape (enum vcx_reg_type reg_type)
21925{
21926 unsigned mult = 2;
21927 if (reg_type == q_reg)
21928 inst.instruction |= 1 << vcx_vec_pos;
21929 else if (reg_type == d_reg)
21930 inst.instruction |= 1 << vcx_size_pos;
21931 else
21932 mult = 1;
21933 /* NOTE:
21934 The documentation says that the Q registers are encoded as 2*N in the D:Vd
21935 bits (or equivalent for N and M registers).
21936 Similarly the D registers are encoded as N in D:Vd bits.
21937 While the S registers are encoded as N in the Vd:D bits.
21938
21939 Taking into account the maximum values of these registers we can see a
21940 nicer pattern for calculation:
21941 Q -> 7, D -> 15, S -> 31
21942
21943 If we say that everything is encoded in the Vd:D bits, then we can say
21944 that Q is encoded as 4*N, and D is encoded as 2*N.
21945 This way the bits will end up the same, and calculation is simpler.
21946 (calculation is now:
21947 1. Multiply by a number determined by the register letter.
21948 2. Encode resulting number in Vd:D bits.)
21949
21950 This is made a little more complicated by automatic handling of 'Q'
21951 registers elsewhere, which means the register number is already 2*N where
21952 N is the number the user wrote after the register letter.
21953 */
21954 return mult;
21955}
21956#undef vcx_vec_pos
21957#undef vcx_size_pos
21958
21959static void
21960vcx_ensure_register_in_range (unsigned R, enum vcx_reg_type reg_type)
21961{
21962 if (reg_type == q_reg)
21963 {
21964 gas_assert (R % 2 == 0);
21965 constraint (R >= 16, _("'q' register must be in range 0-7"));
21966 }
21967 else if (reg_type == d_reg)
21968 constraint (R >= 16, _("'d' register must be in range 0-15"));
21969 else
21970 constraint (R >= 32, _("'s' register must be in range 0-31"));
21971}
21972
21973static void (*vcx_assign_vec[3]) (unsigned) = {
21974 vcx_assign_vec_d,
21975 vcx_assign_vec_m,
21976 vcx_assign_vec_n
21977};
21978
21979static void
21980vcx_handle_register_arguments (unsigned num_registers,
21981 enum vcx_reg_type reg_type)
21982{
1ed818b4 21983 unsigned R, i;
5aae9ae9 21984 unsigned reg_mult = vcx_handle_shape (reg_type);
1ed818b4 21985 for (i = 0; i < num_registers; i++)
5aae9ae9
MM
21986 {
21987 R = inst.operands[i+1].reg;
21988 vcx_ensure_register_in_range (R, reg_type);
21989 if (num_registers == 3 && i > 0)
21990 {
21991 if (i == 2)
21992 vcx_assign_vec[1] (R * reg_mult);
21993 else
21994 vcx_assign_vec[2] (R * reg_mult);
21995 continue;
21996 }
21997 vcx_assign_vec[i](R * reg_mult);
21998 }
21999}
22000
22001static void
22002vcx_handle_insn_block (enum vcx_reg_type reg_type)
22003{
22004 if (reg_type == q_reg)
22005 if (inst.cond > COND_ALWAYS)
22006 inst.pred_insn_type = INSIDE_VPT_INSN;
22007 else
22008 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
22009 else if (inst.cond == COND_ALWAYS)
22010 inst.pred_insn_type = OUTSIDE_PRED_INSN;
22011 else
22012 inst.error = BAD_NOT_IT;
22013}
22014
22015static void
22016vcx_handle_common_checks (unsigned num_args, enum neon_shape rs)
22017{
22018 constraint (!mark_feature_used (&arm_ext_cde), _(BAD_CDE));
22019 cde_handle_coproc ();
22020 enum vcx_reg_type reg_type = vcx_get_reg_type (rs);
22021 vcx_handle_register_arguments (num_args, reg_type);
22022 vcx_handle_insn_block (reg_type);
22023 if (reg_type == q_reg)
22024 constraint (!mark_feature_used (&mve_ext),
22025 _("vcx instructions with Q registers require MVE"));
22026 else
22027 constraint (!(ARM_FSET_CPU_SUBSET (armv8m_fp, cpu_variant)
22028 && mark_feature_used (&armv8m_fp))
22029 && !mark_feature_used (&mve_ext),
22030 _("vcx instructions with S or D registers require either MVE"
22031 " or Armv8-M floating point etension."));
22032}
22033
22034static void
22035do_vcx1 (void)
22036{
22037 enum neon_shape rs = neon_select_shape (NS_PQI, NS_PDI, NS_PFI, NS_NULL);
22038 vcx_handle_common_checks (1, rs);
22039
22040 unsigned imm = inst.operands[2].imm;
22041 inst.instruction |= (imm & 0x03f);
22042 inst.instruction |= (imm & 0x040) << 1;
22043 inst.instruction |= (imm & 0x780) << 9;
22044 if (rs != NS_PQI)
22045 constraint (imm >= 2048,
22046 _("vcx1 with S or D registers takes immediate within 0-2047"));
22047 inst.instruction |= (imm & 0x800) << 13;
22048}
22049
22050static void
22051do_vcx2 (void)
22052{
22053 enum neon_shape rs = neon_select_shape (NS_PQQI, NS_PDDI, NS_PFFI, NS_NULL);
22054 vcx_handle_common_checks (2, rs);
22055
22056 unsigned imm = inst.operands[3].imm;
22057 inst.instruction |= (imm & 0x01) << 4;
22058 inst.instruction |= (imm & 0x02) << 6;
22059 inst.instruction |= (imm & 0x3c) << 14;
22060 if (rs != NS_PQQI)
22061 constraint (imm >= 64,
22062 _("vcx2 with S or D registers takes immediate within 0-63"));
22063 inst.instruction |= (imm & 0x40) << 18;
22064}
22065
22066static void
22067do_vcx3 (void)
22068{
22069 enum neon_shape rs = neon_select_shape (NS_PQQQI, NS_PDDDI, NS_PFFFI, NS_NULL);
22070 vcx_handle_common_checks (3, rs);
22071
22072 unsigned imm = inst.operands[4].imm;
22073 inst.instruction |= (imm & 0x1) << 4;
22074 inst.instruction |= (imm & 0x6) << 19;
22075 if (rs != NS_PQQQI)
22076 constraint (imm >= 8,
22077 _("vcx2 with S or D registers takes immediate within 0-7"));
22078 inst.instruction |= (imm & 0x8) << 21;
22079}
22080
91ff7894
MGD
22081/* Crypto v1 instructions. */
22082static void
22083do_crypto_2op_1 (unsigned elttype, int op)
22084{
5ee91343 22085 set_pred_insn_type (OUTSIDE_PRED_INSN);
91ff7894
MGD
22086
22087 if (neon_check_type (2, NS_QQ, N_EQK | N_UNT, elttype | N_UNT | N_KEY).type
22088 == NT_invtype)
22089 return;
22090
22091 inst.error = NULL;
22092
22093 NEON_ENCODE (INTEGER, inst);
22094 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
22095 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
22096 inst.instruction |= LOW4 (inst.operands[1].reg);
22097 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
22098 if (op != -1)
22099 inst.instruction |= op << 6;
22100
22101 if (thumb_mode)
22102 inst.instruction |= 0xfc000000;
22103 else
22104 inst.instruction |= 0xf0000000;
22105}
22106
48adcd8e
MGD
22107static void
22108do_crypto_3op_1 (int u, int op)
22109{
5ee91343 22110 set_pred_insn_type (OUTSIDE_PRED_INSN);
48adcd8e
MGD
22111
22112 if (neon_check_type (3, NS_QQQ, N_EQK | N_UNT, N_EQK | N_UNT,
22113 N_32 | N_UNT | N_KEY).type == NT_invtype)
22114 return;
22115
22116 inst.error = NULL;
22117
22118 NEON_ENCODE (INTEGER, inst);
22119 neon_three_same (1, u, 8 << op);
22120}
22121
91ff7894
MGD
22122static void
22123do_aese (void)
22124{
22125 do_crypto_2op_1 (N_8, 0);
22126}
22127
22128static void
22129do_aesd (void)
22130{
22131 do_crypto_2op_1 (N_8, 1);
22132}
22133
22134static void
22135do_aesmc (void)
22136{
22137 do_crypto_2op_1 (N_8, 2);
22138}
22139
22140static void
22141do_aesimc (void)
22142{
22143 do_crypto_2op_1 (N_8, 3);
22144}
22145
48adcd8e
MGD
22146static void
22147do_sha1c (void)
22148{
22149 do_crypto_3op_1 (0, 0);
22150}
22151
22152static void
22153do_sha1p (void)
22154{
22155 do_crypto_3op_1 (0, 1);
22156}
22157
22158static void
22159do_sha1m (void)
22160{
22161 do_crypto_3op_1 (0, 2);
22162}
22163
22164static void
22165do_sha1su0 (void)
22166{
22167 do_crypto_3op_1 (0, 3);
22168}
91ff7894 22169
48adcd8e
MGD
22170static void
22171do_sha256h (void)
22172{
22173 do_crypto_3op_1 (1, 0);
22174}
22175
22176static void
22177do_sha256h2 (void)
22178{
22179 do_crypto_3op_1 (1, 1);
22180}
22181
22182static void
22183do_sha256su1 (void)
22184{
22185 do_crypto_3op_1 (1, 2);
22186}
3c9017d2
MGD
22187
22188static void
22189do_sha1h (void)
22190{
22191 do_crypto_2op_1 (N_32, -1);
22192}
22193
22194static void
22195do_sha1su1 (void)
22196{
22197 do_crypto_2op_1 (N_32, 0);
22198}
22199
22200static void
22201do_sha256su0 (void)
22202{
22203 do_crypto_2op_1 (N_32, 1);
22204}
dd5181d5
KT
22205
22206static void
22207do_crc32_1 (unsigned int poly, unsigned int sz)
22208{
22209 unsigned int Rd = inst.operands[0].reg;
22210 unsigned int Rn = inst.operands[1].reg;
22211 unsigned int Rm = inst.operands[2].reg;
22212
5ee91343 22213 set_pred_insn_type (OUTSIDE_PRED_INSN);
dd5181d5
KT
22214 inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
22215 inst.instruction |= LOW4 (Rn) << 16;
22216 inst.instruction |= LOW4 (Rm);
22217 inst.instruction |= sz << (thumb_mode ? 4 : 21);
22218 inst.instruction |= poly << (thumb_mode ? 20 : 9);
22219
22220 if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
22221 as_warn (UNPRED_REG ("r15"));
dd5181d5
KT
22222}
22223
22224static void
22225do_crc32b (void)
22226{
22227 do_crc32_1 (0, 0);
22228}
22229
22230static void
22231do_crc32h (void)
22232{
22233 do_crc32_1 (0, 1);
22234}
22235
22236static void
22237do_crc32w (void)
22238{
22239 do_crc32_1 (0, 2);
22240}
22241
22242static void
22243do_crc32cb (void)
22244{
22245 do_crc32_1 (1, 0);
22246}
22247
22248static void
22249do_crc32ch (void)
22250{
22251 do_crc32_1 (1, 1);
22252}
22253
22254static void
22255do_crc32cw (void)
22256{
22257 do_crc32_1 (1, 2);
22258}
22259
49e8a725
SN
22260static void
22261do_vjcvt (void)
22262{
22263 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
22264 _(BAD_FPU));
22265 neon_check_type (2, NS_FD, N_S32, N_F64);
22266 do_vfp_sp_dp_cvt ();
22267 do_vfp_cond_or_thumb ();
22268}
22269
aab2c27d
MM
22270static void
22271do_vdot (void)
22272{
22273 enum neon_shape rs;
22274 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
22275 set_pred_insn_type (OUTSIDE_PRED_INSN);
22276 if (inst.operands[2].isscalar)
22277 {
22278 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
22279 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22280
22281 inst.instruction |= (1 << 25);
22282 int index = inst.operands[2].reg & 0xf;
22283 constraint ((index != 1 && index != 0), _("index must be 0 or 1"));
22284 inst.operands[2].reg >>= 4;
22285 constraint (!(inst.operands[2].reg < 16),
22286 _("indexed register must be less than 16"));
22287 neon_three_args (rs == NS_QQS);
22288 inst.instruction |= (index << 5);
22289 }
22290 else
22291 {
22292 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
22293 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22294 neon_three_args (rs == NS_QQQ);
22295 }
22296}
22297
22298static void
22299do_vmmla (void)
22300{
22301 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
22302 neon_check_type (3, rs, N_EQK, N_EQK, N_BF16 | N_KEY);
22303
22304 constraint (!mark_feature_used (&fpu_neon_ext_armv8), _(BAD_FPU));
22305 set_pred_insn_type (OUTSIDE_PRED_INSN);
22306
22307 neon_three_args (1);
22308}
22309
5287ad62
JB
22310\f
22311/* Overall per-instruction processing. */
22312
22313/* We need to be able to fix up arbitrary expressions in some statements.
22314 This is so that we can handle symbols that are an arbitrary distance from
22315 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
22316 which returns part of an address in a form which will be valid for
22317 a data instruction. We do this by pushing the expression into a symbol
22318 in the expr_section, and creating a fix for that. */
22319
22320static void
22321fix_new_arm (fragS * frag,
22322 int where,
22323 short int size,
22324 expressionS * exp,
22325 int pc_rel,
22326 int reloc)
22327{
22328 fixS * new_fix;
22329
22330 switch (exp->X_op)
22331 {
22332 case O_constant:
6e7ce2cd
PB
22333 if (pc_rel)
22334 {
22335 /* Create an absolute valued symbol, so we have something to
477330fc
RM
22336 refer to in the object file. Unfortunately for us, gas's
22337 generic expression parsing will already have folded out
22338 any use of .set foo/.type foo %function that may have
22339 been used to set type information of the target location,
22340 that's being specified symbolically. We have to presume
22341 the user knows what they are doing. */
6e7ce2cd
PB
22342 char name[16 + 8];
22343 symbolS *symbol;
22344
22345 sprintf (name, "*ABS*0x%lx", (unsigned long)exp->X_add_number);
22346
22347 symbol = symbol_find_or_make (name);
22348 S_SET_SEGMENT (symbol, absolute_section);
22349 symbol_set_frag (symbol, &zero_address_frag);
22350 S_SET_VALUE (symbol, exp->X_add_number);
22351 exp->X_op = O_symbol;
22352 exp->X_add_symbol = symbol;
22353 exp->X_add_number = 0;
22354 }
22355 /* FALLTHROUGH */
5287ad62
JB
22356 case O_symbol:
22357 case O_add:
22358 case O_subtract:
21d799b5 22359 new_fix = fix_new_exp (frag, where, size, exp, pc_rel,
477330fc 22360 (enum bfd_reloc_code_real) reloc);
5287ad62
JB
22361 break;
22362
22363 default:
21d799b5 22364 new_fix = (fixS *) fix_new (frag, where, size, make_expr_symbol (exp), 0,
477330fc 22365 pc_rel, (enum bfd_reloc_code_real) reloc);
5287ad62
JB
22366 break;
22367 }
22368
22369 /* Mark whether the fix is to a THUMB instruction, or an ARM
22370 instruction. */
22371 new_fix->tc_fix_data = thumb_mode;
22372}
22373
22374/* Create a frg for an instruction requiring relaxation. */
22375static void
22376output_relax_insn (void)
22377{
22378 char * to;
22379 symbolS *sym;
0110f2b8
PB
22380 int offset;
22381
6e1cb1a6
PB
22382 /* The size of the instruction is unknown, so tie the debug info to the
22383 start of the instruction. */
22384 dwarf2_emit_insn (0);
6e1cb1a6 22385
e2b0ab59 22386 switch (inst.relocs[0].exp.X_op)
0110f2b8
PB
22387 {
22388 case O_symbol:
e2b0ab59
AV
22389 sym = inst.relocs[0].exp.X_add_symbol;
22390 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
22391 break;
22392 case O_constant:
22393 sym = NULL;
e2b0ab59 22394 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
22395 break;
22396 default:
e2b0ab59 22397 sym = make_expr_symbol (&inst.relocs[0].exp);
0110f2b8
PB
22398 offset = 0;
22399 break;
22400 }
22401 to = frag_var (rs_machine_dependent, INSN_SIZE, THUMB_SIZE,
22402 inst.relax, sym, offset, NULL/*offset, opcode*/);
22403 md_number_to_chars (to, inst.instruction, THUMB_SIZE);
0110f2b8
PB
22404}
22405
22406/* Write a 32-bit thumb instruction to buf. */
22407static void
22408put_thumb32_insn (char * buf, unsigned long insn)
22409{
22410 md_number_to_chars (buf, insn >> 16, THUMB_SIZE);
22411 md_number_to_chars (buf + THUMB_SIZE, insn, THUMB_SIZE);
22412}
22413
b99bd4ef 22414static void
c19d1205 22415output_inst (const char * str)
b99bd4ef 22416{
c19d1205 22417 char * to = NULL;
b99bd4ef 22418
c19d1205 22419 if (inst.error)
b99bd4ef 22420 {
c19d1205 22421 as_bad ("%s -- `%s'", inst.error, str);
b99bd4ef
NC
22422 return;
22423 }
5f4273c7
NC
22424 if (inst.relax)
22425 {
22426 output_relax_insn ();
0110f2b8 22427 return;
5f4273c7 22428 }
c19d1205
ZW
22429 if (inst.size == 0)
22430 return;
b99bd4ef 22431
c19d1205 22432 to = frag_more (inst.size);
8dc2430f
NC
22433 /* PR 9814: Record the thumb mode into the current frag so that we know
22434 what type of NOP padding to use, if necessary. We override any previous
22435 setting so that if the mode has changed then the NOPS that we use will
22436 match the encoding of the last instruction in the frag. */
cd000bff 22437 frag_now->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
c19d1205
ZW
22438
22439 if (thumb_mode && (inst.size > THUMB_SIZE))
b99bd4ef 22440 {
9c2799c2 22441 gas_assert (inst.size == (2 * THUMB_SIZE));
0110f2b8 22442 put_thumb32_insn (to, inst.instruction);
b99bd4ef 22443 }
c19d1205 22444 else if (inst.size > INSN_SIZE)
b99bd4ef 22445 {
9c2799c2 22446 gas_assert (inst.size == (2 * INSN_SIZE));
c19d1205
ZW
22447 md_number_to_chars (to, inst.instruction, INSN_SIZE);
22448 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
b99bd4ef 22449 }
c19d1205
ZW
22450 else
22451 md_number_to_chars (to, inst.instruction, inst.size);
b99bd4ef 22452
e2b0ab59
AV
22453 int r;
22454 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
22455 {
22456 if (inst.relocs[r].type != BFD_RELOC_UNUSED)
22457 fix_new_arm (frag_now, to - frag_now->fr_literal,
22458 inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
22459 inst.relocs[r].type);
22460 }
b99bd4ef 22461
c19d1205 22462 dwarf2_emit_insn (inst.size);
c19d1205 22463}
b99bd4ef 22464
e07e6e58
NC
22465static char *
22466output_it_inst (int cond, int mask, char * to)
22467{
22468 unsigned long instruction = 0xbf00;
22469
22470 mask &= 0xf;
22471 instruction |= mask;
22472 instruction |= cond << 4;
22473
22474 if (to == NULL)
22475 {
22476 to = frag_more (2);
22477#ifdef OBJ_ELF
22478 dwarf2_emit_insn (2);
22479#endif
22480 }
22481
22482 md_number_to_chars (to, instruction, 2);
22483
22484 return to;
22485}
22486
c19d1205
ZW
22487/* Tag values used in struct asm_opcode's tag field. */
22488enum opcode_tag
22489{
22490 OT_unconditional, /* Instruction cannot be conditionalized.
22491 The ARM condition field is still 0xE. */
22492 OT_unconditionalF, /* Instruction cannot be conditionalized
22493 and carries 0xF in its ARM condition field. */
22494 OT_csuffix, /* Instruction takes a conditional suffix. */
5ee91343
AV
22495 OT_csuffixF, /* Some forms of the instruction take a scalar
22496 conditional suffix, others place 0xF where the
22497 condition field would be, others take a vector
22498 conditional suffix. */
c19d1205
ZW
22499 OT_cinfix3, /* Instruction takes a conditional infix,
22500 beginning at character index 3. (In
22501 unified mode, it becomes a suffix.) */
088fa78e
KH
22502 OT_cinfix3_deprecated, /* The same as OT_cinfix3. This is used for
22503 tsts, cmps, cmns, and teqs. */
e3cb604e
PB
22504 OT_cinfix3_legacy, /* Legacy instruction takes a conditional infix at
22505 character index 3, even in unified mode. Used for
22506 legacy instructions where suffix and infix forms
22507 may be ambiguous. */
c19d1205 22508 OT_csuf_or_in3, /* Instruction takes either a conditional
e3cb604e 22509 suffix or an infix at character index 3. */
c19d1205
ZW
22510 OT_odd_infix_unc, /* This is the unconditional variant of an
22511 instruction that takes a conditional infix
22512 at an unusual position. In unified mode,
22513 this variant will accept a suffix. */
22514 OT_odd_infix_0 /* Values greater than or equal to OT_odd_infix_0
22515 are the conditional variants of instructions that
22516 take conditional infixes in unusual positions.
22517 The infix appears at character index
22518 (tag - OT_odd_infix_0). These are not accepted
22519 in unified mode. */
22520};
b99bd4ef 22521
c19d1205
ZW
22522/* Subroutine of md_assemble, responsible for looking up the primary
22523 opcode from the mnemonic the user wrote. STR points to the
22524 beginning of the mnemonic.
22525
22526 This is not simply a hash table lookup, because of conditional
22527 variants. Most instructions have conditional variants, which are
22528 expressed with a _conditional affix_ to the mnemonic. If we were
22529 to encode each conditional variant as a literal string in the opcode
22530 table, it would have approximately 20,000 entries.
22531
22532 Most mnemonics take this affix as a suffix, and in unified syntax,
22533 'most' is upgraded to 'all'. However, in the divided syntax, some
22534 instructions take the affix as an infix, notably the s-variants of
22535 the arithmetic instructions. Of those instructions, all but six
22536 have the infix appear after the third character of the mnemonic.
22537
22538 Accordingly, the algorithm for looking up primary opcodes given
22539 an identifier is:
22540
22541 1. Look up the identifier in the opcode table.
22542 If we find a match, go to step U.
22543
22544 2. Look up the last two characters of the identifier in the
22545 conditions table. If we find a match, look up the first N-2
22546 characters of the identifier in the opcode table. If we
22547 find a match, go to step CE.
22548
22549 3. Look up the fourth and fifth characters of the identifier in
22550 the conditions table. If we find a match, extract those
22551 characters from the identifier, and look up the remaining
22552 characters in the opcode table. If we find a match, go
22553 to step CM.
22554
22555 4. Fail.
22556
22557 U. Examine the tag field of the opcode structure, in case this is
22558 one of the six instructions with its conditional infix in an
22559 unusual place. If it is, the tag tells us where to find the
22560 infix; look it up in the conditions table and set inst.cond
22561 accordingly. Otherwise, this is an unconditional instruction.
22562 Again set inst.cond accordingly. Return the opcode structure.
22563
22564 CE. Examine the tag field to make sure this is an instruction that
22565 should receive a conditional suffix. If it is not, fail.
22566 Otherwise, set inst.cond from the suffix we already looked up,
22567 and return the opcode structure.
22568
22569 CM. Examine the tag field to make sure this is an instruction that
22570 should receive a conditional infix after the third character.
22571 If it is not, fail. Otherwise, undo the edits to the current
22572 line of input and proceed as for case CE. */
22573
22574static const struct asm_opcode *
22575opcode_lookup (char **str)
22576{
22577 char *end, *base;
22578 char *affix;
22579 const struct asm_opcode *opcode;
22580 const struct asm_cond *cond;
e3cb604e 22581 char save[2];
c19d1205
ZW
22582
22583 /* Scan up to the end of the mnemonic, which must end in white space,
721a8186 22584 '.' (in unified mode, or for Neon/VFP instructions), or end of string. */
c19d1205 22585 for (base = end = *str; *end != '\0'; end++)
721a8186 22586 if (*end == ' ' || *end == '.')
c19d1205 22587 break;
b99bd4ef 22588
c19d1205 22589 if (end == base)
c921be7d 22590 return NULL;
b99bd4ef 22591
5287ad62 22592 /* Handle a possible width suffix and/or Neon type suffix. */
c19d1205 22593 if (end[0] == '.')
b99bd4ef 22594 {
5287ad62 22595 int offset = 2;
5f4273c7 22596
267d2029 22597 /* The .w and .n suffixes are only valid if the unified syntax is in
477330fc 22598 use. */
267d2029 22599 if (unified_syntax && end[1] == 'w')
c19d1205 22600 inst.size_req = 4;
267d2029 22601 else if (unified_syntax && end[1] == 'n')
c19d1205
ZW
22602 inst.size_req = 2;
22603 else
477330fc 22604 offset = 0;
5287ad62
JB
22605
22606 inst.vectype.elems = 0;
22607
22608 *str = end + offset;
b99bd4ef 22609
5f4273c7 22610 if (end[offset] == '.')
5287ad62 22611 {
267d2029 22612 /* See if we have a Neon type suffix (possible in either unified or
477330fc
RM
22613 non-unified ARM syntax mode). */
22614 if (parse_neon_type (&inst.vectype, str) == FAIL)
c921be7d 22615 return NULL;
477330fc 22616 }
5287ad62 22617 else if (end[offset] != '\0' && end[offset] != ' ')
477330fc 22618 return NULL;
b99bd4ef 22619 }
c19d1205
ZW
22620 else
22621 *str = end;
b99bd4ef 22622
c19d1205 22623 /* Look for unaffixed or special-case affixed mnemonic. */
21d799b5 22624 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 22625 end - base);
c19d1205 22626 if (opcode)
b99bd4ef 22627 {
c19d1205
ZW
22628 /* step U */
22629 if (opcode->tag < OT_odd_infix_0)
b99bd4ef 22630 {
c19d1205
ZW
22631 inst.cond = COND_ALWAYS;
22632 return opcode;
b99bd4ef 22633 }
b99bd4ef 22634
278df34e 22635 if (warn_on_deprecated && unified_syntax)
5c3696f8 22636 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205 22637 affix = base + (opcode->tag - OT_odd_infix_0);
21d799b5 22638 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
9c2799c2 22639 gas_assert (cond);
b99bd4ef 22640
c19d1205
ZW
22641 inst.cond = cond->value;
22642 return opcode;
22643 }
5ee91343
AV
22644 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
22645 {
22646 /* Cannot have a conditional suffix on a mnemonic of less than a character.
22647 */
22648 if (end - base < 2)
22649 return NULL;
22650 affix = end - 1;
22651 cond = (const struct asm_cond *) hash_find_n (arm_vcond_hsh, affix, 1);
22652 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
22653 affix - base);
22654 /* If this opcode can not be vector predicated then don't accept it with a
22655 vector predication code. */
22656 if (opcode && !opcode->mayBeVecPred)
22657 opcode = NULL;
22658 }
22659 if (!opcode || !cond)
22660 {
22661 /* Cannot have a conditional suffix on a mnemonic of less than two
22662 characters. */
22663 if (end - base < 3)
22664 return NULL;
b99bd4ef 22665
5ee91343
AV
22666 /* Look for suffixed mnemonic. */
22667 affix = end - 2;
22668 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
22669 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
22670 affix - base);
22671 }
b99bd4ef 22672
c19d1205
ZW
22673 if (opcode && cond)
22674 {
22675 /* step CE */
22676 switch (opcode->tag)
22677 {
e3cb604e
PB
22678 case OT_cinfix3_legacy:
22679 /* Ignore conditional suffixes matched on infix only mnemonics. */
22680 break;
22681
c19d1205 22682 case OT_cinfix3:
088fa78e 22683 case OT_cinfix3_deprecated:
c19d1205
ZW
22684 case OT_odd_infix_unc:
22685 if (!unified_syntax)
0198d5e6 22686 return NULL;
1a0670f3 22687 /* Fall through. */
c19d1205
ZW
22688
22689 case OT_csuffix:
477330fc 22690 case OT_csuffixF:
c19d1205
ZW
22691 case OT_csuf_or_in3:
22692 inst.cond = cond->value;
22693 return opcode;
22694
22695 case OT_unconditional:
22696 case OT_unconditionalF:
dfa9f0d5 22697 if (thumb_mode)
c921be7d 22698 inst.cond = cond->value;
dfa9f0d5
PB
22699 else
22700 {
c921be7d 22701 /* Delayed diagnostic. */
dfa9f0d5
PB
22702 inst.error = BAD_COND;
22703 inst.cond = COND_ALWAYS;
22704 }
c19d1205 22705 return opcode;
b99bd4ef 22706
c19d1205 22707 default:
c921be7d 22708 return NULL;
c19d1205
ZW
22709 }
22710 }
b99bd4ef 22711
c19d1205
ZW
22712 /* Cannot have a usual-position infix on a mnemonic of less than
22713 six characters (five would be a suffix). */
22714 if (end - base < 6)
c921be7d 22715 return NULL;
b99bd4ef 22716
c19d1205
ZW
22717 /* Look for infixed mnemonic in the usual position. */
22718 affix = base + 3;
21d799b5 22719 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
e3cb604e 22720 if (!cond)
c921be7d 22721 return NULL;
e3cb604e
PB
22722
22723 memcpy (save, affix, 2);
22724 memmove (affix, affix + 2, (end - affix) - 2);
21d799b5 22725 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 22726 (end - base) - 2);
e3cb604e
PB
22727 memmove (affix + 2, affix, (end - affix) - 2);
22728 memcpy (affix, save, 2);
22729
088fa78e
KH
22730 if (opcode
22731 && (opcode->tag == OT_cinfix3
22732 || opcode->tag == OT_cinfix3_deprecated
22733 || opcode->tag == OT_csuf_or_in3
22734 || opcode->tag == OT_cinfix3_legacy))
b99bd4ef 22735 {
c921be7d 22736 /* Step CM. */
278df34e 22737 if (warn_on_deprecated && unified_syntax
088fa78e
KH
22738 && (opcode->tag == OT_cinfix3
22739 || opcode->tag == OT_cinfix3_deprecated))
5c3696f8 22740 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205
ZW
22741
22742 inst.cond = cond->value;
22743 return opcode;
b99bd4ef
NC
22744 }
22745
c921be7d 22746 return NULL;
b99bd4ef
NC
22747}
22748
e07e6e58
NC
22749/* This function generates an initial IT instruction, leaving its block
22750 virtually open for the new instructions. Eventually,
5ee91343 22751 the mask will be updated by now_pred_add_mask () each time
e07e6e58
NC
22752 a new instruction needs to be included in the IT block.
22753 Finally, the block is closed with close_automatic_it_block ().
22754 The block closure can be requested either from md_assemble (),
22755 a tencode (), or due to a label hook. */
22756
22757static void
22758new_automatic_it_block (int cond)
22759{
5ee91343
AV
22760 now_pred.state = AUTOMATIC_PRED_BLOCK;
22761 now_pred.mask = 0x18;
22762 now_pred.cc = cond;
22763 now_pred.block_length = 1;
cd000bff 22764 mapping_state (MAP_THUMB);
5ee91343
AV
22765 now_pred.insn = output_it_inst (cond, now_pred.mask, NULL);
22766 now_pred.warn_deprecated = FALSE;
22767 now_pred.insn_cond = TRUE;
e07e6e58
NC
22768}
22769
22770/* Close an automatic IT block.
22771 See comments in new_automatic_it_block (). */
22772
22773static void
22774close_automatic_it_block (void)
22775{
5ee91343
AV
22776 now_pred.mask = 0x10;
22777 now_pred.block_length = 0;
e07e6e58
NC
22778}
22779
22780/* Update the mask of the current automatically-generated IT
22781 instruction. See comments in new_automatic_it_block (). */
22782
22783static void
5ee91343 22784now_pred_add_mask (int cond)
e07e6e58
NC
22785{
22786#define CLEAR_BIT(value, nbit) ((value) & ~(1 << (nbit)))
22787#define SET_BIT_VALUE(value, bitvalue, nbit) (CLEAR_BIT (value, nbit) \
477330fc 22788 | ((bitvalue) << (nbit)))
e07e6e58 22789 const int resulting_bit = (cond & 1);
c921be7d 22790
5ee91343
AV
22791 now_pred.mask &= 0xf;
22792 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 22793 resulting_bit,
5ee91343
AV
22794 (5 - now_pred.block_length));
22795 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 22796 1,
5ee91343
AV
22797 ((5 - now_pred.block_length) - 1));
22798 output_it_inst (now_pred.cc, now_pred.mask, now_pred.insn);
e07e6e58
NC
22799
22800#undef CLEAR_BIT
22801#undef SET_BIT_VALUE
e07e6e58
NC
22802}
22803
22804/* The IT blocks handling machinery is accessed through the these functions:
22805 it_fsm_pre_encode () from md_assemble ()
5ee91343
AV
22806 set_pred_insn_type () optional, from the tencode functions
22807 set_pred_insn_type_last () ditto
22808 in_pred_block () ditto
e07e6e58 22809 it_fsm_post_encode () from md_assemble ()
33eaf5de 22810 force_automatic_it_block_close () from label handling functions
e07e6e58
NC
22811
22812 Rationale:
22813 1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
477330fc
RM
22814 initializing the IT insn type with a generic initial value depending
22815 on the inst.condition.
e07e6e58 22816 2) During the tencode function, two things may happen:
477330fc 22817 a) The tencode function overrides the IT insn type by
5ee91343
AV
22818 calling either set_pred_insn_type (type) or
22819 set_pred_insn_type_last ().
477330fc 22820 b) The tencode function queries the IT block state by
5ee91343 22821 calling in_pred_block () (i.e. to determine narrow/not narrow mode).
477330fc 22822
5ee91343
AV
22823 Both set_pred_insn_type and in_pred_block run the internal FSM state
22824 handling function (handle_pred_state), because: a) setting the IT insn
477330fc
RM
22825 type may incur in an invalid state (exiting the function),
22826 and b) querying the state requires the FSM to be updated.
22827 Specifically we want to avoid creating an IT block for conditional
22828 branches, so it_fsm_pre_encode is actually a guess and we can't
22829 determine whether an IT block is required until the tencode () routine
22830 has decided what type of instruction this actually it.
5ee91343
AV
22831 Because of this, if set_pred_insn_type and in_pred_block have to be
22832 used, set_pred_insn_type has to be called first.
477330fc 22833
5ee91343
AV
22834 set_pred_insn_type_last () is a wrapper of set_pred_insn_type (type),
22835 that determines the insn IT type depending on the inst.cond code.
477330fc
RM
22836 When a tencode () routine encodes an instruction that can be
22837 either outside an IT block, or, in the case of being inside, has to be
5ee91343 22838 the last one, set_pred_insn_type_last () will determine the proper
477330fc 22839 IT instruction type based on the inst.cond code. Otherwise,
5ee91343 22840 set_pred_insn_type can be called for overriding that logic or
477330fc
RM
22841 for covering other cases.
22842
5ee91343
AV
22843 Calling handle_pred_state () may not transition the IT block state to
22844 OUTSIDE_PRED_BLOCK immediately, since the (current) state could be
477330fc 22845 still queried. Instead, if the FSM determines that the state should
5ee91343 22846 be transitioned to OUTSIDE_PRED_BLOCK, a flag is marked to be closed
477330fc
RM
22847 after the tencode () function: that's what it_fsm_post_encode () does.
22848
5ee91343 22849 Since in_pred_block () calls the state handling function to get an
477330fc
RM
22850 updated state, an error may occur (due to invalid insns combination).
22851 In that case, inst.error is set.
22852 Therefore, inst.error has to be checked after the execution of
22853 the tencode () routine.
e07e6e58
NC
22854
22855 3) Back in md_assemble(), it_fsm_post_encode () is called to commit
477330fc 22856 any pending state change (if any) that didn't take place in
5ee91343 22857 handle_pred_state () as explained above. */
e07e6e58
NC
22858
22859static void
22860it_fsm_pre_encode (void)
22861{
22862 if (inst.cond != COND_ALWAYS)
5ee91343 22863 inst.pred_insn_type = INSIDE_IT_INSN;
e07e6e58 22864 else
5ee91343 22865 inst.pred_insn_type = OUTSIDE_PRED_INSN;
e07e6e58 22866
5ee91343 22867 now_pred.state_handled = 0;
e07e6e58
NC
22868}
22869
22870/* IT state FSM handling function. */
5ee91343
AV
22871/* MVE instructions and non-MVE instructions are handled differently because of
22872 the introduction of VPT blocks.
22873 Specifications say that any non-MVE instruction inside a VPT block is
22874 UNPREDICTABLE, with the exception of the BKPT instruction. Whereas most MVE
22875 instructions are deemed to be UNPREDICTABLE if inside an IT block. For the
35c228db 22876 few exceptions we have MVE_UNPREDICABLE_INSN.
5ee91343
AV
22877 The error messages provided depending on the different combinations possible
22878 are described in the cases below:
22879 For 'most' MVE instructions:
22880 1) In an IT block, with an IT code: syntax error
22881 2) In an IT block, with a VPT code: error: must be in a VPT block
22882 3) In an IT block, with no code: warning: UNPREDICTABLE
22883 4) In a VPT block, with an IT code: syntax error
22884 5) In a VPT block, with a VPT code: OK!
22885 6) In a VPT block, with no code: error: missing code
22886 7) Outside a pred block, with an IT code: error: syntax error
22887 8) Outside a pred block, with a VPT code: error: should be in a VPT block
22888 9) Outside a pred block, with no code: OK!
22889 For non-MVE instructions:
22890 10) In an IT block, with an IT code: OK!
22891 11) In an IT block, with a VPT code: syntax error
22892 12) In an IT block, with no code: error: missing code
22893 13) In a VPT block, with an IT code: error: should be in an IT block
22894 14) In a VPT block, with a VPT code: syntax error
22895 15) In a VPT block, with no code: UNPREDICTABLE
22896 16) Outside a pred block, with an IT code: error: should be in an IT block
22897 17) Outside a pred block, with a VPT code: syntax error
22898 18) Outside a pred block, with no code: OK!
22899 */
22900
e07e6e58
NC
22901
22902static int
5ee91343 22903handle_pred_state (void)
e07e6e58 22904{
5ee91343
AV
22905 now_pred.state_handled = 1;
22906 now_pred.insn_cond = FALSE;
e07e6e58 22907
5ee91343 22908 switch (now_pred.state)
e07e6e58 22909 {
5ee91343
AV
22910 case OUTSIDE_PRED_BLOCK:
22911 switch (inst.pred_insn_type)
e07e6e58 22912 {
35c228db 22913 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
22914 case MVE_OUTSIDE_PRED_INSN:
22915 if (inst.cond < COND_ALWAYS)
22916 {
22917 /* Case 7: Outside a pred block, with an IT code: error: syntax
22918 error. */
22919 inst.error = BAD_SYNTAX;
22920 return FAIL;
22921 }
22922 /* Case 9: Outside a pred block, with no code: OK! */
22923 break;
22924 case OUTSIDE_PRED_INSN:
22925 if (inst.cond > COND_ALWAYS)
22926 {
22927 /* Case 17: Outside a pred block, with a VPT code: syntax error.
22928 */
22929 inst.error = BAD_SYNTAX;
22930 return FAIL;
22931 }
22932 /* Case 18: Outside a pred block, with no code: OK! */
e07e6e58
NC
22933 break;
22934
5ee91343
AV
22935 case INSIDE_VPT_INSN:
22936 /* Case 8: Outside a pred block, with a VPT code: error: should be in
22937 a VPT block. */
22938 inst.error = BAD_OUT_VPT;
22939 return FAIL;
22940
e07e6e58
NC
22941 case INSIDE_IT_INSN:
22942 case INSIDE_IT_LAST_INSN:
5ee91343 22943 if (inst.cond < COND_ALWAYS)
e07e6e58 22944 {
5ee91343
AV
22945 /* Case 16: Outside a pred block, with an IT code: error: should
22946 be in an IT block. */
22947 if (thumb_mode == 0)
e07e6e58 22948 {
5ee91343
AV
22949 if (unified_syntax
22950 && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
22951 as_tsktsk (_("Warning: conditional outside an IT block"\
22952 " for Thumb."));
e07e6e58
NC
22953 }
22954 else
22955 {
5ee91343
AV
22956 if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
22957 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
22958 {
22959 /* Automatically generate the IT instruction. */
22960 new_automatic_it_block (inst.cond);
22961 if (inst.pred_insn_type == INSIDE_IT_LAST_INSN)
22962 close_automatic_it_block ();
22963 }
22964 else
22965 {
22966 inst.error = BAD_OUT_IT;
22967 return FAIL;
22968 }
e07e6e58 22969 }
5ee91343 22970 break;
e07e6e58 22971 }
5ee91343
AV
22972 else if (inst.cond > COND_ALWAYS)
22973 {
22974 /* Case 17: Outside a pred block, with a VPT code: syntax error.
22975 */
22976 inst.error = BAD_SYNTAX;
22977 return FAIL;
22978 }
22979 else
22980 gas_assert (0);
e07e6e58
NC
22981 case IF_INSIDE_IT_LAST_INSN:
22982 case NEUTRAL_IT_INSN:
22983 break;
22984
5ee91343
AV
22985 case VPT_INSN:
22986 if (inst.cond != COND_ALWAYS)
22987 first_error (BAD_SYNTAX);
22988 now_pred.state = MANUAL_PRED_BLOCK;
22989 now_pred.block_length = 0;
22990 now_pred.type = VECTOR_PRED;
22991 now_pred.cc = 0;
22992 break;
e07e6e58 22993 case IT_INSN:
5ee91343
AV
22994 now_pred.state = MANUAL_PRED_BLOCK;
22995 now_pred.block_length = 0;
22996 now_pred.type = SCALAR_PRED;
e07e6e58
NC
22997 break;
22998 }
22999 break;
23000
5ee91343 23001 case AUTOMATIC_PRED_BLOCK:
e07e6e58
NC
23002 /* Three things may happen now:
23003 a) We should increment current it block size;
23004 b) We should close current it block (closing insn or 4 insns);
23005 c) We should close current it block and start a new one (due
23006 to incompatible conditions or
23007 4 insns-length block reached). */
23008
5ee91343 23009 switch (inst.pred_insn_type)
e07e6e58 23010 {
5ee91343
AV
23011 case INSIDE_VPT_INSN:
23012 case VPT_INSN:
35c228db 23013 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
23014 case MVE_OUTSIDE_PRED_INSN:
23015 gas_assert (0);
23016 case OUTSIDE_PRED_INSN:
2b0f3761 23017 /* The closure of the block shall happen immediately,
5ee91343 23018 so any in_pred_block () call reports the block as closed. */
e07e6e58
NC
23019 force_automatic_it_block_close ();
23020 break;
23021
23022 case INSIDE_IT_INSN:
23023 case INSIDE_IT_LAST_INSN:
23024 case IF_INSIDE_IT_LAST_INSN:
5ee91343 23025 now_pred.block_length++;
e07e6e58 23026
5ee91343
AV
23027 if (now_pred.block_length > 4
23028 || !now_pred_compatible (inst.cond))
e07e6e58
NC
23029 {
23030 force_automatic_it_block_close ();
5ee91343 23031 if (inst.pred_insn_type != IF_INSIDE_IT_LAST_INSN)
e07e6e58
NC
23032 new_automatic_it_block (inst.cond);
23033 }
23034 else
23035 {
5ee91343
AV
23036 now_pred.insn_cond = TRUE;
23037 now_pred_add_mask (inst.cond);
e07e6e58
NC
23038 }
23039
5ee91343
AV
23040 if (now_pred.state == AUTOMATIC_PRED_BLOCK
23041 && (inst.pred_insn_type == INSIDE_IT_LAST_INSN
23042 || inst.pred_insn_type == IF_INSIDE_IT_LAST_INSN))
e07e6e58
NC
23043 close_automatic_it_block ();
23044 break;
23045
4934a27c 23046 /* Fallthrough. */
e07e6e58 23047 case NEUTRAL_IT_INSN:
5ee91343
AV
23048 now_pred.block_length++;
23049 now_pred.insn_cond = TRUE;
e07e6e58 23050
5ee91343 23051 if (now_pred.block_length > 4)
e07e6e58
NC
23052 force_automatic_it_block_close ();
23053 else
5ee91343 23054 now_pred_add_mask (now_pred.cc & 1);
e07e6e58
NC
23055 break;
23056
23057 case IT_INSN:
23058 close_automatic_it_block ();
5ee91343 23059 now_pred.state = MANUAL_PRED_BLOCK;
e07e6e58
NC
23060 break;
23061 }
23062 break;
23063
5ee91343 23064 case MANUAL_PRED_BLOCK:
e07e6e58 23065 {
5ee91343
AV
23066 int cond, is_last;
23067 if (now_pred.type == SCALAR_PRED)
e07e6e58 23068 {
5ee91343
AV
23069 /* Check conditional suffixes. */
23070 cond = now_pred.cc ^ ((now_pred.mask >> 4) & 1) ^ 1;
23071 now_pred.mask <<= 1;
23072 now_pred.mask &= 0x1f;
23073 is_last = (now_pred.mask == 0x10);
23074 }
23075 else
23076 {
23077 now_pred.cc ^= (now_pred.mask >> 4);
23078 cond = now_pred.cc + 0xf;
23079 now_pred.mask <<= 1;
23080 now_pred.mask &= 0x1f;
23081 is_last = now_pred.mask == 0x10;
23082 }
23083 now_pred.insn_cond = TRUE;
e07e6e58 23084
5ee91343
AV
23085 switch (inst.pred_insn_type)
23086 {
23087 case OUTSIDE_PRED_INSN:
23088 if (now_pred.type == SCALAR_PRED)
23089 {
23090 if (inst.cond == COND_ALWAYS)
23091 {
23092 /* Case 12: In an IT block, with no code: error: missing
23093 code. */
23094 inst.error = BAD_NOT_IT;
23095 return FAIL;
23096 }
23097 else if (inst.cond > COND_ALWAYS)
23098 {
23099 /* Case 11: In an IT block, with a VPT code: syntax error.
23100 */
23101 inst.error = BAD_SYNTAX;
23102 return FAIL;
23103 }
23104 else if (thumb_mode)
23105 {
23106 /* This is for some special cases where a non-MVE
23107 instruction is not allowed in an IT block, such as cbz,
23108 but are put into one with a condition code.
23109 You could argue this should be a syntax error, but we
23110 gave the 'not allowed in IT block' diagnostic in the
23111 past so we will keep doing so. */
23112 inst.error = BAD_NOT_IT;
23113 return FAIL;
23114 }
23115 break;
23116 }
23117 else
23118 {
23119 /* Case 15: In a VPT block, with no code: UNPREDICTABLE. */
23120 as_tsktsk (MVE_NOT_VPT);
23121 return SUCCESS;
23122 }
23123 case MVE_OUTSIDE_PRED_INSN:
23124 if (now_pred.type == SCALAR_PRED)
23125 {
23126 if (inst.cond == COND_ALWAYS)
23127 {
23128 /* Case 3: In an IT block, with no code: warning:
23129 UNPREDICTABLE. */
23130 as_tsktsk (MVE_NOT_IT);
23131 return SUCCESS;
23132 }
23133 else if (inst.cond < COND_ALWAYS)
23134 {
23135 /* Case 1: In an IT block, with an IT code: syntax error.
23136 */
23137 inst.error = BAD_SYNTAX;
23138 return FAIL;
23139 }
23140 else
23141 gas_assert (0);
23142 }
23143 else
23144 {
23145 if (inst.cond < COND_ALWAYS)
23146 {
23147 /* Case 4: In a VPT block, with an IT code: syntax error.
23148 */
23149 inst.error = BAD_SYNTAX;
23150 return FAIL;
23151 }
23152 else if (inst.cond == COND_ALWAYS)
23153 {
23154 /* Case 6: In a VPT block, with no code: error: missing
23155 code. */
23156 inst.error = BAD_NOT_VPT;
23157 return FAIL;
23158 }
23159 else
23160 {
23161 gas_assert (0);
23162 }
23163 }
35c228db
AV
23164 case MVE_UNPREDICABLE_INSN:
23165 as_tsktsk (now_pred.type == SCALAR_PRED ? MVE_NOT_IT : MVE_NOT_VPT);
23166 return SUCCESS;
e07e6e58 23167 case INSIDE_IT_INSN:
5ee91343 23168 if (inst.cond > COND_ALWAYS)
e07e6e58 23169 {
5ee91343
AV
23170 /* Case 11: In an IT block, with a VPT code: syntax error. */
23171 /* Case 14: In a VPT block, with a VPT code: syntax error. */
23172 inst.error = BAD_SYNTAX;
23173 return FAIL;
23174 }
23175 else if (now_pred.type == SCALAR_PRED)
23176 {
23177 /* Case 10: In an IT block, with an IT code: OK! */
23178 if (cond != inst.cond)
23179 {
23180 inst.error = now_pred.type == SCALAR_PRED ? BAD_IT_COND :
23181 BAD_VPT_COND;
23182 return FAIL;
23183 }
23184 }
23185 else
23186 {
23187 /* Case 13: In a VPT block, with an IT code: error: should be
23188 in an IT block. */
23189 inst.error = BAD_OUT_IT;
e07e6e58
NC
23190 return FAIL;
23191 }
23192 break;
23193
5ee91343
AV
23194 case INSIDE_VPT_INSN:
23195 if (now_pred.type == SCALAR_PRED)
23196 {
23197 /* Case 2: In an IT block, with a VPT code: error: must be in a
23198 VPT block. */
23199 inst.error = BAD_OUT_VPT;
23200 return FAIL;
23201 }
23202 /* Case 5: In a VPT block, with a VPT code: OK! */
23203 else if (cond != inst.cond)
23204 {
23205 inst.error = BAD_VPT_COND;
23206 return FAIL;
23207 }
23208 break;
e07e6e58
NC
23209 case INSIDE_IT_LAST_INSN:
23210 case IF_INSIDE_IT_LAST_INSN:
5ee91343
AV
23211 if (now_pred.type == VECTOR_PRED || inst.cond > COND_ALWAYS)
23212 {
23213 /* Case 4: In a VPT block, with an IT code: syntax error. */
23214 /* Case 11: In an IT block, with a VPT code: syntax error. */
23215 inst.error = BAD_SYNTAX;
23216 return FAIL;
23217 }
23218 else if (cond != inst.cond)
e07e6e58
NC
23219 {
23220 inst.error = BAD_IT_COND;
23221 return FAIL;
23222 }
23223 if (!is_last)
23224 {
23225 inst.error = BAD_BRANCH;
23226 return FAIL;
23227 }
23228 break;
23229
23230 case NEUTRAL_IT_INSN:
5ee91343
AV
23231 /* The BKPT instruction is unconditional even in a IT or VPT
23232 block. */
e07e6e58
NC
23233 break;
23234
23235 case IT_INSN:
5ee91343
AV
23236 if (now_pred.type == SCALAR_PRED)
23237 {
23238 inst.error = BAD_IT_IT;
23239 return FAIL;
23240 }
23241 /* fall through. */
23242 case VPT_INSN:
23243 if (inst.cond == COND_ALWAYS)
23244 {
23245 /* Executing a VPT/VPST instruction inside an IT block or a
23246 VPT/VPST/IT instruction inside a VPT block is UNPREDICTABLE.
23247 */
23248 if (now_pred.type == SCALAR_PRED)
23249 as_tsktsk (MVE_NOT_IT);
23250 else
23251 as_tsktsk (MVE_NOT_VPT);
23252 return SUCCESS;
23253 }
23254 else
23255 {
23256 /* VPT/VPST do not accept condition codes. */
23257 inst.error = BAD_SYNTAX;
23258 return FAIL;
23259 }
e07e6e58 23260 }
5ee91343 23261 }
e07e6e58
NC
23262 break;
23263 }
23264
23265 return SUCCESS;
23266}
23267
5a01bb1d
MGD
23268struct depr_insn_mask
23269{
23270 unsigned long pattern;
23271 unsigned long mask;
23272 const char* description;
23273};
23274
23275/* List of 16-bit instruction patterns deprecated in an IT block in
23276 ARMv8. */
23277static const struct depr_insn_mask depr_it_insns[] = {
23278 { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
23279 { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
23280 { 0xa000, 0xb800, N_("ADR") },
23281 { 0x4800, 0xf800, N_("Literal loads") },
23282 { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
23283 { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
c8de034b
JW
23284 /* NOTE: 0x00dd is not the real encoding, instead, it is the 'tvalue'
23285 field in asm_opcode. 'tvalue' is used at the stage this check happen. */
23286 { 0x00dd, 0x7fff, N_("ADD/SUB sp, sp #imm") },
5a01bb1d
MGD
23287 { 0, 0, NULL }
23288};
23289
e07e6e58
NC
23290static void
23291it_fsm_post_encode (void)
23292{
23293 int is_last;
23294
5ee91343
AV
23295 if (!now_pred.state_handled)
23296 handle_pred_state ();
e07e6e58 23297
5ee91343 23298 if (now_pred.insn_cond
24f19ccb 23299 && warn_on_restrict_it
5ee91343 23300 && !now_pred.warn_deprecated
5a01bb1d 23301 && warn_on_deprecated
164446e0
AF
23302 && (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)
23303 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8r))
df9909b8 23304 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m))
5a01bb1d
MGD
23305 {
23306 if (inst.instruction >= 0x10000)
23307 {
5c3696f8 23308 as_tsktsk (_("IT blocks containing 32-bit Thumb instructions are "
df9909b8 23309 "performance deprecated in ARMv8-A and ARMv8-R"));
5ee91343 23310 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
23311 }
23312 else
23313 {
23314 const struct depr_insn_mask *p = depr_it_insns;
23315
23316 while (p->mask != 0)
23317 {
23318 if ((inst.instruction & p->mask) == p->pattern)
23319 {
df9909b8
TP
23320 as_tsktsk (_("IT blocks containing 16-bit Thumb "
23321 "instructions of the following class are "
23322 "performance deprecated in ARMv8-A and "
23323 "ARMv8-R: %s"), p->description);
5ee91343 23324 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
23325 break;
23326 }
23327
23328 ++p;
23329 }
23330 }
23331
5ee91343 23332 if (now_pred.block_length > 1)
5a01bb1d 23333 {
5c3696f8 23334 as_tsktsk (_("IT blocks containing more than one conditional "
df9909b8
TP
23335 "instruction are performance deprecated in ARMv8-A and "
23336 "ARMv8-R"));
5ee91343 23337 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
23338 }
23339 }
23340
5ee91343
AV
23341 is_last = (now_pred.mask == 0x10);
23342 if (is_last)
23343 {
23344 now_pred.state = OUTSIDE_PRED_BLOCK;
23345 now_pred.mask = 0;
23346 }
e07e6e58
NC
23347}
23348
23349static void
23350force_automatic_it_block_close (void)
23351{
5ee91343 23352 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
e07e6e58
NC
23353 {
23354 close_automatic_it_block ();
5ee91343
AV
23355 now_pred.state = OUTSIDE_PRED_BLOCK;
23356 now_pred.mask = 0;
e07e6e58
NC
23357 }
23358}
23359
23360static int
5ee91343 23361in_pred_block (void)
e07e6e58 23362{
5ee91343
AV
23363 if (!now_pred.state_handled)
23364 handle_pred_state ();
e07e6e58 23365
5ee91343 23366 return now_pred.state != OUTSIDE_PRED_BLOCK;
e07e6e58
NC
23367}
23368
ff8646ee
TP
23369/* Whether OPCODE only has T32 encoding. Since this function is only used by
23370 t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed
23371 here, hence the "known" in the function name. */
fc289b0a
TP
23372
23373static bfd_boolean
ff8646ee 23374known_t32_only_insn (const struct asm_opcode *opcode)
fc289b0a
TP
23375{
23376 /* Original Thumb-1 wide instruction. */
23377 if (opcode->tencode == do_t_blx
23378 || opcode->tencode == do_t_branch23
23379 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
23380 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
23381 return TRUE;
23382
16a1fa25
TP
23383 /* Wide-only instruction added to ARMv8-M Baseline. */
23384 if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m_m_only)
ff8646ee
TP
23385 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics)
23386 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m)
23387 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div))
23388 return TRUE;
23389
23390 return FALSE;
23391}
23392
23393/* Whether wide instruction variant can be used if available for a valid OPCODE
23394 in ARCH. */
23395
23396static bfd_boolean
23397t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode)
23398{
23399 if (known_t32_only_insn (opcode))
23400 return TRUE;
23401
23402 /* Instruction with narrow and wide encoding added to ARMv8-M. Availability
23403 of variant T3 of B.W is checked in do_t_branch. */
23404 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
23405 && opcode->tencode == do_t_branch)
23406 return TRUE;
23407
bada4342
JW
23408 /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */
23409 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
23410 && opcode->tencode == do_t_mov_cmp
23411 /* Make sure CMP instruction is not affected. */
23412 && opcode->aencode == do_mov)
23413 return TRUE;
23414
ff8646ee
TP
23415 /* Wide instruction variants of all instructions with narrow *and* wide
23416 variants become available with ARMv6t2. Other opcodes are either
23417 narrow-only or wide-only and are thus available if OPCODE is valid. */
23418 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2))
23419 return TRUE;
23420
23421 /* OPCODE with narrow only instruction variant or wide variant not
23422 available. */
fc289b0a
TP
23423 return FALSE;
23424}
23425
c19d1205
ZW
23426void
23427md_assemble (char *str)
b99bd4ef 23428{
c19d1205
ZW
23429 char *p = str;
23430 const struct asm_opcode * opcode;
b99bd4ef 23431
c19d1205
ZW
23432 /* Align the previous label if needed. */
23433 if (last_label_seen != NULL)
b99bd4ef 23434 {
c19d1205
ZW
23435 symbol_set_frag (last_label_seen, frag_now);
23436 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
23437 S_SET_SEGMENT (last_label_seen, now_seg);
b99bd4ef
NC
23438 }
23439
c19d1205 23440 memset (&inst, '\0', sizeof (inst));
e2b0ab59
AV
23441 int r;
23442 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
23443 inst.relocs[r].type = BFD_RELOC_UNUSED;
b99bd4ef 23444
c19d1205
ZW
23445 opcode = opcode_lookup (&p);
23446 if (!opcode)
b99bd4ef 23447 {
c19d1205 23448 /* It wasn't an instruction, but it might be a register alias of
dcbf9037 23449 the form alias .req reg, or a Neon .dn/.qn directive. */
c921be7d 23450 if (! create_register_alias (str, p)
477330fc 23451 && ! create_neon_reg_alias (str, p))
c19d1205 23452 as_bad (_("bad instruction `%s'"), str);
b99bd4ef 23453
b99bd4ef
NC
23454 return;
23455 }
23456
278df34e 23457 if (warn_on_deprecated && opcode->tag == OT_cinfix3_deprecated)
5c3696f8 23458 as_tsktsk (_("s suffix on comparison instruction is deprecated"));
088fa78e 23459
037e8744
JB
23460 /* The value which unconditional instructions should have in place of the
23461 condition field. */
23462 inst.uncond_value = (opcode->tag == OT_csuffixF) ? 0xf : -1;
23463
c19d1205 23464 if (thumb_mode)
b99bd4ef 23465 {
e74cfd16 23466 arm_feature_set variant;
8f06b2d8
PB
23467
23468 variant = cpu_variant;
23469 /* Only allow coprocessor instructions on Thumb-2 capable devices. */
e74cfd16
PB
23470 if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2))
23471 ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard);
c19d1205 23472 /* Check that this instruction is supported for this CPU. */
62b3e311
PB
23473 if (!opcode->tvariant
23474 || (thumb_mode == 1
23475 && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
b99bd4ef 23476 {
173205ca
TP
23477 if (opcode->tencode == do_t_swi)
23478 as_bad (_("SVC is not permitted on this architecture"));
23479 else
23480 as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
b99bd4ef
NC
23481 return;
23482 }
c19d1205
ZW
23483 if (inst.cond != COND_ALWAYS && !unified_syntax
23484 && opcode->tencode != do_t_branch)
b99bd4ef 23485 {
c19d1205 23486 as_bad (_("Thumb does not support conditional execution"));
b99bd4ef
NC
23487 return;
23488 }
23489
fc289b0a
TP
23490 /* Two things are addressed here:
23491 1) Implicit require narrow instructions on Thumb-1.
23492 This avoids relaxation accidentally introducing Thumb-2
23493 instructions.
23494 2) Reject wide instructions in non Thumb-2 cores.
23495
23496 Only instructions with narrow and wide variants need to be handled
23497 but selecting all non wide-only instructions is easier. */
23498 if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)
ff8646ee 23499 && !t32_insn_ok (variant, opcode))
076d447c 23500 {
fc289b0a
TP
23501 if (inst.size_req == 0)
23502 inst.size_req = 2;
23503 else if (inst.size_req == 4)
752d5da4 23504 {
ff8646ee
TP
23505 if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m))
23506 as_bad (_("selected processor does not support 32bit wide "
23507 "variant of instruction `%s'"), str);
23508 else
23509 as_bad (_("selected processor does not support `%s' in "
23510 "Thumb-2 mode"), str);
fc289b0a 23511 return;
752d5da4 23512 }
076d447c
PB
23513 }
23514
c19d1205
ZW
23515 inst.instruction = opcode->tvalue;
23516
5be8be5d 23517 if (!parse_operands (p, opcode->operands, /*thumb=*/TRUE))
477330fc 23518 {
5ee91343 23519 /* Prepare the pred_insn_type for those encodings that don't set
477330fc
RM
23520 it. */
23521 it_fsm_pre_encode ();
c19d1205 23522
477330fc 23523 opcode->tencode ();
e07e6e58 23524
477330fc
RM
23525 it_fsm_post_encode ();
23526 }
e27ec89e 23527
0110f2b8 23528 if (!(inst.error || inst.relax))
b99bd4ef 23529 {
9c2799c2 23530 gas_assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
c19d1205
ZW
23531 inst.size = (inst.instruction > 0xffff ? 4 : 2);
23532 if (inst.size_req && inst.size_req != inst.size)
b99bd4ef 23533 {
c19d1205 23534 as_bad (_("cannot honor width suffix -- `%s'"), str);
b99bd4ef
NC
23535 return;
23536 }
23537 }
076d447c
PB
23538
23539 /* Something has gone badly wrong if we try to relax a fixed size
477330fc 23540 instruction. */
9c2799c2 23541 gas_assert (inst.size_req == 0 || !inst.relax);
076d447c 23542
e74cfd16
PB
23543 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
23544 *opcode->tvariant);
ee065d83 23545 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
fc289b0a
TP
23546 set those bits when Thumb-2 32-bit instructions are seen. The impact
23547 of relaxable instructions will be considered later after we finish all
23548 relaxation. */
ff8646ee
TP
23549 if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any))
23550 variant = arm_arch_none;
23551 else
23552 variant = cpu_variant;
23553 if (inst.size == 4 && !t32_insn_ok (variant, opcode))
e74cfd16
PB
23554 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
23555 arm_ext_v6t2);
cd000bff 23556
88714cb8
DG
23557 check_neon_suffixes;
23558
cd000bff 23559 if (!inst.error)
c877a2f2
NC
23560 {
23561 mapping_state (MAP_THUMB);
23562 }
c19d1205 23563 }
3e9e4fcf 23564 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205 23565 {
845b51d6
PB
23566 bfd_boolean is_bx;
23567
23568 /* bx is allowed on v5 cores, and sometimes on v4 cores. */
23569 is_bx = (opcode->aencode == do_bx);
23570
c19d1205 23571 /* Check that this instruction is supported for this CPU. */
845b51d6
PB
23572 if (!(is_bx && fix_v4bx)
23573 && !(opcode->avariant &&
23574 ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)))
b99bd4ef 23575 {
84b52b66 23576 as_bad (_("selected processor does not support `%s' in ARM mode"), str);
c19d1205 23577 return;
b99bd4ef 23578 }
c19d1205 23579 if (inst.size_req)
b99bd4ef 23580 {
c19d1205
ZW
23581 as_bad (_("width suffixes are invalid in ARM mode -- `%s'"), str);
23582 return;
b99bd4ef
NC
23583 }
23584
c19d1205
ZW
23585 inst.instruction = opcode->avalue;
23586 if (opcode->tag == OT_unconditionalF)
eff0bc54 23587 inst.instruction |= 0xFU << 28;
c19d1205
ZW
23588 else
23589 inst.instruction |= inst.cond << 28;
23590 inst.size = INSN_SIZE;
5be8be5d 23591 if (!parse_operands (p, opcode->operands, /*thumb=*/FALSE))
477330fc
RM
23592 {
23593 it_fsm_pre_encode ();
23594 opcode->aencode ();
23595 it_fsm_post_encode ();
23596 }
ee065d83 23597 /* Arm mode bx is marked as both v4T and v5 because it's still required
477330fc 23598 on a hypothetical non-thumb v5 core. */
845b51d6 23599 if (is_bx)
e74cfd16 23600 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t);
ee065d83 23601 else
e74cfd16
PB
23602 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
23603 *opcode->avariant);
88714cb8
DG
23604
23605 check_neon_suffixes;
23606
cd000bff 23607 if (!inst.error)
c877a2f2
NC
23608 {
23609 mapping_state (MAP_ARM);
23610 }
b99bd4ef 23611 }
3e9e4fcf
JB
23612 else
23613 {
23614 as_bad (_("attempt to use an ARM instruction on a Thumb-only processor "
23615 "-- `%s'"), str);
23616 return;
23617 }
c19d1205
ZW
23618 output_inst (str);
23619}
b99bd4ef 23620
e07e6e58 23621static void
5ee91343 23622check_pred_blocks_finished (void)
e07e6e58
NC
23623{
23624#ifdef OBJ_ELF
23625 asection *sect;
23626
23627 for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
5ee91343
AV
23628 if (seg_info (sect)->tc_segment_info_data.current_pred.state
23629 == MANUAL_PRED_BLOCK)
e07e6e58 23630 {
5ee91343
AV
23631 if (now_pred.type == SCALAR_PRED)
23632 as_warn (_("section '%s' finished with an open IT block."),
23633 sect->name);
23634 else
23635 as_warn (_("section '%s' finished with an open VPT/VPST block."),
23636 sect->name);
e07e6e58
NC
23637 }
23638#else
5ee91343
AV
23639 if (now_pred.state == MANUAL_PRED_BLOCK)
23640 {
23641 if (now_pred.type == SCALAR_PRED)
23642 as_warn (_("file finished with an open IT block."));
23643 else
23644 as_warn (_("file finished with an open VPT/VPST block."));
23645 }
e07e6e58
NC
23646#endif
23647}
23648
c19d1205
ZW
23649/* Various frobbings of labels and their addresses. */
23650
23651void
23652arm_start_line_hook (void)
23653{
23654 last_label_seen = NULL;
b99bd4ef
NC
23655}
23656
c19d1205
ZW
23657void
23658arm_frob_label (symbolS * sym)
b99bd4ef 23659{
c19d1205 23660 last_label_seen = sym;
b99bd4ef 23661
c19d1205 23662 ARM_SET_THUMB (sym, thumb_mode);
b99bd4ef 23663
c19d1205
ZW
23664#if defined OBJ_COFF || defined OBJ_ELF
23665 ARM_SET_INTERWORK (sym, support_interwork);
23666#endif
b99bd4ef 23667
e07e6e58
NC
23668 force_automatic_it_block_close ();
23669
5f4273c7 23670 /* Note - do not allow local symbols (.Lxxx) to be labelled
c19d1205
ZW
23671 as Thumb functions. This is because these labels, whilst
23672 they exist inside Thumb code, are not the entry points for
23673 possible ARM->Thumb calls. Also, these labels can be used
23674 as part of a computed goto or switch statement. eg gcc
23675 can generate code that looks like this:
b99bd4ef 23676
c19d1205
ZW
23677 ldr r2, [pc, .Laaa]
23678 lsl r3, r3, #2
23679 ldr r2, [r3, r2]
23680 mov pc, r2
b99bd4ef 23681
c19d1205
ZW
23682 .Lbbb: .word .Lxxx
23683 .Lccc: .word .Lyyy
23684 ..etc...
23685 .Laaa: .word Lbbb
b99bd4ef 23686
c19d1205
ZW
23687 The first instruction loads the address of the jump table.
23688 The second instruction converts a table index into a byte offset.
23689 The third instruction gets the jump address out of the table.
23690 The fourth instruction performs the jump.
b99bd4ef 23691
c19d1205
ZW
23692 If the address stored at .Laaa is that of a symbol which has the
23693 Thumb_Func bit set, then the linker will arrange for this address
23694 to have the bottom bit set, which in turn would mean that the
23695 address computation performed by the third instruction would end
23696 up with the bottom bit set. Since the ARM is capable of unaligned
23697 word loads, the instruction would then load the incorrect address
23698 out of the jump table, and chaos would ensue. */
23699 if (label_is_thumb_function_name
23700 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
fd361982 23701 && (bfd_section_flags (now_seg) & SEC_CODE) != 0)
b99bd4ef 23702 {
c19d1205
ZW
23703 /* When the address of a Thumb function is taken the bottom
23704 bit of that address should be set. This will allow
23705 interworking between Arm and Thumb functions to work
23706 correctly. */
b99bd4ef 23707
c19d1205 23708 THUMB_SET_FUNC (sym, 1);
b99bd4ef 23709
c19d1205 23710 label_is_thumb_function_name = FALSE;
b99bd4ef 23711 }
07a53e5c 23712
07a53e5c 23713 dwarf2_emit_label (sym);
b99bd4ef
NC
23714}
23715
c921be7d 23716bfd_boolean
c19d1205 23717arm_data_in_code (void)
b99bd4ef 23718{
c19d1205 23719 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
b99bd4ef 23720 {
c19d1205
ZW
23721 *input_line_pointer = '/';
23722 input_line_pointer += 5;
23723 *input_line_pointer = 0;
c921be7d 23724 return TRUE;
b99bd4ef
NC
23725 }
23726
c921be7d 23727 return FALSE;
b99bd4ef
NC
23728}
23729
c19d1205
ZW
23730char *
23731arm_canonicalize_symbol_name (char * name)
b99bd4ef 23732{
c19d1205 23733 int len;
b99bd4ef 23734
c19d1205
ZW
23735 if (thumb_mode && (len = strlen (name)) > 5
23736 && streq (name + len - 5, "/data"))
23737 *(name + len - 5) = 0;
b99bd4ef 23738
c19d1205 23739 return name;
b99bd4ef 23740}
c19d1205
ZW
23741\f
23742/* Table of all register names defined by default. The user can
23743 define additional names with .req. Note that all register names
23744 should appear in both upper and lowercase variants. Some registers
23745 also have mixed-case names. */
b99bd4ef 23746
dcbf9037 23747#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, TRUE, 0 }
c19d1205 23748#define REGNUM(p,n,t) REGDEF(p##n, n, t)
5287ad62 23749#define REGNUM2(p,n,t) REGDEF(p##n, 2 * n, t)
c19d1205
ZW
23750#define REGSET(p,t) \
23751 REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
23752 REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
23753 REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
23754 REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
5287ad62
JB
23755#define REGSETH(p,t) \
23756 REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
23757 REGNUM(p,20,t), REGNUM(p,21,t), REGNUM(p,22,t), REGNUM(p,23,t), \
23758 REGNUM(p,24,t), REGNUM(p,25,t), REGNUM(p,26,t), REGNUM(p,27,t), \
23759 REGNUM(p,28,t), REGNUM(p,29,t), REGNUM(p,30,t), REGNUM(p,31,t)
23760#define REGSET2(p,t) \
23761 REGNUM2(p, 0,t), REGNUM2(p, 1,t), REGNUM2(p, 2,t), REGNUM2(p, 3,t), \
23762 REGNUM2(p, 4,t), REGNUM2(p, 5,t), REGNUM2(p, 6,t), REGNUM2(p, 7,t), \
23763 REGNUM2(p, 8,t), REGNUM2(p, 9,t), REGNUM2(p,10,t), REGNUM2(p,11,t), \
23764 REGNUM2(p,12,t), REGNUM2(p,13,t), REGNUM2(p,14,t), REGNUM2(p,15,t)
90ec0d68
MGD
23765#define SPLRBANK(base,bank,t) \
23766 REGDEF(lr_##bank, 768|((base+0)<<16), t), \
23767 REGDEF(sp_##bank, 768|((base+1)<<16), t), \
23768 REGDEF(spsr_##bank, 768|(base<<16)|SPSR_BIT, t), \
23769 REGDEF(LR_##bank, 768|((base+0)<<16), t), \
23770 REGDEF(SP_##bank, 768|((base+1)<<16), t), \
23771 REGDEF(SPSR_##bank, 768|(base<<16)|SPSR_BIT, t)
7ed4c4c5 23772
c19d1205 23773static const struct reg_entry reg_names[] =
7ed4c4c5 23774{
c19d1205
ZW
23775 /* ARM integer registers. */
23776 REGSET(r, RN), REGSET(R, RN),
7ed4c4c5 23777
c19d1205
ZW
23778 /* ATPCS synonyms. */
23779 REGDEF(a1,0,RN), REGDEF(a2,1,RN), REGDEF(a3, 2,RN), REGDEF(a4, 3,RN),
23780 REGDEF(v1,4,RN), REGDEF(v2,5,RN), REGDEF(v3, 6,RN), REGDEF(v4, 7,RN),
23781 REGDEF(v5,8,RN), REGDEF(v6,9,RN), REGDEF(v7,10,RN), REGDEF(v8,11,RN),
7ed4c4c5 23782
c19d1205
ZW
23783 REGDEF(A1,0,RN), REGDEF(A2,1,RN), REGDEF(A3, 2,RN), REGDEF(A4, 3,RN),
23784 REGDEF(V1,4,RN), REGDEF(V2,5,RN), REGDEF(V3, 6,RN), REGDEF(V4, 7,RN),
23785 REGDEF(V5,8,RN), REGDEF(V6,9,RN), REGDEF(V7,10,RN), REGDEF(V8,11,RN),
7ed4c4c5 23786
c19d1205
ZW
23787 /* Well-known aliases. */
23788 REGDEF(wr, 7,RN), REGDEF(sb, 9,RN), REGDEF(sl,10,RN), REGDEF(fp,11,RN),
23789 REGDEF(ip,12,RN), REGDEF(sp,13,RN), REGDEF(lr,14,RN), REGDEF(pc,15,RN),
23790
23791 REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
23792 REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
23793
1b883319
AV
23794 /* Defining the new Zero register from ARMv8.1-M. */
23795 REGDEF(zr,15,ZR),
23796 REGDEF(ZR,15,ZR),
23797
c19d1205
ZW
23798 /* Coprocessor numbers. */
23799 REGSET(p, CP), REGSET(P, CP),
23800
23801 /* Coprocessor register numbers. The "cr" variants are for backward
23802 compatibility. */
23803 REGSET(c, CN), REGSET(C, CN),
23804 REGSET(cr, CN), REGSET(CR, CN),
23805
90ec0d68
MGD
23806 /* ARM banked registers. */
23807 REGDEF(R8_usr,512|(0<<16),RNB), REGDEF(r8_usr,512|(0<<16),RNB),
23808 REGDEF(R9_usr,512|(1<<16),RNB), REGDEF(r9_usr,512|(1<<16),RNB),
23809 REGDEF(R10_usr,512|(2<<16),RNB), REGDEF(r10_usr,512|(2<<16),RNB),
23810 REGDEF(R11_usr,512|(3<<16),RNB), REGDEF(r11_usr,512|(3<<16),RNB),
23811 REGDEF(R12_usr,512|(4<<16),RNB), REGDEF(r12_usr,512|(4<<16),RNB),
23812 REGDEF(SP_usr,512|(5<<16),RNB), REGDEF(sp_usr,512|(5<<16),RNB),
23813 REGDEF(LR_usr,512|(6<<16),RNB), REGDEF(lr_usr,512|(6<<16),RNB),
23814
23815 REGDEF(R8_fiq,512|(8<<16),RNB), REGDEF(r8_fiq,512|(8<<16),RNB),
23816 REGDEF(R9_fiq,512|(9<<16),RNB), REGDEF(r9_fiq,512|(9<<16),RNB),
23817 REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
23818 REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
23819 REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
1472d06f 23820 REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(sp_fiq,512|(13<<16),RNB),
90ec0d68
MGD
23821 REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
23822 REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
23823
23824 SPLRBANK(0,IRQ,RNB), SPLRBANK(0,irq,RNB),
23825 SPLRBANK(2,SVC,RNB), SPLRBANK(2,svc,RNB),
23826 SPLRBANK(4,ABT,RNB), SPLRBANK(4,abt,RNB),
23827 SPLRBANK(6,UND,RNB), SPLRBANK(6,und,RNB),
23828 SPLRBANK(12,MON,RNB), SPLRBANK(12,mon,RNB),
23829 REGDEF(elr_hyp,768|(14<<16),RNB), REGDEF(ELR_hyp,768|(14<<16),RNB),
23830 REGDEF(sp_hyp,768|(15<<16),RNB), REGDEF(SP_hyp,768|(15<<16),RNB),
fa94de6b 23831 REGDEF(spsr_hyp,768|(14<<16)|SPSR_BIT,RNB),
90ec0d68
MGD
23832 REGDEF(SPSR_hyp,768|(14<<16)|SPSR_BIT,RNB),
23833
c19d1205
ZW
23834 /* FPA registers. */
23835 REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
23836 REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
23837
23838 REGNUM(F,0,FN), REGNUM(F,1,FN), REGNUM(F,2,FN), REGNUM(F,3,FN),
23839 REGNUM(F,4,FN), REGNUM(F,5,FN), REGNUM(F,6,FN), REGNUM(F,7, FN),
23840
23841 /* VFP SP registers. */
5287ad62
JB
23842 REGSET(s,VFS), REGSET(S,VFS),
23843 REGSETH(s,VFS), REGSETH(S,VFS),
c19d1205
ZW
23844
23845 /* VFP DP Registers. */
5287ad62
JB
23846 REGSET(d,VFD), REGSET(D,VFD),
23847 /* Extra Neon DP registers. */
23848 REGSETH(d,VFD), REGSETH(D,VFD),
23849
23850 /* Neon QP registers. */
23851 REGSET2(q,NQ), REGSET2(Q,NQ),
c19d1205
ZW
23852
23853 /* VFP control registers. */
23854 REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
23855 REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
cd2cf30b
PB
23856 REGDEF(fpinst,9,VFC), REGDEF(fpinst2,10,VFC),
23857 REGDEF(FPINST,9,VFC), REGDEF(FPINST2,10,VFC),
23858 REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
23859 REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
40c7d507 23860 REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
ba6cd17f
SD
23861 REGDEF(fpscr_nzcvqc,2,VFC), REGDEF(FPSCR_nzcvqc,2,VFC),
23862 REGDEF(vpr,12,VFC), REGDEF(VPR,12,VFC),
23863 REGDEF(fpcxt_ns,14,VFC), REGDEF(FPCXT_NS,14,VFC),
23864 REGDEF(fpcxt_s,15,VFC), REGDEF(FPCXT_S,15,VFC),
c19d1205
ZW
23865
23866 /* Maverick DSP coprocessor registers. */
23867 REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
23868 REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
23869
23870 REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
23871 REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
23872 REGDEF(dspsc,0,DSPSC),
23873
23874 REGNUM(MVAX,0,MVAX), REGNUM(MVAX,1,MVAX),
23875 REGNUM(MVAX,2,MVAX), REGNUM(MVAX,3,MVAX),
23876 REGDEF(DSPSC,0,DSPSC),
23877
23878 /* iWMMXt data registers - p0, c0-15. */
23879 REGSET(wr,MMXWR), REGSET(wR,MMXWR), REGSET(WR, MMXWR),
23880
23881 /* iWMMXt control registers - p1, c0-3. */
23882 REGDEF(wcid, 0,MMXWC), REGDEF(wCID, 0,MMXWC), REGDEF(WCID, 0,MMXWC),
23883 REGDEF(wcon, 1,MMXWC), REGDEF(wCon, 1,MMXWC), REGDEF(WCON, 1,MMXWC),
23884 REGDEF(wcssf, 2,MMXWC), REGDEF(wCSSF, 2,MMXWC), REGDEF(WCSSF, 2,MMXWC),
23885 REGDEF(wcasf, 3,MMXWC), REGDEF(wCASF, 3,MMXWC), REGDEF(WCASF, 3,MMXWC),
23886
23887 /* iWMMXt scalar (constant/offset) registers - p1, c8-11. */
23888 REGDEF(wcgr0, 8,MMXWCG), REGDEF(wCGR0, 8,MMXWCG), REGDEF(WCGR0, 8,MMXWCG),
23889 REGDEF(wcgr1, 9,MMXWCG), REGDEF(wCGR1, 9,MMXWCG), REGDEF(WCGR1, 9,MMXWCG),
23890 REGDEF(wcgr2,10,MMXWCG), REGDEF(wCGR2,10,MMXWCG), REGDEF(WCGR2,10,MMXWCG),
23891 REGDEF(wcgr3,11,MMXWCG), REGDEF(wCGR3,11,MMXWCG), REGDEF(WCGR3,11,MMXWCG),
23892
23893 /* XScale accumulator registers. */
23894 REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
23895};
23896#undef REGDEF
23897#undef REGNUM
23898#undef REGSET
7ed4c4c5 23899
c19d1205
ZW
23900/* Table of all PSR suffixes. Bare "CPSR" and "SPSR" are handled
23901 within psr_required_here. */
23902static const struct asm_psr psrs[] =
23903{
23904 /* Backward compatibility notation. Note that "all" is no longer
23905 truly all possible PSR bits. */
23906 {"all", PSR_c | PSR_f},
23907 {"flg", PSR_f},
23908 {"ctl", PSR_c},
23909
23910 /* Individual flags. */
23911 {"f", PSR_f},
23912 {"c", PSR_c},
23913 {"x", PSR_x},
23914 {"s", PSR_s},
59b42a0d 23915
c19d1205
ZW
23916 /* Combinations of flags. */
23917 {"fs", PSR_f | PSR_s},
23918 {"fx", PSR_f | PSR_x},
23919 {"fc", PSR_f | PSR_c},
23920 {"sf", PSR_s | PSR_f},
23921 {"sx", PSR_s | PSR_x},
23922 {"sc", PSR_s | PSR_c},
23923 {"xf", PSR_x | PSR_f},
23924 {"xs", PSR_x | PSR_s},
23925 {"xc", PSR_x | PSR_c},
23926 {"cf", PSR_c | PSR_f},
23927 {"cs", PSR_c | PSR_s},
23928 {"cx", PSR_c | PSR_x},
23929 {"fsx", PSR_f | PSR_s | PSR_x},
23930 {"fsc", PSR_f | PSR_s | PSR_c},
23931 {"fxs", PSR_f | PSR_x | PSR_s},
23932 {"fxc", PSR_f | PSR_x | PSR_c},
23933 {"fcs", PSR_f | PSR_c | PSR_s},
23934 {"fcx", PSR_f | PSR_c | PSR_x},
23935 {"sfx", PSR_s | PSR_f | PSR_x},
23936 {"sfc", PSR_s | PSR_f | PSR_c},
23937 {"sxf", PSR_s | PSR_x | PSR_f},
23938 {"sxc", PSR_s | PSR_x | PSR_c},
23939 {"scf", PSR_s | PSR_c | PSR_f},
23940 {"scx", PSR_s | PSR_c | PSR_x},
23941 {"xfs", PSR_x | PSR_f | PSR_s},
23942 {"xfc", PSR_x | PSR_f | PSR_c},
23943 {"xsf", PSR_x | PSR_s | PSR_f},
23944 {"xsc", PSR_x | PSR_s | PSR_c},
23945 {"xcf", PSR_x | PSR_c | PSR_f},
23946 {"xcs", PSR_x | PSR_c | PSR_s},
23947 {"cfs", PSR_c | PSR_f | PSR_s},
23948 {"cfx", PSR_c | PSR_f | PSR_x},
23949 {"csf", PSR_c | PSR_s | PSR_f},
23950 {"csx", PSR_c | PSR_s | PSR_x},
23951 {"cxf", PSR_c | PSR_x | PSR_f},
23952 {"cxs", PSR_c | PSR_x | PSR_s},
23953 {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
23954 {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
23955 {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
23956 {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
23957 {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
23958 {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
23959 {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
23960 {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
23961 {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
23962 {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
23963 {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
23964 {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
23965 {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
23966 {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
23967 {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
23968 {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
23969 {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
23970 {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
23971 {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
23972 {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
23973 {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
23974 {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
23975 {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
23976 {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
23977};
23978
62b3e311
PB
23979/* Table of V7M psr names. */
23980static const struct asm_psr v7m_psrs[] =
23981{
1a336194
TP
23982 {"apsr", 0x0 }, {"APSR", 0x0 },
23983 {"iapsr", 0x1 }, {"IAPSR", 0x1 },
23984 {"eapsr", 0x2 }, {"EAPSR", 0x2 },
23985 {"psr", 0x3 }, {"PSR", 0x3 },
23986 {"xpsr", 0x3 }, {"XPSR", 0x3 }, {"xPSR", 3 },
23987 {"ipsr", 0x5 }, {"IPSR", 0x5 },
23988 {"epsr", 0x6 }, {"EPSR", 0x6 },
23989 {"iepsr", 0x7 }, {"IEPSR", 0x7 },
23990 {"msp", 0x8 }, {"MSP", 0x8 },
23991 {"psp", 0x9 }, {"PSP", 0x9 },
23992 {"msplim", 0xa }, {"MSPLIM", 0xa },
23993 {"psplim", 0xb }, {"PSPLIM", 0xb },
23994 {"primask", 0x10}, {"PRIMASK", 0x10},
23995 {"basepri", 0x11}, {"BASEPRI", 0x11},
23996 {"basepri_max", 0x12}, {"BASEPRI_MAX", 0x12},
1a336194
TP
23997 {"faultmask", 0x13}, {"FAULTMASK", 0x13},
23998 {"control", 0x14}, {"CONTROL", 0x14},
23999 {"msp_ns", 0x88}, {"MSP_NS", 0x88},
24000 {"psp_ns", 0x89}, {"PSP_NS", 0x89},
24001 {"msplim_ns", 0x8a}, {"MSPLIM_NS", 0x8a},
24002 {"psplim_ns", 0x8b}, {"PSPLIM_NS", 0x8b},
24003 {"primask_ns", 0x90}, {"PRIMASK_NS", 0x90},
24004 {"basepri_ns", 0x91}, {"BASEPRI_NS", 0x91},
24005 {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
24006 {"control_ns", 0x94}, {"CONTROL_NS", 0x94},
24007 {"sp_ns", 0x98}, {"SP_NS", 0x98 }
62b3e311
PB
24008};
24009
c19d1205
ZW
24010/* Table of all shift-in-operand names. */
24011static const struct asm_shift_name shift_names [] =
b99bd4ef 24012{
c19d1205
ZW
24013 { "asl", SHIFT_LSL }, { "ASL", SHIFT_LSL },
24014 { "lsl", SHIFT_LSL }, { "LSL", SHIFT_LSL },
24015 { "lsr", SHIFT_LSR }, { "LSR", SHIFT_LSR },
24016 { "asr", SHIFT_ASR }, { "ASR", SHIFT_ASR },
24017 { "ror", SHIFT_ROR }, { "ROR", SHIFT_ROR },
f5f10c66
AV
24018 { "rrx", SHIFT_RRX }, { "RRX", SHIFT_RRX },
24019 { "uxtw", SHIFT_UXTW}, { "UXTW", SHIFT_UXTW}
c19d1205 24020};
b99bd4ef 24021
c19d1205
ZW
24022/* Table of all explicit relocation names. */
24023#ifdef OBJ_ELF
24024static struct reloc_entry reloc_names[] =
24025{
24026 { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
24027 { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
24028 { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
24029 { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
24030 { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
24031 { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
24032 { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
24033 { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
24034 { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
24035 { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
b43420e6 24036 { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32},
0855e32b
NS
24037 { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL},
24038 { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC},
477330fc 24039 { "TLSDESC", BFD_RELOC_ARM_TLS_GOTDESC},
0855e32b 24040 { "tlscall", BFD_RELOC_ARM_TLS_CALL},
477330fc 24041 { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
0855e32b 24042 { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
188fd7ae
CL
24043 { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ},
24044 { "gotfuncdesc", BFD_RELOC_ARM_GOTFUNCDESC },
24045 { "GOTFUNCDESC", BFD_RELOC_ARM_GOTFUNCDESC },
24046 { "gotofffuncdesc", BFD_RELOC_ARM_GOTOFFFUNCDESC },
24047 { "GOTOFFFUNCDESC", BFD_RELOC_ARM_GOTOFFFUNCDESC },
24048 { "funcdesc", BFD_RELOC_ARM_FUNCDESC },
5c5a4843
CL
24049 { "FUNCDESC", BFD_RELOC_ARM_FUNCDESC },
24050 { "tlsgd_fdpic", BFD_RELOC_ARM_TLS_GD32_FDPIC }, { "TLSGD_FDPIC", BFD_RELOC_ARM_TLS_GD32_FDPIC },
24051 { "tlsldm_fdpic", BFD_RELOC_ARM_TLS_LDM32_FDPIC }, { "TLSLDM_FDPIC", BFD_RELOC_ARM_TLS_LDM32_FDPIC },
24052 { "gottpoff_fdpic", BFD_RELOC_ARM_TLS_IE32_FDPIC }, { "GOTTPOFF_FDIC", BFD_RELOC_ARM_TLS_IE32_FDPIC },
c19d1205
ZW
24053};
24054#endif
b99bd4ef 24055
5ee91343 24056/* Table of all conditional affixes. */
c19d1205
ZW
24057static const struct asm_cond conds[] =
24058{
24059 {"eq", 0x0},
24060 {"ne", 0x1},
24061 {"cs", 0x2}, {"hs", 0x2},
24062 {"cc", 0x3}, {"ul", 0x3}, {"lo", 0x3},
24063 {"mi", 0x4},
24064 {"pl", 0x5},
24065 {"vs", 0x6},
24066 {"vc", 0x7},
24067 {"hi", 0x8},
24068 {"ls", 0x9},
24069 {"ge", 0xa},
24070 {"lt", 0xb},
24071 {"gt", 0xc},
24072 {"le", 0xd},
24073 {"al", 0xe}
24074};
5ee91343
AV
24075static const struct asm_cond vconds[] =
24076{
24077 {"t", 0xf},
24078 {"e", 0x10}
24079};
bfae80f2 24080
e797f7e0 24081#define UL_BARRIER(L,U,CODE,FEAT) \
823d2571
TG
24082 { L, CODE, ARM_FEATURE_CORE_LOW (FEAT) }, \
24083 { U, CODE, ARM_FEATURE_CORE_LOW (FEAT) }
e797f7e0 24084
62b3e311
PB
24085static struct asm_barrier_opt barrier_opt_names[] =
24086{
e797f7e0
MGD
24087 UL_BARRIER ("sy", "SY", 0xf, ARM_EXT_BARRIER),
24088 UL_BARRIER ("st", "ST", 0xe, ARM_EXT_BARRIER),
24089 UL_BARRIER ("ld", "LD", 0xd, ARM_EXT_V8),
24090 UL_BARRIER ("ish", "ISH", 0xb, ARM_EXT_BARRIER),
24091 UL_BARRIER ("sh", "SH", 0xb, ARM_EXT_BARRIER),
24092 UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER),
24093 UL_BARRIER ("shst", "SHST", 0xa, ARM_EXT_BARRIER),
24094 UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8),
24095 UL_BARRIER ("un", "UN", 0x7, ARM_EXT_BARRIER),
24096 UL_BARRIER ("nsh", "NSH", 0x7, ARM_EXT_BARRIER),
24097 UL_BARRIER ("unst", "UNST", 0x6, ARM_EXT_BARRIER),
24098 UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER),
24099 UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8),
24100 UL_BARRIER ("osh", "OSH", 0x3, ARM_EXT_BARRIER),
24101 UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER),
24102 UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8)
62b3e311
PB
24103};
24104
e797f7e0
MGD
24105#undef UL_BARRIER
24106
c19d1205
ZW
24107/* Table of ARM-format instructions. */
24108
24109/* Macros for gluing together operand strings. N.B. In all cases
24110 other than OPS0, the trailing OP_stop comes from default
24111 zero-initialization of the unspecified elements of the array. */
24112#define OPS0() { OP_stop, }
24113#define OPS1(a) { OP_##a, }
24114#define OPS2(a,b) { OP_##a,OP_##b, }
24115#define OPS3(a,b,c) { OP_##a,OP_##b,OP_##c, }
24116#define OPS4(a,b,c,d) { OP_##a,OP_##b,OP_##c,OP_##d, }
24117#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
24118#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
24119
5be8be5d
DG
24120/* These macros are similar to the OPSn, but do not prepend the OP_ prefix.
24121 This is useful when mixing operands for ARM and THUMB, i.e. using the
24122 MIX_ARM_THUMB_OPERANDS macro.
24123 In order to use these macros, prefix the number of operands with _
24124 e.g. _3. */
24125#define OPS_1(a) { a, }
24126#define OPS_2(a,b) { a,b, }
24127#define OPS_3(a,b,c) { a,b,c, }
24128#define OPS_4(a,b,c,d) { a,b,c,d, }
24129#define OPS_5(a,b,c,d,e) { a,b,c,d,e, }
24130#define OPS_6(a,b,c,d,e,f) { a,b,c,d,e,f, }
24131
c19d1205
ZW
24132/* These macros abstract out the exact format of the mnemonic table and
24133 save some repeated characters. */
24134
24135/* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix. */
24136#define TxCE(mnem, op, top, nops, ops, ae, te) \
21d799b5 24137 { mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
5ee91343 24138 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
24139
24140/* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
24141 a T_MNEM_xyz enumerator. */
24142#define TCE(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24143 TxCE (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 24144#define tCE(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24145 TxCE (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205
ZW
24146
24147/* Second most common sort of mnemonic: has a Thumb variant, takes a conditional
24148 infix after the third character. */
24149#define TxC3(mnem, op, top, nops, ops, ae, te) \
21d799b5 24150 { mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
5ee91343 24151 THUMB_VARIANT, do_##ae, do_##te, 0 }
088fa78e 24152#define TxC3w(mnem, op, top, nops, ops, ae, te) \
21d799b5 24153 { mnem, OPS##nops ops, OT_cinfix3_deprecated, 0x##op, top, ARM_VARIANT, \
5ee91343 24154 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 24155#define TC3(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24156 TxC3 (mnem, aop, 0x##top, nops, ops, ae, te)
088fa78e 24157#define TC3w(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 24158 TxC3w (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 24159#define tC3(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24160 TxC3 (mnem, aop, T_MNEM##top, nops, ops, ae, te)
088fa78e 24161#define tC3w(mnem, aop, top, nops, ops, ae, te) \
21d799b5 24162 TxC3w (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205 24163
c19d1205 24164/* Mnemonic that cannot be conditionalized. The ARM condition-code
dfa9f0d5
PB
24165 field is still 0xE. Many of the Thumb variants can be executed
24166 conditionally, so this is checked separately. */
c19d1205 24167#define TUE(mnem, op, top, nops, ops, ae, te) \
21d799b5 24168 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24169 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 24170
dd5181d5
KT
24171/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
24172 Used by mnemonics that have very minimal differences in the encoding for
24173 ARM and Thumb variants and can be handled in a common function. */
24174#define TUEc(mnem, op, top, nops, ops, en) \
24175 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24176 THUMB_VARIANT, do_##en, do_##en, 0 }
dd5181d5 24177
c19d1205
ZW
24178/* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
24179 condition code field. */
24180#define TUF(mnem, op, top, nops, ops, ae, te) \
21d799b5 24181 { mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 24182 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
24183
24184/* ARM-only variants of all the above. */
6a86118a 24185#define CE(mnem, op, nops, ops, ae) \
5ee91343 24186 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24187
24188#define C3(mnem, op, nops, ops, ae) \
5ee91343 24189 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 24190
cf3cf39d
TP
24191/* Thumb-only variants of TCE and TUE. */
24192#define ToC(mnem, top, nops, ops, te) \
24193 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
5ee91343 24194 do_##te, 0 }
cf3cf39d
TP
24195
24196#define ToU(mnem, top, nops, ops, te) \
24197 { mnem, OPS##nops ops, OT_unconditional, 0x0, 0x##top, 0, THUMB_VARIANT, \
5ee91343 24198 NULL, do_##te, 0 }
cf3cf39d 24199
4389b29a
AV
24200/* T_MNEM_xyz enumerator variants of ToC. */
24201#define toC(mnem, top, nops, ops, te) \
24202 { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \
5ee91343 24203 do_##te, 0 }
4389b29a 24204
f6b2b12d
AV
24205/* T_MNEM_xyz enumerator variants of ToU. */
24206#define toU(mnem, top, nops, ops, te) \
24207 { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \
5ee91343 24208 NULL, do_##te, 0 }
f6b2b12d 24209
e3cb604e
PB
24210/* Legacy mnemonics that always have conditional infix after the third
24211 character. */
24212#define CL(mnem, op, nops, ops, ae) \
21d799b5 24213 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 24214 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
e3cb604e 24215
8f06b2d8
PB
24216/* Coprocessor instructions. Isomorphic between Arm and Thumb-2. */
24217#define cCE(mnem, op, nops, ops, ae) \
5ee91343 24218 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 24219
57785aa2
AV
24220/* mov instructions that are shared between coprocessor and MVE. */
24221#define mcCE(mnem, op, nops, ops, ae) \
24222 { #mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##ae, 0 }
24223
e3cb604e
PB
24224/* Legacy coprocessor instructions where conditional infix and conditional
24225 suffix are ambiguous. For consistency this includes all FPA instructions,
24226 not just the potentially ambiguous ones. */
24227#define cCL(mnem, op, nops, ops, ae) \
21d799b5 24228 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 24229 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
e3cb604e
PB
24230
24231/* Coprocessor, takes either a suffix or a position-3 infix
24232 (for an FPA corner case). */
24233#define C3E(mnem, op, nops, ops, ae) \
21d799b5 24234 { mnem, OPS##nops ops, OT_csuf_or_in3, \
5ee91343 24235 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 24236
6a86118a 24237#define xCM_(m1, m2, m3, op, nops, ops, ae) \
21d799b5
NC
24238 { m1 #m2 m3, OPS##nops ops, \
24239 sizeof (#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof (m1) - 1, \
5ee91343 24240 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24241
24242#define CM(m1, m2, op, nops, ops, ae) \
e07e6e58
NC
24243 xCM_ (m1, , m2, op, nops, ops, ae), \
24244 xCM_ (m1, eq, m2, op, nops, ops, ae), \
24245 xCM_ (m1, ne, m2, op, nops, ops, ae), \
24246 xCM_ (m1, cs, m2, op, nops, ops, ae), \
24247 xCM_ (m1, hs, m2, op, nops, ops, ae), \
24248 xCM_ (m1, cc, m2, op, nops, ops, ae), \
24249 xCM_ (m1, ul, m2, op, nops, ops, ae), \
24250 xCM_ (m1, lo, m2, op, nops, ops, ae), \
24251 xCM_ (m1, mi, m2, op, nops, ops, ae), \
24252 xCM_ (m1, pl, m2, op, nops, ops, ae), \
24253 xCM_ (m1, vs, m2, op, nops, ops, ae), \
24254 xCM_ (m1, vc, m2, op, nops, ops, ae), \
24255 xCM_ (m1, hi, m2, op, nops, ops, ae), \
24256 xCM_ (m1, ls, m2, op, nops, ops, ae), \
24257 xCM_ (m1, ge, m2, op, nops, ops, ae), \
24258 xCM_ (m1, lt, m2, op, nops, ops, ae), \
24259 xCM_ (m1, gt, m2, op, nops, ops, ae), \
24260 xCM_ (m1, le, m2, op, nops, ops, ae), \
24261 xCM_ (m1, al, m2, op, nops, ops, ae)
6a86118a
NC
24262
24263#define UE(mnem, op, nops, ops, ae) \
5ee91343 24264 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
24265
24266#define UF(mnem, op, nops, ops, ae) \
5ee91343 24267 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 24268
5287ad62
JB
24269/* Neon data-processing. ARM versions are unconditional with cond=0xf.
24270 The Thumb and ARM variants are mostly the same (bits 0-23 and 24/28), so we
24271 use the same encoding function for each. */
24272#define NUF(mnem, op, nops, ops, enc) \
24273 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
5ee91343 24274 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
24275
24276/* Neon data processing, version which indirects through neon_enc_tab for
24277 the various overloaded versions of opcodes. */
24278#define nUF(mnem, op, nops, ops, enc) \
21d799b5 24279 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
5ee91343 24280 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
24281
24282/* Neon insn with conditional suffix for the ARM version, non-overloaded
24283 version. */
5ee91343 24284#define NCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
037e8744 24285 { #mnem, OPS##nops ops, tag, 0x##op, 0x##op, ARM_VARIANT, \
5ee91343 24286 THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 24287
037e8744 24288#define NCE(mnem, op, nops, ops, enc) \
5ee91343 24289 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
24290
24291#define NCEF(mnem, op, nops, ops, enc) \
5ee91343 24292 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
037e8744 24293
5287ad62 24294/* Neon insn with conditional suffix for the ARM version, overloaded types. */
5ee91343 24295#define nCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
21d799b5 24296 { #mnem, OPS##nops ops, tag, N_MNEM##op, N_MNEM##op, \
5ee91343 24297 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 24298
037e8744 24299#define nCE(mnem, op, nops, ops, enc) \
5ee91343 24300 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
24301
24302#define nCEF(mnem, op, nops, ops, enc) \
5ee91343
AV
24303 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
24304
24305/* */
24306#define mCEF(mnem, op, nops, ops, enc) \
a302e574 24307 { #mnem, OPS##nops ops, OT_csuffixF, M_MNEM##op, M_MNEM##op, \
5ee91343
AV
24308 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24309
24310
24311/* nCEF but for MVE predicated instructions. */
24312#define mnCEF(mnem, op, nops, ops, enc) \
24313 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
24314
24315/* nCE but for MVE predicated instructions. */
24316#define mnCE(mnem, op, nops, ops, enc) \
24317 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
037e8744 24318
5ee91343
AV
24319/* NUF but for potentially MVE predicated instructions. */
24320#define MNUF(mnem, op, nops, ops, enc) \
24321 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
24322 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24323
24324/* nUF but for potentially MVE predicated instructions. */
24325#define mnUF(mnem, op, nops, ops, enc) \
24326 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
24327 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
24328
24329/* ToC but for potentially MVE predicated instructions. */
24330#define mToC(mnem, top, nops, ops, te) \
24331 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
24332 do_##te, 1 }
24333
24334/* NCE but for MVE predicated instructions. */
24335#define MNCE(mnem, op, nops, ops, enc) \
24336 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
24337
24338/* NCEF but for MVE predicated instructions. */
24339#define MNCEF(mnem, op, nops, ops, enc) \
24340 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
c19d1205
ZW
24341#define do_0 0
24342
c19d1205 24343static const struct asm_opcode insns[] =
bfae80f2 24344{
74db7efb
NC
24345#define ARM_VARIANT & arm_ext_v1 /* Core ARM Instructions. */
24346#define THUMB_VARIANT & arm_ext_v4t
21d799b5
NC
24347 tCE("and", 0000000, _and, 3, (RR, oRR, SH), arit, t_arit3c),
24348 tC3("ands", 0100000, _ands, 3, (RR, oRR, SH), arit, t_arit3c),
24349 tCE("eor", 0200000, _eor, 3, (RR, oRR, SH), arit, t_arit3c),
24350 tC3("eors", 0300000, _eors, 3, (RR, oRR, SH), arit, t_arit3c),
24351 tCE("sub", 0400000, _sub, 3, (RR, oRR, SH), arit, t_add_sub),
24352 tC3("subs", 0500000, _subs, 3, (RR, oRR, SH), arit, t_add_sub),
24353 tCE("add", 0800000, _add, 3, (RR, oRR, SHG), arit, t_add_sub),
24354 tC3("adds", 0900000, _adds, 3, (RR, oRR, SHG), arit, t_add_sub),
24355 tCE("adc", 0a00000, _adc, 3, (RR, oRR, SH), arit, t_arit3c),
24356 tC3("adcs", 0b00000, _adcs, 3, (RR, oRR, SH), arit, t_arit3c),
24357 tCE("sbc", 0c00000, _sbc, 3, (RR, oRR, SH), arit, t_arit3),
24358 tC3("sbcs", 0d00000, _sbcs, 3, (RR, oRR, SH), arit, t_arit3),
24359 tCE("orr", 1800000, _orr, 3, (RR, oRR, SH), arit, t_arit3c),
24360 tC3("orrs", 1900000, _orrs, 3, (RR, oRR, SH), arit, t_arit3c),
24361 tCE("bic", 1c00000, _bic, 3, (RR, oRR, SH), arit, t_arit3),
24362 tC3("bics", 1d00000, _bics, 3, (RR, oRR, SH), arit, t_arit3),
c19d1205
ZW
24363
24364 /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
24365 for setting PSR flag bits. They are obsolete in V6 and do not
24366 have Thumb equivalents. */
21d799b5
NC
24367 tCE("tst", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
24368 tC3w("tsts", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
24369 CL("tstp", 110f000, 2, (RR, SH), cmp),
24370 tCE("cmp", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
24371 tC3w("cmps", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
24372 CL("cmpp", 150f000, 2, (RR, SH), cmp),
24373 tCE("cmn", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
24374 tC3w("cmns", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
24375 CL("cmnp", 170f000, 2, (RR, SH), cmp),
24376
24377 tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
72d98d16 24378 tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
21d799b5
NC
24379 tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
24380 tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
24381
24382 tCE("ldr", 4100000, _ldr, 2, (RR, ADDRGLDR),ldst, t_ldst),
5be8be5d
DG
24383 tC3("ldrb", 4500000, _ldrb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
24384 tCE("str", 4000000, _str, _2, (MIX_ARM_THUMB_OPERANDS (OP_RR,
24385 OP_RRnpc),
24386 OP_ADDRGLDR),ldst, t_ldst),
24387 tC3("strb", 4400000, _strb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
21d799b5
NC
24388
24389 tCE("stm", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24390 tC3("stmia", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24391 tC3("stmea", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24392 tCE("ldm", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24393 tC3("ldmia", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24394 tC3("ldmfd", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24395
21d799b5
NC
24396 tCE("b", a000000, _b, 1, (EXPr), branch, t_branch),
24397 TCE("bl", b000000, f000f800, 1, (EXPr), bl, t_branch23),
bfae80f2 24398
c19d1205 24399 /* Pseudo ops. */
21d799b5 24400 tCE("adr", 28f0000, _adr, 2, (RR, EXP), adr, t_adr),
2fc8bdac 24401 C3(adrl, 28f0000, 2, (RR, EXP), adrl),
21d799b5 24402 tCE("nop", 1a00000, _nop, 1, (oI255c), nop, t_nop),
74db7efb 24403 tCE("udf", 7f000f0, _udf, 1, (oIffffb), bkpt, t_udf),
c19d1205
ZW
24404
24405 /* Thumb-compatibility pseudo ops. */
21d799b5
NC
24406 tCE("lsl", 1a00000, _lsl, 3, (RR, oRR, SH), shift, t_shift),
24407 tC3("lsls", 1b00000, _lsls, 3, (RR, oRR, SH), shift, t_shift),
24408 tCE("lsr", 1a00020, _lsr, 3, (RR, oRR, SH), shift, t_shift),
24409 tC3("lsrs", 1b00020, _lsrs, 3, (RR, oRR, SH), shift, t_shift),
24410 tCE("asr", 1a00040, _asr, 3, (RR, oRR, SH), shift, t_shift),
24411 tC3("asrs", 1b00040, _asrs, 3, (RR, oRR, SH), shift, t_shift),
24412 tCE("ror", 1a00060, _ror, 3, (RR, oRR, SH), shift, t_shift),
24413 tC3("rors", 1b00060, _rors, 3, (RR, oRR, SH), shift, t_shift),
24414 tCE("neg", 2600000, _neg, 2, (RR, RR), rd_rn, t_neg),
24415 tC3("negs", 2700000, _negs, 2, (RR, RR), rd_rn, t_neg),
24416 tCE("push", 92d0000, _push, 1, (REGLST), push_pop, t_push_pop),
24417 tCE("pop", 8bd0000, _pop, 1, (REGLST), push_pop, t_push_pop),
c19d1205 24418
16a4cf17 24419 /* These may simplify to neg. */
21d799b5
NC
24420 TCE("rsb", 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
24421 TC3("rsbs", 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
16a4cf17 24422
173205ca
TP
24423#undef THUMB_VARIANT
24424#define THUMB_VARIANT & arm_ext_os
24425
24426 TCE("swi", f000000, df00, 1, (EXPi), swi, t_swi),
24427 TCE("svc", f000000, df00, 1, (EXPi), swi, t_swi),
24428
c921be7d
NC
24429#undef THUMB_VARIANT
24430#define THUMB_VARIANT & arm_ext_v6
24431
21d799b5 24432 TCE("cpy", 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
c19d1205
ZW
24433
24434 /* V1 instructions with no Thumb analogue prior to V6T2. */
c921be7d
NC
24435#undef THUMB_VARIANT
24436#define THUMB_VARIANT & arm_ext_v6t2
24437
21d799b5
NC
24438 TCE("teq", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
24439 TC3w("teqs", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
24440 CL("teqp", 130f000, 2, (RR, SH), cmp),
c19d1205 24441
5be8be5d
DG
24442 TC3("ldrt", 4300000, f8500e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
24443 TC3("ldrbt", 4700000, f8100e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
24444 TC3("strt", 4200000, f8400e00, 2, (RR_npcsp, ADDR), ldstt, t_ldstt),
24445 TC3("strbt", 4600000, f8000e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
c19d1205 24446
21d799b5
NC
24447 TC3("stmdb", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24448 TC3("stmfd", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205 24449
21d799b5
NC
24450 TC3("ldmdb", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
24451 TC3("ldmea", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205
ZW
24452
24453 /* V1 instructions with no Thumb analogue at all. */
21d799b5 24454 CE("rsc", 0e00000, 3, (RR, oRR, SH), arit),
c19d1205
ZW
24455 C3(rscs, 0f00000, 3, (RR, oRR, SH), arit),
24456
24457 C3(stmib, 9800000, 2, (RRw, REGLST), ldmstm),
24458 C3(stmfa, 9800000, 2, (RRw, REGLST), ldmstm),
24459 C3(stmda, 8000000, 2, (RRw, REGLST), ldmstm),
24460 C3(stmed, 8000000, 2, (RRw, REGLST), ldmstm),
24461 C3(ldmib, 9900000, 2, (RRw, REGLST), ldmstm),
24462 C3(ldmed, 9900000, 2, (RRw, REGLST), ldmstm),
24463 C3(ldmda, 8100000, 2, (RRw, REGLST), ldmstm),
24464 C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm),
24465
c921be7d
NC
24466#undef ARM_VARIANT
24467#define ARM_VARIANT & arm_ext_v2 /* ARM 2 - multiplies. */
24468#undef THUMB_VARIANT
24469#define THUMB_VARIANT & arm_ext_v4t
24470
21d799b5
NC
24471 tCE("mul", 0000090, _mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
24472 tC3("muls", 0100090, _muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
c19d1205 24473
c921be7d
NC
24474#undef THUMB_VARIANT
24475#define THUMB_VARIANT & arm_ext_v6t2
24476
21d799b5 24477 TCE("mla", 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
c19d1205
ZW
24478 C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
24479
24480 /* Generic coprocessor instructions. */
21d799b5
NC
24481 TCE("cdp", e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
24482 TCE("ldc", c100000, ec100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24483 TC3("ldcl", c500000, ec500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24484 TCE("stc", c000000, ec000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24485 TC3("stcl", c400000, ec400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24486 TCE("mcr", e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
db472d6f 24487 TCE("mrc", e100010, ee100010, 6, (RCP, I7b, APSR_RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 24488
c921be7d
NC
24489#undef ARM_VARIANT
24490#define ARM_VARIANT & arm_ext_v2s /* ARM 3 - swp instructions. */
24491
21d799b5 24492 CE("swp", 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
c19d1205
ZW
24493 C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
24494
c921be7d
NC
24495#undef ARM_VARIANT
24496#define ARM_VARIANT & arm_ext_v3 /* ARM 6 Status register instructions. */
24497#undef THUMB_VARIANT
24498#define THUMB_VARIANT & arm_ext_msr
24499
d2cd1205
JB
24500 TCE("mrs", 1000000, f3e08000, 2, (RRnpc, rPSR), mrs, t_mrs),
24501 TCE("msr", 120f000, f3808000, 2, (wPSR, RR_EXi), msr, t_msr),
c19d1205 24502
c921be7d
NC
24503#undef ARM_VARIANT
24504#define ARM_VARIANT & arm_ext_v3m /* ARM 7M long multiplies. */
24505#undef THUMB_VARIANT
24506#define THUMB_VARIANT & arm_ext_v6t2
24507
21d799b5
NC
24508 TCE("smull", 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24509 CM("smull","s", 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24510 TCE("umull", 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24511 CM("umull","s", 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24512 TCE("smlal", 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24513 CM("smlal","s", 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
24514 TCE("umlal", 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
24515 CM("umlal","s", 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
c19d1205 24516
c921be7d
NC
24517#undef ARM_VARIANT
24518#define ARM_VARIANT & arm_ext_v4 /* ARM Architecture 4. */
24519#undef THUMB_VARIANT
24520#define THUMB_VARIANT & arm_ext_v4t
24521
5be8be5d
DG
24522 tC3("ldrh", 01000b0, _ldrh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24523 tC3("strh", 00000b0, _strh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24524 tC3("ldrsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24525 tC3("ldrsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
56c0a61f
RE
24526 tC3("ldsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
24527 tC3("ldsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
c19d1205 24528
c921be7d
NC
24529#undef ARM_VARIANT
24530#define ARM_VARIANT & arm_ext_v4t_5
24531
c19d1205
ZW
24532 /* ARM Architecture 4T. */
24533 /* Note: bx (and blx) are required on V5, even if the processor does
24534 not support Thumb. */
21d799b5 24535 TCE("bx", 12fff10, 4700, 1, (RR), bx, t_bx),
c19d1205 24536
c921be7d
NC
24537#undef ARM_VARIANT
24538#define ARM_VARIANT & arm_ext_v5 /* ARM Architecture 5T. */
24539#undef THUMB_VARIANT
24540#define THUMB_VARIANT & arm_ext_v5t
24541
c19d1205
ZW
24542 /* Note: blx has 2 variants; the .value coded here is for
24543 BLX(2). Only this variant has conditional execution. */
21d799b5
NC
24544 TCE("blx", 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
24545 TUE("bkpt", 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
c19d1205 24546
c921be7d
NC
24547#undef THUMB_VARIANT
24548#define THUMB_VARIANT & arm_ext_v6t2
24549
21d799b5
NC
24550 TCE("clz", 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
24551 TUF("ldc2", c100000, fc100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24552 TUF("ldc2l", c500000, fc500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24553 TUF("stc2", c000000, fc000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24554 TUF("stc2l", c400000, fc400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
24555 TUF("cdp2", e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
24556 TUF("mcr2", e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
24557 TUF("mrc2", e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 24558
c921be7d 24559#undef ARM_VARIANT
74db7efb
NC
24560#define ARM_VARIANT & arm_ext_v5exp /* ARM Architecture 5TExP. */
24561#undef THUMB_VARIANT
24562#define THUMB_VARIANT & arm_ext_v5exp
c921be7d 24563
21d799b5
NC
24564 TCE("smlabb", 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24565 TCE("smlatb", 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24566 TCE("smlabt", 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24567 TCE("smlatt", 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 24568
21d799b5
NC
24569 TCE("smlawb", 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
24570 TCE("smlawt", 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 24571
21d799b5
NC
24572 TCE("smlalbb", 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24573 TCE("smlaltb", 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24574 TCE("smlalbt", 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
24575 TCE("smlaltt", 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
c19d1205 24576
21d799b5
NC
24577 TCE("smulbb", 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24578 TCE("smultb", 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24579 TCE("smulbt", 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24580 TCE("smultt", 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 24581
21d799b5
NC
24582 TCE("smulwb", 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24583 TCE("smulwt", 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 24584
03ee1b7f
NC
24585 TCE("qadd", 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24586 TCE("qdadd", 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24587 TCE("qsub", 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
24588 TCE("qdsub", 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
c19d1205 24589
c921be7d 24590#undef ARM_VARIANT
74db7efb
NC
24591#define ARM_VARIANT & arm_ext_v5e /* ARM Architecture 5TE. */
24592#undef THUMB_VARIANT
24593#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 24594
21d799b5 24595 TUF("pld", 450f000, f810f000, 1, (ADDR), pld, t_pld),
5be8be5d
DG
24596 TC3("ldrd", 00000d0, e8500000, 3, (RRnpc_npcsp, oRRnpc_npcsp, ADDRGLDRS),
24597 ldrd, t_ldstd),
24598 TC3("strd", 00000f0, e8400000, 3, (RRnpc_npcsp, oRRnpc_npcsp,
24599 ADDRGLDRS), ldrd, t_ldstd),
c19d1205 24600
21d799b5
NC
24601 TCE("mcrr", c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
24602 TCE("mrrc", c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
c19d1205 24603
c921be7d
NC
24604#undef ARM_VARIANT
24605#define ARM_VARIANT & arm_ext_v5j /* ARM Architecture 5TEJ. */
24606
21d799b5 24607 TCE("bxj", 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
c19d1205 24608
c921be7d
NC
24609#undef ARM_VARIANT
24610#define ARM_VARIANT & arm_ext_v6 /* ARM V6. */
24611#undef THUMB_VARIANT
24612#define THUMB_VARIANT & arm_ext_v6
24613
21d799b5
NC
24614 TUF("cpsie", 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
24615 TUF("cpsid", 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
24616 tCE("rev", 6bf0f30, _rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24617 tCE("rev16", 6bf0fb0, _rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24618 tCE("revsh", 6ff0fb0, _revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
24619 tCE("sxth", 6bf0070, _sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24620 tCE("uxth", 6ff0070, _uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24621 tCE("sxtb", 6af0070, _sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24622 tCE("uxtb", 6ef0070, _uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24623 TUF("setend", 1010000, b650, 1, (ENDI), setend, t_setend),
c19d1205 24624
c921be7d 24625#undef THUMB_VARIANT
ff8646ee 24626#define THUMB_VARIANT & arm_ext_v6t2_v8m
c921be7d 24627
5be8be5d
DG
24628 TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
24629 TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
24630 strex, t_strex),
ff8646ee
TP
24631#undef THUMB_VARIANT
24632#define THUMB_VARIANT & arm_ext_v6t2
24633
21d799b5
NC
24634 TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
24635 TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
62b3e311 24636
21d799b5
NC
24637 TCE("ssat", 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
24638 TCE("usat", 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
62b3e311 24639
9e3c6df6 24640/* ARM V6 not included in V7M. */
c921be7d
NC
24641#undef THUMB_VARIANT
24642#define THUMB_VARIANT & arm_ext_v6_notm
9e3c6df6 24643 TUF("rfeia", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6 24644 TUF("rfe", 8900a00, e990c000, 1, (RRw), rfe, rfe),
9e3c6df6
PB
24645 UF(rfeib, 9900a00, 1, (RRw), rfe),
24646 UF(rfeda, 8100a00, 1, (RRw), rfe),
24647 TUF("rfedb", 9100a00, e810c000, 1, (RRw), rfe, rfe),
24648 TUF("rfefd", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6
RE
24649 UF(rfefa, 8100a00, 1, (RRw), rfe),
24650 TUF("rfeea", 9100a00, e810c000, 1, (RRw), rfe, rfe),
24651 UF(rfeed, 9900a00, 1, (RRw), rfe),
9e3c6df6 24652 TUF("srsia", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
d709e4e6
RE
24653 TUF("srs", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
24654 TUF("srsea", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
9e3c6df6 24655 UF(srsib, 9c00500, 2, (oRRw, I31w), srs),
d709e4e6 24656 UF(srsfa, 9c00500, 2, (oRRw, I31w), srs),
9e3c6df6 24657 UF(srsda, 8400500, 2, (oRRw, I31w), srs),
d709e4e6 24658 UF(srsed, 8400500, 2, (oRRw, I31w), srs),
9e3c6df6 24659 TUF("srsdb", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
d709e4e6 24660 TUF("srsfd", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
941c9cad 24661 TUF("cps", 1020000, f3af8100, 1, (I31b), imm0, t_cps),
c921be7d 24662
9e3c6df6
PB
24663/* ARM V6 not included in V7M (eg. integer SIMD). */
24664#undef THUMB_VARIANT
24665#define THUMB_VARIANT & arm_ext_v6_dsp
21d799b5
NC
24666 TCE("pkhbt", 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
24667 TCE("pkhtb", 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
24668 TCE("qadd16", 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24669 TCE("qadd8", 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24670 TCE("qasx", 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24671 /* Old name for QASX. */
74db7efb 24672 TCE("qaddsubx",6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 24673 TCE("qsax", 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24674 /* Old name for QSAX. */
74db7efb 24675 TCE("qsubaddx",6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24676 TCE("qsub16", 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24677 TCE("qsub8", 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24678 TCE("sadd16", 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24679 TCE("sadd8", 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24680 TCE("sasx", 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24681 /* Old name for SASX. */
74db7efb 24682 TCE("saddsubx",6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24683 TCE("shadd16", 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24684 TCE("shadd8", 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24685 TCE("shasx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24686 /* Old name for SHASX. */
21d799b5 24687 TCE("shaddsubx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24688 TCE("shsax", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24689 /* Old name for SHSAX. */
21d799b5
NC
24690 TCE("shsubaddx", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24691 TCE("shsub16", 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24692 TCE("shsub8", 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24693 TCE("ssax", 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24694 /* Old name for SSAX. */
74db7efb 24695 TCE("ssubaddx",6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24696 TCE("ssub16", 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24697 TCE("ssub8", 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24698 TCE("uadd16", 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24699 TCE("uadd8", 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24700 TCE("uasx", 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24701 /* Old name for UASX. */
74db7efb 24702 TCE("uaddsubx",6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24703 TCE("uhadd16", 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24704 TCE("uhadd8", 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24705 TCE("uhasx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24706 /* Old name for UHASX. */
21d799b5
NC
24707 TCE("uhaddsubx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24708 TCE("uhsax", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24709 /* Old name for UHSAX. */
21d799b5
NC
24710 TCE("uhsubaddx", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24711 TCE("uhsub16", 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24712 TCE("uhsub8", 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24713 TCE("uqadd16", 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24714 TCE("uqadd8", 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 24715 TCE("uqasx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24716 /* Old name for UQASX. */
21d799b5
NC
24717 TCE("uqaddsubx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24718 TCE("uqsax", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24719 /* Old name for UQSAX. */
21d799b5
NC
24720 TCE("uqsubaddx", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24721 TCE("uqsub16", 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24722 TCE("uqsub8", 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24723 TCE("usub16", 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24724 TCE("usax", 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 24725 /* Old name for USAX. */
74db7efb 24726 TCE("usubaddx",6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 24727 TCE("usub8", 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
24728 TCE("sxtah", 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24729 TCE("sxtab16", 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24730 TCE("sxtab", 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24731 TCE("sxtb16", 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24732 TCE("uxtah", 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24733 TCE("uxtab16", 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24734 TCE("uxtab", 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
24735 TCE("uxtb16", 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
24736 TCE("sel", 6800fb0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
24737 TCE("smlad", 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24738 TCE("smladx", 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24739 TCE("smlald", 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24740 TCE("smlaldx", 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24741 TCE("smlsd", 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24742 TCE("smlsdx", 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24743 TCE("smlsld", 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24744 TCE("smlsldx", 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
24745 TCE("smmla", 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24746 TCE("smmlar", 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24747 TCE("smmls", 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24748 TCE("smmlsr", 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24749 TCE("smmul", 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24750 TCE("smmulr", 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24751 TCE("smuad", 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24752 TCE("smuadx", 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24753 TCE("smusd", 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24754 TCE("smusdx", 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
21d799b5
NC
24755 TCE("ssat16", 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
24756 TCE("umaal", 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
24757 TCE("usad8", 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
24758 TCE("usada8", 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
24759 TCE("usat16", 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
c19d1205 24760
c921be7d 24761#undef ARM_VARIANT
55e8aae7 24762#define ARM_VARIANT & arm_ext_v6k_v6t2
c921be7d 24763#undef THUMB_VARIANT
55e8aae7 24764#define THUMB_VARIANT & arm_ext_v6k_v6t2
c921be7d 24765
21d799b5
NC
24766 tCE("yield", 320f001, _yield, 0, (), noargs, t_hint),
24767 tCE("wfe", 320f002, _wfe, 0, (), noargs, t_hint),
24768 tCE("wfi", 320f003, _wfi, 0, (), noargs, t_hint),
24769 tCE("sev", 320f004, _sev, 0, (), noargs, t_hint),
c19d1205 24770
c921be7d
NC
24771#undef THUMB_VARIANT
24772#define THUMB_VARIANT & arm_ext_v6_notm
5be8be5d
DG
24773 TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc_npcsp, oRRnpc_npcsp, RRnpcb),
24774 ldrexd, t_ldrexd),
24775 TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc_npcsp, RRnpc_npcsp, oRRnpc_npcsp,
24776 RRnpcb), strexd, t_strexd),
ebdca51a 24777
c921be7d 24778#undef THUMB_VARIANT
ff8646ee 24779#define THUMB_VARIANT & arm_ext_v6t2_v8m
5be8be5d
DG
24780 TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
24781 rd_rn, rd_rn),
24782 TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
24783 rd_rn, rd_rn),
24784 TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 24785 strex, t_strexbh),
5be8be5d 24786 TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 24787 strex, t_strexbh),
21d799b5 24788 TUF("clrex", 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
c19d1205 24789
c921be7d 24790#undef ARM_VARIANT
f4c65163 24791#define ARM_VARIANT & arm_ext_sec
74db7efb 24792#undef THUMB_VARIANT
f4c65163 24793#define THUMB_VARIANT & arm_ext_sec
c921be7d 24794
21d799b5 24795 TCE("smc", 1600070, f7f08000, 1, (EXPi), smc, t_smc),
c19d1205 24796
90ec0d68
MGD
24797#undef ARM_VARIANT
24798#define ARM_VARIANT & arm_ext_virt
24799#undef THUMB_VARIANT
24800#define THUMB_VARIANT & arm_ext_virt
24801
24802 TCE("hvc", 1400070, f7e08000, 1, (EXPi), hvc, t_hvc),
24803 TCE("eret", 160006e, f3de8f00, 0, (), noargs, noargs),
24804
ddfded2f
MW
24805#undef ARM_VARIANT
24806#define ARM_VARIANT & arm_ext_pan
24807#undef THUMB_VARIANT
24808#define THUMB_VARIANT & arm_ext_pan
24809
24810 TUF("setpan", 1100000, b610, 1, (I7), setpan, t_setpan),
24811
c921be7d 24812#undef ARM_VARIANT
74db7efb 24813#define ARM_VARIANT & arm_ext_v6t2
f4c65163
MGD
24814#undef THUMB_VARIANT
24815#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 24816
21d799b5
NC
24817 TCE("bfc", 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
24818 TCE("bfi", 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
24819 TCE("sbfx", 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
24820 TCE("ubfx", 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
c19d1205 24821
21d799b5 24822 TCE("mls", 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
21d799b5 24823 TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
c19d1205 24824
5be8be5d
DG
24825 TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24826 TC3("ldrsht", 03000f0, f9300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24827 TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
24828 TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
c19d1205 24829
91d8b670
JG
24830#undef ARM_VARIANT
24831#define ARM_VARIANT & arm_ext_v3
24832#undef THUMB_VARIANT
24833#define THUMB_VARIANT & arm_ext_v6t2
24834
24835 TUE("csdb", 320f014, f3af8014, 0, (), noargs, t_csdb),
c597cc3d
SD
24836 TUF("ssbb", 57ff040, f3bf8f40, 0, (), noargs, t_csdb),
24837 TUF("pssbb", 57ff044, f3bf8f44, 0, (), noargs, t_csdb),
91d8b670
JG
24838
24839#undef ARM_VARIANT
24840#define ARM_VARIANT & arm_ext_v6t2
ff8646ee
TP
24841#undef THUMB_VARIANT
24842#define THUMB_VARIANT & arm_ext_v6t2_v8m
24843 TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
24844 TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
24845
bf3eeda7 24846 /* Thumb-only instructions. */
74db7efb 24847#undef ARM_VARIANT
bf3eeda7
NS
24848#define ARM_VARIANT NULL
24849 TUE("cbnz", 0, b900, 2, (RR, EXP), 0, t_cbz),
24850 TUE("cbz", 0, b100, 2, (RR, EXP), 0, t_cbz),
c921be7d
NC
24851
24852 /* ARM does not really have an IT instruction, so always allow it.
24853 The opcode is copied from Thumb in order to allow warnings in
24854 -mimplicit-it=[never | arm] modes. */
24855#undef ARM_VARIANT
24856#define ARM_VARIANT & arm_ext_v1
ff8646ee
TP
24857#undef THUMB_VARIANT
24858#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 24859
21d799b5
NC
24860 TUE("it", bf08, bf08, 1, (COND), it, t_it),
24861 TUE("itt", bf0c, bf0c, 1, (COND), it, t_it),
24862 TUE("ite", bf04, bf04, 1, (COND), it, t_it),
24863 TUE("ittt", bf0e, bf0e, 1, (COND), it, t_it),
24864 TUE("itet", bf06, bf06, 1, (COND), it, t_it),
24865 TUE("itte", bf0a, bf0a, 1, (COND), it, t_it),
24866 TUE("itee", bf02, bf02, 1, (COND), it, t_it),
24867 TUE("itttt", bf0f, bf0f, 1, (COND), it, t_it),
24868 TUE("itett", bf07, bf07, 1, (COND), it, t_it),
24869 TUE("ittet", bf0b, bf0b, 1, (COND), it, t_it),
24870 TUE("iteet", bf03, bf03, 1, (COND), it, t_it),
24871 TUE("ittte", bf0d, bf0d, 1, (COND), it, t_it),
24872 TUE("itete", bf05, bf05, 1, (COND), it, t_it),
24873 TUE("ittee", bf09, bf09, 1, (COND), it, t_it),
24874 TUE("iteee", bf01, bf01, 1, (COND), it, t_it),
1c444d06 24875 /* ARM/Thumb-2 instructions with no Thumb-1 equivalent. */
21d799b5
NC
24876 TC3("rrx", 01a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rrx),
24877 TC3("rrxs", 01b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rrx),
c19d1205 24878
92e90b6e 24879 /* Thumb2 only instructions. */
c921be7d
NC
24880#undef ARM_VARIANT
24881#define ARM_VARIANT NULL
92e90b6e 24882
21d799b5
NC
24883 TCE("addw", 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
24884 TCE("subw", 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
24885 TCE("orn", 0, ea600000, 3, (RR, oRR, SH), 0, t_orn),
24886 TCE("orns", 0, ea700000, 3, (RR, oRR, SH), 0, t_orn),
24887 TCE("tbb", 0, e8d0f000, 1, (TB), 0, t_tb),
24888 TCE("tbh", 0, e8d0f010, 1, (TB), 0, t_tb),
92e90b6e 24889
eea54501
MGD
24890 /* Hardware division instructions. */
24891#undef ARM_VARIANT
24892#define ARM_VARIANT & arm_ext_adiv
c921be7d
NC
24893#undef THUMB_VARIANT
24894#define THUMB_VARIANT & arm_ext_div
24895
eea54501
MGD
24896 TCE("sdiv", 710f010, fb90f0f0, 3, (RR, oRR, RR), div, t_div),
24897 TCE("udiv", 730f010, fbb0f0f0, 3, (RR, oRR, RR), div, t_div),
62b3e311 24898
7e806470 24899 /* ARM V6M/V7 instructions. */
c921be7d
NC
24900#undef ARM_VARIANT
24901#define ARM_VARIANT & arm_ext_barrier
24902#undef THUMB_VARIANT
24903#define THUMB_VARIANT & arm_ext_barrier
24904
ccb84d65
JB
24905 TUF("dmb", 57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier, barrier),
24906 TUF("dsb", 57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier, barrier),
24907 TUF("isb", 57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier, barrier),
7e806470 24908
62b3e311 24909 /* ARM V7 instructions. */
c921be7d
NC
24910#undef ARM_VARIANT
24911#define ARM_VARIANT & arm_ext_v7
24912#undef THUMB_VARIANT
24913#define THUMB_VARIANT & arm_ext_v7
24914
21d799b5
NC
24915 TUF("pli", 450f000, f910f000, 1, (ADDR), pli, t_pld),
24916 TCE("dbg", 320f0f0, f3af80f0, 1, (I15), dbg, t_dbg),
62b3e311 24917
74db7efb 24918#undef ARM_VARIANT
60e5ef9f 24919#define ARM_VARIANT & arm_ext_mp
74db7efb 24920#undef THUMB_VARIANT
60e5ef9f
MGD
24921#define THUMB_VARIANT & arm_ext_mp
24922
24923 TUF("pldw", 410f000, f830f000, 1, (ADDR), pld, t_pld),
24924
53c4b28b
MGD
24925 /* AArchv8 instructions. */
24926#undef ARM_VARIANT
24927#define ARM_VARIANT & arm_ext_v8
4ed7ed8d
TP
24928
24929/* Instructions shared between armv8-a and armv8-m. */
53c4b28b 24930#undef THUMB_VARIANT
4ed7ed8d 24931#define THUMB_VARIANT & arm_ext_atomics
53c4b28b 24932
4ed7ed8d
TP
24933 TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
24934 TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
24935 TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
24936 TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
24937 TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
24938 TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
4b8c8c02 24939 TCE("ldaex", 1900e9f, e8d00fef, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
4b8c8c02
RE
24940 TCE("ldaexb", 1d00e9f, e8d00fcf, 2, (RRnpc,RRnpcb), rd_rn, rd_rn),
24941 TCE("ldaexh", 1f00e9f, e8d00fdf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
24942 TCE("stlex", 1800e90, e8c00fe0, 3, (RRnpc, RRnpc, RRnpcb),
24943 stlex, t_stlex),
4b8c8c02
RE
24944 TCE("stlexb", 1c00e90, e8c00fc0, 3, (RRnpc, RRnpc, RRnpcb),
24945 stlex, t_stlex),
24946 TCE("stlexh", 1e00e90, e8c00fd0, 3, (RRnpc, RRnpc, RRnpcb),
24947 stlex, t_stlex),
4ed7ed8d
TP
24948#undef THUMB_VARIANT
24949#define THUMB_VARIANT & arm_ext_v8
53c4b28b 24950
4ed7ed8d 24951 tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
4ed7ed8d
TP
24952 TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
24953 ldrexd, t_ldrexd),
24954 TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
24955 strexd, t_strexd),
f7dd2fb2
TC
24956
24957/* Defined in V8 but is in undefined encoding space for earlier
24958 architectures. However earlier architectures are required to treat
24959 this instuction as a semihosting trap as well. Hence while not explicitly
24960 defined as such, it is in fact correct to define the instruction for all
24961 architectures. */
24962#undef THUMB_VARIANT
24963#define THUMB_VARIANT & arm_ext_v1
24964#undef ARM_VARIANT
24965#define ARM_VARIANT & arm_ext_v1
24966 TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
24967
8884b720 24968 /* ARMv8 T32 only. */
74db7efb 24969#undef ARM_VARIANT
b79f7053
MGD
24970#define ARM_VARIANT NULL
24971 TUF("dcps1", 0, f78f8001, 0, (), noargs, noargs),
24972 TUF("dcps2", 0, f78f8002, 0, (), noargs, noargs),
24973 TUF("dcps3", 0, f78f8003, 0, (), noargs, noargs),
24974
33399f07
MGD
24975 /* FP for ARMv8. */
24976#undef ARM_VARIANT
a715796b 24977#define ARM_VARIANT & fpu_vfp_ext_armv8xd
33399f07 24978#undef THUMB_VARIANT
a715796b 24979#define THUMB_VARIANT & fpu_vfp_ext_armv8xd
33399f07
MGD
24980
24981 nUF(vseleq, _vseleq, 3, (RVSD, RVSD, RVSD), vsel),
24982 nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD), vsel),
24983 nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD), vsel),
24984 nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD), vsel),
30bdf752 24985 nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ), vrintr),
a710b305
AV
24986 mnCE(vrintz, _vrintr, 2, (RNSDQMQ, oRNSDQMQ), vrintz),
24987 mnCE(vrintx, _vrintr, 2, (RNSDQMQ, oRNSDQMQ), vrintx),
24988 mnUF(vrinta, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrinta),
24989 mnUF(vrintn, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintn),
24990 mnUF(vrintp, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintp),
24991 mnUF(vrintm, _vrinta, 2, (RNSDQMQ, oRNSDQMQ), vrintm),
33399f07 24992
91ff7894
MGD
24993 /* Crypto v1 extensions. */
24994#undef ARM_VARIANT
24995#define ARM_VARIANT & fpu_crypto_ext_armv8
24996#undef THUMB_VARIANT
24997#define THUMB_VARIANT & fpu_crypto_ext_armv8
24998
24999 nUF(aese, _aes, 2, (RNQ, RNQ), aese),
25000 nUF(aesd, _aes, 2, (RNQ, RNQ), aesd),
25001 nUF(aesmc, _aes, 2, (RNQ, RNQ), aesmc),
25002 nUF(aesimc, _aes, 2, (RNQ, RNQ), aesimc),
48adcd8e
MGD
25003 nUF(sha1c, _sha3op, 3, (RNQ, RNQ, RNQ), sha1c),
25004 nUF(sha1p, _sha3op, 3, (RNQ, RNQ, RNQ), sha1p),
25005 nUF(sha1m, _sha3op, 3, (RNQ, RNQ, RNQ), sha1m),
25006 nUF(sha1su0, _sha3op, 3, (RNQ, RNQ, RNQ), sha1su0),
25007 nUF(sha256h, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h),
25008 nUF(sha256h2, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h2),
25009 nUF(sha256su1, _sha3op, 3, (RNQ, RNQ, RNQ), sha256su1),
3c9017d2
MGD
25010 nUF(sha1h, _sha1h, 2, (RNQ, RNQ), sha1h),
25011 nUF(sha1su1, _sha2op, 2, (RNQ, RNQ), sha1su1),
25012 nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
91ff7894 25013
dd5181d5 25014#undef ARM_VARIANT
8b301fbb 25015#define ARM_VARIANT & arm_ext_crc
dd5181d5 25016#undef THUMB_VARIANT
8b301fbb 25017#define THUMB_VARIANT & arm_ext_crc
dd5181d5
KT
25018 TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
25019 TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
25020 TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
25021 TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
25022 TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
25023 TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
25024
105bde57
MW
25025 /* ARMv8.2 RAS extension. */
25026#undef ARM_VARIANT
4d1464f2 25027#define ARM_VARIANT & arm_ext_ras
105bde57 25028#undef THUMB_VARIANT
4d1464f2 25029#define THUMB_VARIANT & arm_ext_ras
105bde57
MW
25030 TUE ("esb", 320f010, f3af8010, 0, (), noargs, noargs),
25031
49e8a725
SN
25032#undef ARM_VARIANT
25033#define ARM_VARIANT & arm_ext_v8_3
25034#undef THUMB_VARIANT
25035#define THUMB_VARIANT & arm_ext_v8_3
25036 NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
25037
c604a79a
JW
25038#undef ARM_VARIANT
25039#define ARM_VARIANT & fpu_neon_ext_dotprod
25040#undef THUMB_VARIANT
25041#define THUMB_VARIANT & fpu_neon_ext_dotprod
25042 NUF (vsdot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_s),
25043 NUF (vudot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_u),
25044
c921be7d
NC
25045#undef ARM_VARIANT
25046#define ARM_VARIANT & fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
53c4b28b
MGD
25047#undef THUMB_VARIANT
25048#define THUMB_VARIANT NULL
c921be7d 25049
21d799b5
NC
25050 cCE("wfs", e200110, 1, (RR), rd),
25051 cCE("rfs", e300110, 1, (RR), rd),
25052 cCE("wfc", e400110, 1, (RR), rd),
25053 cCE("rfc", e500110, 1, (RR), rd),
25054
25055 cCL("ldfs", c100100, 2, (RF, ADDRGLDC), rd_cpaddr),
25056 cCL("ldfd", c108100, 2, (RF, ADDRGLDC), rd_cpaddr),
25057 cCL("ldfe", c500100, 2, (RF, ADDRGLDC), rd_cpaddr),
25058 cCL("ldfp", c508100, 2, (RF, ADDRGLDC), rd_cpaddr),
25059
25060 cCL("stfs", c000100, 2, (RF, ADDRGLDC), rd_cpaddr),
25061 cCL("stfd", c008100, 2, (RF, ADDRGLDC), rd_cpaddr),
25062 cCL("stfe", c400100, 2, (RF, ADDRGLDC), rd_cpaddr),
25063 cCL("stfp", c408100, 2, (RF, ADDRGLDC), rd_cpaddr),
25064
25065 cCL("mvfs", e008100, 2, (RF, RF_IF), rd_rm),
25066 cCL("mvfsp", e008120, 2, (RF, RF_IF), rd_rm),
25067 cCL("mvfsm", e008140, 2, (RF, RF_IF), rd_rm),
25068 cCL("mvfsz", e008160, 2, (RF, RF_IF), rd_rm),
25069 cCL("mvfd", e008180, 2, (RF, RF_IF), rd_rm),
25070 cCL("mvfdp", e0081a0, 2, (RF, RF_IF), rd_rm),
25071 cCL("mvfdm", e0081c0, 2, (RF, RF_IF), rd_rm),
25072 cCL("mvfdz", e0081e0, 2, (RF, RF_IF), rd_rm),
25073 cCL("mvfe", e088100, 2, (RF, RF_IF), rd_rm),
25074 cCL("mvfep", e088120, 2, (RF, RF_IF), rd_rm),
25075 cCL("mvfem", e088140, 2, (RF, RF_IF), rd_rm),
25076 cCL("mvfez", e088160, 2, (RF, RF_IF), rd_rm),
25077
25078 cCL("mnfs", e108100, 2, (RF, RF_IF), rd_rm),
25079 cCL("mnfsp", e108120, 2, (RF, RF_IF), rd_rm),
25080 cCL("mnfsm", e108140, 2, (RF, RF_IF), rd_rm),
25081 cCL("mnfsz", e108160, 2, (RF, RF_IF), rd_rm),
25082 cCL("mnfd", e108180, 2, (RF, RF_IF), rd_rm),
25083 cCL("mnfdp", e1081a0, 2, (RF, RF_IF), rd_rm),
25084 cCL("mnfdm", e1081c0, 2, (RF, RF_IF), rd_rm),
25085 cCL("mnfdz", e1081e0, 2, (RF, RF_IF), rd_rm),
25086 cCL("mnfe", e188100, 2, (RF, RF_IF), rd_rm),
25087 cCL("mnfep", e188120, 2, (RF, RF_IF), rd_rm),
25088 cCL("mnfem", e188140, 2, (RF, RF_IF), rd_rm),
25089 cCL("mnfez", e188160, 2, (RF, RF_IF), rd_rm),
25090
25091 cCL("abss", e208100, 2, (RF, RF_IF), rd_rm),
25092 cCL("abssp", e208120, 2, (RF, RF_IF), rd_rm),
25093 cCL("abssm", e208140, 2, (RF, RF_IF), rd_rm),
25094 cCL("abssz", e208160, 2, (RF, RF_IF), rd_rm),
25095 cCL("absd", e208180, 2, (RF, RF_IF), rd_rm),
25096 cCL("absdp", e2081a0, 2, (RF, RF_IF), rd_rm),
25097 cCL("absdm", e2081c0, 2, (RF, RF_IF), rd_rm),
25098 cCL("absdz", e2081e0, 2, (RF, RF_IF), rd_rm),
25099 cCL("abse", e288100, 2, (RF, RF_IF), rd_rm),
25100 cCL("absep", e288120, 2, (RF, RF_IF), rd_rm),
25101 cCL("absem", e288140, 2, (RF, RF_IF), rd_rm),
25102 cCL("absez", e288160, 2, (RF, RF_IF), rd_rm),
25103
25104 cCL("rnds", e308100, 2, (RF, RF_IF), rd_rm),
25105 cCL("rndsp", e308120, 2, (RF, RF_IF), rd_rm),
25106 cCL("rndsm", e308140, 2, (RF, RF_IF), rd_rm),
25107 cCL("rndsz", e308160, 2, (RF, RF_IF), rd_rm),
25108 cCL("rndd", e308180, 2, (RF, RF_IF), rd_rm),
25109 cCL("rnddp", e3081a0, 2, (RF, RF_IF), rd_rm),
25110 cCL("rnddm", e3081c0, 2, (RF, RF_IF), rd_rm),
25111 cCL("rnddz", e3081e0, 2, (RF, RF_IF), rd_rm),
25112 cCL("rnde", e388100, 2, (RF, RF_IF), rd_rm),
25113 cCL("rndep", e388120, 2, (RF, RF_IF), rd_rm),
25114 cCL("rndem", e388140, 2, (RF, RF_IF), rd_rm),
25115 cCL("rndez", e388160, 2, (RF, RF_IF), rd_rm),
25116
25117 cCL("sqts", e408100, 2, (RF, RF_IF), rd_rm),
25118 cCL("sqtsp", e408120, 2, (RF, RF_IF), rd_rm),
25119 cCL("sqtsm", e408140, 2, (RF, RF_IF), rd_rm),
25120 cCL("sqtsz", e408160, 2, (RF, RF_IF), rd_rm),
25121 cCL("sqtd", e408180, 2, (RF, RF_IF), rd_rm),
25122 cCL("sqtdp", e4081a0, 2, (RF, RF_IF), rd_rm),
25123 cCL("sqtdm", e4081c0, 2, (RF, RF_IF), rd_rm),
25124 cCL("sqtdz", e4081e0, 2, (RF, RF_IF), rd_rm),
25125 cCL("sqte", e488100, 2, (RF, RF_IF), rd_rm),
25126 cCL("sqtep", e488120, 2, (RF, RF_IF), rd_rm),
25127 cCL("sqtem", e488140, 2, (RF, RF_IF), rd_rm),
25128 cCL("sqtez", e488160, 2, (RF, RF_IF), rd_rm),
25129
25130 cCL("logs", e508100, 2, (RF, RF_IF), rd_rm),
25131 cCL("logsp", e508120, 2, (RF, RF_IF), rd_rm),
25132 cCL("logsm", e508140, 2, (RF, RF_IF), rd_rm),
25133 cCL("logsz", e508160, 2, (RF, RF_IF), rd_rm),
25134 cCL("logd", e508180, 2, (RF, RF_IF), rd_rm),
25135 cCL("logdp", e5081a0, 2, (RF, RF_IF), rd_rm),
25136 cCL("logdm", e5081c0, 2, (RF, RF_IF), rd_rm),
25137 cCL("logdz", e5081e0, 2, (RF, RF_IF), rd_rm),
25138 cCL("loge", e588100, 2, (RF, RF_IF), rd_rm),
25139 cCL("logep", e588120, 2, (RF, RF_IF), rd_rm),
25140 cCL("logem", e588140, 2, (RF, RF_IF), rd_rm),
25141 cCL("logez", e588160, 2, (RF, RF_IF), rd_rm),
25142
25143 cCL("lgns", e608100, 2, (RF, RF_IF), rd_rm),
25144 cCL("lgnsp", e608120, 2, (RF, RF_IF), rd_rm),
25145 cCL("lgnsm", e608140, 2, (RF, RF_IF), rd_rm),
25146 cCL("lgnsz", e608160, 2, (RF, RF_IF), rd_rm),
25147 cCL("lgnd", e608180, 2, (RF, RF_IF), rd_rm),
25148 cCL("lgndp", e6081a0, 2, (RF, RF_IF), rd_rm),
25149 cCL("lgndm", e6081c0, 2, (RF, RF_IF), rd_rm),
25150 cCL("lgndz", e6081e0, 2, (RF, RF_IF), rd_rm),
25151 cCL("lgne", e688100, 2, (RF, RF_IF), rd_rm),
25152 cCL("lgnep", e688120, 2, (RF, RF_IF), rd_rm),
25153 cCL("lgnem", e688140, 2, (RF, RF_IF), rd_rm),
25154 cCL("lgnez", e688160, 2, (RF, RF_IF), rd_rm),
25155
25156 cCL("exps", e708100, 2, (RF, RF_IF), rd_rm),
25157 cCL("expsp", e708120, 2, (RF, RF_IF), rd_rm),
25158 cCL("expsm", e708140, 2, (RF, RF_IF), rd_rm),
25159 cCL("expsz", e708160, 2, (RF, RF_IF), rd_rm),
25160 cCL("expd", e708180, 2, (RF, RF_IF), rd_rm),
25161 cCL("expdp", e7081a0, 2, (RF, RF_IF), rd_rm),
25162 cCL("expdm", e7081c0, 2, (RF, RF_IF), rd_rm),
25163 cCL("expdz", e7081e0, 2, (RF, RF_IF), rd_rm),
25164 cCL("expe", e788100, 2, (RF, RF_IF), rd_rm),
25165 cCL("expep", e788120, 2, (RF, RF_IF), rd_rm),
25166 cCL("expem", e788140, 2, (RF, RF_IF), rd_rm),
25167 cCL("expdz", e788160, 2, (RF, RF_IF), rd_rm),
25168
25169 cCL("sins", e808100, 2, (RF, RF_IF), rd_rm),
25170 cCL("sinsp", e808120, 2, (RF, RF_IF), rd_rm),
25171 cCL("sinsm", e808140, 2, (RF, RF_IF), rd_rm),
25172 cCL("sinsz", e808160, 2, (RF, RF_IF), rd_rm),
25173 cCL("sind", e808180, 2, (RF, RF_IF), rd_rm),
25174 cCL("sindp", e8081a0, 2, (RF, RF_IF), rd_rm),
25175 cCL("sindm", e8081c0, 2, (RF, RF_IF), rd_rm),
25176 cCL("sindz", e8081e0, 2, (RF, RF_IF), rd_rm),
25177 cCL("sine", e888100, 2, (RF, RF_IF), rd_rm),
25178 cCL("sinep", e888120, 2, (RF, RF_IF), rd_rm),
25179 cCL("sinem", e888140, 2, (RF, RF_IF), rd_rm),
25180 cCL("sinez", e888160, 2, (RF, RF_IF), rd_rm),
25181
25182 cCL("coss", e908100, 2, (RF, RF_IF), rd_rm),
25183 cCL("cossp", e908120, 2, (RF, RF_IF), rd_rm),
25184 cCL("cossm", e908140, 2, (RF, RF_IF), rd_rm),
25185 cCL("cossz", e908160, 2, (RF, RF_IF), rd_rm),
25186 cCL("cosd", e908180, 2, (RF, RF_IF), rd_rm),
25187 cCL("cosdp", e9081a0, 2, (RF, RF_IF), rd_rm),
25188 cCL("cosdm", e9081c0, 2, (RF, RF_IF), rd_rm),
25189 cCL("cosdz", e9081e0, 2, (RF, RF_IF), rd_rm),
25190 cCL("cose", e988100, 2, (RF, RF_IF), rd_rm),
25191 cCL("cosep", e988120, 2, (RF, RF_IF), rd_rm),
25192 cCL("cosem", e988140, 2, (RF, RF_IF), rd_rm),
25193 cCL("cosez", e988160, 2, (RF, RF_IF), rd_rm),
25194
25195 cCL("tans", ea08100, 2, (RF, RF_IF), rd_rm),
25196 cCL("tansp", ea08120, 2, (RF, RF_IF), rd_rm),
25197 cCL("tansm", ea08140, 2, (RF, RF_IF), rd_rm),
25198 cCL("tansz", ea08160, 2, (RF, RF_IF), rd_rm),
25199 cCL("tand", ea08180, 2, (RF, RF_IF), rd_rm),
25200 cCL("tandp", ea081a0, 2, (RF, RF_IF), rd_rm),
25201 cCL("tandm", ea081c0, 2, (RF, RF_IF), rd_rm),
25202 cCL("tandz", ea081e0, 2, (RF, RF_IF), rd_rm),
25203 cCL("tane", ea88100, 2, (RF, RF_IF), rd_rm),
25204 cCL("tanep", ea88120, 2, (RF, RF_IF), rd_rm),
25205 cCL("tanem", ea88140, 2, (RF, RF_IF), rd_rm),
25206 cCL("tanez", ea88160, 2, (RF, RF_IF), rd_rm),
25207
25208 cCL("asns", eb08100, 2, (RF, RF_IF), rd_rm),
25209 cCL("asnsp", eb08120, 2, (RF, RF_IF), rd_rm),
25210 cCL("asnsm", eb08140, 2, (RF, RF_IF), rd_rm),
25211 cCL("asnsz", eb08160, 2, (RF, RF_IF), rd_rm),
25212 cCL("asnd", eb08180, 2, (RF, RF_IF), rd_rm),
25213 cCL("asndp", eb081a0, 2, (RF, RF_IF), rd_rm),
25214 cCL("asndm", eb081c0, 2, (RF, RF_IF), rd_rm),
25215 cCL("asndz", eb081e0, 2, (RF, RF_IF), rd_rm),
25216 cCL("asne", eb88100, 2, (RF, RF_IF), rd_rm),
25217 cCL("asnep", eb88120, 2, (RF, RF_IF), rd_rm),
25218 cCL("asnem", eb88140, 2, (RF, RF_IF), rd_rm),
25219 cCL("asnez", eb88160, 2, (RF, RF_IF), rd_rm),
25220
25221 cCL("acss", ec08100, 2, (RF, RF_IF), rd_rm),
25222 cCL("acssp", ec08120, 2, (RF, RF_IF), rd_rm),
25223 cCL("acssm", ec08140, 2, (RF, RF_IF), rd_rm),
25224 cCL("acssz", ec08160, 2, (RF, RF_IF), rd_rm),
25225 cCL("acsd", ec08180, 2, (RF, RF_IF), rd_rm),
25226 cCL("acsdp", ec081a0, 2, (RF, RF_IF), rd_rm),
25227 cCL("acsdm", ec081c0, 2, (RF, RF_IF), rd_rm),
25228 cCL("acsdz", ec081e0, 2, (RF, RF_IF), rd_rm),
25229 cCL("acse", ec88100, 2, (RF, RF_IF), rd_rm),
25230 cCL("acsep", ec88120, 2, (RF, RF_IF), rd_rm),
25231 cCL("acsem", ec88140, 2, (RF, RF_IF), rd_rm),
25232 cCL("acsez", ec88160, 2, (RF, RF_IF), rd_rm),
25233
25234 cCL("atns", ed08100, 2, (RF, RF_IF), rd_rm),
25235 cCL("atnsp", ed08120, 2, (RF, RF_IF), rd_rm),
25236 cCL("atnsm", ed08140, 2, (RF, RF_IF), rd_rm),
25237 cCL("atnsz", ed08160, 2, (RF, RF_IF), rd_rm),
25238 cCL("atnd", ed08180, 2, (RF, RF_IF), rd_rm),
25239 cCL("atndp", ed081a0, 2, (RF, RF_IF), rd_rm),
25240 cCL("atndm", ed081c0, 2, (RF, RF_IF), rd_rm),
25241 cCL("atndz", ed081e0, 2, (RF, RF_IF), rd_rm),
25242 cCL("atne", ed88100, 2, (RF, RF_IF), rd_rm),
25243 cCL("atnep", ed88120, 2, (RF, RF_IF), rd_rm),
25244 cCL("atnem", ed88140, 2, (RF, RF_IF), rd_rm),
25245 cCL("atnez", ed88160, 2, (RF, RF_IF), rd_rm),
25246
25247 cCL("urds", ee08100, 2, (RF, RF_IF), rd_rm),
25248 cCL("urdsp", ee08120, 2, (RF, RF_IF), rd_rm),
25249 cCL("urdsm", ee08140, 2, (RF, RF_IF), rd_rm),
25250 cCL("urdsz", ee08160, 2, (RF, RF_IF), rd_rm),
25251 cCL("urdd", ee08180, 2, (RF, RF_IF), rd_rm),
25252 cCL("urddp", ee081a0, 2, (RF, RF_IF), rd_rm),
25253 cCL("urddm", ee081c0, 2, (RF, RF_IF), rd_rm),
25254 cCL("urddz", ee081e0, 2, (RF, RF_IF), rd_rm),
25255 cCL("urde", ee88100, 2, (RF, RF_IF), rd_rm),
25256 cCL("urdep", ee88120, 2, (RF, RF_IF), rd_rm),
25257 cCL("urdem", ee88140, 2, (RF, RF_IF), rd_rm),
25258 cCL("urdez", ee88160, 2, (RF, RF_IF), rd_rm),
25259
25260 cCL("nrms", ef08100, 2, (RF, RF_IF), rd_rm),
25261 cCL("nrmsp", ef08120, 2, (RF, RF_IF), rd_rm),
25262 cCL("nrmsm", ef08140, 2, (RF, RF_IF), rd_rm),
25263 cCL("nrmsz", ef08160, 2, (RF, RF_IF), rd_rm),
25264 cCL("nrmd", ef08180, 2, (RF, RF_IF), rd_rm),
25265 cCL("nrmdp", ef081a0, 2, (RF, RF_IF), rd_rm),
25266 cCL("nrmdm", ef081c0, 2, (RF, RF_IF), rd_rm),
25267 cCL("nrmdz", ef081e0, 2, (RF, RF_IF), rd_rm),
25268 cCL("nrme", ef88100, 2, (RF, RF_IF), rd_rm),
25269 cCL("nrmep", ef88120, 2, (RF, RF_IF), rd_rm),
25270 cCL("nrmem", ef88140, 2, (RF, RF_IF), rd_rm),
25271 cCL("nrmez", ef88160, 2, (RF, RF_IF), rd_rm),
25272
25273 cCL("adfs", e000100, 3, (RF, RF, RF_IF), rd_rn_rm),
25274 cCL("adfsp", e000120, 3, (RF, RF, RF_IF), rd_rn_rm),
25275 cCL("adfsm", e000140, 3, (RF, RF, RF_IF), rd_rn_rm),
25276 cCL("adfsz", e000160, 3, (RF, RF, RF_IF), rd_rn_rm),
25277 cCL("adfd", e000180, 3, (RF, RF, RF_IF), rd_rn_rm),
25278 cCL("adfdp", e0001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25279 cCL("adfdm", e0001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25280 cCL("adfdz", e0001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25281 cCL("adfe", e080100, 3, (RF, RF, RF_IF), rd_rn_rm),
25282 cCL("adfep", e080120, 3, (RF, RF, RF_IF), rd_rn_rm),
25283 cCL("adfem", e080140, 3, (RF, RF, RF_IF), rd_rn_rm),
25284 cCL("adfez", e080160, 3, (RF, RF, RF_IF), rd_rn_rm),
25285
25286 cCL("sufs", e200100, 3, (RF, RF, RF_IF), rd_rn_rm),
25287 cCL("sufsp", e200120, 3, (RF, RF, RF_IF), rd_rn_rm),
25288 cCL("sufsm", e200140, 3, (RF, RF, RF_IF), rd_rn_rm),
25289 cCL("sufsz", e200160, 3, (RF, RF, RF_IF), rd_rn_rm),
25290 cCL("sufd", e200180, 3, (RF, RF, RF_IF), rd_rn_rm),
25291 cCL("sufdp", e2001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25292 cCL("sufdm", e2001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25293 cCL("sufdz", e2001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25294 cCL("sufe", e280100, 3, (RF, RF, RF_IF), rd_rn_rm),
25295 cCL("sufep", e280120, 3, (RF, RF, RF_IF), rd_rn_rm),
25296 cCL("sufem", e280140, 3, (RF, RF, RF_IF), rd_rn_rm),
25297 cCL("sufez", e280160, 3, (RF, RF, RF_IF), rd_rn_rm),
25298
25299 cCL("rsfs", e300100, 3, (RF, RF, RF_IF), rd_rn_rm),
25300 cCL("rsfsp", e300120, 3, (RF, RF, RF_IF), rd_rn_rm),
25301 cCL("rsfsm", e300140, 3, (RF, RF, RF_IF), rd_rn_rm),
25302 cCL("rsfsz", e300160, 3, (RF, RF, RF_IF), rd_rn_rm),
25303 cCL("rsfd", e300180, 3, (RF, RF, RF_IF), rd_rn_rm),
25304 cCL("rsfdp", e3001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25305 cCL("rsfdm", e3001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25306 cCL("rsfdz", e3001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25307 cCL("rsfe", e380100, 3, (RF, RF, RF_IF), rd_rn_rm),
25308 cCL("rsfep", e380120, 3, (RF, RF, RF_IF), rd_rn_rm),
25309 cCL("rsfem", e380140, 3, (RF, RF, RF_IF), rd_rn_rm),
25310 cCL("rsfez", e380160, 3, (RF, RF, RF_IF), rd_rn_rm),
25311
25312 cCL("mufs", e100100, 3, (RF, RF, RF_IF), rd_rn_rm),
25313 cCL("mufsp", e100120, 3, (RF, RF, RF_IF), rd_rn_rm),
25314 cCL("mufsm", e100140, 3, (RF, RF, RF_IF), rd_rn_rm),
25315 cCL("mufsz", e100160, 3, (RF, RF, RF_IF), rd_rn_rm),
25316 cCL("mufd", e100180, 3, (RF, RF, RF_IF), rd_rn_rm),
25317 cCL("mufdp", e1001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25318 cCL("mufdm", e1001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25319 cCL("mufdz", e1001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25320 cCL("mufe", e180100, 3, (RF, RF, RF_IF), rd_rn_rm),
25321 cCL("mufep", e180120, 3, (RF, RF, RF_IF), rd_rn_rm),
25322 cCL("mufem", e180140, 3, (RF, RF, RF_IF), rd_rn_rm),
25323 cCL("mufez", e180160, 3, (RF, RF, RF_IF), rd_rn_rm),
25324
25325 cCL("dvfs", e400100, 3, (RF, RF, RF_IF), rd_rn_rm),
25326 cCL("dvfsp", e400120, 3, (RF, RF, RF_IF), rd_rn_rm),
25327 cCL("dvfsm", e400140, 3, (RF, RF, RF_IF), rd_rn_rm),
25328 cCL("dvfsz", e400160, 3, (RF, RF, RF_IF), rd_rn_rm),
25329 cCL("dvfd", e400180, 3, (RF, RF, RF_IF), rd_rn_rm),
25330 cCL("dvfdp", e4001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25331 cCL("dvfdm", e4001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25332 cCL("dvfdz", e4001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25333 cCL("dvfe", e480100, 3, (RF, RF, RF_IF), rd_rn_rm),
25334 cCL("dvfep", e480120, 3, (RF, RF, RF_IF), rd_rn_rm),
25335 cCL("dvfem", e480140, 3, (RF, RF, RF_IF), rd_rn_rm),
25336 cCL("dvfez", e480160, 3, (RF, RF, RF_IF), rd_rn_rm),
25337
25338 cCL("rdfs", e500100, 3, (RF, RF, RF_IF), rd_rn_rm),
25339 cCL("rdfsp", e500120, 3, (RF, RF, RF_IF), rd_rn_rm),
25340 cCL("rdfsm", e500140, 3, (RF, RF, RF_IF), rd_rn_rm),
25341 cCL("rdfsz", e500160, 3, (RF, RF, RF_IF), rd_rn_rm),
25342 cCL("rdfd", e500180, 3, (RF, RF, RF_IF), rd_rn_rm),
25343 cCL("rdfdp", e5001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25344 cCL("rdfdm", e5001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25345 cCL("rdfdz", e5001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25346 cCL("rdfe", e580100, 3, (RF, RF, RF_IF), rd_rn_rm),
25347 cCL("rdfep", e580120, 3, (RF, RF, RF_IF), rd_rn_rm),
25348 cCL("rdfem", e580140, 3, (RF, RF, RF_IF), rd_rn_rm),
25349 cCL("rdfez", e580160, 3, (RF, RF, RF_IF), rd_rn_rm),
25350
25351 cCL("pows", e600100, 3, (RF, RF, RF_IF), rd_rn_rm),
25352 cCL("powsp", e600120, 3, (RF, RF, RF_IF), rd_rn_rm),
25353 cCL("powsm", e600140, 3, (RF, RF, RF_IF), rd_rn_rm),
25354 cCL("powsz", e600160, 3, (RF, RF, RF_IF), rd_rn_rm),
25355 cCL("powd", e600180, 3, (RF, RF, RF_IF), rd_rn_rm),
25356 cCL("powdp", e6001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25357 cCL("powdm", e6001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25358 cCL("powdz", e6001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25359 cCL("powe", e680100, 3, (RF, RF, RF_IF), rd_rn_rm),
25360 cCL("powep", e680120, 3, (RF, RF, RF_IF), rd_rn_rm),
25361 cCL("powem", e680140, 3, (RF, RF, RF_IF), rd_rn_rm),
25362 cCL("powez", e680160, 3, (RF, RF, RF_IF), rd_rn_rm),
25363
25364 cCL("rpws", e700100, 3, (RF, RF, RF_IF), rd_rn_rm),
25365 cCL("rpwsp", e700120, 3, (RF, RF, RF_IF), rd_rn_rm),
25366 cCL("rpwsm", e700140, 3, (RF, RF, RF_IF), rd_rn_rm),
25367 cCL("rpwsz", e700160, 3, (RF, RF, RF_IF), rd_rn_rm),
25368 cCL("rpwd", e700180, 3, (RF, RF, RF_IF), rd_rn_rm),
25369 cCL("rpwdp", e7001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25370 cCL("rpwdm", e7001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25371 cCL("rpwdz", e7001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25372 cCL("rpwe", e780100, 3, (RF, RF, RF_IF), rd_rn_rm),
25373 cCL("rpwep", e780120, 3, (RF, RF, RF_IF), rd_rn_rm),
25374 cCL("rpwem", e780140, 3, (RF, RF, RF_IF), rd_rn_rm),
25375 cCL("rpwez", e780160, 3, (RF, RF, RF_IF), rd_rn_rm),
25376
25377 cCL("rmfs", e800100, 3, (RF, RF, RF_IF), rd_rn_rm),
25378 cCL("rmfsp", e800120, 3, (RF, RF, RF_IF), rd_rn_rm),
25379 cCL("rmfsm", e800140, 3, (RF, RF, RF_IF), rd_rn_rm),
25380 cCL("rmfsz", e800160, 3, (RF, RF, RF_IF), rd_rn_rm),
25381 cCL("rmfd", e800180, 3, (RF, RF, RF_IF), rd_rn_rm),
25382 cCL("rmfdp", e8001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25383 cCL("rmfdm", e8001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25384 cCL("rmfdz", e8001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25385 cCL("rmfe", e880100, 3, (RF, RF, RF_IF), rd_rn_rm),
25386 cCL("rmfep", e880120, 3, (RF, RF, RF_IF), rd_rn_rm),
25387 cCL("rmfem", e880140, 3, (RF, RF, RF_IF), rd_rn_rm),
25388 cCL("rmfez", e880160, 3, (RF, RF, RF_IF), rd_rn_rm),
25389
25390 cCL("fmls", e900100, 3, (RF, RF, RF_IF), rd_rn_rm),
25391 cCL("fmlsp", e900120, 3, (RF, RF, RF_IF), rd_rn_rm),
25392 cCL("fmlsm", e900140, 3, (RF, RF, RF_IF), rd_rn_rm),
25393 cCL("fmlsz", e900160, 3, (RF, RF, RF_IF), rd_rn_rm),
25394 cCL("fmld", e900180, 3, (RF, RF, RF_IF), rd_rn_rm),
25395 cCL("fmldp", e9001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25396 cCL("fmldm", e9001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25397 cCL("fmldz", e9001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25398 cCL("fmle", e980100, 3, (RF, RF, RF_IF), rd_rn_rm),
25399 cCL("fmlep", e980120, 3, (RF, RF, RF_IF), rd_rn_rm),
25400 cCL("fmlem", e980140, 3, (RF, RF, RF_IF), rd_rn_rm),
25401 cCL("fmlez", e980160, 3, (RF, RF, RF_IF), rd_rn_rm),
25402
25403 cCL("fdvs", ea00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25404 cCL("fdvsp", ea00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25405 cCL("fdvsm", ea00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25406 cCL("fdvsz", ea00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25407 cCL("fdvd", ea00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25408 cCL("fdvdp", ea001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25409 cCL("fdvdm", ea001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25410 cCL("fdvdz", ea001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25411 cCL("fdve", ea80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25412 cCL("fdvep", ea80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25413 cCL("fdvem", ea80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25414 cCL("fdvez", ea80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25415
25416 cCL("frds", eb00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25417 cCL("frdsp", eb00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25418 cCL("frdsm", eb00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25419 cCL("frdsz", eb00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25420 cCL("frdd", eb00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25421 cCL("frddp", eb001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25422 cCL("frddm", eb001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25423 cCL("frddz", eb001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25424 cCL("frde", eb80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25425 cCL("frdep", eb80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25426 cCL("frdem", eb80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25427 cCL("frdez", eb80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25428
25429 cCL("pols", ec00100, 3, (RF, RF, RF_IF), rd_rn_rm),
25430 cCL("polsp", ec00120, 3, (RF, RF, RF_IF), rd_rn_rm),
25431 cCL("polsm", ec00140, 3, (RF, RF, RF_IF), rd_rn_rm),
25432 cCL("polsz", ec00160, 3, (RF, RF, RF_IF), rd_rn_rm),
25433 cCL("pold", ec00180, 3, (RF, RF, RF_IF), rd_rn_rm),
25434 cCL("poldp", ec001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
25435 cCL("poldm", ec001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
25436 cCL("poldz", ec001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
25437 cCL("pole", ec80100, 3, (RF, RF, RF_IF), rd_rn_rm),
25438 cCL("polep", ec80120, 3, (RF, RF, RF_IF), rd_rn_rm),
25439 cCL("polem", ec80140, 3, (RF, RF, RF_IF), rd_rn_rm),
25440 cCL("polez", ec80160, 3, (RF, RF, RF_IF), rd_rn_rm),
25441
25442 cCE("cmf", e90f110, 2, (RF, RF_IF), fpa_cmp),
25443 C3E("cmfe", ed0f110, 2, (RF, RF_IF), fpa_cmp),
25444 cCE("cnf", eb0f110, 2, (RF, RF_IF), fpa_cmp),
25445 C3E("cnfe", ef0f110, 2, (RF, RF_IF), fpa_cmp),
25446
25447 cCL("flts", e000110, 2, (RF, RR), rn_rd),
25448 cCL("fltsp", e000130, 2, (RF, RR), rn_rd),
25449 cCL("fltsm", e000150, 2, (RF, RR), rn_rd),
25450 cCL("fltsz", e000170, 2, (RF, RR), rn_rd),
25451 cCL("fltd", e000190, 2, (RF, RR), rn_rd),
25452 cCL("fltdp", e0001b0, 2, (RF, RR), rn_rd),
25453 cCL("fltdm", e0001d0, 2, (RF, RR), rn_rd),
25454 cCL("fltdz", e0001f0, 2, (RF, RR), rn_rd),
25455 cCL("flte", e080110, 2, (RF, RR), rn_rd),
25456 cCL("fltep", e080130, 2, (RF, RR), rn_rd),
25457 cCL("fltem", e080150, 2, (RF, RR), rn_rd),
25458 cCL("fltez", e080170, 2, (RF, RR), rn_rd),
b99bd4ef 25459
c19d1205
ZW
25460 /* The implementation of the FIX instruction is broken on some
25461 assemblers, in that it accepts a precision specifier as well as a
25462 rounding specifier, despite the fact that this is meaningless.
25463 To be more compatible, we accept it as well, though of course it
25464 does not set any bits. */
21d799b5
NC
25465 cCE("fix", e100110, 2, (RR, RF), rd_rm),
25466 cCL("fixp", e100130, 2, (RR, RF), rd_rm),
25467 cCL("fixm", e100150, 2, (RR, RF), rd_rm),
25468 cCL("fixz", e100170, 2, (RR, RF), rd_rm),
25469 cCL("fixsp", e100130, 2, (RR, RF), rd_rm),
25470 cCL("fixsm", e100150, 2, (RR, RF), rd_rm),
25471 cCL("fixsz", e100170, 2, (RR, RF), rd_rm),
25472 cCL("fixdp", e100130, 2, (RR, RF), rd_rm),
25473 cCL("fixdm", e100150, 2, (RR, RF), rd_rm),
25474 cCL("fixdz", e100170, 2, (RR, RF), rd_rm),
25475 cCL("fixep", e100130, 2, (RR, RF), rd_rm),
25476 cCL("fixem", e100150, 2, (RR, RF), rd_rm),
25477 cCL("fixez", e100170, 2, (RR, RF), rd_rm),
bfae80f2 25478
c19d1205 25479 /* Instructions that were new with the real FPA, call them V2. */
c921be7d
NC
25480#undef ARM_VARIANT
25481#define ARM_VARIANT & fpu_fpa_ext_v2
25482
21d799b5
NC
25483 cCE("lfm", c100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25484 cCL("lfmfd", c900200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25485 cCL("lfmea", d100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25486 cCE("sfm", c000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25487 cCL("sfmfd", d000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
25488 cCL("sfmea", c800200, 3, (RF, I4b, ADDR), fpa_ldmstm),
c19d1205 25489
c921be7d
NC
25490#undef ARM_VARIANT
25491#define ARM_VARIANT & fpu_vfp_ext_v1xd /* VFP V1xD (single precision). */
ba6cd17f
SD
25492#undef THUMB_VARIANT
25493#define THUMB_VARIANT & arm_ext_v6t2
25494 mcCE(vmrs, ef00a10, 2, (APSR_RR, RVC), vmrs),
25495 mcCE(vmsr, ee00a10, 2, (RVC, RR), vmsr),
ef8f595f
MI
25496 mcCE(fldd, d100b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
25497 mcCE(fstd, d000b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
25498 mcCE(flds, d100a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
25499 mcCE(fsts, d000a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
90e9955a
SP
25500
25501 /* Memory operations. */
25502 mcCE(fldmias, c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
25503 mcCE(fldmdbs, d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25504 mcCE(fstmias, c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
25505 mcCE(fstmdbs, d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
ba6cd17f 25506#undef THUMB_VARIANT
c921be7d 25507
c19d1205 25508 /* Moves and type conversions. */
21d799b5
NC
25509 cCE("fmstat", ef1fa10, 0, (), noargs),
25510 cCE("fsitos", eb80ac0, 2, (RVS, RVS), vfp_sp_monadic),
25511 cCE("fuitos", eb80a40, 2, (RVS, RVS), vfp_sp_monadic),
25512 cCE("ftosis", ebd0a40, 2, (RVS, RVS), vfp_sp_monadic),
25513 cCE("ftosizs", ebd0ac0, 2, (RVS, RVS), vfp_sp_monadic),
25514 cCE("ftouis", ebc0a40, 2, (RVS, RVS), vfp_sp_monadic),
25515 cCE("ftouizs", ebc0ac0, 2, (RVS, RVS), vfp_sp_monadic),
25516 cCE("fmrx", ef00a10, 2, (RR, RVC), rd_rn),
25517 cCE("fmxr", ee00a10, 2, (RVC, RR), rn_rd),
c19d1205
ZW
25518
25519 /* Memory operations. */
55881a11 25520 cCE("fldmfds", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
55881a11
MGD
25521 cCE("fldmeas", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25522 cCE("fldmiax", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25523 cCE("fldmfdx", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25524 cCE("fldmdbx", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
25525 cCE("fldmeax", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
55881a11 25526 cCE("fstmeas", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
55881a11
MGD
25527 cCE("fstmfds", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
25528 cCE("fstmiax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25529 cCE("fstmeax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
25530 cCE("fstmdbx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
25531 cCE("fstmfdx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
bfae80f2 25532
c19d1205 25533 /* Monadic operations. */
21d799b5
NC
25534 cCE("fabss", eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
25535 cCE("fnegs", eb10a40, 2, (RVS, RVS), vfp_sp_monadic),
25536 cCE("fsqrts", eb10ac0, 2, (RVS, RVS), vfp_sp_monadic),
c19d1205
ZW
25537
25538 /* Dyadic operations. */
21d799b5
NC
25539 cCE("fadds", e300a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25540 cCE("fsubs", e300a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25541 cCE("fmuls", e200a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25542 cCE("fdivs", e800a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25543 cCE("fmacs", e000a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25544 cCE("fmscs", e100a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25545 cCE("fnmuls", e200a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25546 cCE("fnmacs", e000a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25547 cCE("fnmscs", e100a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
b99bd4ef 25548
c19d1205 25549 /* Comparisons. */
21d799b5
NC
25550 cCE("fcmps", eb40a40, 2, (RVS, RVS), vfp_sp_monadic),
25551 cCE("fcmpzs", eb50a40, 1, (RVS), vfp_sp_compare_z),
25552 cCE("fcmpes", eb40ac0, 2, (RVS, RVS), vfp_sp_monadic),
25553 cCE("fcmpezs", eb50ac0, 1, (RVS), vfp_sp_compare_z),
b99bd4ef 25554
62f3b8c8
PB
25555 /* Double precision load/store are still present on single precision
25556 implementations. */
55881a11
MGD
25557 cCE("fldmiad", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25558 cCE("fldmfdd", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25559 cCE("fldmdbd", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25560 cCE("fldmead", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25561 cCE("fstmiad", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25562 cCE("fstmead", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
25563 cCE("fstmdbd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
25564 cCE("fstmfdd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
62f3b8c8 25565
c921be7d
NC
25566#undef ARM_VARIANT
25567#define ARM_VARIANT & fpu_vfp_ext_v1 /* VFP V1 (Double precision). */
25568
c19d1205 25569 /* Moves and type conversions. */
21d799b5
NC
25570 cCE("fcvtds", eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt),
25571 cCE("fcvtsd", eb70bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
25572 cCE("fmdhr", e200b10, 2, (RVD, RR), vfp_dp_rn_rd),
25573 cCE("fmdlr", e000b10, 2, (RVD, RR), vfp_dp_rn_rd),
25574 cCE("fmrdh", e300b10, 2, (RR, RVD), vfp_dp_rd_rn),
25575 cCE("fmrdl", e100b10, 2, (RR, RVD), vfp_dp_rd_rn),
25576 cCE("fsitod", eb80bc0, 2, (RVD, RVS), vfp_dp_sp_cvt),
25577 cCE("fuitod", eb80b40, 2, (RVD, RVS), vfp_dp_sp_cvt),
25578 cCE("ftosid", ebd0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
25579 cCE("ftosizd", ebd0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
25580 cCE("ftouid", ebc0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
25581 cCE("ftouizd", ebc0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
c19d1205 25582
c19d1205 25583 /* Monadic operations. */
21d799b5
NC
25584 cCE("fabsd", eb00bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
25585 cCE("fnegd", eb10b40, 2, (RVD, RVD), vfp_dp_rd_rm),
25586 cCE("fsqrtd", eb10bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
c19d1205
ZW
25587
25588 /* Dyadic operations. */
21d799b5
NC
25589 cCE("faddd", e300b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25590 cCE("fsubd", e300b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25591 cCE("fmuld", e200b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25592 cCE("fdivd", e800b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25593 cCE("fmacd", e000b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25594 cCE("fmscd", e100b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25595 cCE("fnmuld", e200b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25596 cCE("fnmacd", e000b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25597 cCE("fnmscd", e100b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
b99bd4ef 25598
c19d1205 25599 /* Comparisons. */
21d799b5
NC
25600 cCE("fcmpd", eb40b40, 2, (RVD, RVD), vfp_dp_rd_rm),
25601 cCE("fcmpzd", eb50b40, 1, (RVD), vfp_dp_rd),
25602 cCE("fcmped", eb40bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
25603 cCE("fcmpezd", eb50bc0, 1, (RVD), vfp_dp_rd),
c19d1205 25604
037e8744
JB
25605/* Instructions which may belong to either the Neon or VFP instruction sets.
25606 Individual encoder functions perform additional architecture checks. */
c921be7d
NC
25607#undef ARM_VARIANT
25608#define ARM_VARIANT & fpu_vfp_ext_v1xd
ef8f595f
MI
25609#undef THUMB_VARIANT
25610#define THUMB_VARIANT & arm_ext_v6t2
25611
25612 NCE(vldm, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25613 NCE(vldmia, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25614 NCE(vldmdb, d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25615 NCE(vstm, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25616 NCE(vstmia, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25617 NCE(vstmdb, d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
25618
25619 NCE(vpop, 0, 1, (VRSDLST), vfp_nsyn_pop),
25620 NCE(vpush, 0, 1, (VRSDLST), vfp_nsyn_push),
25621
c921be7d
NC
25622#undef THUMB_VARIANT
25623#define THUMB_VARIANT & fpu_vfp_ext_v1xd
25624
037e8744
JB
25625 /* These mnemonics are unique to VFP. */
25626 NCE(vsqrt, 0, 2, (RVSD, RVSD), vfp_nsyn_sqrt),
25627 NCE(vdiv, 0, 3, (RVSD, RVSD, RVSD), vfp_nsyn_div),
21d799b5
NC
25628 nCE(vnmul, _vnmul, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
25629 nCE(vnmla, _vnmla, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
25630 nCE(vnmls, _vnmls, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
037e8744
JB
25631 NCE(vcvtz, 0, 2, (RVSD, RVSD), vfp_nsyn_cvtz),
25632
25633 /* Mnemonics shared by Neon and VFP. */
21d799b5 25634 nCEF(vmls, _vmls, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
037e8744 25635
dd9634d9 25636 mnCEF(vcvt, _vcvt, 3, (RNSDQMQ, RNSDQMQ, oI32z), neon_cvt),
e3e535bc 25637 nCEF(vcvtr, _vcvt, 2, (RNSDQ, RNSDQ), neon_cvtr),
dd9634d9
AV
25638 MNCEF(vcvtb, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtb),
25639 MNCEF(vcvtt, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtt),
f31fef98 25640
037e8744
JB
25641
25642 /* NOTE: All VMOV encoding is special-cased! */
037e8744
JB
25643 NCE(vmovq, 0, 1, (VMOV), neon_mov),
25644
32c36c3c
AV
25645#undef THUMB_VARIANT
25646/* Could be either VLDR/VSTR or VLDR/VSTR (system register) which are guarded
25647 by different feature bits. Since we are setting the Thumb guard, we can
25648 require Thumb-1 which makes it a nop guard and set the right feature bit in
25649 do_vldr_vstr (). */
25650#define THUMB_VARIANT & arm_ext_v4t
25651 NCE(vldr, d100b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
25652 NCE(vstr, d000b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
25653
9db2f6b4
RL
25654#undef ARM_VARIANT
25655#define ARM_VARIANT & arm_ext_fp16
25656#undef THUMB_VARIANT
25657#define THUMB_VARIANT & arm_ext_fp16
25658 /* New instructions added from v8.2, allowing the extraction and insertion of
25659 the upper 16 bits of a 32-bit vector register. */
25660 NCE (vmovx, eb00a40, 2, (RVS, RVS), neon_movhf),
25661 NCE (vins, eb00ac0, 2, (RVS, RVS), neon_movhf),
25662
dec41383 25663 /* New backported fma/fms instructions optional in v8.2. */
aab2c27d
MM
25664 NUF (vfmsl, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmsl),
25665 NUF (vfmal, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmal),
dec41383 25666
c921be7d
NC
25667#undef THUMB_VARIANT
25668#define THUMB_VARIANT & fpu_neon_ext_v1
25669#undef ARM_VARIANT
25670#define ARM_VARIANT & fpu_neon_ext_v1
25671
5287ad62
JB
25672 /* Data processing with three registers of the same length. */
25673 /* integer ops, valid types S8 S16 S32 U8 U16 U32. */
25674 NUF(vaba, 0000710, 3, (RNDQ, RNDQ, RNDQ), neon_dyadic_i_su),
25675 NUF(vabaq, 0000710, 3, (RNQ, RNQ, RNQ), neon_dyadic_i_su),
5287ad62 25676 NUF(vhaddq, 0000000, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62 25677 NUF(vrhaddq, 0000100, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62
JB
25678 NUF(vhsubq, 0000200, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
25679 /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62 25680 NUF(vqaddq, 0000010, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
5287ad62 25681 NUF(vqsubq, 0000210, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
627907b7 25682 NUF(vrshlq, 0000500, 3, (RNQ, oRNQ, RNQ), neon_rshl),
627907b7 25683 NUF(vqrshlq, 0000510, 3, (RNQ, oRNQ, RNQ), neon_rshl),
5287ad62 25684 /* If not immediate, fall back to neon_dyadic_i64_su.
5150f0d8
AV
25685 shl should accept I8 I16 I32 I64,
25686 qshl should accept S8 S16 S32 S64 U8 U16 U32 U64. */
25687 nUF(vshlq, _vshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_shl),
25688 nUF(vqshlq, _vqshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_qshl),
5287ad62 25689 /* Logic ops, types optional & ignored. */
4316f0d2 25690 nUF(vandq, _vand, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25691 nUF(vbicq, _vbic, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25692 nUF(vorrq, _vorr, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25693 nUF(vornq, _vorn, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 25694 nUF(veorq, _veor, 3, (RNQ, oRNQ, RNQ), neon_logic),
5287ad62
JB
25695 /* Bitfield ops, untyped. */
25696 NUF(vbsl, 1100110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25697 NUF(vbslq, 1100110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
25698 NUF(vbit, 1200110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25699 NUF(vbitq, 1200110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
25700 NUF(vbif, 1300110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
25701 NUF(vbifq, 1300110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
cc933301 25702 /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32. */
21d799b5 25703 nUF(vabdq, _vabd, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 25704 nUF(vmaxq, _vmax, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 25705 nUF(vminq, _vmin, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
5287ad62
JB
25706 /* Comparisons. Types S8 S16 S32 U8 U16 U32 F32. Non-immediate versions fall
25707 back to neon_dyadic_if_su. */
21d799b5
NC
25708 nUF(vcge, _vcge, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
25709 nUF(vcgeq, _vcge, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
25710 nUF(vcgt, _vcgt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
25711 nUF(vcgtq, _vcgt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
25712 nUF(vclt, _vclt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
25713 nUF(vcltq, _vclt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
25714 nUF(vcle, _vcle, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
25715 nUF(vcleq, _vcle, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
428e3f1f 25716 /* Comparison. Type I8 I16 I32 F32. */
21d799b5
NC
25717 nUF(vceq, _vceq, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_ceq),
25718 nUF(vceqq, _vceq, 3, (RNQ, oRNQ, RNDQ_I0), neon_ceq),
5287ad62 25719 /* As above, D registers only. */
21d799b5
NC
25720 nUF(vpmax, _vpmax, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
25721 nUF(vpmin, _vpmin, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
5287ad62 25722 /* Int and float variants, signedness unimportant. */
21d799b5
NC
25723 nUF(vmlaq, _vmla, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
25724 nUF(vmlsq, _vmls, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
25725 nUF(vpadd, _vpadd, 3, (RND, oRND, RND), neon_dyadic_if_i_d),
5287ad62 25726 /* Add/sub take types I8 I16 I32 I64 F32. */
21d799b5
NC
25727 nUF(vaddq, _vadd, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
25728 nUF(vsubq, _vsub, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
5287ad62
JB
25729 /* vtst takes sizes 8, 16, 32. */
25730 NUF(vtst, 0000810, 3, (RNDQ, oRNDQ, RNDQ), neon_tst),
25731 NUF(vtstq, 0000810, 3, (RNQ, oRNQ, RNQ), neon_tst),
25732 /* VMUL takes I8 I16 I32 F32 P8. */
21d799b5 25733 nUF(vmulq, _vmul, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mul),
5287ad62 25734 /* VQD{R}MULH takes S16 S32. */
21d799b5 25735 nUF(vqdmulhq, _vqdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
21d799b5 25736 nUF(vqrdmulhq, _vqrdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
5287ad62
JB
25737 NUF(vacge, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
25738 NUF(vacgeq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
25739 NUF(vacgt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
25740 NUF(vacgtq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
92559b5b
PB
25741 NUF(vaclt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
25742 NUF(vacltq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
25743 NUF(vacle, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
25744 NUF(vacleq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
5287ad62
JB
25745 NUF(vrecps, 0000f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
25746 NUF(vrecpsq, 0000f10, 3, (RNQ, oRNQ, RNQ), neon_step),
25747 NUF(vrsqrts, 0200f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
25748 NUF(vrsqrtsq, 0200f10, 3, (RNQ, oRNQ, RNQ), neon_step),
d6b4b13e 25749 /* ARM v8.1 extension. */
643afb90
MW
25750 nUF (vqrdmlahq, _vqrdmlah, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
25751 nUF (vqrdmlsh, _vqrdmlsh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
25752 nUF (vqrdmlshq, _vqrdmlsh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
5287ad62
JB
25753
25754 /* Two address, int/float. Types S8 S16 S32 F32. */
5287ad62 25755 NUF(vabsq, 1b10300, 2, (RNQ, RNQ), neon_abs_neg),
5287ad62
JB
25756 NUF(vnegq, 1b10380, 2, (RNQ, RNQ), neon_abs_neg),
25757
25758 /* Data processing with two registers and a shift amount. */
25759 /* Right shifts, and variants with rounding.
25760 Types accepted S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62 25761 NUF(vshrq, 0800010, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
5287ad62
JB
25762 NUF(vrshrq, 0800210, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
25763 NUF(vsra, 0800110, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
25764 NUF(vsraq, 0800110, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
25765 NUF(vrsra, 0800310, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
25766 NUF(vrsraq, 0800310, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
25767 /* Shift and insert. Sizes accepted 8 16 32 64. */
5287ad62 25768 NUF(vsliq, 1800510, 3, (RNQ, oRNQ, I63), neon_sli),
5287ad62
JB
25769 NUF(vsriq, 1800410, 3, (RNQ, oRNQ, I64), neon_sri),
25770 /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64. */
5287ad62
JB
25771 NUF(vqshluq, 1800610, 3, (RNQ, oRNQ, I63), neon_qshlu_imm),
25772 /* Right shift immediate, saturating & narrowing, with rounding variants.
25773 Types accepted S16 S32 S64 U16 U32 U64. */
25774 NUF(vqshrn, 0800910, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
25775 NUF(vqrshrn, 0800950, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
25776 /* As above, unsigned. Types accepted S16 S32 S64. */
25777 NUF(vqshrun, 0800810, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
25778 NUF(vqrshrun, 0800850, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
25779 /* Right shift narrowing. Types accepted I16 I32 I64. */
25780 NUF(vshrn, 0800810, 3, (RND, RNQ, I32z), neon_rshift_narrow),
25781 NUF(vrshrn, 0800850, 3, (RND, RNQ, I32z), neon_rshift_narrow),
25782 /* Special case. Types S8 S16 S32 U8 U16 U32. Handles max shift variant. */
21d799b5 25783 nUF(vshll, _vshll, 3, (RNQ, RND, I32), neon_shll),
5287ad62 25784 /* CVT with optional immediate for fixed-point variant. */
21d799b5 25785 nUF(vcvtq, _vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
b7fc2769 25786
4316f0d2 25787 nUF(vmvnq, _vmvn, 2, (RNQ, RNDQ_Ibig), neon_mvn),
5287ad62
JB
25788
25789 /* Data processing, three registers of different lengths. */
25790 /* Dyadic, long insns. Types S8 S16 S32 U8 U16 U32. */
25791 NUF(vabal, 0800500, 3, (RNQ, RND, RND), neon_abal),
5287ad62
JB
25792 /* If not scalar, fall back to neon_dyadic_long.
25793 Vector types as above, scalar types S16 S32 U16 U32. */
21d799b5
NC
25794 nUF(vmlal, _vmlal, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
25795 nUF(vmlsl, _vmlsl, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
5287ad62
JB
25796 /* Dyadic, widening insns. Types S8 S16 S32 U8 U16 U32. */
25797 NUF(vaddw, 0800100, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
25798 NUF(vsubw, 0800300, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
25799 /* Dyadic, narrowing insns. Types I16 I32 I64. */
25800 NUF(vaddhn, 0800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25801 NUF(vraddhn, 1800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25802 NUF(vsubhn, 0800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25803 NUF(vrsubhn, 1800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
25804 /* Saturating doubling multiplies. Types S16 S32. */
21d799b5
NC
25805 nUF(vqdmlal, _vqdmlal, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
25806 nUF(vqdmlsl, _vqdmlsl, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
25807 nUF(vqdmull, _vqdmull, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
5287ad62
JB
25808 /* VMULL. Vector types S8 S16 S32 U8 U16 U32 P8, scalar types
25809 S16 S32 U16 U32. */
21d799b5 25810 nUF(vmull, _vmull, 3, (RNQ, RND, RND_RNSC), neon_vmull),
5287ad62
JB
25811
25812 /* Extract. Size 8. */
3b8d421e
PB
25813 NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I15), neon_ext),
25814 NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I15), neon_ext),
5287ad62
JB
25815
25816 /* Two registers, miscellaneous. */
25817 /* Reverse. Sizes 8 16 32 (must be < size in opcode). */
5287ad62 25818 NUF(vrev64q, 1b00000, 2, (RNQ, RNQ), neon_rev),
5287ad62 25819 NUF(vrev32q, 1b00080, 2, (RNQ, RNQ), neon_rev),
5287ad62
JB
25820 NUF(vrev16q, 1b00100, 2, (RNQ, RNQ), neon_rev),
25821 /* Vector replicate. Sizes 8 16 32. */
21d799b5 25822 nCE(vdupq, _vdup, 2, (RNQ, RR_RNSC), neon_dup),
5287ad62
JB
25823 /* VMOVL. Types S8 S16 S32 U8 U16 U32. */
25824 NUF(vmovl, 0800a10, 2, (RNQ, RND), neon_movl),
25825 /* VMOVN. Types I16 I32 I64. */
21d799b5 25826 nUF(vmovn, _vmovn, 2, (RND, RNQ), neon_movn),
5287ad62 25827 /* VQMOVN. Types S16 S32 S64 U16 U32 U64. */
21d799b5 25828 nUF(vqmovn, _vqmovn, 2, (RND, RNQ), neon_qmovn),
5287ad62 25829 /* VQMOVUN. Types S16 S32 S64. */
21d799b5 25830 nUF(vqmovun, _vqmovun, 2, (RND, RNQ), neon_qmovun),
5287ad62
JB
25831 /* VZIP / VUZP. Sizes 8 16 32. */
25832 NUF(vzip, 1b20180, 2, (RNDQ, RNDQ), neon_zip_uzp),
25833 NUF(vzipq, 1b20180, 2, (RNQ, RNQ), neon_zip_uzp),
25834 NUF(vuzp, 1b20100, 2, (RNDQ, RNDQ), neon_zip_uzp),
25835 NUF(vuzpq, 1b20100, 2, (RNQ, RNQ), neon_zip_uzp),
25836 /* VQABS / VQNEG. Types S8 S16 S32. */
5287ad62 25837 NUF(vqabsq, 1b00700, 2, (RNQ, RNQ), neon_sat_abs_neg),
5287ad62
JB
25838 NUF(vqnegq, 1b00780, 2, (RNQ, RNQ), neon_sat_abs_neg),
25839 /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32. */
25840 NUF(vpadal, 1b00600, 2, (RNDQ, RNDQ), neon_pair_long),
25841 NUF(vpadalq, 1b00600, 2, (RNQ, RNQ), neon_pair_long),
25842 NUF(vpaddl, 1b00200, 2, (RNDQ, RNDQ), neon_pair_long),
25843 NUF(vpaddlq, 1b00200, 2, (RNQ, RNQ), neon_pair_long),
cc933301 25844 /* Reciprocal estimates. Types U32 F16 F32. */
5287ad62
JB
25845 NUF(vrecpe, 1b30400, 2, (RNDQ, RNDQ), neon_recip_est),
25846 NUF(vrecpeq, 1b30400, 2, (RNQ, RNQ), neon_recip_est),
25847 NUF(vrsqrte, 1b30480, 2, (RNDQ, RNDQ), neon_recip_est),
25848 NUF(vrsqrteq, 1b30480, 2, (RNQ, RNQ), neon_recip_est),
25849 /* VCLS. Types S8 S16 S32. */
5287ad62
JB
25850 NUF(vclsq, 1b00400, 2, (RNQ, RNQ), neon_cls),
25851 /* VCLZ. Types I8 I16 I32. */
5287ad62
JB
25852 NUF(vclzq, 1b00480, 2, (RNQ, RNQ), neon_clz),
25853 /* VCNT. Size 8. */
25854 NUF(vcnt, 1b00500, 2, (RNDQ, RNDQ), neon_cnt),
25855 NUF(vcntq, 1b00500, 2, (RNQ, RNQ), neon_cnt),
25856 /* Two address, untyped. */
25857 NUF(vswp, 1b20000, 2, (RNDQ, RNDQ), neon_swp),
25858 NUF(vswpq, 1b20000, 2, (RNQ, RNQ), neon_swp),
25859 /* VTRN. Sizes 8 16 32. */
21d799b5
NC
25860 nUF(vtrn, _vtrn, 2, (RNDQ, RNDQ), neon_trn),
25861 nUF(vtrnq, _vtrn, 2, (RNQ, RNQ), neon_trn),
5287ad62
JB
25862
25863 /* Table lookup. Size 8. */
25864 NUF(vtbl, 1b00800, 3, (RND, NRDLST, RND), neon_tbl_tbx),
25865 NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
25866
c921be7d
NC
25867#undef THUMB_VARIANT
25868#define THUMB_VARIANT & fpu_vfp_v3_or_neon_ext
25869#undef ARM_VARIANT
25870#define ARM_VARIANT & fpu_vfp_v3_or_neon_ext
25871
5287ad62 25872 /* Neon element/structure load/store. */
21d799b5
NC
25873 nUF(vld1, _vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
25874 nUF(vst1, _vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
25875 nUF(vld2, _vld2, 2, (NSTRLST, ADDR), neon_ldx_stx),
25876 nUF(vst2, _vst2, 2, (NSTRLST, ADDR), neon_ldx_stx),
25877 nUF(vld3, _vld3, 2, (NSTRLST, ADDR), neon_ldx_stx),
25878 nUF(vst3, _vst3, 2, (NSTRLST, ADDR), neon_ldx_stx),
25879 nUF(vld4, _vld4, 2, (NSTRLST, ADDR), neon_ldx_stx),
25880 nUF(vst4, _vst4, 2, (NSTRLST, ADDR), neon_ldx_stx),
5287ad62 25881
c921be7d 25882#undef THUMB_VARIANT
74db7efb
NC
25883#define THUMB_VARIANT & fpu_vfp_ext_v3xd
25884#undef ARM_VARIANT
25885#define ARM_VARIANT & fpu_vfp_ext_v3xd
62f3b8c8
PB
25886 cCE("fconsts", eb00a00, 2, (RVS, I255), vfp_sp_const),
25887 cCE("fshtos", eba0a40, 2, (RVS, I16z), vfp_sp_conv_16),
25888 cCE("fsltos", eba0ac0, 2, (RVS, I32), vfp_sp_conv_32),
25889 cCE("fuhtos", ebb0a40, 2, (RVS, I16z), vfp_sp_conv_16),
25890 cCE("fultos", ebb0ac0, 2, (RVS, I32), vfp_sp_conv_32),
25891 cCE("ftoshs", ebe0a40, 2, (RVS, I16z), vfp_sp_conv_16),
25892 cCE("ftosls", ebe0ac0, 2, (RVS, I32), vfp_sp_conv_32),
25893 cCE("ftouhs", ebf0a40, 2, (RVS, I16z), vfp_sp_conv_16),
25894 cCE("ftouls", ebf0ac0, 2, (RVS, I32), vfp_sp_conv_32),
25895
74db7efb 25896#undef THUMB_VARIANT
c921be7d
NC
25897#define THUMB_VARIANT & fpu_vfp_ext_v3
25898#undef ARM_VARIANT
25899#define ARM_VARIANT & fpu_vfp_ext_v3
25900
21d799b5 25901 cCE("fconstd", eb00b00, 2, (RVD, I255), vfp_dp_const),
21d799b5 25902 cCE("fshtod", eba0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 25903 cCE("fsltod", eba0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 25904 cCE("fuhtod", ebb0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 25905 cCE("fultod", ebb0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 25906 cCE("ftoshd", ebe0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 25907 cCE("ftosld", ebe0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 25908 cCE("ftouhd", ebf0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 25909 cCE("ftould", ebf0bc0, 2, (RVD, I32), vfp_dp_conv_32),
c19d1205 25910
74db7efb
NC
25911#undef ARM_VARIANT
25912#define ARM_VARIANT & fpu_vfp_ext_fma
25913#undef THUMB_VARIANT
25914#define THUMB_VARIANT & fpu_vfp_ext_fma
aab2c27d 25915 /* Mnemonics shared by Neon, VFP, MVE and BF16. These are included in the
62f3b8c8
PB
25916 VFP FMA variant; NEON and VFP FMA always includes the NEON
25917 FMA instructions. */
d58196e0 25918 mnCEF(vfma, _vfma, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_fmac),
aab2c27d 25919 TUF ("vfmat", c300850, fc300850, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), mve_vfma, mve_vfma),
d58196e0
AV
25920 mnCEF(vfms, _vfms, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), neon_fmac),
25921
62f3b8c8
PB
25922 /* ffmas/ffmad/ffmss/ffmsd are dummy mnemonics to satisfy gas;
25923 the v form should always be used. */
25924 cCE("ffmas", ea00a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25925 cCE("ffnmas", ea00a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
25926 cCE("ffmad", ea00b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25927 cCE("ffnmad", ea00b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
25928 nCE(vfnma, _vfnma, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
25929 nCE(vfnms, _vfnms, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
25930
5287ad62 25931#undef THUMB_VARIANT
c921be7d
NC
25932#undef ARM_VARIANT
25933#define ARM_VARIANT & arm_cext_xscale /* Intel XScale extensions. */
25934
21d799b5
NC
25935 cCE("mia", e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
25936 cCE("miaph", e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
25937 cCE("miabb", e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
25938 cCE("miabt", e2d0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
25939 cCE("miatb", e2e0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
25940 cCE("miatt", e2f0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
25941 cCE("mar", c400000, 3, (RXA, RRnpc, RRnpc), xsc_mar),
25942 cCE("mra", c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra),
c19d1205 25943
c921be7d
NC
25944#undef ARM_VARIANT
25945#define ARM_VARIANT & arm_cext_iwmmxt /* Intel Wireless MMX technology. */
25946
21d799b5
NC
25947 cCE("tandcb", e13f130, 1, (RR), iwmmxt_tandorc),
25948 cCE("tandch", e53f130, 1, (RR), iwmmxt_tandorc),
25949 cCE("tandcw", e93f130, 1, (RR), iwmmxt_tandorc),
25950 cCE("tbcstb", e400010, 2, (RIWR, RR), rn_rd),
25951 cCE("tbcsth", e400050, 2, (RIWR, RR), rn_rd),
25952 cCE("tbcstw", e400090, 2, (RIWR, RR), rn_rd),
25953 cCE("textrcb", e130170, 2, (RR, I7), iwmmxt_textrc),
25954 cCE("textrch", e530170, 2, (RR, I7), iwmmxt_textrc),
25955 cCE("textrcw", e930170, 2, (RR, I7), iwmmxt_textrc),
74db7efb
NC
25956 cCE("textrmub",e100070, 3, (RR, RIWR, I7), iwmmxt_textrm),
25957 cCE("textrmuh",e500070, 3, (RR, RIWR, I7), iwmmxt_textrm),
25958 cCE("textrmuw",e900070, 3, (RR, RIWR, I7), iwmmxt_textrm),
25959 cCE("textrmsb",e100078, 3, (RR, RIWR, I7), iwmmxt_textrm),
25960 cCE("textrmsh",e500078, 3, (RR, RIWR, I7), iwmmxt_textrm),
25961 cCE("textrmsw",e900078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21d799b5
NC
25962 cCE("tinsrb", e600010, 3, (RIWR, RR, I7), iwmmxt_tinsr),
25963 cCE("tinsrh", e600050, 3, (RIWR, RR, I7), iwmmxt_tinsr),
25964 cCE("tinsrw", e600090, 3, (RIWR, RR, I7), iwmmxt_tinsr),
25965 cCE("tmcr", e000110, 2, (RIWC_RIWG, RR), rn_rd),
25966 cCE("tmcrr", c400000, 3, (RIWR, RR, RR), rm_rd_rn),
25967 cCE("tmia", e200010, 3, (RIWR, RR, RR), iwmmxt_tmia),
25968 cCE("tmiaph", e280010, 3, (RIWR, RR, RR), iwmmxt_tmia),
25969 cCE("tmiabb", e2c0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
25970 cCE("tmiabt", e2d0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
25971 cCE("tmiatb", e2e0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
25972 cCE("tmiatt", e2f0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
74db7efb
NC
25973 cCE("tmovmskb",e100030, 2, (RR, RIWR), rd_rn),
25974 cCE("tmovmskh",e500030, 2, (RR, RIWR), rd_rn),
25975 cCE("tmovmskw",e900030, 2, (RR, RIWR), rd_rn),
21d799b5
NC
25976 cCE("tmrc", e100110, 2, (RR, RIWC_RIWG), rd_rn),
25977 cCE("tmrrc", c500000, 3, (RR, RR, RIWR), rd_rn_rm),
25978 cCE("torcb", e13f150, 1, (RR), iwmmxt_tandorc),
25979 cCE("torch", e53f150, 1, (RR), iwmmxt_tandorc),
25980 cCE("torcw", e93f150, 1, (RR), iwmmxt_tandorc),
25981 cCE("waccb", e0001c0, 2, (RIWR, RIWR), rd_rn),
25982 cCE("wacch", e4001c0, 2, (RIWR, RIWR), rd_rn),
25983 cCE("waccw", e8001c0, 2, (RIWR, RIWR), rd_rn),
25984 cCE("waddbss", e300180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25985 cCE("waddb", e000180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25986 cCE("waddbus", e100180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25987 cCE("waddhss", e700180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25988 cCE("waddh", e400180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25989 cCE("waddhus", e500180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25990 cCE("waddwss", eb00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25991 cCE("waddw", e800180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25992 cCE("waddwus", e900180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25993 cCE("waligni", e000020, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_waligni),
74db7efb
NC
25994 cCE("walignr0",e800020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25995 cCE("walignr1",e900020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25996 cCE("walignr2",ea00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25997 cCE("walignr3",eb00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
25998 cCE("wand", e200000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
25999 cCE("wandn", e300000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26000 cCE("wavg2b", e800000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26001 cCE("wavg2br", e900000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26002 cCE("wavg2h", ec00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26003 cCE("wavg2hr", ed00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26004 cCE("wcmpeqb", e000060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26005 cCE("wcmpeqh", e400060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26006 cCE("wcmpeqw", e800060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
26007 cCE("wcmpgtub",e100060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26008 cCE("wcmpgtuh",e500060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26009 cCE("wcmpgtuw",e900060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26010 cCE("wcmpgtsb",e300060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26011 cCE("wcmpgtsh",e700060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26012 cCE("wcmpgtsw",eb00060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
26013 cCE("wldrb", c100000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26014 cCE("wldrh", c500000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26015 cCE("wldrw", c100100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
26016 cCE("wldrd", c500100, 2, (RIWR, ADDR), iwmmxt_wldstd),
26017 cCE("wmacs", e600100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26018 cCE("wmacsz", e700100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26019 cCE("wmacu", e400100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26020 cCE("wmacuz", e500100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26021 cCE("wmadds", ea00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26022 cCE("wmaddu", e800100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26023 cCE("wmaxsb", e200160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26024 cCE("wmaxsh", e600160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26025 cCE("wmaxsw", ea00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26026 cCE("wmaxub", e000160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26027 cCE("wmaxuh", e400160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26028 cCE("wmaxuw", e800160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26029 cCE("wminsb", e300160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26030 cCE("wminsh", e700160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26031 cCE("wminsw", eb00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26032 cCE("wminub", e100160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26033 cCE("wminuh", e500160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26034 cCE("wminuw", e900160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26035 cCE("wmov", e000000, 2, (RIWR, RIWR), iwmmxt_wmov),
26036 cCE("wmulsm", e300100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26037 cCE("wmulsl", e200100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26038 cCE("wmulum", e100100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26039 cCE("wmulul", e000100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26040 cCE("wor", e000000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
26041 cCE("wpackhss",e700080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26042 cCE("wpackhus",e500080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26043 cCE("wpackwss",eb00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26044 cCE("wpackwus",e900080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26045 cCE("wpackdss",ef00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26046 cCE("wpackdus",ed00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
26047 cCE("wrorh", e700040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26048 cCE("wrorhg", e700148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26049 cCE("wrorw", eb00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26050 cCE("wrorwg", eb00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26051 cCE("wrord", ef00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26052 cCE("wrordg", ef00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26053 cCE("wsadb", e000120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26054 cCE("wsadbz", e100120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26055 cCE("wsadh", e400120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26056 cCE("wsadhz", e500120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26057 cCE("wshufh", e0001e0, 3, (RIWR, RIWR, I255), iwmmxt_wshufh),
26058 cCE("wsllh", e500040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26059 cCE("wsllhg", e500148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26060 cCE("wsllw", e900040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26061 cCE("wsllwg", e900148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26062 cCE("wslld", ed00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26063 cCE("wslldg", ed00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26064 cCE("wsrah", e400040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26065 cCE("wsrahg", e400148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26066 cCE("wsraw", e800040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26067 cCE("wsrawg", e800148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26068 cCE("wsrad", ec00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26069 cCE("wsradg", ec00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26070 cCE("wsrlh", e600040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26071 cCE("wsrlhg", e600148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26072 cCE("wsrlw", ea00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26073 cCE("wsrlwg", ea00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26074 cCE("wsrld", ee00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
26075 cCE("wsrldg", ee00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
26076 cCE("wstrb", c000000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26077 cCE("wstrh", c400000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
26078 cCE("wstrw", c000100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
26079 cCE("wstrd", c400100, 2, (RIWR, ADDR), iwmmxt_wldstd),
26080 cCE("wsubbss", e3001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26081 cCE("wsubb", e0001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26082 cCE("wsubbus", e1001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26083 cCE("wsubhss", e7001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26084 cCE("wsubh", e4001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26085 cCE("wsubhus", e5001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26086 cCE("wsubwss", eb001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26087 cCE("wsubw", e8001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26088 cCE("wsubwus", e9001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26089 cCE("wunpckehub",e0000c0, 2, (RIWR, RIWR), rd_rn),
26090 cCE("wunpckehuh",e4000c0, 2, (RIWR, RIWR), rd_rn),
26091 cCE("wunpckehuw",e8000c0, 2, (RIWR, RIWR), rd_rn),
26092 cCE("wunpckehsb",e2000c0, 2, (RIWR, RIWR), rd_rn),
26093 cCE("wunpckehsh",e6000c0, 2, (RIWR, RIWR), rd_rn),
26094 cCE("wunpckehsw",ea000c0, 2, (RIWR, RIWR), rd_rn),
26095 cCE("wunpckihb", e1000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26096 cCE("wunpckihh", e5000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26097 cCE("wunpckihw", e9000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26098 cCE("wunpckelub",e0000e0, 2, (RIWR, RIWR), rd_rn),
26099 cCE("wunpckeluh",e4000e0, 2, (RIWR, RIWR), rd_rn),
26100 cCE("wunpckeluw",e8000e0, 2, (RIWR, RIWR), rd_rn),
26101 cCE("wunpckelsb",e2000e0, 2, (RIWR, RIWR), rd_rn),
26102 cCE("wunpckelsh",e6000e0, 2, (RIWR, RIWR), rd_rn),
26103 cCE("wunpckelsw",ea000e0, 2, (RIWR, RIWR), rd_rn),
26104 cCE("wunpckilb", e1000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26105 cCE("wunpckilh", e5000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26106 cCE("wunpckilw", e9000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26107 cCE("wxor", e100000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26108 cCE("wzero", e300000, 1, (RIWR), iwmmxt_wzero),
c19d1205 26109
c921be7d
NC
26110#undef ARM_VARIANT
26111#define ARM_VARIANT & arm_cext_iwmmxt2 /* Intel Wireless MMX technology, version 2. */
26112
21d799b5
NC
26113 cCE("torvscb", e12f190, 1, (RR), iwmmxt_tandorc),
26114 cCE("torvsch", e52f190, 1, (RR), iwmmxt_tandorc),
26115 cCE("torvscw", e92f190, 1, (RR), iwmmxt_tandorc),
26116 cCE("wabsb", e2001c0, 2, (RIWR, RIWR), rd_rn),
26117 cCE("wabsh", e6001c0, 2, (RIWR, RIWR), rd_rn),
26118 cCE("wabsw", ea001c0, 2, (RIWR, RIWR), rd_rn),
26119 cCE("wabsdiffb", e1001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26120 cCE("wabsdiffh", e5001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26121 cCE("wabsdiffw", e9001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26122 cCE("waddbhusl", e2001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26123 cCE("waddbhusm", e6001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26124 cCE("waddhc", e600180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26125 cCE("waddwc", ea00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26126 cCE("waddsubhx", ea001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26127 cCE("wavg4", e400000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26128 cCE("wavg4r", e500000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26129 cCE("wmaddsn", ee00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26130 cCE("wmaddsx", eb00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26131 cCE("wmaddun", ec00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26132 cCE("wmaddux", e900100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26133 cCE("wmerge", e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
26134 cCE("wmiabb", e0000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26135 cCE("wmiabt", e1000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26136 cCE("wmiatb", e2000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26137 cCE("wmiatt", e3000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26138 cCE("wmiabbn", e4000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26139 cCE("wmiabtn", e5000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26140 cCE("wmiatbn", e6000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26141 cCE("wmiattn", e7000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26142 cCE("wmiawbb", e800120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26143 cCE("wmiawbt", e900120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26144 cCE("wmiawtb", ea00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26145 cCE("wmiawtt", eb00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26146 cCE("wmiawbbn", ec00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26147 cCE("wmiawbtn", ed00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26148 cCE("wmiawtbn", ee00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26149 cCE("wmiawttn", ef00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26150 cCE("wmulsmr", ef00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26151 cCE("wmulumr", ed00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26152 cCE("wmulwumr", ec000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26153 cCE("wmulwsmr", ee000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26154 cCE("wmulwum", ed000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26155 cCE("wmulwsm", ef000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26156 cCE("wmulwl", eb000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26157 cCE("wqmiabb", e8000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26158 cCE("wqmiabt", e9000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26159 cCE("wqmiatb", ea000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26160 cCE("wqmiatt", eb000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26161 cCE("wqmiabbn", ec000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26162 cCE("wqmiabtn", ed000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26163 cCE("wqmiatbn", ee000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26164 cCE("wqmiattn", ef000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26165 cCE("wqmulm", e100080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26166 cCE("wqmulmr", e300080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26167 cCE("wqmulwm", ec000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26168 cCE("wqmulwmr", ee000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
26169 cCE("wsubaddhx", ed001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
2d447fca 26170
c921be7d
NC
26171#undef ARM_VARIANT
26172#define ARM_VARIANT & arm_cext_maverick /* Cirrus Maverick instructions. */
26173
21d799b5
NC
26174 cCE("cfldrs", c100400, 2, (RMF, ADDRGLDC), rd_cpaddr),
26175 cCE("cfldrd", c500400, 2, (RMD, ADDRGLDC), rd_cpaddr),
26176 cCE("cfldr32", c100500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
26177 cCE("cfldr64", c500500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
26178 cCE("cfstrs", c000400, 2, (RMF, ADDRGLDC), rd_cpaddr),
26179 cCE("cfstrd", c400400, 2, (RMD, ADDRGLDC), rd_cpaddr),
26180 cCE("cfstr32", c000500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
26181 cCE("cfstr64", c400500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
26182 cCE("cfmvsr", e000450, 2, (RMF, RR), rn_rd),
26183 cCE("cfmvrs", e100450, 2, (RR, RMF), rd_rn),
26184 cCE("cfmvdlr", e000410, 2, (RMD, RR), rn_rd),
26185 cCE("cfmvrdl", e100410, 2, (RR, RMD), rd_rn),
26186 cCE("cfmvdhr", e000430, 2, (RMD, RR), rn_rd),
26187 cCE("cfmvrdh", e100430, 2, (RR, RMD), rd_rn),
74db7efb
NC
26188 cCE("cfmv64lr",e000510, 2, (RMDX, RR), rn_rd),
26189 cCE("cfmvr64l",e100510, 2, (RR, RMDX), rd_rn),
26190 cCE("cfmv64hr",e000530, 2, (RMDX, RR), rn_rd),
26191 cCE("cfmvr64h",e100530, 2, (RR, RMDX), rd_rn),
26192 cCE("cfmval32",e200440, 2, (RMAX, RMFX), rd_rn),
26193 cCE("cfmv32al",e100440, 2, (RMFX, RMAX), rd_rn),
26194 cCE("cfmvam32",e200460, 2, (RMAX, RMFX), rd_rn),
26195 cCE("cfmv32am",e100460, 2, (RMFX, RMAX), rd_rn),
26196 cCE("cfmvah32",e200480, 2, (RMAX, RMFX), rd_rn),
26197 cCE("cfmv32ah",e100480, 2, (RMFX, RMAX), rd_rn),
21d799b5
NC
26198 cCE("cfmva32", e2004a0, 2, (RMAX, RMFX), rd_rn),
26199 cCE("cfmv32a", e1004a0, 2, (RMFX, RMAX), rd_rn),
26200 cCE("cfmva64", e2004c0, 2, (RMAX, RMDX), rd_rn),
26201 cCE("cfmv64a", e1004c0, 2, (RMDX, RMAX), rd_rn),
74db7efb
NC
26202 cCE("cfmvsc32",e2004e0, 2, (RMDS, RMDX), mav_dspsc),
26203 cCE("cfmv32sc",e1004e0, 2, (RMDX, RMDS), rd),
21d799b5
NC
26204 cCE("cfcpys", e000400, 2, (RMF, RMF), rd_rn),
26205 cCE("cfcpyd", e000420, 2, (RMD, RMD), rd_rn),
26206 cCE("cfcvtsd", e000460, 2, (RMD, RMF), rd_rn),
26207 cCE("cfcvtds", e000440, 2, (RMF, RMD), rd_rn),
74db7efb
NC
26208 cCE("cfcvt32s",e000480, 2, (RMF, RMFX), rd_rn),
26209 cCE("cfcvt32d",e0004a0, 2, (RMD, RMFX), rd_rn),
26210 cCE("cfcvt64s",e0004c0, 2, (RMF, RMDX), rd_rn),
26211 cCE("cfcvt64d",e0004e0, 2, (RMD, RMDX), rd_rn),
26212 cCE("cfcvts32",e100580, 2, (RMFX, RMF), rd_rn),
26213 cCE("cfcvtd32",e1005a0, 2, (RMFX, RMD), rd_rn),
21d799b5
NC
26214 cCE("cftruncs32",e1005c0, 2, (RMFX, RMF), rd_rn),
26215 cCE("cftruncd32",e1005e0, 2, (RMFX, RMD), rd_rn),
74db7efb
NC
26216 cCE("cfrshl32",e000550, 3, (RMFX, RMFX, RR), mav_triple),
26217 cCE("cfrshl64",e000570, 3, (RMDX, RMDX, RR), mav_triple),
21d799b5
NC
26218 cCE("cfsh32", e000500, 3, (RMFX, RMFX, I63s), mav_shift),
26219 cCE("cfsh64", e200500, 3, (RMDX, RMDX, I63s), mav_shift),
26220 cCE("cfcmps", e100490, 3, (RR, RMF, RMF), rd_rn_rm),
26221 cCE("cfcmpd", e1004b0, 3, (RR, RMD, RMD), rd_rn_rm),
26222 cCE("cfcmp32", e100590, 3, (RR, RMFX, RMFX), rd_rn_rm),
26223 cCE("cfcmp64", e1005b0, 3, (RR, RMDX, RMDX), rd_rn_rm),
26224 cCE("cfabss", e300400, 2, (RMF, RMF), rd_rn),
26225 cCE("cfabsd", e300420, 2, (RMD, RMD), rd_rn),
26226 cCE("cfnegs", e300440, 2, (RMF, RMF), rd_rn),
26227 cCE("cfnegd", e300460, 2, (RMD, RMD), rd_rn),
26228 cCE("cfadds", e300480, 3, (RMF, RMF, RMF), rd_rn_rm),
26229 cCE("cfaddd", e3004a0, 3, (RMD, RMD, RMD), rd_rn_rm),
26230 cCE("cfsubs", e3004c0, 3, (RMF, RMF, RMF), rd_rn_rm),
26231 cCE("cfsubd", e3004e0, 3, (RMD, RMD, RMD), rd_rn_rm),
26232 cCE("cfmuls", e100400, 3, (RMF, RMF, RMF), rd_rn_rm),
26233 cCE("cfmuld", e100420, 3, (RMD, RMD, RMD), rd_rn_rm),
26234 cCE("cfabs32", e300500, 2, (RMFX, RMFX), rd_rn),
26235 cCE("cfabs64", e300520, 2, (RMDX, RMDX), rd_rn),
26236 cCE("cfneg32", e300540, 2, (RMFX, RMFX), rd_rn),
26237 cCE("cfneg64", e300560, 2, (RMDX, RMDX), rd_rn),
26238 cCE("cfadd32", e300580, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26239 cCE("cfadd64", e3005a0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26240 cCE("cfsub32", e3005c0, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26241 cCE("cfsub64", e3005e0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26242 cCE("cfmul32", e100500, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26243 cCE("cfmul64", e100520, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
26244 cCE("cfmac32", e100540, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
26245 cCE("cfmsc32", e100560, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
74db7efb
NC
26246 cCE("cfmadd32",e000600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
26247 cCE("cfmsub32",e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21d799b5
NC
26248 cCE("cfmadda32", e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
26249 cCE("cfmsuba32", e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
4ed7ed8d 26250
7fadb25d
SD
26251 /* ARMv8.5-A instructions. */
26252#undef ARM_VARIANT
26253#define ARM_VARIANT & arm_ext_sb
26254#undef THUMB_VARIANT
26255#define THUMB_VARIANT & arm_ext_sb
26256 TUF("sb", 57ff070, f3bf8f70, 0, (), noargs, noargs),
26257
dad0c3bf
SD
26258#undef ARM_VARIANT
26259#define ARM_VARIANT & arm_ext_predres
26260#undef THUMB_VARIANT
26261#define THUMB_VARIANT & arm_ext_predres
26262 CE("cfprctx", e070f93, 1, (RRnpc), rd),
26263 CE("dvprctx", e070fb3, 1, (RRnpc), rd),
26264 CE("cpprctx", e070ff3, 1, (RRnpc), rd),
26265
16a1fa25 26266 /* ARMv8-M instructions. */
4ed7ed8d
TP
26267#undef ARM_VARIANT
26268#define ARM_VARIANT NULL
26269#undef THUMB_VARIANT
26270#define THUMB_VARIANT & arm_ext_v8m
cf3cf39d
TP
26271 ToU("sg", e97fe97f, 0, (), noargs),
26272 ToC("blxns", 4784, 1, (RRnpc), t_blx),
26273 ToC("bxns", 4704, 1, (RRnpc), t_bx),
26274 ToC("tt", e840f000, 2, (RRnpc, RRnpc), tt),
26275 ToC("ttt", e840f040, 2, (RRnpc, RRnpc), tt),
26276 ToC("tta", e840f080, 2, (RRnpc, RRnpc), tt),
26277 ToC("ttat", e840f0c0, 2, (RRnpc, RRnpc), tt),
16a1fa25
TP
26278
26279 /* FP for ARMv8-M Mainline. Enabled for ARMv8-M Mainline because the
26280 instructions behave as nop if no VFP is present. */
26281#undef THUMB_VARIANT
26282#define THUMB_VARIANT & arm_ext_v8m_main
cf3cf39d
TP
26283 ToC("vlldm", ec300a00, 1, (RRnpc), rn),
26284 ToC("vlstm", ec200a00, 1, (RRnpc), rn),
4389b29a
AV
26285
26286 /* Armv8.1-M Mainline instructions. */
26287#undef THUMB_VARIANT
26288#define THUMB_VARIANT & arm_ext_v8_1m_main
e39c1607
SD
26289 toU("cinc", _cinc, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26290 toU("cinv", _cinv, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26291 toU("cneg", _cneg, 3, (RRnpcsp, RR_ZR, COND), t_cond),
26292 toU("csel", _csel, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26293 toU("csetm", _csetm, 2, (RRnpcsp, COND), t_cond),
26294 toU("cset", _cset, 2, (RRnpcsp, COND), t_cond),
26295 toU("csinc", _csinc, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26296 toU("csinv", _csinv, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26297 toU("csneg", _csneg, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
26298
4389b29a 26299 toC("bf", _bf, 2, (EXPs, EXPs), t_branch_future),
f6b2b12d 26300 toU("bfcsel", _bfcsel, 4, (EXPs, EXPs, EXPs, COND), t_branch_future),
f1c7f421 26301 toC("bfx", _bfx, 2, (EXPs, RRnpcsp), t_branch_future),
65d1bc05 26302 toC("bfl", _bfl, 2, (EXPs, EXPs), t_branch_future),
f1c7f421 26303 toC("bflx", _bflx, 2, (EXPs, RRnpcsp), t_branch_future),
60f993ce
AV
26304
26305 toU("dls", _dls, 2, (LR, RRnpcsp), t_loloop),
26306 toU("wls", _wls, 3, (LR, RRnpcsp, EXP), t_loloop),
26307 toU("le", _le, 2, (oLR, EXP), t_loloop),
4b5a202f 26308
efd6b359 26309 ToC("clrm", e89f0000, 1, (CLRMLST), t_clrm),
5ee91343
AV
26310 ToC("vscclrm", ec9f0a00, 1, (VRSDVLST), t_vscclrm),
26311
26312#undef THUMB_VARIANT
26313#define THUMB_VARIANT & mve_ext
23d00a41
SD
26314 ToC("lsll", ea50010d, 3, (RRe, RRo, RRnpcsp_I32), mve_scalar_shift),
26315 ToC("lsrl", ea50011f, 3, (RRe, RRo, I32), mve_scalar_shift),
26316 ToC("asrl", ea50012d, 3, (RRe, RRo, RRnpcsp_I32), mve_scalar_shift),
08132bdd
SP
26317 ToC("uqrshll", ea51010d, 4, (RRe, RRo, I48_I64, RRnpcsp), mve_scalar_shift1),
26318 ToC("sqrshrl", ea51012d, 4, (RRe, RRo, I48_I64, RRnpcsp), mve_scalar_shift1),
23d00a41
SD
26319 ToC("uqshll", ea51010f, 3, (RRe, RRo, I32), mve_scalar_shift),
26320 ToC("urshrl", ea51011f, 3, (RRe, RRo, I32), mve_scalar_shift),
26321 ToC("srshrl", ea51012f, 3, (RRe, RRo, I32), mve_scalar_shift),
26322 ToC("sqshll", ea51013f, 3, (RRe, RRo, I32), mve_scalar_shift),
26323 ToC("uqrshl", ea500f0d, 2, (RRnpcsp, RRnpcsp), mve_scalar_shift),
26324 ToC("sqrshr", ea500f2d, 2, (RRnpcsp, RRnpcsp), mve_scalar_shift),
26325 ToC("uqshl", ea500f0f, 2, (RRnpcsp, I32), mve_scalar_shift),
26326 ToC("urshr", ea500f1f, 2, (RRnpcsp, I32), mve_scalar_shift),
26327 ToC("srshr", ea500f2f, 2, (RRnpcsp, I32), mve_scalar_shift),
26328 ToC("sqshl", ea500f3f, 2, (RRnpcsp, I32), mve_scalar_shift),
1b883319
AV
26329
26330 ToC("vpt", ee410f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26331 ToC("vptt", ee018f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26332 ToC("vpte", ee418f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26333 ToC("vpttt", ee014f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26334 ToC("vptte", ee01cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26335 ToC("vptet", ee41cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26336 ToC("vptee", ee414f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26337 ToC("vptttt", ee012f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26338 ToC("vpttte", ee016f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26339 ToC("vpttet", ee01ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26340 ToC("vpttee", ee01af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26341 ToC("vptett", ee41af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26342 ToC("vptete", ee41ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26343 ToC("vpteet", ee416f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26344 ToC("vpteee", ee412f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
26345
5ee91343
AV
26346 ToC("vpst", fe710f4d, 0, (), mve_vpt),
26347 ToC("vpstt", fe318f4d, 0, (), mve_vpt),
26348 ToC("vpste", fe718f4d, 0, (), mve_vpt),
26349 ToC("vpsttt", fe314f4d, 0, (), mve_vpt),
26350 ToC("vpstte", fe31cf4d, 0, (), mve_vpt),
26351 ToC("vpstet", fe71cf4d, 0, (), mve_vpt),
26352 ToC("vpstee", fe714f4d, 0, (), mve_vpt),
26353 ToC("vpstttt", fe312f4d, 0, (), mve_vpt),
26354 ToC("vpsttte", fe316f4d, 0, (), mve_vpt),
26355 ToC("vpsttet", fe31ef4d, 0, (), mve_vpt),
26356 ToC("vpsttee", fe31af4d, 0, (), mve_vpt),
26357 ToC("vpstett", fe71af4d, 0, (), mve_vpt),
26358 ToC("vpstete", fe71ef4d, 0, (), mve_vpt),
26359 ToC("vpsteet", fe716f4d, 0, (), mve_vpt),
26360 ToC("vpsteee", fe712f4d, 0, (), mve_vpt),
26361
a302e574 26362 /* MVE and MVE FP only. */
7df54120 26363 mToC("vhcadd", ee000f00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vhcadd),
efd0b310 26364 mCEF(vctp, _vctp, 1, (RRnpc), mve_vctp),
c2dafc2a
AV
26365 mCEF(vadc, _vadc, 3, (RMQ, RMQ, RMQ), mve_vadc),
26366 mCEF(vadci, _vadci, 3, (RMQ, RMQ, RMQ), mve_vadc),
26367 mToC("vsbc", fe300f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
26368 mToC("vsbci", fe301f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
886e1c73 26369 mCEF(vmullb, _vmullb, 3, (RMQ, RMQ, RMQ), mve_vmull),
a302e574
AV
26370 mCEF(vabav, _vabav, 3, (RRnpcsp, RMQ, RMQ), mve_vabav),
26371 mCEF(vmladav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26372 mCEF(vmladava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26373 mCEF(vmladavx, _vmladavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
26374 mCEF(vmladavax, _vmladavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
26375 mCEF(vmlav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26376 mCEF(vmlava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26377 mCEF(vmlsdav, _vmlsdav, 3, (RRe, RMQ, RMQ), mve_vmladav),
26378 mCEF(vmlsdava, _vmlsdava, 3, (RRe, RMQ, RMQ), mve_vmladav),
26379 mCEF(vmlsdavx, _vmlsdavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
26380 mCEF(vmlsdavax, _vmlsdavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
26381
35c228db
AV
26382 mCEF(vst20, _vst20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26383 mCEF(vst21, _vst21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26384 mCEF(vst40, _vst40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26385 mCEF(vst41, _vst41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26386 mCEF(vst42, _vst42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26387 mCEF(vst43, _vst43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26388 mCEF(vld20, _vld20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26389 mCEF(vld21, _vld21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
26390 mCEF(vld40, _vld40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26391 mCEF(vld41, _vld41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26392 mCEF(vld42, _vld42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
26393 mCEF(vld43, _vld43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
f5f10c66
AV
26394 mCEF(vstrb, _vstrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26395 mCEF(vstrh, _vstrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26396 mCEF(vstrw, _vstrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26397 mCEF(vstrd, _vstrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26398 mCEF(vldrb, _vldrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26399 mCEF(vldrh, _vldrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26400 mCEF(vldrw, _vldrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
26401 mCEF(vldrd, _vldrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
35c228db 26402
57785aa2
AV
26403 mCEF(vmovnt, _vmovnt, 2, (RMQ, RMQ), mve_movn),
26404 mCEF(vmovnb, _vmovnb, 2, (RMQ, RMQ), mve_movn),
c2dafc2a 26405 mCEF(vbrsr, _vbrsr, 3, (RMQ, RMQ, RR), mve_vbrsr),
26c1e780
AV
26406 mCEF(vaddlv, _vaddlv, 3, (RRe, RRo, RMQ), mve_vaddlv),
26407 mCEF(vaddlva, _vaddlva, 3, (RRe, RRo, RMQ), mve_vaddlv),
26408 mCEF(vaddv, _vaddv, 2, (RRe, RMQ), mve_vaddv),
26409 mCEF(vaddva, _vaddva, 2, (RRe, RMQ), mve_vaddv),
b409bdb6
AV
26410 mCEF(vddup, _vddup, 3, (RMQ, RRe, EXPi), mve_viddup),
26411 mCEF(vdwdup, _vdwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
26412 mCEF(vidup, _vidup, 3, (RMQ, RRe, EXPi), mve_viddup),
26413 mCEF(viwdup, _viwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
935295b5
AV
26414 mToC("vmaxa", ee330e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
26415 mToC("vmina", ee331e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
13ccd4c0
AV
26416 mCEF(vmaxv, _vmaxv, 2, (RR, RMQ), mve_vmaxv),
26417 mCEF(vmaxav, _vmaxav, 2, (RR, RMQ), mve_vmaxv),
26418 mCEF(vminv, _vminv, 2, (RR, RMQ), mve_vmaxv),
26419 mCEF(vminav, _vminav, 2, (RR, RMQ), mve_vmaxv),
57785aa2 26420
93925576
AV
26421 mCEF(vmlaldav, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26422 mCEF(vmlaldava, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26423 mCEF(vmlaldavx, _vmlaldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26424 mCEF(vmlaldavax, _vmlaldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26425 mCEF(vmlalv, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26426 mCEF(vmlalva, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26427 mCEF(vmlsldav, _vmlsldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26428 mCEF(vmlsldava, _vmlsldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26429 mCEF(vmlsldavx, _vmlsldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26430 mCEF(vmlsldavax, _vmlsldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
26431 mToC("vrmlaldavh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26432 mToC("vrmlaldavha",ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26433 mCEF(vrmlaldavhx, _vrmlaldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26434 mCEF(vrmlaldavhax, _vrmlaldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26435 mToC("vrmlalvh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26436 mToC("vrmlalvha", ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26437 mCEF(vrmlsldavh, _vrmlsldavh, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26438 mCEF(vrmlsldavha, _vrmlsldavha, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26439 mCEF(vrmlsldavhx, _vrmlsldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26440 mCEF(vrmlsldavhax, _vrmlsldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
26441
2d78f95b
AV
26442 mToC("vmlas", ee011e40, 3, (RMQ, RMQ, RR), mve_vmlas),
26443 mToC("vmulh", ee010e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
26444 mToC("vrmulh", ee011e01, 3, (RMQ, RMQ, RMQ), mve_vmulh),
3063888e
AV
26445 mToC("vpnot", fe310f4d, 0, (), mve_vpnot),
26446 mToC("vpsel", fe310f01, 3, (RMQ, RMQ, RMQ), mve_vpsel),
2d78f95b 26447
8b8b22a4
AV
26448 mToC("vqdmladh", ee000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26449 mToC("vqdmladhx", ee001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26450 mToC("vqrdmladh", ee000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26451 mToC("vqrdmladhx",ee001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26452 mToC("vqdmlsdh", fe000e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26453 mToC("vqdmlsdhx", fe001e00, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26454 mToC("vqrdmlsdh", fe000e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
26455 mToC("vqrdmlsdhx",fe001e01, 3, (RMQ, RMQ, RMQ), mve_vqdmladh),
42b16635
AV
26456 mToC("vqdmlah", ee000e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
26457 mToC("vqdmlash", ee001e60, 3, (RMQ, RMQ, RR), mve_vqdmlah),
26458 mToC("vqrdmlash", ee001e40, 3, (RMQ, RMQ, RR), mve_vqdmlah),
35d1cfc2
AV
26459 mToC("vqdmullt", ee301f00, 3, (RMQ, RMQ, RMQRR), mve_vqdmull),
26460 mToC("vqdmullb", ee300f00, 3, (RMQ, RMQ, RMQRR), mve_vqdmull),
1be7aba3
AV
26461 mCEF(vqmovnt, _vqmovnt, 2, (RMQ, RMQ), mve_vqmovn),
26462 mCEF(vqmovnb, _vqmovnb, 2, (RMQ, RMQ), mve_vqmovn),
26463 mCEF(vqmovunt, _vqmovunt, 2, (RMQ, RMQ), mve_vqmovn),
26464 mCEF(vqmovunb, _vqmovunb, 2, (RMQ, RMQ), mve_vqmovn),
8b8b22a4 26465
4aa88b50
AV
26466 mCEF(vshrnt, _vshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26467 mCEF(vshrnb, _vshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26468 mCEF(vrshrnt, _vrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26469 mCEF(vrshrnb, _vrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26470 mCEF(vqshrnt, _vqrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26471 mCEF(vqshrnb, _vqrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26472 mCEF(vqshrunt, _vqrshrunt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26473 mCEF(vqshrunb, _vqrshrunb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26474 mCEF(vqrshrnt, _vqrshrnt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26475 mCEF(vqrshrnb, _vqrshrnb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26476 mCEF(vqrshrunt, _vqrshrunt, 3, (RMQ, RMQ, I32z), mve_vshrn),
26477 mCEF(vqrshrunb, _vqrshrunb, 3, (RMQ, RMQ, I32z), mve_vshrn),
26478
acca5630
AV
26479 mToC("vshlc", eea00fc0, 3, (RMQ, RR, I32z), mve_vshlc),
26480 mToC("vshllt", ee201e00, 3, (RMQ, RMQ, I32), mve_vshll),
26481 mToC("vshllb", ee200e00, 3, (RMQ, RMQ, I32), mve_vshll),
26482
1f6234a3
AV
26483 toU("dlstp", _dlstp, 2, (LR, RR), t_loloop),
26484 toU("wlstp", _wlstp, 3, (LR, RR, EXP), t_loloop),
26485 toU("letp", _letp, 2, (LR, EXP), t_loloop),
26486 toU("lctp", _lctp, 0, (), t_loloop),
26487
5d281bf0
AV
26488#undef THUMB_VARIANT
26489#define THUMB_VARIANT & mve_fp_ext
26490 mToC("vcmul", ee300e00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vcmul),
f30ee27c 26491 mToC("vfmas", ee311e40, 3, (RMQ, RMQ, RR), mve_vfmas),
935295b5
AV
26492 mToC("vmaxnma", ee3f0e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
26493 mToC("vminnma", ee3f1e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
8cd78170
AV
26494 mToC("vmaxnmv", eeee0f00, 2, (RR, RMQ), mve_vmaxnmv),
26495 mToC("vmaxnmav",eeec0f00, 2, (RR, RMQ), mve_vmaxnmv),
26496 mToC("vminnmv", eeee0f80, 2, (RR, RMQ), mve_vmaxnmv),
26497 mToC("vminnmav",eeec0f80, 2, (RR, RMQ), mve_vmaxnmv),
5d281bf0 26498
5ee91343 26499#undef ARM_VARIANT
57785aa2 26500#define ARM_VARIANT & fpu_vfp_ext_v1
5ee91343
AV
26501#undef THUMB_VARIANT
26502#define THUMB_VARIANT & arm_ext_v6t2
a8465a06
AV
26503 mnCEF(vmla, _vmla, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mac_maybe_scalar),
26504 mnCEF(vmul, _vmul, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ_RR), neon_mul),
5ee91343 26505
57785aa2
AV
26506 mcCE(fcpyd, eb00b40, 2, (RVD, RVD), vfp_dp_rd_rm),
26507
26508#undef ARM_VARIANT
26509#define ARM_VARIANT & fpu_vfp_ext_v1xd
26510
26511 MNCE(vmov, 0, 1, (VMOV), neon_mov),
26512 mcCE(fmrs, e100a10, 2, (RR, RVS), vfp_reg_from_sp),
26513 mcCE(fmsr, e000a10, 2, (RVS, RR), vfp_sp_from_reg),
26514 mcCE(fcpys, eb00a40, 2, (RVS, RVS), vfp_sp_monadic),
26515
886e1c73
AV
26516 mCEF(vmullt, _vmullt, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ), mve_vmull),
26517 mnCEF(vadd, _vadd, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
26518 mnCEF(vsub, _vsub, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
5ee91343 26519
485dee97
AV
26520 MNCEF(vabs, 1b10300, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
26521 MNCEF(vneg, 1b10380, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
26522
57785aa2
AV
26523 mCEF(vmovlt, _vmovlt, 1, (VMOV), mve_movl),
26524 mCEF(vmovlb, _vmovlb, 1, (VMOV), mve_movl),
26525
1b883319
AV
26526 mnCE(vcmp, _vcmp, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
26527 mnCE(vcmpe, _vcmpe, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
26528
57785aa2
AV
26529#undef ARM_VARIANT
26530#define ARM_VARIANT & fpu_vfp_ext_v2
26531
26532 mcCE(fmsrr, c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
26533 mcCE(fmrrs, c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
26534 mcCE(fmdrr, c400b10, 3, (RVD, RR, RR), vfp_dp_rm_rd_rn),
26535 mcCE(fmrrd, c500b10, 3, (RR, RR, RVD), vfp_dp_rd_rn_rm),
26536
dd9634d9
AV
26537#undef ARM_VARIANT
26538#define ARM_VARIANT & fpu_vfp_ext_armv8xd
26539 mnUF(vcvta, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvta),
26540 mnUF(vcvtp, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtp),
26541 mnUF(vcvtn, _vcvta, 3, (RNSDQMQ, oRNSDQMQ, oI32z), neon_cvtn),
26542 mnUF(vcvtm, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtm),
935295b5
AV
26543 mnUF(vmaxnm, _vmaxnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
26544 mnUF(vminnm, _vminnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
dd9634d9
AV
26545
26546#undef ARM_VARIANT
5ee91343 26547#define ARM_VARIANT & fpu_neon_ext_v1
f601a00c 26548 mnUF(vabd, _vabd, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
5ee91343 26549 mnUF(vabdl, _vabdl, 3, (RNQMQ, RNDMQ, RNDMQ), neon_dyadic_long),
66d1f7cc
AV
26550 mnUF(vaddl, _vaddl, 3, (RNSDQMQ, oRNSDMQ, RNSDMQR), neon_dyadic_long),
26551 mnUF(vsubl, _vsubl, 3, (RNSDQMQ, oRNSDMQ, RNSDMQR), neon_dyadic_long),
f601a00c
AV
26552 mnUF(vand, _vand, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26553 mnUF(vbic, _vbic, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26554 mnUF(vorr, _vorr, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26555 mnUF(vorn, _vorn, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
26556 mnUF(veor, _veor, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_logic),
f30ee27c
AV
26557 MNUF(vcls, 1b00400, 2, (RNDQMQ, RNDQMQ), neon_cls),
26558 MNUF(vclz, 1b00480, 2, (RNDQMQ, RNDQMQ), neon_clz),
b409bdb6 26559 mnCE(vdup, _vdup, 2, (RNDQMQ, RR_RNSC), neon_dup),
7df54120
AV
26560 MNUF(vhadd, 00000000, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
26561 MNUF(vrhadd, 00000100, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_i_su),
26562 MNUF(vhsub, 00000200, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
935295b5
AV
26563 mnUF(vmin, _vmin, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
26564 mnUF(vmax, _vmax, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
a8465a06
AV
26565 MNUF(vqadd, 0000010, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
26566 MNUF(vqsub, 0000210, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i64_su),
1a186d29
AV
26567 mnUF(vmvn, _vmvn, 2, (RNDQMQ, RNDQMQ_Ibig), neon_mvn),
26568 MNUF(vqabs, 1b00700, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
26569 MNUF(vqneg, 1b00780, 2, (RNDQMQ, RNDQMQ), neon_sat_abs_neg),
42b16635
AV
26570 mnUF(vqrdmlah, _vqrdmlah,3, (RNDQMQ, oRNDQMQ, RNDQ_RNSC_RR), neon_qrdmlah),
26571 mnUF(vqdmulh, _vqdmulh, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
26572 mnUF(vqrdmulh, _vqrdmulh,3, (RNDQMQ, oRNDQMQ, RNDQMQ_RNSC_RR), neon_qdmulh),
1be7aba3
AV
26573 MNUF(vqrshl, 0000510, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
26574 MNUF(vrshl, 0000500, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_rshl),
4401c241
AV
26575 MNUF(vshr, 0800010, 3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
26576 MNUF(vrshr, 0800210, 3, (RNDQMQ, oRNDQMQ, I64z), neon_rshift_round_imm),
26577 MNUF(vsli, 1800510, 3, (RNDQMQ, oRNDQMQ, I63), neon_sli),
26578 MNUF(vsri, 1800410, 3, (RNDQMQ, oRNDQMQ, I64z), neon_sri),
26579 MNUF(vrev64, 1b00000, 2, (RNDQMQ, RNDQMQ), neon_rev),
26580 MNUF(vrev32, 1b00080, 2, (RNDQMQ, RNDQMQ), neon_rev),
26581 MNUF(vrev16, 1b00100, 2, (RNDQMQ, RNDQMQ), neon_rev),
5150f0d8
AV
26582 mnUF(vshl, _vshl, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_shl),
26583 mnUF(vqshl, _vqshl, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_I63b_RR), neon_qshl),
26584 MNUF(vqshlu, 1800610, 3, (RNDQMQ, oRNDQMQ, I63), neon_qshlu_imm),
5d281bf0
AV
26585
26586#undef ARM_VARIANT
26587#define ARM_VARIANT & arm_ext_v8_3
26588#undef THUMB_VARIANT
26589#define THUMB_VARIANT & arm_ext_v6t2_v8m
26590 MNUF (vcadd, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ, EXPi), vcadd),
26591 MNUF (vcmla, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ_RNSC, EXPi), vcmla),
aab2c27d
MM
26592
26593#undef ARM_VARIANT
26594#define ARM_VARIANT &arm_ext_bf16
26595#undef THUMB_VARIANT
26596#define THUMB_VARIANT &arm_ext_bf16
26597 TUF ("vdot", c000d00, fc000d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), vdot, vdot),
26598 TUF ("vmmla", c000c40, fc000c40, 3, (RNQ, RNQ, RNQ), vmmla, vmmla),
26599 TUF ("vfmab", c300810, fc300810, 3, (RNDQ, RNDQ, RNDQ_RNSC), bfloat_vfma, bfloat_vfma),
26600
26601#undef ARM_VARIANT
26602#define ARM_VARIANT &arm_ext_i8mm
26603#undef THUMB_VARIANT
26604#define THUMB_VARIANT &arm_ext_i8mm
26605 TUF ("vsmmla", c200c40, fc200c40, 3, (RNQ, RNQ, RNQ), vsmmla, vsmmla),
26606 TUF ("vummla", c200c50, fc200c50, 3, (RNQ, RNQ, RNQ), vummla, vummla),
616ce08e 26607 TUF ("vusmmla", ca00c40, fca00c40, 3, (RNQ, RNQ, RNQ), vsmmla, vsmmla),
aab2c27d
MM
26608 TUF ("vusdot", c800d00, fc800d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), vusdot, vusdot),
26609 TUF ("vsudot", c800d10, fc800d10, 3, (RNDQ, RNDQ, RNSC), vsudot, vsudot),
4934a27c
MM
26610
26611#undef ARM_VARIANT
26612#undef THUMB_VARIANT
26613#define THUMB_VARIANT &arm_ext_cde
26614 ToC ("cx1", ee000000, 3, (RCP, APSR_RR, I8191), cx1),
26615 ToC ("cx1a", fe000000, 3, (RCP, APSR_RR, I8191), cx1a),
26616 ToC ("cx1d", ee000040, 4, (RCP, RR, APSR_RR, I8191), cx1d),
26617 ToC ("cx1da", fe000040, 4, (RCP, RR, APSR_RR, I8191), cx1da),
26618
26619 ToC ("cx2", ee400000, 4, (RCP, APSR_RR, APSR_RR, I511), cx2),
26620 ToC ("cx2a", fe400000, 4, (RCP, APSR_RR, APSR_RR, I511), cx2a),
26621 ToC ("cx2d", ee400040, 5, (RCP, RR, APSR_RR, APSR_RR, I511), cx2d),
26622 ToC ("cx2da", fe400040, 5, (RCP, RR, APSR_RR, APSR_RR, I511), cx2da),
26623
26624 ToC ("cx3", ee800000, 5, (RCP, APSR_RR, APSR_RR, APSR_RR, I63), cx3),
26625 ToC ("cx3a", fe800000, 5, (RCP, APSR_RR, APSR_RR, APSR_RR, I63), cx3a),
26626 ToC ("cx3d", ee800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3d),
26627 ToC ("cx3da", fe800040, 6, (RCP, RR, APSR_RR, APSR_RR, APSR_RR, I63), cx3da),
5aae9ae9
MM
26628
26629 mToC ("vcx1", ec200000, 3, (RCP, RNSDMQ, I4095), vcx1),
26630 mToC ("vcx1a", fc200000, 3, (RCP, RNSDMQ, I4095), vcx1),
26631
26632 mToC ("vcx2", ec300000, 4, (RCP, RNSDMQ, RNSDMQ, I127), vcx2),
26633 mToC ("vcx2a", fc300000, 4, (RCP, RNSDMQ, RNSDMQ, I127), vcx2),
26634
26635 mToC ("vcx3", ec800000, 5, (RCP, RNSDMQ, RNSDMQ, RNSDMQ, I15), vcx3),
26636 mToC ("vcx3a", fc800000, 5, (RCP, RNSDMQ, RNSDMQ, RNSDMQ, I15), vcx3),
c19d1205 26637};
5aae9ae9 26638
c19d1205
ZW
26639#undef ARM_VARIANT
26640#undef THUMB_VARIANT
26641#undef TCE
c19d1205
ZW
26642#undef TUE
26643#undef TUF
26644#undef TCC
8f06b2d8 26645#undef cCE
e3cb604e
PB
26646#undef cCL
26647#undef C3E
4389b29a 26648#undef C3
c19d1205
ZW
26649#undef CE
26650#undef CM
4389b29a 26651#undef CL
c19d1205
ZW
26652#undef UE
26653#undef UF
26654#undef UT
5287ad62
JB
26655#undef NUF
26656#undef nUF
26657#undef NCE
26658#undef nCE
c19d1205
ZW
26659#undef OPS0
26660#undef OPS1
26661#undef OPS2
26662#undef OPS3
26663#undef OPS4
26664#undef OPS5
26665#undef OPS6
26666#undef do_0
4389b29a
AV
26667#undef ToC
26668#undef toC
26669#undef ToU
f6b2b12d 26670#undef toU
c19d1205
ZW
26671\f
26672/* MD interface: bits in the object file. */
bfae80f2 26673
c19d1205
ZW
26674/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
26675 for use in the a.out file, and stores them in the array pointed to by buf.
26676 This knows about the endian-ness of the target machine and does
26677 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
26678 2 (short) and 4 (long) Floating numbers are put out as a series of
26679 LITTLENUMS (shorts, here at least). */
b99bd4ef 26680
c19d1205
ZW
26681void
26682md_number_to_chars (char * buf, valueT val, int n)
26683{
26684 if (target_big_endian)
26685 number_to_chars_bigendian (buf, val, n);
26686 else
26687 number_to_chars_littleendian (buf, val, n);
bfae80f2
RE
26688}
26689
c19d1205
ZW
26690static valueT
26691md_chars_to_number (char * buf, int n)
bfae80f2 26692{
c19d1205
ZW
26693 valueT result = 0;
26694 unsigned char * where = (unsigned char *) buf;
bfae80f2 26695
c19d1205 26696 if (target_big_endian)
b99bd4ef 26697 {
c19d1205
ZW
26698 while (n--)
26699 {
26700 result <<= 8;
26701 result |= (*where++ & 255);
26702 }
b99bd4ef 26703 }
c19d1205 26704 else
b99bd4ef 26705 {
c19d1205
ZW
26706 while (n--)
26707 {
26708 result <<= 8;
26709 result |= (where[n] & 255);
26710 }
bfae80f2 26711 }
b99bd4ef 26712
c19d1205 26713 return result;
bfae80f2 26714}
b99bd4ef 26715
c19d1205 26716/* MD interface: Sections. */
b99bd4ef 26717
fa94de6b
RM
26718/* Calculate the maximum variable size (i.e., excluding fr_fix)
26719 that an rs_machine_dependent frag may reach. */
26720
26721unsigned int
26722arm_frag_max_var (fragS *fragp)
26723{
26724 /* We only use rs_machine_dependent for variable-size Thumb instructions,
26725 which are either THUMB_SIZE (2) or INSN_SIZE (4).
26726
26727 Note that we generate relaxable instructions even for cases that don't
26728 really need it, like an immediate that's a trivial constant. So we're
26729 overestimating the instruction size for some of those cases. Rather
26730 than putting more intelligence here, it would probably be better to
26731 avoid generating a relaxation frag in the first place when it can be
26732 determined up front that a short instruction will suffice. */
26733
26734 gas_assert (fragp->fr_type == rs_machine_dependent);
26735 return INSN_SIZE;
26736}
26737
0110f2b8
PB
26738/* Estimate the size of a frag before relaxing. Assume everything fits in
26739 2 bytes. */
26740
c19d1205 26741int
0110f2b8 26742md_estimate_size_before_relax (fragS * fragp,
c19d1205
ZW
26743 segT segtype ATTRIBUTE_UNUSED)
26744{
0110f2b8
PB
26745 fragp->fr_var = 2;
26746 return 2;
26747}
26748
26749/* Convert a machine dependent frag. */
26750
26751void
26752md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
26753{
26754 unsigned long insn;
26755 unsigned long old_op;
26756 char *buf;
26757 expressionS exp;
26758 fixS *fixp;
26759 int reloc_type;
26760 int pc_rel;
26761 int opcode;
26762
26763 buf = fragp->fr_literal + fragp->fr_fix;
26764
26765 old_op = bfd_get_16(abfd, buf);
5f4273c7
NC
26766 if (fragp->fr_symbol)
26767 {
0110f2b8
PB
26768 exp.X_op = O_symbol;
26769 exp.X_add_symbol = fragp->fr_symbol;
5f4273c7
NC
26770 }
26771 else
26772 {
0110f2b8 26773 exp.X_op = O_constant;
5f4273c7 26774 }
0110f2b8
PB
26775 exp.X_add_number = fragp->fr_offset;
26776 opcode = fragp->fr_subtype;
26777 switch (opcode)
26778 {
26779 case T_MNEM_ldr_pc:
26780 case T_MNEM_ldr_pc2:
26781 case T_MNEM_ldr_sp:
26782 case T_MNEM_str_sp:
26783 case T_MNEM_ldr:
26784 case T_MNEM_ldrb:
26785 case T_MNEM_ldrh:
26786 case T_MNEM_str:
26787 case T_MNEM_strb:
26788 case T_MNEM_strh:
26789 if (fragp->fr_var == 4)
26790 {
5f4273c7 26791 insn = THUMB_OP32 (opcode);
0110f2b8
PB
26792 if ((old_op >> 12) == 4 || (old_op >> 12) == 9)
26793 {
26794 insn |= (old_op & 0x700) << 4;
26795 }
26796 else
26797 {
26798 insn |= (old_op & 7) << 12;
26799 insn |= (old_op & 0x38) << 13;
26800 }
26801 insn |= 0x00000c00;
26802 put_thumb32_insn (buf, insn);
26803 reloc_type = BFD_RELOC_ARM_T32_OFFSET_IMM;
26804 }
26805 else
26806 {
26807 reloc_type = BFD_RELOC_ARM_THUMB_OFFSET;
26808 }
26809 pc_rel = (opcode == T_MNEM_ldr_pc2);
26810 break;
26811 case T_MNEM_adr:
26812 if (fragp->fr_var == 4)
26813 {
26814 insn = THUMB_OP32 (opcode);
26815 insn |= (old_op & 0xf0) << 4;
26816 put_thumb32_insn (buf, insn);
26817 reloc_type = BFD_RELOC_ARM_T32_ADD_PC12;
26818 }
26819 else
26820 {
26821 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
26822 exp.X_add_number -= 4;
26823 }
26824 pc_rel = 1;
26825 break;
26826 case T_MNEM_mov:
26827 case T_MNEM_movs:
26828 case T_MNEM_cmp:
26829 case T_MNEM_cmn:
26830 if (fragp->fr_var == 4)
26831 {
26832 int r0off = (opcode == T_MNEM_mov
26833 || opcode == T_MNEM_movs) ? 0 : 8;
26834 insn = THUMB_OP32 (opcode);
26835 insn = (insn & 0xe1ffffff) | 0x10000000;
26836 insn |= (old_op & 0x700) << r0off;
26837 put_thumb32_insn (buf, insn);
26838 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
26839 }
26840 else
26841 {
26842 reloc_type = BFD_RELOC_ARM_THUMB_IMM;
26843 }
26844 pc_rel = 0;
26845 break;
26846 case T_MNEM_b:
26847 if (fragp->fr_var == 4)
26848 {
26849 insn = THUMB_OP32(opcode);
26850 put_thumb32_insn (buf, insn);
26851 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH25;
26852 }
26853 else
26854 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH12;
26855 pc_rel = 1;
26856 break;
26857 case T_MNEM_bcond:
26858 if (fragp->fr_var == 4)
26859 {
26860 insn = THUMB_OP32(opcode);
26861 insn |= (old_op & 0xf00) << 14;
26862 put_thumb32_insn (buf, insn);
26863 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH20;
26864 }
26865 else
26866 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH9;
26867 pc_rel = 1;
26868 break;
26869 case T_MNEM_add_sp:
26870 case T_MNEM_add_pc:
26871 case T_MNEM_inc_sp:
26872 case T_MNEM_dec_sp:
26873 if (fragp->fr_var == 4)
26874 {
26875 /* ??? Choose between add and addw. */
26876 insn = THUMB_OP32 (opcode);
26877 insn |= (old_op & 0xf0) << 4;
26878 put_thumb32_insn (buf, insn);
16805f35
PB
26879 if (opcode == T_MNEM_add_pc)
26880 reloc_type = BFD_RELOC_ARM_T32_IMM12;
26881 else
26882 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
0110f2b8
PB
26883 }
26884 else
26885 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
26886 pc_rel = 0;
26887 break;
26888
26889 case T_MNEM_addi:
26890 case T_MNEM_addis:
26891 case T_MNEM_subi:
26892 case T_MNEM_subis:
26893 if (fragp->fr_var == 4)
26894 {
26895 insn = THUMB_OP32 (opcode);
26896 insn |= (old_op & 0xf0) << 4;
26897 insn |= (old_op & 0xf) << 16;
26898 put_thumb32_insn (buf, insn);
16805f35
PB
26899 if (insn & (1 << 20))
26900 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
26901 else
26902 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8
PB
26903 }
26904 else
26905 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
26906 pc_rel = 0;
26907 break;
26908 default:
5f4273c7 26909 abort ();
0110f2b8
PB
26910 }
26911 fixp = fix_new_exp (fragp, fragp->fr_fix, fragp->fr_var, &exp, pc_rel,
21d799b5 26912 (enum bfd_reloc_code_real) reloc_type);
0110f2b8
PB
26913 fixp->fx_file = fragp->fr_file;
26914 fixp->fx_line = fragp->fr_line;
26915 fragp->fr_fix += fragp->fr_var;
3cfdb781
TG
26916
26917 /* Set whether we use thumb-2 ISA based on final relaxation results. */
26918 if (thumb_mode && fragp->fr_var == 4 && no_cpu_selected ()
26919 && !ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2))
26920 ARM_MERGE_FEATURE_SETS (arm_arch_used, thumb_arch_used, arm_ext_v6t2);
0110f2b8
PB
26921}
26922
26923/* Return the size of a relaxable immediate operand instruction.
26924 SHIFT and SIZE specify the form of the allowable immediate. */
26925static int
26926relax_immediate (fragS *fragp, int size, int shift)
26927{
26928 offsetT offset;
26929 offsetT mask;
26930 offsetT low;
26931
26932 /* ??? Should be able to do better than this. */
26933 if (fragp->fr_symbol)
26934 return 4;
26935
26936 low = (1 << shift) - 1;
26937 mask = (1 << (shift + size)) - (1 << shift);
26938 offset = fragp->fr_offset;
26939 /* Force misaligned offsets to 32-bit variant. */
26940 if (offset & low)
5e77afaa 26941 return 4;
0110f2b8
PB
26942 if (offset & ~mask)
26943 return 4;
26944 return 2;
26945}
26946
5e77afaa
PB
26947/* Get the address of a symbol during relaxation. */
26948static addressT
5f4273c7 26949relaxed_symbol_addr (fragS *fragp, long stretch)
5e77afaa
PB
26950{
26951 fragS *sym_frag;
26952 addressT addr;
26953 symbolS *sym;
26954
26955 sym = fragp->fr_symbol;
26956 sym_frag = symbol_get_frag (sym);
26957 know (S_GET_SEGMENT (sym) != absolute_section
26958 || sym_frag == &zero_address_frag);
26959 addr = S_GET_VALUE (sym) + fragp->fr_offset;
26960
26961 /* If frag has yet to be reached on this pass, assume it will
26962 move by STRETCH just as we did. If this is not so, it will
26963 be because some frag between grows, and that will force
26964 another pass. */
26965
26966 if (stretch != 0
26967 && sym_frag->relax_marker != fragp->relax_marker)
4396b686
PB
26968 {
26969 fragS *f;
26970
26971 /* Adjust stretch for any alignment frag. Note that if have
26972 been expanding the earlier code, the symbol may be
26973 defined in what appears to be an earlier frag. FIXME:
26974 This doesn't handle the fr_subtype field, which specifies
26975 a maximum number of bytes to skip when doing an
26976 alignment. */
26977 for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
26978 {
26979 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
26980 {
26981 if (stretch < 0)
26982 stretch = - ((- stretch)
26983 & ~ ((1 << (int) f->fr_offset) - 1));
26984 else
26985 stretch &= ~ ((1 << (int) f->fr_offset) - 1);
26986 if (stretch == 0)
26987 break;
26988 }
26989 }
26990 if (f != NULL)
26991 addr += stretch;
26992 }
5e77afaa
PB
26993
26994 return addr;
26995}
26996
0110f2b8
PB
26997/* Return the size of a relaxable adr pseudo-instruction or PC-relative
26998 load. */
26999static int
5e77afaa 27000relax_adr (fragS *fragp, asection *sec, long stretch)
0110f2b8
PB
27001{
27002 addressT addr;
27003 offsetT val;
27004
27005 /* Assume worst case for symbols not known to be in the same section. */
974da60d
NC
27006 if (fragp->fr_symbol == NULL
27007 || !S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
27008 || sec != S_GET_SEGMENT (fragp->fr_symbol)
27009 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
27010 return 4;
27011
5f4273c7 27012 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
27013 addr = fragp->fr_address + fragp->fr_fix;
27014 addr = (addr + 4) & ~3;
5e77afaa 27015 /* Force misaligned targets to 32-bit variant. */
0110f2b8 27016 if (val & 3)
5e77afaa 27017 return 4;
0110f2b8
PB
27018 val -= addr;
27019 if (val < 0 || val > 1020)
27020 return 4;
27021 return 2;
27022}
27023
27024/* Return the size of a relaxable add/sub immediate instruction. */
27025static int
27026relax_addsub (fragS *fragp, asection *sec)
27027{
27028 char *buf;
27029 int op;
27030
27031 buf = fragp->fr_literal + fragp->fr_fix;
27032 op = bfd_get_16(sec->owner, buf);
27033 if ((op & 0xf) == ((op >> 4) & 0xf))
27034 return relax_immediate (fragp, 8, 0);
27035 else
27036 return relax_immediate (fragp, 3, 0);
27037}
27038
e83a675f
RE
27039/* Return TRUE iff the definition of symbol S could be pre-empted
27040 (overridden) at link or load time. */
27041static bfd_boolean
27042symbol_preemptible (symbolS *s)
27043{
27044 /* Weak symbols can always be pre-empted. */
27045 if (S_IS_WEAK (s))
27046 return TRUE;
27047
27048 /* Non-global symbols cannot be pre-empted. */
27049 if (! S_IS_EXTERNAL (s))
27050 return FALSE;
27051
27052#ifdef OBJ_ELF
27053 /* In ELF, a global symbol can be marked protected, or private. In that
27054 case it can't be pre-empted (other definitions in the same link unit
27055 would violate the ODR). */
27056 if (ELF_ST_VISIBILITY (S_GET_OTHER (s)) > STV_DEFAULT)
27057 return FALSE;
27058#endif
27059
27060 /* Other global symbols might be pre-empted. */
27061 return TRUE;
27062}
0110f2b8
PB
27063
27064/* Return the size of a relaxable branch instruction. BITS is the
27065 size of the offset field in the narrow instruction. */
27066
27067static int
5e77afaa 27068relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
0110f2b8
PB
27069{
27070 addressT addr;
27071 offsetT val;
27072 offsetT limit;
27073
27074 /* Assume worst case for symbols not known to be in the same section. */
5f4273c7 27075 if (!S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
27076 || sec != S_GET_SEGMENT (fragp->fr_symbol)
27077 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
27078 return 4;
27079
267bf995 27080#ifdef OBJ_ELF
e83a675f 27081 /* A branch to a function in ARM state will require interworking. */
267bf995
RR
27082 if (S_IS_DEFINED (fragp->fr_symbol)
27083 && ARM_IS_FUNC (fragp->fr_symbol))
27084 return 4;
e83a675f 27085#endif
0d9b4b55 27086
e83a675f 27087 if (symbol_preemptible (fragp->fr_symbol))
0d9b4b55 27088 return 4;
267bf995 27089
5f4273c7 27090 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
27091 addr = fragp->fr_address + fragp->fr_fix + 4;
27092 val -= addr;
27093
27094 /* Offset is a signed value *2 */
27095 limit = 1 << bits;
27096 if (val >= limit || val < -limit)
27097 return 4;
27098 return 2;
27099}
27100
27101
27102/* Relax a machine dependent frag. This returns the amount by which
27103 the current size of the frag should change. */
27104
27105int
5e77afaa 27106arm_relax_frag (asection *sec, fragS *fragp, long stretch)
0110f2b8
PB
27107{
27108 int oldsize;
27109 int newsize;
27110
27111 oldsize = fragp->fr_var;
27112 switch (fragp->fr_subtype)
27113 {
27114 case T_MNEM_ldr_pc2:
5f4273c7 27115 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
27116 break;
27117 case T_MNEM_ldr_pc:
27118 case T_MNEM_ldr_sp:
27119 case T_MNEM_str_sp:
5f4273c7 27120 newsize = relax_immediate (fragp, 8, 2);
0110f2b8
PB
27121 break;
27122 case T_MNEM_ldr:
27123 case T_MNEM_str:
5f4273c7 27124 newsize = relax_immediate (fragp, 5, 2);
0110f2b8
PB
27125 break;
27126 case T_MNEM_ldrh:
27127 case T_MNEM_strh:
5f4273c7 27128 newsize = relax_immediate (fragp, 5, 1);
0110f2b8
PB
27129 break;
27130 case T_MNEM_ldrb:
27131 case T_MNEM_strb:
5f4273c7 27132 newsize = relax_immediate (fragp, 5, 0);
0110f2b8
PB
27133 break;
27134 case T_MNEM_adr:
5f4273c7 27135 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
27136 break;
27137 case T_MNEM_mov:
27138 case T_MNEM_movs:
27139 case T_MNEM_cmp:
27140 case T_MNEM_cmn:
5f4273c7 27141 newsize = relax_immediate (fragp, 8, 0);
0110f2b8
PB
27142 break;
27143 case T_MNEM_b:
5f4273c7 27144 newsize = relax_branch (fragp, sec, 11, stretch);
0110f2b8
PB
27145 break;
27146 case T_MNEM_bcond:
5f4273c7 27147 newsize = relax_branch (fragp, sec, 8, stretch);
0110f2b8
PB
27148 break;
27149 case T_MNEM_add_sp:
27150 case T_MNEM_add_pc:
27151 newsize = relax_immediate (fragp, 8, 2);
27152 break;
27153 case T_MNEM_inc_sp:
27154 case T_MNEM_dec_sp:
27155 newsize = relax_immediate (fragp, 7, 2);
27156 break;
27157 case T_MNEM_addi:
27158 case T_MNEM_addis:
27159 case T_MNEM_subi:
27160 case T_MNEM_subis:
27161 newsize = relax_addsub (fragp, sec);
27162 break;
27163 default:
5f4273c7 27164 abort ();
0110f2b8 27165 }
5e77afaa
PB
27166
27167 fragp->fr_var = newsize;
27168 /* Freeze wide instructions that are at or before the same location as
27169 in the previous pass. This avoids infinite loops.
5f4273c7
NC
27170 Don't freeze them unconditionally because targets may be artificially
27171 misaligned by the expansion of preceding frags. */
5e77afaa 27172 if (stretch <= 0 && newsize > 2)
0110f2b8 27173 {
0110f2b8 27174 md_convert_frag (sec->owner, sec, fragp);
5f4273c7 27175 frag_wane (fragp);
0110f2b8 27176 }
5e77afaa 27177
0110f2b8 27178 return newsize - oldsize;
c19d1205 27179}
b99bd4ef 27180
c19d1205 27181/* Round up a section size to the appropriate boundary. */
b99bd4ef 27182
c19d1205
ZW
27183valueT
27184md_section_align (segT segment ATTRIBUTE_UNUSED,
27185 valueT size)
27186{
6844c0cc 27187 return size;
bfae80f2 27188}
b99bd4ef 27189
c19d1205
ZW
27190/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
27191 of an rs_align_code fragment. */
27192
27193void
27194arm_handle_align (fragS * fragP)
bfae80f2 27195{
d9235011 27196 static unsigned char const arm_noop[2][2][4] =
e7495e45
NS
27197 {
27198 { /* ARMv1 */
27199 {0x00, 0x00, 0xa0, 0xe1}, /* LE */
27200 {0xe1, 0xa0, 0x00, 0x00}, /* BE */
27201 },
27202 { /* ARMv6k */
27203 {0x00, 0xf0, 0x20, 0xe3}, /* LE */
27204 {0xe3, 0x20, 0xf0, 0x00}, /* BE */
27205 },
27206 };
d9235011 27207 static unsigned char const thumb_noop[2][2][2] =
e7495e45
NS
27208 {
27209 { /* Thumb-1 */
27210 {0xc0, 0x46}, /* LE */
27211 {0x46, 0xc0}, /* BE */
27212 },
27213 { /* Thumb-2 */
27214 {0x00, 0xbf}, /* LE */
27215 {0xbf, 0x00} /* BE */
27216 }
27217 };
d9235011 27218 static unsigned char const wide_thumb_noop[2][4] =
e7495e45
NS
27219 { /* Wide Thumb-2 */
27220 {0xaf, 0xf3, 0x00, 0x80}, /* LE */
27221 {0xf3, 0xaf, 0x80, 0x00}, /* BE */
27222 };
c921be7d 27223
e7495e45 27224 unsigned bytes, fix, noop_size;
c19d1205 27225 char * p;
d9235011
TS
27226 const unsigned char * noop;
27227 const unsigned char *narrow_noop = NULL;
cd000bff
DJ
27228#ifdef OBJ_ELF
27229 enum mstate state;
27230#endif
bfae80f2 27231
c19d1205 27232 if (fragP->fr_type != rs_align_code)
bfae80f2
RE
27233 return;
27234
c19d1205
ZW
27235 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
27236 p = fragP->fr_literal + fragP->fr_fix;
27237 fix = 0;
bfae80f2 27238
c19d1205
ZW
27239 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
27240 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
bfae80f2 27241
cd000bff 27242 gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
8dc2430f 27243
cd000bff 27244 if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
a737bd4d 27245 {
7f78eb34
JW
27246 if (ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
27247 ? selected_cpu : arm_arch_none, arm_ext_v6t2))
e7495e45
NS
27248 {
27249 narrow_noop = thumb_noop[1][target_big_endian];
27250 noop = wide_thumb_noop[target_big_endian];
27251 }
c19d1205 27252 else
e7495e45
NS
27253 noop = thumb_noop[0][target_big_endian];
27254 noop_size = 2;
cd000bff
DJ
27255#ifdef OBJ_ELF
27256 state = MAP_THUMB;
27257#endif
7ed4c4c5
NC
27258 }
27259 else
27260 {
7f78eb34
JW
27261 noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
27262 ? selected_cpu : arm_arch_none,
27263 arm_ext_v6k) != 0]
e7495e45
NS
27264 [target_big_endian];
27265 noop_size = 4;
cd000bff
DJ
27266#ifdef OBJ_ELF
27267 state = MAP_ARM;
27268#endif
7ed4c4c5 27269 }
c921be7d 27270
e7495e45 27271 fragP->fr_var = noop_size;
c921be7d 27272
c19d1205 27273 if (bytes & (noop_size - 1))
7ed4c4c5 27274 {
c19d1205 27275 fix = bytes & (noop_size - 1);
cd000bff
DJ
27276#ifdef OBJ_ELF
27277 insert_data_mapping_symbol (state, fragP->fr_fix, fragP, fix);
27278#endif
c19d1205
ZW
27279 memset (p, 0, fix);
27280 p += fix;
27281 bytes -= fix;
a737bd4d 27282 }
a737bd4d 27283
e7495e45
NS
27284 if (narrow_noop)
27285 {
27286 if (bytes & noop_size)
27287 {
27288 /* Insert a narrow noop. */
27289 memcpy (p, narrow_noop, noop_size);
27290 p += noop_size;
27291 bytes -= noop_size;
27292 fix += noop_size;
27293 }
27294
27295 /* Use wide noops for the remainder */
27296 noop_size = 4;
27297 }
27298
c19d1205 27299 while (bytes >= noop_size)
a737bd4d 27300 {
c19d1205
ZW
27301 memcpy (p, noop, noop_size);
27302 p += noop_size;
27303 bytes -= noop_size;
27304 fix += noop_size;
a737bd4d
NC
27305 }
27306
c19d1205 27307 fragP->fr_fix += fix;
a737bd4d
NC
27308}
27309
c19d1205
ZW
27310/* Called from md_do_align. Used to create an alignment
27311 frag in a code section. */
27312
27313void
27314arm_frag_align_code (int n, int max)
bfae80f2 27315{
c19d1205 27316 char * p;
7ed4c4c5 27317
c19d1205 27318 /* We assume that there will never be a requirement
6ec8e702 27319 to support alignments greater than MAX_MEM_FOR_RS_ALIGN_CODE bytes. */
c19d1205 27320 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
6ec8e702
NC
27321 {
27322 char err_msg[128];
27323
fa94de6b 27324 sprintf (err_msg,
477330fc
RM
27325 _("alignments greater than %d bytes not supported in .text sections."),
27326 MAX_MEM_FOR_RS_ALIGN_CODE + 1);
20203fb9 27327 as_fatal ("%s", err_msg);
6ec8e702 27328 }
bfae80f2 27329
c19d1205
ZW
27330 p = frag_var (rs_align_code,
27331 MAX_MEM_FOR_RS_ALIGN_CODE,
27332 1,
27333 (relax_substateT) max,
27334 (symbolS *) NULL,
27335 (offsetT) n,
27336 (char *) NULL);
27337 *p = 0;
27338}
bfae80f2 27339
8dc2430f
NC
27340/* Perform target specific initialisation of a frag.
27341 Note - despite the name this initialisation is not done when the frag
27342 is created, but only when its type is assigned. A frag can be created
27343 and used a long time before its type is set, so beware of assuming that
33eaf5de 27344 this initialisation is performed first. */
bfae80f2 27345
cd000bff
DJ
27346#ifndef OBJ_ELF
27347void
27348arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
27349{
27350 /* Record whether this frag is in an ARM or a THUMB area. */
2e98972e 27351 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
cd000bff
DJ
27352}
27353
27354#else /* OBJ_ELF is defined. */
c19d1205 27355void
cd000bff 27356arm_init_frag (fragS * fragP, int max_chars)
c19d1205 27357{
e8d84ca1 27358 bfd_boolean frag_thumb_mode;
b968d18a 27359
8dc2430f
NC
27360 /* If the current ARM vs THUMB mode has not already
27361 been recorded into this frag then do so now. */
cd000bff 27362 if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
b968d18a
JW
27363 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
27364
e8d84ca1
NC
27365 /* PR 21809: Do not set a mapping state for debug sections
27366 - it just confuses other tools. */
fd361982 27367 if (bfd_section_flags (now_seg) & SEC_DEBUGGING)
e8d84ca1
NC
27368 return;
27369
b968d18a 27370 frag_thumb_mode = fragP->tc_frag_data.thumb_mode ^ MODE_RECORDED;
cd000bff 27371
f9c1b181
RL
27372 /* Record a mapping symbol for alignment frags. We will delete this
27373 later if the alignment ends up empty. */
27374 switch (fragP->fr_type)
27375 {
27376 case rs_align:
27377 case rs_align_test:
27378 case rs_fill:
27379 mapping_state_2 (MAP_DATA, max_chars);
27380 break;
27381 case rs_align_code:
b968d18a 27382 mapping_state_2 (frag_thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
f9c1b181
RL
27383 break;
27384 default:
27385 break;
cd000bff 27386 }
bfae80f2
RE
27387}
27388
c19d1205
ZW
27389/* When we change sections we need to issue a new mapping symbol. */
27390
27391void
27392arm_elf_change_section (void)
bfae80f2 27393{
c19d1205
ZW
27394 /* Link an unlinked unwind index table section to the .text section. */
27395 if (elf_section_type (now_seg) == SHT_ARM_EXIDX
27396 && elf_linked_to_section (now_seg) == NULL)
27397 elf_linked_to_section (now_seg) = text_section;
bfae80f2
RE
27398}
27399
c19d1205
ZW
27400int
27401arm_elf_section_type (const char * str, size_t len)
e45d0630 27402{
c19d1205
ZW
27403 if (len == 5 && strncmp (str, "exidx", 5) == 0)
27404 return SHT_ARM_EXIDX;
e45d0630 27405
c19d1205
ZW
27406 return -1;
27407}
27408\f
27409/* Code to deal with unwinding tables. */
e45d0630 27410
c19d1205 27411static void add_unwind_adjustsp (offsetT);
e45d0630 27412
5f4273c7 27413/* Generate any deferred unwind frame offset. */
e45d0630 27414
bfae80f2 27415static void
c19d1205 27416flush_pending_unwind (void)
bfae80f2 27417{
c19d1205 27418 offsetT offset;
bfae80f2 27419
c19d1205
ZW
27420 offset = unwind.pending_offset;
27421 unwind.pending_offset = 0;
27422 if (offset != 0)
27423 add_unwind_adjustsp (offset);
bfae80f2
RE
27424}
27425
c19d1205
ZW
27426/* Add an opcode to this list for this function. Two-byte opcodes should
27427 be passed as op[0] << 8 | op[1]. The list of opcodes is built in reverse
27428 order. */
27429
bfae80f2 27430static void
c19d1205 27431add_unwind_opcode (valueT op, int length)
bfae80f2 27432{
c19d1205
ZW
27433 /* Add any deferred stack adjustment. */
27434 if (unwind.pending_offset)
27435 flush_pending_unwind ();
bfae80f2 27436
c19d1205 27437 unwind.sp_restored = 0;
bfae80f2 27438
c19d1205 27439 if (unwind.opcode_count + length > unwind.opcode_alloc)
bfae80f2 27440 {
c19d1205
ZW
27441 unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
27442 if (unwind.opcodes)
325801bd
TS
27443 unwind.opcodes = XRESIZEVEC (unsigned char, unwind.opcodes,
27444 unwind.opcode_alloc);
c19d1205 27445 else
325801bd 27446 unwind.opcodes = XNEWVEC (unsigned char, unwind.opcode_alloc);
bfae80f2 27447 }
c19d1205 27448 while (length > 0)
bfae80f2 27449 {
c19d1205
ZW
27450 length--;
27451 unwind.opcodes[unwind.opcode_count] = op & 0xff;
27452 op >>= 8;
27453 unwind.opcode_count++;
bfae80f2 27454 }
bfae80f2
RE
27455}
27456
c19d1205
ZW
27457/* Add unwind opcodes to adjust the stack pointer. */
27458
bfae80f2 27459static void
c19d1205 27460add_unwind_adjustsp (offsetT offset)
bfae80f2 27461{
c19d1205 27462 valueT op;
bfae80f2 27463
c19d1205 27464 if (offset > 0x200)
bfae80f2 27465 {
c19d1205
ZW
27466 /* We need at most 5 bytes to hold a 32-bit value in a uleb128. */
27467 char bytes[5];
27468 int n;
27469 valueT o;
bfae80f2 27470
c19d1205
ZW
27471 /* Long form: 0xb2, uleb128. */
27472 /* This might not fit in a word so add the individual bytes,
27473 remembering the list is built in reverse order. */
27474 o = (valueT) ((offset - 0x204) >> 2);
27475 if (o == 0)
27476 add_unwind_opcode (0, 1);
bfae80f2 27477
c19d1205
ZW
27478 /* Calculate the uleb128 encoding of the offset. */
27479 n = 0;
27480 while (o)
27481 {
27482 bytes[n] = o & 0x7f;
27483 o >>= 7;
27484 if (o)
27485 bytes[n] |= 0x80;
27486 n++;
27487 }
27488 /* Add the insn. */
27489 for (; n; n--)
27490 add_unwind_opcode (bytes[n - 1], 1);
27491 add_unwind_opcode (0xb2, 1);
27492 }
27493 else if (offset > 0x100)
bfae80f2 27494 {
c19d1205
ZW
27495 /* Two short opcodes. */
27496 add_unwind_opcode (0x3f, 1);
27497 op = (offset - 0x104) >> 2;
27498 add_unwind_opcode (op, 1);
bfae80f2 27499 }
c19d1205
ZW
27500 else if (offset > 0)
27501 {
27502 /* Short opcode. */
27503 op = (offset - 4) >> 2;
27504 add_unwind_opcode (op, 1);
27505 }
27506 else if (offset < 0)
bfae80f2 27507 {
c19d1205
ZW
27508 offset = -offset;
27509 while (offset > 0x100)
bfae80f2 27510 {
c19d1205
ZW
27511 add_unwind_opcode (0x7f, 1);
27512 offset -= 0x100;
bfae80f2 27513 }
c19d1205
ZW
27514 op = ((offset - 4) >> 2) | 0x40;
27515 add_unwind_opcode (op, 1);
bfae80f2 27516 }
bfae80f2
RE
27517}
27518
c19d1205 27519/* Finish the list of unwind opcodes for this function. */
0198d5e6 27520
c19d1205
ZW
27521static void
27522finish_unwind_opcodes (void)
bfae80f2 27523{
c19d1205 27524 valueT op;
bfae80f2 27525
c19d1205 27526 if (unwind.fp_used)
bfae80f2 27527 {
708587a4 27528 /* Adjust sp as necessary. */
c19d1205
ZW
27529 unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
27530 flush_pending_unwind ();
bfae80f2 27531
c19d1205
ZW
27532 /* After restoring sp from the frame pointer. */
27533 op = 0x90 | unwind.fp_reg;
27534 add_unwind_opcode (op, 1);
27535 }
27536 else
27537 flush_pending_unwind ();
bfae80f2
RE
27538}
27539
bfae80f2 27540
c19d1205
ZW
27541/* Start an exception table entry. If idx is nonzero this is an index table
27542 entry. */
bfae80f2
RE
27543
27544static void
c19d1205 27545start_unwind_section (const segT text_seg, int idx)
bfae80f2 27546{
c19d1205
ZW
27547 const char * text_name;
27548 const char * prefix;
27549 const char * prefix_once;
a8c4d40b 27550 struct elf_section_match match;
c19d1205 27551 char * sec_name;
c19d1205
ZW
27552 int type;
27553 int flags;
27554 int linkonce;
bfae80f2 27555
c19d1205 27556 if (idx)
bfae80f2 27557 {
c19d1205
ZW
27558 prefix = ELF_STRING_ARM_unwind;
27559 prefix_once = ELF_STRING_ARM_unwind_once;
27560 type = SHT_ARM_EXIDX;
bfae80f2 27561 }
c19d1205 27562 else
bfae80f2 27563 {
c19d1205
ZW
27564 prefix = ELF_STRING_ARM_unwind_info;
27565 prefix_once = ELF_STRING_ARM_unwind_info_once;
27566 type = SHT_PROGBITS;
bfae80f2
RE
27567 }
27568
c19d1205
ZW
27569 text_name = segment_name (text_seg);
27570 if (streq (text_name, ".text"))
27571 text_name = "";
27572
27573 if (strncmp (text_name, ".gnu.linkonce.t.",
27574 strlen (".gnu.linkonce.t.")) == 0)
bfae80f2 27575 {
c19d1205
ZW
27576 prefix = prefix_once;
27577 text_name += strlen (".gnu.linkonce.t.");
bfae80f2
RE
27578 }
27579
29a2809e 27580 sec_name = concat (prefix, text_name, (char *) NULL);
bfae80f2 27581
c19d1205
ZW
27582 flags = SHF_ALLOC;
27583 linkonce = 0;
a8c4d40b 27584 memset (&match, 0, sizeof (match));
bfae80f2 27585
c19d1205
ZW
27586 /* Handle COMDAT group. */
27587 if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
bfae80f2 27588 {
a8c4d40b
L
27589 match.group_name = elf_group_name (text_seg);
27590 if (match.group_name == NULL)
c19d1205 27591 {
bd3ba5d1 27592 as_bad (_("Group section `%s' has no group signature"),
c19d1205
ZW
27593 segment_name (text_seg));
27594 ignore_rest_of_line ();
27595 return;
27596 }
27597 flags |= SHF_GROUP;
27598 linkonce = 1;
bfae80f2
RE
27599 }
27600
a8c4d40b 27601 obj_elf_change_section (sec_name, type, flags, 0, &match,
a91e1603 27602 linkonce, 0);
bfae80f2 27603
5f4273c7 27604 /* Set the section link for index tables. */
c19d1205
ZW
27605 if (idx)
27606 elf_linked_to_section (now_seg) = text_seg;
bfae80f2
RE
27607}
27608
bfae80f2 27609
c19d1205
ZW
27610/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
27611 personality routine data. Returns zero, or the index table value for
cad0da33 27612 an inline entry. */
c19d1205
ZW
27613
27614static valueT
27615create_unwind_entry (int have_data)
bfae80f2 27616{
c19d1205
ZW
27617 int size;
27618 addressT where;
27619 char *ptr;
27620 /* The current word of data. */
27621 valueT data;
27622 /* The number of bytes left in this word. */
27623 int n;
bfae80f2 27624
c19d1205 27625 finish_unwind_opcodes ();
bfae80f2 27626
c19d1205
ZW
27627 /* Remember the current text section. */
27628 unwind.saved_seg = now_seg;
27629 unwind.saved_subseg = now_subseg;
bfae80f2 27630
c19d1205 27631 start_unwind_section (now_seg, 0);
bfae80f2 27632
c19d1205 27633 if (unwind.personality_routine == NULL)
bfae80f2 27634 {
c19d1205
ZW
27635 if (unwind.personality_index == -2)
27636 {
27637 if (have_data)
5f4273c7 27638 as_bad (_("handlerdata in cantunwind frame"));
c19d1205
ZW
27639 return 1; /* EXIDX_CANTUNWIND. */
27640 }
bfae80f2 27641
c19d1205
ZW
27642 /* Use a default personality routine if none is specified. */
27643 if (unwind.personality_index == -1)
27644 {
27645 if (unwind.opcode_count > 3)
27646 unwind.personality_index = 1;
27647 else
27648 unwind.personality_index = 0;
27649 }
bfae80f2 27650
c19d1205
ZW
27651 /* Space for the personality routine entry. */
27652 if (unwind.personality_index == 0)
27653 {
27654 if (unwind.opcode_count > 3)
27655 as_bad (_("too many unwind opcodes for personality routine 0"));
bfae80f2 27656
c19d1205
ZW
27657 if (!have_data)
27658 {
27659 /* All the data is inline in the index table. */
27660 data = 0x80;
27661 n = 3;
27662 while (unwind.opcode_count > 0)
27663 {
27664 unwind.opcode_count--;
27665 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
27666 n--;
27667 }
bfae80f2 27668
c19d1205
ZW
27669 /* Pad with "finish" opcodes. */
27670 while (n--)
27671 data = (data << 8) | 0xb0;
bfae80f2 27672
c19d1205
ZW
27673 return data;
27674 }
27675 size = 0;
27676 }
27677 else
27678 /* We get two opcodes "free" in the first word. */
27679 size = unwind.opcode_count - 2;
27680 }
27681 else
5011093d 27682 {
cad0da33
NC
27683 /* PR 16765: Missing or misplaced unwind directives can trigger this. */
27684 if (unwind.personality_index != -1)
27685 {
27686 as_bad (_("attempt to recreate an unwind entry"));
27687 return 1;
27688 }
5011093d
NC
27689
27690 /* An extra byte is required for the opcode count. */
27691 size = unwind.opcode_count + 1;
27692 }
bfae80f2 27693
c19d1205
ZW
27694 size = (size + 3) >> 2;
27695 if (size > 0xff)
27696 as_bad (_("too many unwind opcodes"));
bfae80f2 27697
c19d1205
ZW
27698 frag_align (2, 0, 0);
27699 record_alignment (now_seg, 2);
27700 unwind.table_entry = expr_build_dot ();
27701
27702 /* Allocate the table entry. */
27703 ptr = frag_more ((size << 2) + 4);
74929e7b
NC
27704 /* PR 13449: Zero the table entries in case some of them are not used. */
27705 memset (ptr, 0, (size << 2) + 4);
c19d1205 27706 where = frag_now_fix () - ((size << 2) + 4);
bfae80f2 27707
c19d1205 27708 switch (unwind.personality_index)
bfae80f2 27709 {
c19d1205
ZW
27710 case -1:
27711 /* ??? Should this be a PLT generating relocation? */
27712 /* Custom personality routine. */
27713 fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
27714 BFD_RELOC_ARM_PREL31);
bfae80f2 27715
c19d1205
ZW
27716 where += 4;
27717 ptr += 4;
bfae80f2 27718
c19d1205 27719 /* Set the first byte to the number of additional words. */
5011093d 27720 data = size > 0 ? size - 1 : 0;
c19d1205
ZW
27721 n = 3;
27722 break;
bfae80f2 27723
c19d1205
ZW
27724 /* ABI defined personality routines. */
27725 case 0:
27726 /* Three opcodes bytes are packed into the first word. */
27727 data = 0x80;
27728 n = 3;
27729 break;
bfae80f2 27730
c19d1205
ZW
27731 case 1:
27732 case 2:
27733 /* The size and first two opcode bytes go in the first word. */
27734 data = ((0x80 + unwind.personality_index) << 8) | size;
27735 n = 2;
27736 break;
bfae80f2 27737
c19d1205
ZW
27738 default:
27739 /* Should never happen. */
27740 abort ();
27741 }
bfae80f2 27742
c19d1205
ZW
27743 /* Pack the opcodes into words (MSB first), reversing the list at the same
27744 time. */
27745 while (unwind.opcode_count > 0)
27746 {
27747 if (n == 0)
27748 {
27749 md_number_to_chars (ptr, data, 4);
27750 ptr += 4;
27751 n = 4;
27752 data = 0;
27753 }
27754 unwind.opcode_count--;
27755 n--;
27756 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
27757 }
27758
27759 /* Finish off the last word. */
27760 if (n < 4)
27761 {
27762 /* Pad with "finish" opcodes. */
27763 while (n--)
27764 data = (data << 8) | 0xb0;
27765
27766 md_number_to_chars (ptr, data, 4);
27767 }
27768
27769 if (!have_data)
27770 {
27771 /* Add an empty descriptor if there is no user-specified data. */
27772 ptr = frag_more (4);
27773 md_number_to_chars (ptr, 0, 4);
27774 }
27775
27776 return 0;
bfae80f2
RE
27777}
27778
f0927246
NC
27779
27780/* Initialize the DWARF-2 unwind information for this procedure. */
27781
27782void
27783tc_arm_frame_initial_instructions (void)
27784{
27785 cfi_add_CFA_def_cfa (REG_SP, 0);
27786}
27787#endif /* OBJ_ELF */
27788
c19d1205
ZW
27789/* Convert REGNAME to a DWARF-2 register number. */
27790
27791int
1df69f4f 27792tc_arm_regname_to_dw2regnum (char *regname)
bfae80f2 27793{
1df69f4f 27794 int reg = arm_reg_parse (&regname, REG_TYPE_RN);
1f5afe1c
NC
27795 if (reg != FAIL)
27796 return reg;
c19d1205 27797
1f5afe1c
NC
27798 /* PR 16694: Allow VFP registers as well. */
27799 reg = arm_reg_parse (&regname, REG_TYPE_VFS);
27800 if (reg != FAIL)
27801 return 64 + reg;
c19d1205 27802
1f5afe1c
NC
27803 reg = arm_reg_parse (&regname, REG_TYPE_VFD);
27804 if (reg != FAIL)
27805 return reg + 256;
27806
0198d5e6 27807 return FAIL;
bfae80f2
RE
27808}
27809
f0927246 27810#ifdef TE_PE
c19d1205 27811void
f0927246 27812tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
bfae80f2 27813{
91d6fa6a 27814 expressionS exp;
bfae80f2 27815
91d6fa6a
NC
27816 exp.X_op = O_secrel;
27817 exp.X_add_symbol = symbol;
27818 exp.X_add_number = 0;
27819 emit_expr (&exp, size);
f0927246
NC
27820}
27821#endif
bfae80f2 27822
c19d1205 27823/* MD interface: Symbol and relocation handling. */
bfae80f2 27824
2fc8bdac
ZW
27825/* Return the address within the segment that a PC-relative fixup is
27826 relative to. For ARM, PC-relative fixups applied to instructions
27827 are generally relative to the location of the fixup plus 8 bytes.
27828 Thumb branches are offset by 4, and Thumb loads relative to PC
27829 require special handling. */
bfae80f2 27830
c19d1205 27831long
2fc8bdac 27832md_pcrel_from_section (fixS * fixP, segT seg)
bfae80f2 27833{
2fc8bdac
ZW
27834 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
27835
27836 /* If this is pc-relative and we are going to emit a relocation
27837 then we just want to put out any pipeline compensation that the linker
53baae48
NC
27838 will need. Otherwise we want to use the calculated base.
27839 For WinCE we skip the bias for externals as well, since this
27840 is how the MS ARM-CE assembler behaves and we want to be compatible. */
5f4273c7 27841 if (fixP->fx_pcrel
2fc8bdac 27842 && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
53baae48
NC
27843 || (arm_force_relocation (fixP)
27844#ifdef TE_WINCE
27845 && !S_IS_EXTERNAL (fixP->fx_addsy)
27846#endif
27847 )))
2fc8bdac 27848 base = 0;
bfae80f2 27849
267bf995 27850
c19d1205 27851 switch (fixP->fx_r_type)
bfae80f2 27852 {
2fc8bdac
ZW
27853 /* PC relative addressing on the Thumb is slightly odd as the
27854 bottom two bits of the PC are forced to zero for the
27855 calculation. This happens *after* application of the
27856 pipeline offset. However, Thumb adrl already adjusts for
27857 this, so we need not do it again. */
c19d1205 27858 case BFD_RELOC_ARM_THUMB_ADD:
2fc8bdac 27859 return base & ~3;
c19d1205
ZW
27860
27861 case BFD_RELOC_ARM_THUMB_OFFSET:
27862 case BFD_RELOC_ARM_T32_OFFSET_IMM:
e9f89963 27863 case BFD_RELOC_ARM_T32_ADD_PC12:
8f06b2d8 27864 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
2fc8bdac 27865 return (base + 4) & ~3;
c19d1205 27866
2fc8bdac 27867 /* Thumb branches are simply offset by +4. */
e12437dc 27868 case BFD_RELOC_THUMB_PCREL_BRANCH5:
2fc8bdac
ZW
27869 case BFD_RELOC_THUMB_PCREL_BRANCH7:
27870 case BFD_RELOC_THUMB_PCREL_BRANCH9:
27871 case BFD_RELOC_THUMB_PCREL_BRANCH12:
27872 case BFD_RELOC_THUMB_PCREL_BRANCH20:
2fc8bdac 27873 case BFD_RELOC_THUMB_PCREL_BRANCH25:
f6b2b12d 27874 case BFD_RELOC_THUMB_PCREL_BFCSEL:
e5d6e09e 27875 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 27876 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 27877 case BFD_RELOC_ARM_THUMB_BF13:
60f993ce 27878 case BFD_RELOC_ARM_THUMB_LOOP12:
2fc8bdac 27879 return base + 4;
bfae80f2 27880
267bf995 27881 case BFD_RELOC_THUMB_PCREL_BRANCH23:
486499d0
CL
27882 if (fixP->fx_addsy
27883 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 27884 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995 27885 && ARM_IS_FUNC (fixP->fx_addsy)
477330fc
RM
27886 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
27887 base = fixP->fx_where + fixP->fx_frag->fr_address;
267bf995
RR
27888 return base + 4;
27889
00adf2d4
JB
27890 /* BLX is like branches above, but forces the low two bits of PC to
27891 zero. */
486499d0
CL
27892 case BFD_RELOC_THUMB_PCREL_BLX:
27893 if (fixP->fx_addsy
27894 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 27895 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
27896 && THUMB_IS_FUNC (fixP->fx_addsy)
27897 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
27898 base = fixP->fx_where + fixP->fx_frag->fr_address;
00adf2d4
JB
27899 return (base + 4) & ~3;
27900
2fc8bdac
ZW
27901 /* ARM mode branches are offset by +8. However, the Windows CE
27902 loader expects the relocation not to take this into account. */
267bf995 27903 case BFD_RELOC_ARM_PCREL_BLX:
486499d0
CL
27904 if (fixP->fx_addsy
27905 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 27906 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
27907 && ARM_IS_FUNC (fixP->fx_addsy)
27908 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
27909 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 27910 return base + 8;
267bf995 27911
486499d0
CL
27912 case BFD_RELOC_ARM_PCREL_CALL:
27913 if (fixP->fx_addsy
27914 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 27915 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
27916 && THUMB_IS_FUNC (fixP->fx_addsy)
27917 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
27918 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 27919 return base + 8;
267bf995 27920
2fc8bdac 27921 case BFD_RELOC_ARM_PCREL_BRANCH:
39b41c9c 27922 case BFD_RELOC_ARM_PCREL_JUMP:
2fc8bdac 27923 case BFD_RELOC_ARM_PLT32:
c19d1205 27924#ifdef TE_WINCE
5f4273c7 27925 /* When handling fixups immediately, because we have already
477330fc 27926 discovered the value of a symbol, or the address of the frag involved
53baae48 27927 we must account for the offset by +8, as the OS loader will never see the reloc.
477330fc
RM
27928 see fixup_segment() in write.c
27929 The S_IS_EXTERNAL test handles the case of global symbols.
27930 Those need the calculated base, not just the pipe compensation the linker will need. */
53baae48
NC
27931 if (fixP->fx_pcrel
27932 && fixP->fx_addsy != NULL
27933 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27934 && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP)))
27935 return base + 8;
2fc8bdac 27936 return base;
c19d1205 27937#else
2fc8bdac 27938 return base + 8;
c19d1205 27939#endif
2fc8bdac 27940
267bf995 27941
2fc8bdac
ZW
27942 /* ARM mode loads relative to PC are also offset by +8. Unlike
27943 branches, the Windows CE loader *does* expect the relocation
27944 to take this into account. */
27945 case BFD_RELOC_ARM_OFFSET_IMM:
27946 case BFD_RELOC_ARM_OFFSET_IMM8:
27947 case BFD_RELOC_ARM_HWLITERAL:
27948 case BFD_RELOC_ARM_LITERAL:
27949 case BFD_RELOC_ARM_CP_OFF_IMM:
27950 return base + 8;
27951
27952
27953 /* Other PC-relative relocations are un-offset. */
27954 default:
27955 return base;
27956 }
bfae80f2
RE
27957}
27958
8b2d793c
NC
27959static bfd_boolean flag_warn_syms = TRUE;
27960
ae8714c2
NC
27961bfd_boolean
27962arm_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char * name)
bfae80f2 27963{
8b2d793c
NC
27964 /* PR 18347 - Warn if the user attempts to create a symbol with the same
27965 name as an ARM instruction. Whilst strictly speaking it is allowed, it
27966 does mean that the resulting code might be very confusing to the reader.
27967 Also this warning can be triggered if the user omits an operand before
27968 an immediate address, eg:
27969
27970 LDR =foo
27971
27972 GAS treats this as an assignment of the value of the symbol foo to a
27973 symbol LDR, and so (without this code) it will not issue any kind of
27974 warning or error message.
27975
27976 Note - ARM instructions are case-insensitive but the strings in the hash
27977 table are all stored in lower case, so we must first ensure that name is
ae8714c2
NC
27978 lower case too. */
27979 if (flag_warn_syms && arm_ops_hsh)
8b2d793c
NC
27980 {
27981 char * nbuf = strdup (name);
27982 char * p;
27983
27984 for (p = nbuf; *p; p++)
27985 *p = TOLOWER (*p);
27986 if (hash_find (arm_ops_hsh, nbuf) != NULL)
27987 {
27988 static struct hash_control * already_warned = NULL;
27989
27990 if (already_warned == NULL)
27991 already_warned = hash_new ();
27992 /* Only warn about the symbol once. To keep the code
27993 simple we let hash_insert do the lookup for us. */
3076e594 27994 if (hash_insert (already_warned, nbuf, NULL) == NULL)
ae8714c2 27995 as_warn (_("[-mwarn-syms]: Assignment makes a symbol match an ARM instruction: %s"), name);
8b2d793c
NC
27996 }
27997 else
27998 free (nbuf);
27999 }
3739860c 28000
ae8714c2
NC
28001 return FALSE;
28002}
28003
28004/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
28005 Otherwise we have no need to default values of symbols. */
28006
28007symbolS *
28008md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
28009{
28010#ifdef OBJ_ELF
28011 if (name[0] == '_' && name[1] == 'G'
28012 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
28013 {
28014 if (!GOT_symbol)
28015 {
28016 if (symbol_find (name))
28017 as_bad (_("GOT already in the symbol table"));
28018
28019 GOT_symbol = symbol_new (name, undefined_section,
28020 (valueT) 0, & zero_address_frag);
28021 }
28022
28023 return GOT_symbol;
28024 }
28025#endif
28026
c921be7d 28027 return NULL;
bfae80f2
RE
28028}
28029
55cf6793 28030/* Subroutine of md_apply_fix. Check to see if an immediate can be
c19d1205
ZW
28031 computed as two separate immediate values, added together. We
28032 already know that this value cannot be computed by just one ARM
28033 instruction. */
28034
28035static unsigned int
28036validate_immediate_twopart (unsigned int val,
28037 unsigned int * highpart)
bfae80f2 28038{
c19d1205
ZW
28039 unsigned int a;
28040 unsigned int i;
bfae80f2 28041
c19d1205
ZW
28042 for (i = 0; i < 32; i += 2)
28043 if (((a = rotate_left (val, i)) & 0xff) != 0)
28044 {
28045 if (a & 0xff00)
28046 {
28047 if (a & ~ 0xffff)
28048 continue;
28049 * highpart = (a >> 8) | ((i + 24) << 7);
28050 }
28051 else if (a & 0xff0000)
28052 {
28053 if (a & 0xff000000)
28054 continue;
28055 * highpart = (a >> 16) | ((i + 16) << 7);
28056 }
28057 else
28058 {
9c2799c2 28059 gas_assert (a & 0xff000000);
c19d1205
ZW
28060 * highpart = (a >> 24) | ((i + 8) << 7);
28061 }
bfae80f2 28062
c19d1205
ZW
28063 return (a & 0xff) | (i << 7);
28064 }
bfae80f2 28065
c19d1205 28066 return FAIL;
bfae80f2
RE
28067}
28068
c19d1205
ZW
28069static int
28070validate_offset_imm (unsigned int val, int hwse)
28071{
28072 if ((hwse && val > 255) || val > 4095)
28073 return FAIL;
28074 return val;
28075}
bfae80f2 28076
55cf6793 28077/* Subroutine of md_apply_fix. Do those data_ops which can take a
c19d1205
ZW
28078 negative immediate constant by altering the instruction. A bit of
28079 a hack really.
28080 MOV <-> MVN
28081 AND <-> BIC
28082 ADC <-> SBC
28083 by inverting the second operand, and
28084 ADD <-> SUB
28085 CMP <-> CMN
28086 by negating the second operand. */
bfae80f2 28087
c19d1205
ZW
28088static int
28089negate_data_op (unsigned long * instruction,
28090 unsigned long value)
bfae80f2 28091{
c19d1205
ZW
28092 int op, new_inst;
28093 unsigned long negated, inverted;
bfae80f2 28094
c19d1205
ZW
28095 negated = encode_arm_immediate (-value);
28096 inverted = encode_arm_immediate (~value);
bfae80f2 28097
c19d1205
ZW
28098 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
28099 switch (op)
bfae80f2 28100 {
c19d1205
ZW
28101 /* First negates. */
28102 case OPCODE_SUB: /* ADD <-> SUB */
28103 new_inst = OPCODE_ADD;
28104 value = negated;
28105 break;
bfae80f2 28106
c19d1205
ZW
28107 case OPCODE_ADD:
28108 new_inst = OPCODE_SUB;
28109 value = negated;
28110 break;
bfae80f2 28111
c19d1205
ZW
28112 case OPCODE_CMP: /* CMP <-> CMN */
28113 new_inst = OPCODE_CMN;
28114 value = negated;
28115 break;
bfae80f2 28116
c19d1205
ZW
28117 case OPCODE_CMN:
28118 new_inst = OPCODE_CMP;
28119 value = negated;
28120 break;
bfae80f2 28121
c19d1205
ZW
28122 /* Now Inverted ops. */
28123 case OPCODE_MOV: /* MOV <-> MVN */
28124 new_inst = OPCODE_MVN;
28125 value = inverted;
28126 break;
bfae80f2 28127
c19d1205
ZW
28128 case OPCODE_MVN:
28129 new_inst = OPCODE_MOV;
28130 value = inverted;
28131 break;
bfae80f2 28132
c19d1205
ZW
28133 case OPCODE_AND: /* AND <-> BIC */
28134 new_inst = OPCODE_BIC;
28135 value = inverted;
28136 break;
bfae80f2 28137
c19d1205
ZW
28138 case OPCODE_BIC:
28139 new_inst = OPCODE_AND;
28140 value = inverted;
28141 break;
bfae80f2 28142
c19d1205
ZW
28143 case OPCODE_ADC: /* ADC <-> SBC */
28144 new_inst = OPCODE_SBC;
28145 value = inverted;
28146 break;
bfae80f2 28147
c19d1205
ZW
28148 case OPCODE_SBC:
28149 new_inst = OPCODE_ADC;
28150 value = inverted;
28151 break;
bfae80f2 28152
c19d1205
ZW
28153 /* We cannot do anything. */
28154 default:
28155 return FAIL;
b99bd4ef
NC
28156 }
28157
c19d1205
ZW
28158 if (value == (unsigned) FAIL)
28159 return FAIL;
28160
28161 *instruction &= OPCODE_MASK;
28162 *instruction |= new_inst << DATA_OP_SHIFT;
28163 return value;
b99bd4ef
NC
28164}
28165
ef8d22e6
PB
28166/* Like negate_data_op, but for Thumb-2. */
28167
28168static unsigned int
16dd5e42 28169thumb32_negate_data_op (offsetT *instruction, unsigned int value)
ef8d22e6
PB
28170{
28171 int op, new_inst;
28172 int rd;
16dd5e42 28173 unsigned int negated, inverted;
ef8d22e6
PB
28174
28175 negated = encode_thumb32_immediate (-value);
28176 inverted = encode_thumb32_immediate (~value);
28177
28178 rd = (*instruction >> 8) & 0xf;
28179 op = (*instruction >> T2_DATA_OP_SHIFT) & 0xf;
28180 switch (op)
28181 {
28182 /* ADD <-> SUB. Includes CMP <-> CMN. */
28183 case T2_OPCODE_SUB:
28184 new_inst = T2_OPCODE_ADD;
28185 value = negated;
28186 break;
28187
28188 case T2_OPCODE_ADD:
28189 new_inst = T2_OPCODE_SUB;
28190 value = negated;
28191 break;
28192
28193 /* ORR <-> ORN. Includes MOV <-> MVN. */
28194 case T2_OPCODE_ORR:
28195 new_inst = T2_OPCODE_ORN;
28196 value = inverted;
28197 break;
28198
28199 case T2_OPCODE_ORN:
28200 new_inst = T2_OPCODE_ORR;
28201 value = inverted;
28202 break;
28203
28204 /* AND <-> BIC. TST has no inverted equivalent. */
28205 case T2_OPCODE_AND:
28206 new_inst = T2_OPCODE_BIC;
28207 if (rd == 15)
28208 value = FAIL;
28209 else
28210 value = inverted;
28211 break;
28212
28213 case T2_OPCODE_BIC:
28214 new_inst = T2_OPCODE_AND;
28215 value = inverted;
28216 break;
28217
28218 /* ADC <-> SBC */
28219 case T2_OPCODE_ADC:
28220 new_inst = T2_OPCODE_SBC;
28221 value = inverted;
28222 break;
28223
28224 case T2_OPCODE_SBC:
28225 new_inst = T2_OPCODE_ADC;
28226 value = inverted;
28227 break;
28228
28229 /* We cannot do anything. */
28230 default:
28231 return FAIL;
28232 }
28233
16dd5e42 28234 if (value == (unsigned int)FAIL)
ef8d22e6
PB
28235 return FAIL;
28236
28237 *instruction &= T2_OPCODE_MASK;
28238 *instruction |= new_inst << T2_DATA_OP_SHIFT;
28239 return value;
28240}
28241
8f06b2d8 28242/* Read a 32-bit thumb instruction from buf. */
0198d5e6 28243
8f06b2d8
PB
28244static unsigned long
28245get_thumb32_insn (char * buf)
28246{
28247 unsigned long insn;
28248 insn = md_chars_to_number (buf, THUMB_SIZE) << 16;
28249 insn |= md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28250
28251 return insn;
28252}
28253
a8bc6c78
PB
28254/* We usually want to set the low bit on the address of thumb function
28255 symbols. In particular .word foo - . should have the low bit set.
28256 Generic code tries to fold the difference of two symbols to
28257 a constant. Prevent this and force a relocation when the first symbols
28258 is a thumb function. */
c921be7d
NC
28259
28260bfd_boolean
a8bc6c78
PB
28261arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
28262{
28263 if (op == O_subtract
28264 && l->X_op == O_symbol
28265 && r->X_op == O_symbol
28266 && THUMB_IS_FUNC (l->X_add_symbol))
28267 {
28268 l->X_op = O_subtract;
28269 l->X_op_symbol = r->X_add_symbol;
28270 l->X_add_number -= r->X_add_number;
c921be7d 28271 return TRUE;
a8bc6c78 28272 }
c921be7d 28273
a8bc6c78 28274 /* Process as normal. */
c921be7d 28275 return FALSE;
a8bc6c78
PB
28276}
28277
4a42ebbc
RR
28278/* Encode Thumb2 unconditional branches and calls. The encoding
28279 for the 2 are identical for the immediate values. */
28280
28281static void
28282encode_thumb2_b_bl_offset (char * buf, offsetT value)
28283{
28284#define T2I1I2MASK ((1 << 13) | (1 << 11))
28285 offsetT newval;
28286 offsetT newval2;
28287 addressT S, I1, I2, lo, hi;
28288
28289 S = (value >> 24) & 0x01;
28290 I1 = (value >> 23) & 0x01;
28291 I2 = (value >> 22) & 0x01;
28292 hi = (value >> 12) & 0x3ff;
fa94de6b 28293 lo = (value >> 1) & 0x7ff;
4a42ebbc
RR
28294 newval = md_chars_to_number (buf, THUMB_SIZE);
28295 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
28296 newval |= (S << 10) | hi;
28297 newval2 &= ~T2I1I2MASK;
28298 newval2 |= (((I1 ^ S) << 13) | ((I2 ^ S) << 11) | lo) ^ T2I1I2MASK;
28299 md_number_to_chars (buf, newval, THUMB_SIZE);
28300 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
28301}
28302
c19d1205 28303void
55cf6793 28304md_apply_fix (fixS * fixP,
c19d1205
ZW
28305 valueT * valP,
28306 segT seg)
28307{
28308 offsetT value = * valP;
28309 offsetT newval;
28310 unsigned int newimm;
28311 unsigned long temp;
28312 int sign;
28313 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
b99bd4ef 28314
9c2799c2 28315 gas_assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
b99bd4ef 28316
c19d1205 28317 /* Note whether this will delete the relocation. */
4962c51a 28318
c19d1205
ZW
28319 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
28320 fixP->fx_done = 1;
b99bd4ef 28321
adbaf948 28322 /* On a 64-bit host, silently truncate 'value' to 32 bits for
5f4273c7 28323 consistency with the behaviour on 32-bit hosts. Remember value
adbaf948
ZW
28324 for emit_reloc. */
28325 value &= 0xffffffff;
28326 value ^= 0x80000000;
5f4273c7 28327 value -= 0x80000000;
adbaf948
ZW
28328
28329 *valP = value;
c19d1205 28330 fixP->fx_addnumber = value;
b99bd4ef 28331
adbaf948
ZW
28332 /* Same treatment for fixP->fx_offset. */
28333 fixP->fx_offset &= 0xffffffff;
28334 fixP->fx_offset ^= 0x80000000;
28335 fixP->fx_offset -= 0x80000000;
28336
c19d1205 28337 switch (fixP->fx_r_type)
b99bd4ef 28338 {
c19d1205
ZW
28339 case BFD_RELOC_NONE:
28340 /* This will need to go in the object file. */
28341 fixP->fx_done = 0;
28342 break;
b99bd4ef 28343
c19d1205
ZW
28344 case BFD_RELOC_ARM_IMMEDIATE:
28345 /* We claim that this fixup has been processed here,
28346 even if in fact we generate an error because we do
28347 not have a reloc for it, so tc_gen_reloc will reject it. */
28348 fixP->fx_done = 1;
b99bd4ef 28349
77db8e2e 28350 if (fixP->fx_addsy)
b99bd4ef 28351 {
77db8e2e 28352 const char *msg = 0;
b99bd4ef 28353
77db8e2e
NC
28354 if (! S_IS_DEFINED (fixP->fx_addsy))
28355 msg = _("undefined symbol %s used as an immediate value");
28356 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
28357 msg = _("symbol %s is in a different section");
28358 else if (S_IS_WEAK (fixP->fx_addsy))
28359 msg = _("symbol %s is weak and may be overridden later");
28360
28361 if (msg)
28362 {
28363 as_bad_where (fixP->fx_file, fixP->fx_line,
28364 msg, S_GET_NAME (fixP->fx_addsy));
28365 break;
28366 }
42e5fcbf
AS
28367 }
28368
c19d1205
ZW
28369 temp = md_chars_to_number (buf, INSN_SIZE);
28370
5e73442d
SL
28371 /* If the offset is negative, we should use encoding A2 for ADR. */
28372 if ((temp & 0xfff0000) == 0x28f0000 && value < 0)
28373 newimm = negate_data_op (&temp, value);
28374 else
28375 {
28376 newimm = encode_arm_immediate (value);
28377
28378 /* If the instruction will fail, see if we can fix things up by
28379 changing the opcode. */
28380 if (newimm == (unsigned int) FAIL)
28381 newimm = negate_data_op (&temp, value);
bada4342
JW
28382 /* MOV accepts both ARM modified immediate (A1 encoding) and
28383 UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
28384 When disassembling, MOV is preferred when there is no encoding
28385 overlap. */
28386 if (newimm == (unsigned int) FAIL
28387 && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
28388 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
28389 && !((temp >> SBIT_SHIFT) & 0x1)
28390 && value >= 0 && value <= 0xffff)
28391 {
28392 /* Clear bits[23:20] to change encoding from A1 to A2. */
28393 temp &= 0xff0fffff;
28394 /* Encoding high 4bits imm. Code below will encode the remaining
28395 low 12bits. */
28396 temp |= (value & 0x0000f000) << 4;
28397 newimm = value & 0x00000fff;
28398 }
5e73442d
SL
28399 }
28400
28401 if (newimm == (unsigned int) FAIL)
b99bd4ef 28402 {
c19d1205
ZW
28403 as_bad_where (fixP->fx_file, fixP->fx_line,
28404 _("invalid constant (%lx) after fixup"),
28405 (unsigned long) value);
28406 break;
b99bd4ef 28407 }
b99bd4ef 28408
c19d1205
ZW
28409 newimm |= (temp & 0xfffff000);
28410 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
28411 break;
b99bd4ef 28412
c19d1205
ZW
28413 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
28414 {
28415 unsigned int highpart = 0;
28416 unsigned int newinsn = 0xe1a00000; /* nop. */
b99bd4ef 28417
77db8e2e 28418 if (fixP->fx_addsy)
42e5fcbf 28419 {
77db8e2e 28420 const char *msg = 0;
42e5fcbf 28421
77db8e2e
NC
28422 if (! S_IS_DEFINED (fixP->fx_addsy))
28423 msg = _("undefined symbol %s used as an immediate value");
28424 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
28425 msg = _("symbol %s is in a different section");
28426 else if (S_IS_WEAK (fixP->fx_addsy))
28427 msg = _("symbol %s is weak and may be overridden later");
42e5fcbf 28428
77db8e2e
NC
28429 if (msg)
28430 {
28431 as_bad_where (fixP->fx_file, fixP->fx_line,
28432 msg, S_GET_NAME (fixP->fx_addsy));
28433 break;
28434 }
28435 }
fa94de6b 28436
c19d1205
ZW
28437 newimm = encode_arm_immediate (value);
28438 temp = md_chars_to_number (buf, INSN_SIZE);
b99bd4ef 28439
c19d1205
ZW
28440 /* If the instruction will fail, see if we can fix things up by
28441 changing the opcode. */
28442 if (newimm == (unsigned int) FAIL
28443 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
28444 {
28445 /* No ? OK - try using two ADD instructions to generate
28446 the value. */
28447 newimm = validate_immediate_twopart (value, & highpart);
b99bd4ef 28448
c19d1205
ZW
28449 /* Yes - then make sure that the second instruction is
28450 also an add. */
28451 if (newimm != (unsigned int) FAIL)
28452 newinsn = temp;
28453 /* Still No ? Try using a negated value. */
28454 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
28455 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
28456 /* Otherwise - give up. */
28457 else
28458 {
28459 as_bad_where (fixP->fx_file, fixP->fx_line,
28460 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
28461 (long) value);
28462 break;
28463 }
b99bd4ef 28464
c19d1205
ZW
28465 /* Replace the first operand in the 2nd instruction (which
28466 is the PC) with the destination register. We have
28467 already added in the PC in the first instruction and we
28468 do not want to do it again. */
28469 newinsn &= ~ 0xf0000;
28470 newinsn |= ((newinsn & 0x0f000) << 4);
28471 }
b99bd4ef 28472
c19d1205
ZW
28473 newimm |= (temp & 0xfffff000);
28474 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
b99bd4ef 28475
c19d1205
ZW
28476 highpart |= (newinsn & 0xfffff000);
28477 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
28478 }
28479 break;
b99bd4ef 28480
c19d1205 28481 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
28482 if (!fixP->fx_done && seg->use_rela_p)
28483 value = 0;
1a0670f3 28484 /* Fall through. */
00a97672 28485
c19d1205 28486 case BFD_RELOC_ARM_LITERAL:
26d97720 28487 sign = value > 0;
b99bd4ef 28488
c19d1205
ZW
28489 if (value < 0)
28490 value = - value;
b99bd4ef 28491
c19d1205 28492 if (validate_offset_imm (value, 0) == FAIL)
f03698e6 28493 {
c19d1205
ZW
28494 if (fixP->fx_r_type == BFD_RELOC_ARM_LITERAL)
28495 as_bad_where (fixP->fx_file, fixP->fx_line,
28496 _("invalid literal constant: pool needs to be closer"));
28497 else
28498 as_bad_where (fixP->fx_file, fixP->fx_line,
28499 _("bad immediate value for offset (%ld)"),
28500 (long) value);
28501 break;
f03698e6
RE
28502 }
28503
c19d1205 28504 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
28505 if (value == 0)
28506 newval &= 0xfffff000;
28507 else
28508 {
28509 newval &= 0xff7ff000;
28510 newval |= value | (sign ? INDEX_UP : 0);
28511 }
c19d1205
ZW
28512 md_number_to_chars (buf, newval, INSN_SIZE);
28513 break;
b99bd4ef 28514
c19d1205
ZW
28515 case BFD_RELOC_ARM_OFFSET_IMM8:
28516 case BFD_RELOC_ARM_HWLITERAL:
26d97720 28517 sign = value > 0;
b99bd4ef 28518
c19d1205
ZW
28519 if (value < 0)
28520 value = - value;
b99bd4ef 28521
c19d1205 28522 if (validate_offset_imm (value, 1) == FAIL)
b99bd4ef 28523 {
c19d1205
ZW
28524 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
28525 as_bad_where (fixP->fx_file, fixP->fx_line,
28526 _("invalid literal constant: pool needs to be closer"));
28527 else
427d0db6
RM
28528 as_bad_where (fixP->fx_file, fixP->fx_line,
28529 _("bad immediate value for 8-bit offset (%ld)"),
28530 (long) value);
c19d1205 28531 break;
b99bd4ef
NC
28532 }
28533
c19d1205 28534 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
28535 if (value == 0)
28536 newval &= 0xfffff0f0;
28537 else
28538 {
28539 newval &= 0xff7ff0f0;
28540 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
28541 }
c19d1205
ZW
28542 md_number_to_chars (buf, newval, INSN_SIZE);
28543 break;
b99bd4ef 28544
c19d1205
ZW
28545 case BFD_RELOC_ARM_T32_OFFSET_U8:
28546 if (value < 0 || value > 1020 || value % 4 != 0)
28547 as_bad_where (fixP->fx_file, fixP->fx_line,
28548 _("bad immediate value for offset (%ld)"), (long) value);
28549 value /= 4;
b99bd4ef 28550
c19d1205 28551 newval = md_chars_to_number (buf+2, THUMB_SIZE);
c19d1205
ZW
28552 newval |= value;
28553 md_number_to_chars (buf+2, newval, THUMB_SIZE);
28554 break;
b99bd4ef 28555
c19d1205
ZW
28556 case BFD_RELOC_ARM_T32_OFFSET_IMM:
28557 /* This is a complicated relocation used for all varieties of Thumb32
28558 load/store instruction with immediate offset:
28559
28560 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
477330fc 28561 *4, optional writeback(W)
c19d1205
ZW
28562 (doubleword load/store)
28563
28564 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
28565 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
28566 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
28567 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
28568 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
28569
28570 Uppercase letters indicate bits that are already encoded at
28571 this point. Lowercase letters are our problem. For the
28572 second block of instructions, the secondary opcode nybble
28573 (bits 8..11) is present, and bit 23 is zero, even if this is
28574 a PC-relative operation. */
28575 newval = md_chars_to_number (buf, THUMB_SIZE);
28576 newval <<= 16;
28577 newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
b99bd4ef 28578
c19d1205 28579 if ((newval & 0xf0000000) == 0xe0000000)
b99bd4ef 28580 {
c19d1205
ZW
28581 /* Doubleword load/store: 8-bit offset, scaled by 4. */
28582 if (value >= 0)
28583 newval |= (1 << 23);
28584 else
28585 value = -value;
28586 if (value % 4 != 0)
28587 {
28588 as_bad_where (fixP->fx_file, fixP->fx_line,
28589 _("offset not a multiple of 4"));
28590 break;
28591 }
28592 value /= 4;
216d22bc 28593 if (value > 0xff)
c19d1205
ZW
28594 {
28595 as_bad_where (fixP->fx_file, fixP->fx_line,
28596 _("offset out of range"));
28597 break;
28598 }
28599 newval &= ~0xff;
b99bd4ef 28600 }
c19d1205 28601 else if ((newval & 0x000f0000) == 0x000f0000)
b99bd4ef 28602 {
c19d1205
ZW
28603 /* PC-relative, 12-bit offset. */
28604 if (value >= 0)
28605 newval |= (1 << 23);
28606 else
28607 value = -value;
216d22bc 28608 if (value > 0xfff)
c19d1205
ZW
28609 {
28610 as_bad_where (fixP->fx_file, fixP->fx_line,
28611 _("offset out of range"));
28612 break;
28613 }
28614 newval &= ~0xfff;
b99bd4ef 28615 }
c19d1205 28616 else if ((newval & 0x00000100) == 0x00000100)
b99bd4ef 28617 {
c19d1205
ZW
28618 /* Writeback: 8-bit, +/- offset. */
28619 if (value >= 0)
28620 newval |= (1 << 9);
28621 else
28622 value = -value;
216d22bc 28623 if (value > 0xff)
c19d1205
ZW
28624 {
28625 as_bad_where (fixP->fx_file, fixP->fx_line,
28626 _("offset out of range"));
28627 break;
28628 }
28629 newval &= ~0xff;
b99bd4ef 28630 }
c19d1205 28631 else if ((newval & 0x00000f00) == 0x00000e00)
b99bd4ef 28632 {
c19d1205 28633 /* T-instruction: positive 8-bit offset. */
216d22bc 28634 if (value < 0 || value > 0xff)
b99bd4ef 28635 {
c19d1205
ZW
28636 as_bad_where (fixP->fx_file, fixP->fx_line,
28637 _("offset out of range"));
28638 break;
b99bd4ef 28639 }
c19d1205
ZW
28640 newval &= ~0xff;
28641 newval |= value;
b99bd4ef
NC
28642 }
28643 else
b99bd4ef 28644 {
c19d1205
ZW
28645 /* Positive 12-bit or negative 8-bit offset. */
28646 int limit;
28647 if (value >= 0)
b99bd4ef 28648 {
c19d1205
ZW
28649 newval |= (1 << 23);
28650 limit = 0xfff;
28651 }
28652 else
28653 {
28654 value = -value;
28655 limit = 0xff;
28656 }
28657 if (value > limit)
28658 {
28659 as_bad_where (fixP->fx_file, fixP->fx_line,
28660 _("offset out of range"));
28661 break;
b99bd4ef 28662 }
c19d1205 28663 newval &= ~limit;
b99bd4ef 28664 }
b99bd4ef 28665
c19d1205
ZW
28666 newval |= value;
28667 md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
28668 md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
28669 break;
404ff6b5 28670
c19d1205
ZW
28671 case BFD_RELOC_ARM_SHIFT_IMM:
28672 newval = md_chars_to_number (buf, INSN_SIZE);
28673 if (((unsigned long) value) > 32
28674 || (value == 32
28675 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
28676 {
28677 as_bad_where (fixP->fx_file, fixP->fx_line,
28678 _("shift expression is too large"));
28679 break;
28680 }
404ff6b5 28681
c19d1205
ZW
28682 if (value == 0)
28683 /* Shifts of zero must be done as lsl. */
28684 newval &= ~0x60;
28685 else if (value == 32)
28686 value = 0;
28687 newval &= 0xfffff07f;
28688 newval |= (value & 0x1f) << 7;
28689 md_number_to_chars (buf, newval, INSN_SIZE);
28690 break;
404ff6b5 28691
c19d1205 28692 case BFD_RELOC_ARM_T32_IMMEDIATE:
16805f35 28693 case BFD_RELOC_ARM_T32_ADD_IMM:
92e90b6e 28694 case BFD_RELOC_ARM_T32_IMM12:
e9f89963 28695 case BFD_RELOC_ARM_T32_ADD_PC12:
c19d1205
ZW
28696 /* We claim that this fixup has been processed here,
28697 even if in fact we generate an error because we do
28698 not have a reloc for it, so tc_gen_reloc will reject it. */
28699 fixP->fx_done = 1;
404ff6b5 28700
c19d1205
ZW
28701 if (fixP->fx_addsy
28702 && ! S_IS_DEFINED (fixP->fx_addsy))
28703 {
28704 as_bad_where (fixP->fx_file, fixP->fx_line,
28705 _("undefined symbol %s used as an immediate value"),
28706 S_GET_NAME (fixP->fx_addsy));
28707 break;
28708 }
404ff6b5 28709
c19d1205
ZW
28710 newval = md_chars_to_number (buf, THUMB_SIZE);
28711 newval <<= 16;
28712 newval |= md_chars_to_number (buf+2, THUMB_SIZE);
404ff6b5 28713
16805f35 28714 newimm = FAIL;
bada4342
JW
28715 if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
28716 /* ARMv8-M Baseline MOV will reach here, but it doesn't support
28717 Thumb2 modified immediate encoding (T2). */
28718 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
16805f35 28719 || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
ef8d22e6
PB
28720 {
28721 newimm = encode_thumb32_immediate (value);
28722 if (newimm == (unsigned int) FAIL)
28723 newimm = thumb32_negate_data_op (&newval, value);
28724 }
bada4342 28725 if (newimm == (unsigned int) FAIL)
92e90b6e 28726 {
bada4342 28727 if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
e9f89963 28728 {
bada4342
JW
28729 /* Turn add/sum into addw/subw. */
28730 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
28731 newval = (newval & 0xfeffffff) | 0x02000000;
28732 /* No flat 12-bit imm encoding for addsw/subsw. */
28733 if ((newval & 0x00100000) == 0)
40f246e3 28734 {
bada4342
JW
28735 /* 12 bit immediate for addw/subw. */
28736 if (value < 0)
28737 {
28738 value = -value;
28739 newval ^= 0x00a00000;
28740 }
28741 if (value > 0xfff)
28742 newimm = (unsigned int) FAIL;
28743 else
28744 newimm = value;
28745 }
28746 }
28747 else
28748 {
28749 /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
28750 UINT16 (T3 encoding), MOVW only accepts UINT16. When
28751 disassembling, MOV is preferred when there is no encoding
db7bf105 28752 overlap. */
bada4342 28753 if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
db7bf105
NC
28754 /* NOTE: MOV uses the ORR opcode in Thumb 2 mode
28755 but with the Rn field [19:16] set to 1111. */
28756 && (((newval >> 16) & 0xf) == 0xf)
bada4342
JW
28757 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
28758 && !((newval >> T2_SBIT_SHIFT) & 0x1)
db7bf105 28759 && value >= 0 && value <= 0xffff)
bada4342
JW
28760 {
28761 /* Toggle bit[25] to change encoding from T2 to T3. */
28762 newval ^= 1 << 25;
28763 /* Clear bits[19:16]. */
28764 newval &= 0xfff0ffff;
28765 /* Encoding high 4bits imm. Code below will encode the
28766 remaining low 12bits. */
28767 newval |= (value & 0x0000f000) << 4;
28768 newimm = value & 0x00000fff;
40f246e3 28769 }
e9f89963 28770 }
92e90b6e 28771 }
cc8a6dd0 28772
c19d1205 28773 if (newimm == (unsigned int)FAIL)
3631a3c8 28774 {
c19d1205
ZW
28775 as_bad_where (fixP->fx_file, fixP->fx_line,
28776 _("invalid constant (%lx) after fixup"),
28777 (unsigned long) value);
28778 break;
3631a3c8
NC
28779 }
28780
c19d1205
ZW
28781 newval |= (newimm & 0x800) << 15;
28782 newval |= (newimm & 0x700) << 4;
28783 newval |= (newimm & 0x0ff);
cc8a6dd0 28784
c19d1205
ZW
28785 md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
28786 md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
28787 break;
a737bd4d 28788
3eb17e6b 28789 case BFD_RELOC_ARM_SMC:
ba85f98c 28790 if (((unsigned long) value) > 0xf)
c19d1205 28791 as_bad_where (fixP->fx_file, fixP->fx_line,
3eb17e6b 28792 _("invalid smc expression"));
ba85f98c 28793
2fc8bdac 28794 newval = md_chars_to_number (buf, INSN_SIZE);
ba85f98c 28795 newval |= (value & 0xf);
c19d1205
ZW
28796 md_number_to_chars (buf, newval, INSN_SIZE);
28797 break;
a737bd4d 28798
90ec0d68
MGD
28799 case BFD_RELOC_ARM_HVC:
28800 if (((unsigned long) value) > 0xffff)
28801 as_bad_where (fixP->fx_file, fixP->fx_line,
28802 _("invalid hvc expression"));
28803 newval = md_chars_to_number (buf, INSN_SIZE);
28804 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
28805 md_number_to_chars (buf, newval, INSN_SIZE);
28806 break;
28807
c19d1205 28808 case BFD_RELOC_ARM_SWI:
adbaf948 28809 if (fixP->tc_fix_data != 0)
c19d1205
ZW
28810 {
28811 if (((unsigned long) value) > 0xff)
28812 as_bad_where (fixP->fx_file, fixP->fx_line,
28813 _("invalid swi expression"));
2fc8bdac 28814 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205
ZW
28815 newval |= value;
28816 md_number_to_chars (buf, newval, THUMB_SIZE);
28817 }
28818 else
28819 {
28820 if (((unsigned long) value) > 0x00ffffff)
28821 as_bad_where (fixP->fx_file, fixP->fx_line,
28822 _("invalid swi expression"));
2fc8bdac 28823 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
28824 newval |= value;
28825 md_number_to_chars (buf, newval, INSN_SIZE);
28826 }
28827 break;
a737bd4d 28828
c19d1205
ZW
28829 case BFD_RELOC_ARM_MULTI:
28830 if (((unsigned long) value) > 0xffff)
28831 as_bad_where (fixP->fx_file, fixP->fx_line,
28832 _("invalid expression in load/store multiple"));
28833 newval = value | md_chars_to_number (buf, INSN_SIZE);
28834 md_number_to_chars (buf, newval, INSN_SIZE);
28835 break;
a737bd4d 28836
c19d1205 28837#ifdef OBJ_ELF
39b41c9c 28838 case BFD_RELOC_ARM_PCREL_CALL:
267bf995
RR
28839
28840 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
28841 && fixP->fx_addsy
34e77a92 28842 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
28843 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28844 && THUMB_IS_FUNC (fixP->fx_addsy))
28845 /* Flip the bl to blx. This is a simple flip
28846 bit here because we generate PCREL_CALL for
28847 unconditional bls. */
28848 {
28849 newval = md_chars_to_number (buf, INSN_SIZE);
28850 newval = newval | 0x10000000;
28851 md_number_to_chars (buf, newval, INSN_SIZE);
28852 temp = 1;
28853 fixP->fx_done = 1;
28854 }
39b41c9c
PB
28855 else
28856 temp = 3;
28857 goto arm_branch_common;
28858
28859 case BFD_RELOC_ARM_PCREL_JUMP:
267bf995
RR
28860 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
28861 && fixP->fx_addsy
34e77a92 28862 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
28863 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28864 && THUMB_IS_FUNC (fixP->fx_addsy))
28865 {
28866 /* This would map to a bl<cond>, b<cond>,
28867 b<always> to a Thumb function. We
28868 need to force a relocation for this particular
28869 case. */
28870 newval = md_chars_to_number (buf, INSN_SIZE);
28871 fixP->fx_done = 0;
28872 }
1a0670f3 28873 /* Fall through. */
267bf995 28874
2fc8bdac 28875 case BFD_RELOC_ARM_PLT32:
c19d1205 28876#endif
39b41c9c
PB
28877 case BFD_RELOC_ARM_PCREL_BRANCH:
28878 temp = 3;
28879 goto arm_branch_common;
a737bd4d 28880
39b41c9c 28881 case BFD_RELOC_ARM_PCREL_BLX:
267bf995 28882
39b41c9c 28883 temp = 1;
267bf995
RR
28884 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
28885 && fixP->fx_addsy
34e77a92 28886 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
28887 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
28888 && ARM_IS_FUNC (fixP->fx_addsy))
28889 {
28890 /* Flip the blx to a bl and warn. */
28891 const char *name = S_GET_NAME (fixP->fx_addsy);
28892 newval = 0xeb000000;
28893 as_warn_where (fixP->fx_file, fixP->fx_line,
28894 _("blx to '%s' an ARM ISA state function changed to bl"),
28895 name);
28896 md_number_to_chars (buf, newval, INSN_SIZE);
28897 temp = 3;
28898 fixP->fx_done = 1;
28899 }
28900
28901#ifdef OBJ_ELF
28902 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
477330fc 28903 fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
267bf995
RR
28904#endif
28905
39b41c9c 28906 arm_branch_common:
c19d1205 28907 /* We are going to store value (shifted right by two) in the
39b41c9c
PB
28908 instruction, in a 24 bit, signed field. Bits 26 through 32 either
28909 all clear or all set and bit 0 must be clear. For B/BL bit 1 must
de194d85 28910 also be clear. */
39b41c9c 28911 if (value & temp)
c19d1205 28912 as_bad_where (fixP->fx_file, fixP->fx_line,
2fc8bdac
ZW
28913 _("misaligned branch destination"));
28914 if ((value & (offsetT)0xfe000000) != (offsetT)0
28915 && (value & (offsetT)0xfe000000) != (offsetT)0xfe000000)
08f10d51 28916 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 28917
2fc8bdac 28918 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 28919 {
2fc8bdac
ZW
28920 newval = md_chars_to_number (buf, INSN_SIZE);
28921 newval |= (value >> 2) & 0x00ffffff;
7ae2971b
PB
28922 /* Set the H bit on BLX instructions. */
28923 if (temp == 1)
28924 {
28925 if (value & 2)
28926 newval |= 0x01000000;
28927 else
28928 newval &= ~0x01000000;
28929 }
2fc8bdac 28930 md_number_to_chars (buf, newval, INSN_SIZE);
c19d1205 28931 }
c19d1205 28932 break;
a737bd4d 28933
25fe350b
MS
28934 case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CBZ */
28935 /* CBZ can only branch forward. */
a737bd4d 28936
738755b0 28937 /* Attempts to use CBZ to branch to the next instruction
477330fc
RM
28938 (which, strictly speaking, are prohibited) will be turned into
28939 no-ops.
738755b0
MS
28940
28941 FIXME: It may be better to remove the instruction completely and
28942 perform relaxation. */
28943 if (value == -2)
2fc8bdac
ZW
28944 {
28945 newval = md_chars_to_number (buf, THUMB_SIZE);
738755b0 28946 newval = 0xbf00; /* NOP encoding T1 */
2fc8bdac
ZW
28947 md_number_to_chars (buf, newval, THUMB_SIZE);
28948 }
738755b0
MS
28949 else
28950 {
28951 if (value & ~0x7e)
08f10d51 28952 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
738755b0 28953
477330fc 28954 if (fixP->fx_done || !seg->use_rela_p)
738755b0
MS
28955 {
28956 newval = md_chars_to_number (buf, THUMB_SIZE);
28957 newval |= ((value & 0x3e) << 2) | ((value & 0x40) << 3);
28958 md_number_to_chars (buf, newval, THUMB_SIZE);
28959 }
28960 }
c19d1205 28961 break;
a737bd4d 28962
c19d1205 28963 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
e8f8842d 28964 if (out_of_range_p (value, 8))
08f10d51 28965 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 28966
2fc8bdac
ZW
28967 if (fixP->fx_done || !seg->use_rela_p)
28968 {
28969 newval = md_chars_to_number (buf, THUMB_SIZE);
28970 newval |= (value & 0x1ff) >> 1;
28971 md_number_to_chars (buf, newval, THUMB_SIZE);
28972 }
c19d1205 28973 break;
a737bd4d 28974
c19d1205 28975 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
e8f8842d 28976 if (out_of_range_p (value, 11))
08f10d51 28977 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 28978
2fc8bdac
ZW
28979 if (fixP->fx_done || !seg->use_rela_p)
28980 {
28981 newval = md_chars_to_number (buf, THUMB_SIZE);
28982 newval |= (value & 0xfff) >> 1;
28983 md_number_to_chars (buf, newval, THUMB_SIZE);
28984 }
c19d1205 28985 break;
a737bd4d 28986
e8f8842d 28987 /* This relocation is misnamed, it should be BRANCH21. */
c19d1205 28988 case BFD_RELOC_THUMB_PCREL_BRANCH20:
267bf995
RR
28989 if (fixP->fx_addsy
28990 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 28991 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
28992 && ARM_IS_FUNC (fixP->fx_addsy)
28993 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
28994 {
28995 /* Force a relocation for a branch 20 bits wide. */
28996 fixP->fx_done = 0;
28997 }
e8f8842d 28998 if (out_of_range_p (value, 20))
2fc8bdac
ZW
28999 as_bad_where (fixP->fx_file, fixP->fx_line,
29000 _("conditional branch out of range"));
404ff6b5 29001
2fc8bdac
ZW
29002 if (fixP->fx_done || !seg->use_rela_p)
29003 {
29004 offsetT newval2;
29005 addressT S, J1, J2, lo, hi;
404ff6b5 29006
2fc8bdac
ZW
29007 S = (value & 0x00100000) >> 20;
29008 J2 = (value & 0x00080000) >> 19;
29009 J1 = (value & 0x00040000) >> 18;
29010 hi = (value & 0x0003f000) >> 12;
29011 lo = (value & 0x00000ffe) >> 1;
6c43fab6 29012
2fc8bdac
ZW
29013 newval = md_chars_to_number (buf, THUMB_SIZE);
29014 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29015 newval |= (S << 10) | hi;
29016 newval2 |= (J1 << 13) | (J2 << 11) | lo;
29017 md_number_to_chars (buf, newval, THUMB_SIZE);
29018 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
29019 }
c19d1205 29020 break;
6c43fab6 29021
c19d1205 29022 case BFD_RELOC_THUMB_PCREL_BLX:
267bf995
RR
29023 /* If there is a blx from a thumb state function to
29024 another thumb function flip this to a bl and warn
29025 about it. */
29026
29027 if (fixP->fx_addsy
34e77a92 29028 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
29029 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29030 && THUMB_IS_FUNC (fixP->fx_addsy))
29031 {
29032 const char *name = S_GET_NAME (fixP->fx_addsy);
29033 as_warn_where (fixP->fx_file, fixP->fx_line,
29034 _("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
29035 name);
29036 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29037 newval = newval | 0x1000;
29038 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
29039 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
29040 fixP->fx_done = 1;
29041 }
29042
29043
29044 goto thumb_bl_common;
29045
c19d1205 29046 case BFD_RELOC_THUMB_PCREL_BRANCH23:
267bf995
RR
29047 /* A bl from Thumb state ISA to an internal ARM state function
29048 is converted to a blx. */
29049 if (fixP->fx_addsy
29050 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 29051 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
29052 && ARM_IS_FUNC (fixP->fx_addsy)
29053 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
29054 {
29055 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29056 newval = newval & ~0x1000;
29057 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
29058 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
29059 fixP->fx_done = 1;
29060 }
29061
29062 thumb_bl_common:
29063
2fc8bdac
ZW
29064 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
29065 /* For a BLX instruction, make sure that the relocation is rounded up
29066 to a word boundary. This follows the semantics of the instruction
29067 which specifies that bit 1 of the target address will come from bit
29068 1 of the base address. */
d406f3e4
JB
29069 value = (value + 3) & ~ 3;
29070
29071#ifdef OBJ_ELF
29072 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
29073 && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
29074 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
29075#endif
404ff6b5 29076
e8f8842d 29077 if (out_of_range_p (value, 22))
2b2f5df9 29078 {
fc289b0a 29079 if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)))
2b2f5df9 29080 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
e8f8842d 29081 else if (out_of_range_p (value, 24))
2b2f5df9
NC
29082 as_bad_where (fixP->fx_file, fixP->fx_line,
29083 _("Thumb2 branch out of range"));
29084 }
4a42ebbc
RR
29085
29086 if (fixP->fx_done || !seg->use_rela_p)
29087 encode_thumb2_b_bl_offset (buf, value);
29088
c19d1205 29089 break;
404ff6b5 29090
c19d1205 29091 case BFD_RELOC_THUMB_PCREL_BRANCH25:
e8f8842d 29092 if (out_of_range_p (value, 24))
08f10d51 29093 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
6c43fab6 29094
2fc8bdac 29095 if (fixP->fx_done || !seg->use_rela_p)
4a42ebbc 29096 encode_thumb2_b_bl_offset (buf, value);
6c43fab6 29097
2fc8bdac 29098 break;
a737bd4d 29099
2fc8bdac
ZW
29100 case BFD_RELOC_8:
29101 if (fixP->fx_done || !seg->use_rela_p)
4b1a927e 29102 *buf = value;
c19d1205 29103 break;
a737bd4d 29104
c19d1205 29105 case BFD_RELOC_16:
2fc8bdac 29106 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 29107 md_number_to_chars (buf, value, 2);
c19d1205 29108 break;
a737bd4d 29109
c19d1205 29110#ifdef OBJ_ELF
0855e32b
NS
29111 case BFD_RELOC_ARM_TLS_CALL:
29112 case BFD_RELOC_ARM_THM_TLS_CALL:
29113 case BFD_RELOC_ARM_TLS_DESCSEQ:
29114 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
0855e32b 29115 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205
ZW
29116 case BFD_RELOC_ARM_TLS_GD32:
29117 case BFD_RELOC_ARM_TLS_LE32:
29118 case BFD_RELOC_ARM_TLS_IE32:
29119 case BFD_RELOC_ARM_TLS_LDM32:
29120 case BFD_RELOC_ARM_TLS_LDO32:
29121 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4b1a927e 29122 break;
6c43fab6 29123
5c5a4843
CL
29124 /* Same handling as above, but with the arm_fdpic guard. */
29125 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
29126 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
29127 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
29128 if (arm_fdpic)
29129 {
29130 S_SET_THREAD_LOCAL (fixP->fx_addsy);
29131 }
29132 else
29133 {
29134 as_bad_where (fixP->fx_file, fixP->fx_line,
29135 _("Relocation supported only in FDPIC mode"));
29136 }
29137 break;
29138
c19d1205
ZW
29139 case BFD_RELOC_ARM_GOT32:
29140 case BFD_RELOC_ARM_GOTOFF:
c19d1205 29141 break;
b43420e6
NC
29142
29143 case BFD_RELOC_ARM_GOT_PREL:
29144 if (fixP->fx_done || !seg->use_rela_p)
477330fc 29145 md_number_to_chars (buf, value, 4);
b43420e6
NC
29146 break;
29147
9a6f4e97
NS
29148 case BFD_RELOC_ARM_TARGET2:
29149 /* TARGET2 is not partial-inplace, so we need to write the
477330fc
RM
29150 addend here for REL targets, because it won't be written out
29151 during reloc processing later. */
9a6f4e97
NS
29152 if (fixP->fx_done || !seg->use_rela_p)
29153 md_number_to_chars (buf, fixP->fx_offset, 4);
29154 break;
188fd7ae
CL
29155
29156 /* Relocations for FDPIC. */
29157 case BFD_RELOC_ARM_GOTFUNCDESC:
29158 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
29159 case BFD_RELOC_ARM_FUNCDESC:
29160 if (arm_fdpic)
29161 {
29162 if (fixP->fx_done || !seg->use_rela_p)
29163 md_number_to_chars (buf, 0, 4);
29164 }
29165 else
29166 {
29167 as_bad_where (fixP->fx_file, fixP->fx_line,
29168 _("Relocation supported only in FDPIC mode"));
29169 }
29170 break;
c19d1205 29171#endif
6c43fab6 29172
c19d1205
ZW
29173 case BFD_RELOC_RVA:
29174 case BFD_RELOC_32:
29175 case BFD_RELOC_ARM_TARGET1:
29176 case BFD_RELOC_ARM_ROSEGREL32:
29177 case BFD_RELOC_ARM_SBREL32:
29178 case BFD_RELOC_32_PCREL:
f0927246
NC
29179#ifdef TE_PE
29180 case BFD_RELOC_32_SECREL:
29181#endif
2fc8bdac 29182 if (fixP->fx_done || !seg->use_rela_p)
53baae48
NC
29183#ifdef TE_WINCE
29184 /* For WinCE we only do this for pcrel fixups. */
29185 if (fixP->fx_done || fixP->fx_pcrel)
29186#endif
29187 md_number_to_chars (buf, value, 4);
c19d1205 29188 break;
6c43fab6 29189
c19d1205
ZW
29190#ifdef OBJ_ELF
29191 case BFD_RELOC_ARM_PREL31:
2fc8bdac 29192 if (fixP->fx_done || !seg->use_rela_p)
c19d1205
ZW
29193 {
29194 newval = md_chars_to_number (buf, 4) & 0x80000000;
29195 if ((value ^ (value >> 1)) & 0x40000000)
29196 {
29197 as_bad_where (fixP->fx_file, fixP->fx_line,
29198 _("rel31 relocation overflow"));
29199 }
29200 newval |= value & 0x7fffffff;
29201 md_number_to_chars (buf, newval, 4);
29202 }
29203 break;
c19d1205 29204#endif
a737bd4d 29205
c19d1205 29206 case BFD_RELOC_ARM_CP_OFF_IMM:
8f06b2d8 29207 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
32c36c3c 29208 case BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM:
9db2f6b4
RL
29209 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
29210 newval = md_chars_to_number (buf, INSN_SIZE);
29211 else
29212 newval = get_thumb32_insn (buf);
29213 if ((newval & 0x0f200f00) == 0x0d000900)
29214 {
29215 /* This is a fp16 vstr/vldr. The immediate offset in the mnemonic
29216 has permitted values that are multiples of 2, in the range 0
29217 to 510. */
29218 if (value < -510 || value > 510 || (value & 1))
29219 as_bad_where (fixP->fx_file, fixP->fx_line,
29220 _("co-processor offset out of range"));
29221 }
32c36c3c
AV
29222 else if ((newval & 0xfe001f80) == 0xec000f80)
29223 {
29224 if (value < -511 || value > 512 || (value & 3))
29225 as_bad_where (fixP->fx_file, fixP->fx_line,
29226 _("co-processor offset out of range"));
29227 }
9db2f6b4 29228 else if (value < -1023 || value > 1023 || (value & 3))
c19d1205
ZW
29229 as_bad_where (fixP->fx_file, fixP->fx_line,
29230 _("co-processor offset out of range"));
29231 cp_off_common:
26d97720 29232 sign = value > 0;
c19d1205
ZW
29233 if (value < 0)
29234 value = -value;
8f06b2d8
PB
29235 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
29236 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
29237 newval = md_chars_to_number (buf, INSN_SIZE);
29238 else
29239 newval = get_thumb32_insn (buf);
26d97720 29240 if (value == 0)
32c36c3c
AV
29241 {
29242 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
29243 newval &= 0xffffff80;
29244 else
29245 newval &= 0xffffff00;
29246 }
26d97720
NS
29247 else
29248 {
32c36c3c
AV
29249 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
29250 newval &= 0xff7fff80;
29251 else
29252 newval &= 0xff7fff00;
9db2f6b4
RL
29253 if ((newval & 0x0f200f00) == 0x0d000900)
29254 {
29255 /* This is a fp16 vstr/vldr.
29256
29257 It requires the immediate offset in the instruction is shifted
29258 left by 1 to be a half-word offset.
29259
29260 Here, left shift by 1 first, and later right shift by 2
29261 should get the right offset. */
29262 value <<= 1;
29263 }
26d97720
NS
29264 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
29265 }
8f06b2d8
PB
29266 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
29267 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
29268 md_number_to_chars (buf, newval, INSN_SIZE);
29269 else
29270 put_thumb32_insn (buf, newval);
c19d1205 29271 break;
a737bd4d 29272
c19d1205 29273 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
8f06b2d8 29274 case BFD_RELOC_ARM_T32_CP_OFF_IMM_S2:
c19d1205
ZW
29275 if (value < -255 || value > 255)
29276 as_bad_where (fixP->fx_file, fixP->fx_line,
29277 _("co-processor offset out of range"));
df7849c5 29278 value *= 4;
c19d1205 29279 goto cp_off_common;
6c43fab6 29280
c19d1205
ZW
29281 case BFD_RELOC_ARM_THUMB_OFFSET:
29282 newval = md_chars_to_number (buf, THUMB_SIZE);
29283 /* Exactly what ranges, and where the offset is inserted depends
29284 on the type of instruction, we can establish this from the
29285 top 4 bits. */
29286 switch (newval >> 12)
29287 {
29288 case 4: /* PC load. */
29289 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
29290 forced to zero for these loads; md_pcrel_from has already
29291 compensated for this. */
29292 if (value & 3)
29293 as_bad_where (fixP->fx_file, fixP->fx_line,
29294 _("invalid offset, target not word aligned (0x%08lX)"),
0359e808
NC
29295 (((unsigned long) fixP->fx_frag->fr_address
29296 + (unsigned long) fixP->fx_where) & ~3)
29297 + (unsigned long) value);
749479c8
AO
29298 else if (get_recorded_alignment (seg) < 2)
29299 as_warn_where (fixP->fx_file, fixP->fx_line,
29300 _("section does not have enough alignment to ensure safe PC-relative loads"));
a737bd4d 29301
c19d1205
ZW
29302 if (value & ~0x3fc)
29303 as_bad_where (fixP->fx_file, fixP->fx_line,
29304 _("invalid offset, value too big (0x%08lX)"),
29305 (long) value);
a737bd4d 29306
c19d1205
ZW
29307 newval |= value >> 2;
29308 break;
a737bd4d 29309
c19d1205
ZW
29310 case 9: /* SP load/store. */
29311 if (value & ~0x3fc)
29312 as_bad_where (fixP->fx_file, fixP->fx_line,
29313 _("invalid offset, value too big (0x%08lX)"),
29314 (long) value);
29315 newval |= value >> 2;
29316 break;
6c43fab6 29317
c19d1205
ZW
29318 case 6: /* Word load/store. */
29319 if (value & ~0x7c)
29320 as_bad_where (fixP->fx_file, fixP->fx_line,
29321 _("invalid offset, value too big (0x%08lX)"),
29322 (long) value);
29323 newval |= value << 4; /* 6 - 2. */
29324 break;
a737bd4d 29325
c19d1205
ZW
29326 case 7: /* Byte load/store. */
29327 if (value & ~0x1f)
29328 as_bad_where (fixP->fx_file, fixP->fx_line,
29329 _("invalid offset, value too big (0x%08lX)"),
29330 (long) value);
29331 newval |= value << 6;
29332 break;
a737bd4d 29333
c19d1205
ZW
29334 case 8: /* Halfword load/store. */
29335 if (value & ~0x3e)
29336 as_bad_where (fixP->fx_file, fixP->fx_line,
29337 _("invalid offset, value too big (0x%08lX)"),
29338 (long) value);
29339 newval |= value << 5; /* 6 - 1. */
29340 break;
a737bd4d 29341
c19d1205
ZW
29342 default:
29343 as_bad_where (fixP->fx_file, fixP->fx_line,
29344 "Unable to process relocation for thumb opcode: %lx",
29345 (unsigned long) newval);
29346 break;
29347 }
29348 md_number_to_chars (buf, newval, THUMB_SIZE);
29349 break;
a737bd4d 29350
c19d1205
ZW
29351 case BFD_RELOC_ARM_THUMB_ADD:
29352 /* This is a complicated relocation, since we use it for all of
29353 the following immediate relocations:
a737bd4d 29354
c19d1205
ZW
29355 3bit ADD/SUB
29356 8bit ADD/SUB
29357 9bit ADD/SUB SP word-aligned
29358 10bit ADD PC/SP word-aligned
a737bd4d 29359
c19d1205
ZW
29360 The type of instruction being processed is encoded in the
29361 instruction field:
a737bd4d 29362
c19d1205
ZW
29363 0x8000 SUB
29364 0x00F0 Rd
29365 0x000F Rs
29366 */
29367 newval = md_chars_to_number (buf, THUMB_SIZE);
29368 {
29369 int rd = (newval >> 4) & 0xf;
29370 int rs = newval & 0xf;
29371 int subtract = !!(newval & 0x8000);
a737bd4d 29372
c19d1205
ZW
29373 /* Check for HI regs, only very restricted cases allowed:
29374 Adjusting SP, and using PC or SP to get an address. */
29375 if ((rd > 7 && (rd != REG_SP || rs != REG_SP))
29376 || (rs > 7 && rs != REG_SP && rs != REG_PC))
29377 as_bad_where (fixP->fx_file, fixP->fx_line,
29378 _("invalid Hi register with immediate"));
a737bd4d 29379
c19d1205
ZW
29380 /* If value is negative, choose the opposite instruction. */
29381 if (value < 0)
29382 {
29383 value = -value;
29384 subtract = !subtract;
29385 if (value < 0)
29386 as_bad_where (fixP->fx_file, fixP->fx_line,
29387 _("immediate value out of range"));
29388 }
a737bd4d 29389
c19d1205
ZW
29390 if (rd == REG_SP)
29391 {
75c11999 29392 if (value & ~0x1fc)
c19d1205
ZW
29393 as_bad_where (fixP->fx_file, fixP->fx_line,
29394 _("invalid immediate for stack address calculation"));
29395 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
29396 newval |= value >> 2;
29397 }
29398 else if (rs == REG_PC || rs == REG_SP)
29399 {
c12d2c9d
NC
29400 /* PR gas/18541. If the addition is for a defined symbol
29401 within range of an ADR instruction then accept it. */
29402 if (subtract
29403 && value == 4
29404 && fixP->fx_addsy != NULL)
29405 {
29406 subtract = 0;
29407
29408 if (! S_IS_DEFINED (fixP->fx_addsy)
29409 || S_GET_SEGMENT (fixP->fx_addsy) != seg
29410 || S_IS_WEAK (fixP->fx_addsy))
29411 {
29412 as_bad_where (fixP->fx_file, fixP->fx_line,
29413 _("address calculation needs a strongly defined nearby symbol"));
29414 }
29415 else
29416 {
29417 offsetT v = fixP->fx_where + fixP->fx_frag->fr_address;
29418
29419 /* Round up to the next 4-byte boundary. */
29420 if (v & 3)
29421 v = (v + 3) & ~ 3;
29422 else
29423 v += 4;
29424 v = S_GET_VALUE (fixP->fx_addsy) - v;
29425
29426 if (v & ~0x3fc)
29427 {
29428 as_bad_where (fixP->fx_file, fixP->fx_line,
29429 _("symbol too far away"));
29430 }
29431 else
29432 {
29433 fixP->fx_done = 1;
29434 value = v;
29435 }
29436 }
29437 }
29438
c19d1205
ZW
29439 if (subtract || value & ~0x3fc)
29440 as_bad_where (fixP->fx_file, fixP->fx_line,
29441 _("invalid immediate for address calculation (value = 0x%08lX)"),
5fc177c8 29442 (unsigned long) (subtract ? - value : value));
c19d1205
ZW
29443 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
29444 newval |= rd << 8;
29445 newval |= value >> 2;
29446 }
29447 else if (rs == rd)
29448 {
29449 if (value & ~0xff)
29450 as_bad_where (fixP->fx_file, fixP->fx_line,
29451 _("immediate value out of range"));
29452 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
29453 newval |= (rd << 8) | value;
29454 }
29455 else
29456 {
29457 if (value & ~0x7)
29458 as_bad_where (fixP->fx_file, fixP->fx_line,
29459 _("immediate value out of range"));
29460 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
29461 newval |= rd | (rs << 3) | (value << 6);
29462 }
29463 }
29464 md_number_to_chars (buf, newval, THUMB_SIZE);
29465 break;
a737bd4d 29466
c19d1205
ZW
29467 case BFD_RELOC_ARM_THUMB_IMM:
29468 newval = md_chars_to_number (buf, THUMB_SIZE);
29469 if (value < 0 || value > 255)
29470 as_bad_where (fixP->fx_file, fixP->fx_line,
4e6e072b 29471 _("invalid immediate: %ld is out of range"),
c19d1205
ZW
29472 (long) value);
29473 newval |= value;
29474 md_number_to_chars (buf, newval, THUMB_SIZE);
29475 break;
a737bd4d 29476
c19d1205
ZW
29477 case BFD_RELOC_ARM_THUMB_SHIFT:
29478 /* 5bit shift value (0..32). LSL cannot take 32. */
29479 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf83f;
29480 temp = newval & 0xf800;
29481 if (value < 0 || value > 32 || (value == 32 && temp == T_OPCODE_LSL_I))
29482 as_bad_where (fixP->fx_file, fixP->fx_line,
29483 _("invalid shift value: %ld"), (long) value);
29484 /* Shifts of zero must be encoded as LSL. */
29485 if (value == 0)
29486 newval = (newval & 0x003f) | T_OPCODE_LSL_I;
29487 /* Shifts of 32 are encoded as zero. */
29488 else if (value == 32)
29489 value = 0;
29490 newval |= value << 6;
29491 md_number_to_chars (buf, newval, THUMB_SIZE);
29492 break;
a737bd4d 29493
c19d1205
ZW
29494 case BFD_RELOC_VTABLE_INHERIT:
29495 case BFD_RELOC_VTABLE_ENTRY:
29496 fixP->fx_done = 0;
29497 return;
6c43fab6 29498
b6895b4f
PB
29499 case BFD_RELOC_ARM_MOVW:
29500 case BFD_RELOC_ARM_MOVT:
29501 case BFD_RELOC_ARM_THUMB_MOVW:
29502 case BFD_RELOC_ARM_THUMB_MOVT:
29503 if (fixP->fx_done || !seg->use_rela_p)
29504 {
29505 /* REL format relocations are limited to a 16-bit addend. */
29506 if (!fixP->fx_done)
29507 {
39623e12 29508 if (value < -0x8000 || value > 0x7fff)
b6895b4f 29509 as_bad_where (fixP->fx_file, fixP->fx_line,
ff5075ca 29510 _("offset out of range"));
b6895b4f
PB
29511 }
29512 else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT
29513 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
29514 {
29515 value >>= 16;
29516 }
29517
29518 if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
29519 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
29520 {
29521 newval = get_thumb32_insn (buf);
29522 newval &= 0xfbf08f00;
29523 newval |= (value & 0xf000) << 4;
29524 newval |= (value & 0x0800) << 15;
29525 newval |= (value & 0x0700) << 4;
29526 newval |= (value & 0x00ff);
29527 put_thumb32_insn (buf, newval);
29528 }
29529 else
29530 {
29531 newval = md_chars_to_number (buf, 4);
29532 newval &= 0xfff0f000;
29533 newval |= value & 0x0fff;
29534 newval |= (value & 0xf000) << 4;
29535 md_number_to_chars (buf, newval, 4);
29536 }
29537 }
29538 return;
29539
72d98d16
MG
29540 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
29541 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
29542 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
29543 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
29544 gas_assert (!fixP->fx_done);
29545 {
29546 bfd_vma insn;
29547 bfd_boolean is_mov;
29548 bfd_vma encoded_addend = value;
29549
29550 /* Check that addend can be encoded in instruction. */
29551 if (!seg->use_rela_p && (value < 0 || value > 255))
29552 as_bad_where (fixP->fx_file, fixP->fx_line,
29553 _("the offset 0x%08lX is not representable"),
29554 (unsigned long) encoded_addend);
29555
29556 /* Extract the instruction. */
29557 insn = md_chars_to_number (buf, THUMB_SIZE);
29558 is_mov = (insn & 0xf800) == 0x2000;
29559
29560 /* Encode insn. */
29561 if (is_mov)
29562 {
29563 if (!seg->use_rela_p)
29564 insn |= encoded_addend;
29565 }
29566 else
29567 {
29568 int rd, rs;
29569
29570 /* Extract the instruction. */
29571 /* Encoding is the following
29572 0x8000 SUB
29573 0x00F0 Rd
29574 0x000F Rs
29575 */
29576 /* The following conditions must be true :
29577 - ADD
29578 - Rd == Rs
29579 - Rd <= 7
29580 */
29581 rd = (insn >> 4) & 0xf;
29582 rs = insn & 0xf;
29583 if ((insn & 0x8000) || (rd != rs) || rd > 7)
29584 as_bad_where (fixP->fx_file, fixP->fx_line,
29585 _("Unable to process relocation for thumb opcode: %lx"),
29586 (unsigned long) insn);
29587
29588 /* Encode as ADD immediate8 thumb 1 code. */
29589 insn = 0x3000 | (rd << 8);
29590
29591 /* Place the encoded addend into the first 8 bits of the
29592 instruction. */
29593 if (!seg->use_rela_p)
29594 insn |= encoded_addend;
29595 }
29596
29597 /* Update the instruction. */
29598 md_number_to_chars (buf, insn, THUMB_SIZE);
29599 }
29600 break;
29601
4962c51a
MS
29602 case BFD_RELOC_ARM_ALU_PC_G0_NC:
29603 case BFD_RELOC_ARM_ALU_PC_G0:
29604 case BFD_RELOC_ARM_ALU_PC_G1_NC:
29605 case BFD_RELOC_ARM_ALU_PC_G1:
29606 case BFD_RELOC_ARM_ALU_PC_G2:
29607 case BFD_RELOC_ARM_ALU_SB_G0_NC:
29608 case BFD_RELOC_ARM_ALU_SB_G0:
29609 case BFD_RELOC_ARM_ALU_SB_G1_NC:
29610 case BFD_RELOC_ARM_ALU_SB_G1:
29611 case BFD_RELOC_ARM_ALU_SB_G2:
9c2799c2 29612 gas_assert (!fixP->fx_done);
4962c51a
MS
29613 if (!seg->use_rela_p)
29614 {
477330fc
RM
29615 bfd_vma insn;
29616 bfd_vma encoded_addend;
3ca4a8ec 29617 bfd_vma addend_abs = llabs (value);
477330fc
RM
29618
29619 /* Check that the absolute value of the addend can be
29620 expressed as an 8-bit constant plus a rotation. */
29621 encoded_addend = encode_arm_immediate (addend_abs);
29622 if (encoded_addend == (unsigned int) FAIL)
4962c51a 29623 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29624 _("the offset 0x%08lX is not representable"),
29625 (unsigned long) addend_abs);
29626
29627 /* Extract the instruction. */
29628 insn = md_chars_to_number (buf, INSN_SIZE);
29629
29630 /* If the addend is positive, use an ADD instruction.
29631 Otherwise use a SUB. Take care not to destroy the S bit. */
29632 insn &= 0xff1fffff;
29633 if (value < 0)
29634 insn |= 1 << 22;
29635 else
29636 insn |= 1 << 23;
29637
29638 /* Place the encoded addend into the first 12 bits of the
29639 instruction. */
29640 insn &= 0xfffff000;
29641 insn |= encoded_addend;
29642
29643 /* Update the instruction. */
29644 md_number_to_chars (buf, insn, INSN_SIZE);
4962c51a
MS
29645 }
29646 break;
29647
29648 case BFD_RELOC_ARM_LDR_PC_G0:
29649 case BFD_RELOC_ARM_LDR_PC_G1:
29650 case BFD_RELOC_ARM_LDR_PC_G2:
29651 case BFD_RELOC_ARM_LDR_SB_G0:
29652 case BFD_RELOC_ARM_LDR_SB_G1:
29653 case BFD_RELOC_ARM_LDR_SB_G2:
9c2799c2 29654 gas_assert (!fixP->fx_done);
4962c51a 29655 if (!seg->use_rela_p)
477330fc
RM
29656 {
29657 bfd_vma insn;
3ca4a8ec 29658 bfd_vma addend_abs = llabs (value);
4962c51a 29659
477330fc
RM
29660 /* Check that the absolute value of the addend can be
29661 encoded in 12 bits. */
29662 if (addend_abs >= 0x1000)
4962c51a 29663 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29664 _("bad offset 0x%08lX (only 12 bits available for the magnitude)"),
29665 (unsigned long) addend_abs);
29666
29667 /* Extract the instruction. */
29668 insn = md_chars_to_number (buf, INSN_SIZE);
29669
29670 /* If the addend is negative, clear bit 23 of the instruction.
29671 Otherwise set it. */
29672 if (value < 0)
29673 insn &= ~(1 << 23);
29674 else
29675 insn |= 1 << 23;
29676
29677 /* Place the absolute value of the addend into the first 12 bits
29678 of the instruction. */
29679 insn &= 0xfffff000;
29680 insn |= addend_abs;
29681
29682 /* Update the instruction. */
29683 md_number_to_chars (buf, insn, INSN_SIZE);
29684 }
4962c51a
MS
29685 break;
29686
29687 case BFD_RELOC_ARM_LDRS_PC_G0:
29688 case BFD_RELOC_ARM_LDRS_PC_G1:
29689 case BFD_RELOC_ARM_LDRS_PC_G2:
29690 case BFD_RELOC_ARM_LDRS_SB_G0:
29691 case BFD_RELOC_ARM_LDRS_SB_G1:
29692 case BFD_RELOC_ARM_LDRS_SB_G2:
9c2799c2 29693 gas_assert (!fixP->fx_done);
4962c51a 29694 if (!seg->use_rela_p)
477330fc
RM
29695 {
29696 bfd_vma insn;
3ca4a8ec 29697 bfd_vma addend_abs = llabs (value);
4962c51a 29698
477330fc
RM
29699 /* Check that the absolute value of the addend can be
29700 encoded in 8 bits. */
29701 if (addend_abs >= 0x100)
4962c51a 29702 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29703 _("bad offset 0x%08lX (only 8 bits available for the magnitude)"),
29704 (unsigned long) addend_abs);
29705
29706 /* Extract the instruction. */
29707 insn = md_chars_to_number (buf, INSN_SIZE);
29708
29709 /* If the addend is negative, clear bit 23 of the instruction.
29710 Otherwise set it. */
29711 if (value < 0)
29712 insn &= ~(1 << 23);
29713 else
29714 insn |= 1 << 23;
29715
29716 /* Place the first four bits of the absolute value of the addend
29717 into the first 4 bits of the instruction, and the remaining
29718 four into bits 8 .. 11. */
29719 insn &= 0xfffff0f0;
29720 insn |= (addend_abs & 0xf) | ((addend_abs & 0xf0) << 4);
29721
29722 /* Update the instruction. */
29723 md_number_to_chars (buf, insn, INSN_SIZE);
29724 }
4962c51a
MS
29725 break;
29726
29727 case BFD_RELOC_ARM_LDC_PC_G0:
29728 case BFD_RELOC_ARM_LDC_PC_G1:
29729 case BFD_RELOC_ARM_LDC_PC_G2:
29730 case BFD_RELOC_ARM_LDC_SB_G0:
29731 case BFD_RELOC_ARM_LDC_SB_G1:
29732 case BFD_RELOC_ARM_LDC_SB_G2:
9c2799c2 29733 gas_assert (!fixP->fx_done);
4962c51a 29734 if (!seg->use_rela_p)
477330fc
RM
29735 {
29736 bfd_vma insn;
3ca4a8ec 29737 bfd_vma addend_abs = llabs (value);
4962c51a 29738
477330fc
RM
29739 /* Check that the absolute value of the addend is a multiple of
29740 four and, when divided by four, fits in 8 bits. */
29741 if (addend_abs & 0x3)
4962c51a 29742 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29743 _("bad offset 0x%08lX (must be word-aligned)"),
29744 (unsigned long) addend_abs);
4962c51a 29745
477330fc 29746 if ((addend_abs >> 2) > 0xff)
4962c51a 29747 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
29748 _("bad offset 0x%08lX (must be an 8-bit number of words)"),
29749 (unsigned long) addend_abs);
29750
29751 /* Extract the instruction. */
29752 insn = md_chars_to_number (buf, INSN_SIZE);
29753
29754 /* If the addend is negative, clear bit 23 of the instruction.
29755 Otherwise set it. */
29756 if (value < 0)
29757 insn &= ~(1 << 23);
29758 else
29759 insn |= 1 << 23;
29760
29761 /* Place the addend (divided by four) into the first eight
29762 bits of the instruction. */
29763 insn &= 0xfffffff0;
29764 insn |= addend_abs >> 2;
29765
29766 /* Update the instruction. */
29767 md_number_to_chars (buf, insn, INSN_SIZE);
29768 }
4962c51a
MS
29769 break;
29770
e12437dc
AV
29771 case BFD_RELOC_THUMB_PCREL_BRANCH5:
29772 if (fixP->fx_addsy
29773 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29774 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
29775 && ARM_IS_FUNC (fixP->fx_addsy)
29776 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29777 {
29778 /* Force a relocation for a branch 5 bits wide. */
29779 fixP->fx_done = 0;
29780 }
29781 if (v8_1_branch_value_check (value, 5, FALSE) == FAIL)
29782 as_bad_where (fixP->fx_file, fixP->fx_line,
29783 BAD_BRANCH_OFF);
29784
29785 if (fixP->fx_done || !seg->use_rela_p)
29786 {
29787 addressT boff = value >> 1;
29788
29789 newval = md_chars_to_number (buf, THUMB_SIZE);
29790 newval |= (boff << 7);
29791 md_number_to_chars (buf, newval, THUMB_SIZE);
29792 }
29793 break;
29794
f6b2b12d
AV
29795 case BFD_RELOC_THUMB_PCREL_BFCSEL:
29796 if (fixP->fx_addsy
29797 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29798 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
29799 && ARM_IS_FUNC (fixP->fx_addsy)
29800 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29801 {
29802 fixP->fx_done = 0;
29803 }
29804 if ((value & ~0x7f) && ((value & ~0x3f) != ~0x3f))
29805 as_bad_where (fixP->fx_file, fixP->fx_line,
29806 _("branch out of range"));
29807
29808 if (fixP->fx_done || !seg->use_rela_p)
29809 {
29810 newval = md_chars_to_number (buf, THUMB_SIZE);
29811
29812 addressT boff = ((newval & 0x0780) >> 7) << 1;
29813 addressT diff = value - boff;
29814
29815 if (diff == 4)
29816 {
29817 newval |= 1 << 1; /* T bit. */
29818 }
29819 else if (diff != 2)
29820 {
29821 as_bad_where (fixP->fx_file, fixP->fx_line,
29822 _("out of range label-relative fixup value"));
29823 }
29824 md_number_to_chars (buf, newval, THUMB_SIZE);
29825 }
29826 break;
29827
e5d6e09e
AV
29828 case BFD_RELOC_ARM_THUMB_BF17:
29829 if (fixP->fx_addsy
29830 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29831 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
29832 && ARM_IS_FUNC (fixP->fx_addsy)
29833 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29834 {
29835 /* Force a relocation for a branch 17 bits wide. */
29836 fixP->fx_done = 0;
29837 }
29838
29839 if (v8_1_branch_value_check (value, 17, TRUE) == FAIL)
29840 as_bad_where (fixP->fx_file, fixP->fx_line,
29841 BAD_BRANCH_OFF);
29842
29843 if (fixP->fx_done || !seg->use_rela_p)
29844 {
29845 offsetT newval2;
29846 addressT immA, immB, immC;
29847
29848 immA = (value & 0x0001f000) >> 12;
29849 immB = (value & 0x00000ffc) >> 2;
29850 immC = (value & 0x00000002) >> 1;
29851
29852 newval = md_chars_to_number (buf, THUMB_SIZE);
29853 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29854 newval |= immA;
29855 newval2 |= (immC << 11) | (immB << 1);
29856 md_number_to_chars (buf, newval, THUMB_SIZE);
29857 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
29858 }
29859 break;
29860
1caf72a5
AV
29861 case BFD_RELOC_ARM_THUMB_BF19:
29862 if (fixP->fx_addsy
29863 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29864 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
29865 && ARM_IS_FUNC (fixP->fx_addsy)
29866 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29867 {
29868 /* Force a relocation for a branch 19 bits wide. */
29869 fixP->fx_done = 0;
29870 }
29871
29872 if (v8_1_branch_value_check (value, 19, TRUE) == FAIL)
29873 as_bad_where (fixP->fx_file, fixP->fx_line,
29874 BAD_BRANCH_OFF);
29875
29876 if (fixP->fx_done || !seg->use_rela_p)
29877 {
29878 offsetT newval2;
29879 addressT immA, immB, immC;
29880
29881 immA = (value & 0x0007f000) >> 12;
29882 immB = (value & 0x00000ffc) >> 2;
29883 immC = (value & 0x00000002) >> 1;
29884
29885 newval = md_chars_to_number (buf, THUMB_SIZE);
29886 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29887 newval |= immA;
29888 newval2 |= (immC << 11) | (immB << 1);
29889 md_number_to_chars (buf, newval, THUMB_SIZE);
29890 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
29891 }
29892 break;
29893
1889da70
AV
29894 case BFD_RELOC_ARM_THUMB_BF13:
29895 if (fixP->fx_addsy
29896 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29897 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
29898 && ARM_IS_FUNC (fixP->fx_addsy)
29899 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29900 {
29901 /* Force a relocation for a branch 13 bits wide. */
29902 fixP->fx_done = 0;
29903 }
29904
29905 if (v8_1_branch_value_check (value, 13, TRUE) == FAIL)
29906 as_bad_where (fixP->fx_file, fixP->fx_line,
29907 BAD_BRANCH_OFF);
29908
29909 if (fixP->fx_done || !seg->use_rela_p)
29910 {
29911 offsetT newval2;
29912 addressT immA, immB, immC;
29913
29914 immA = (value & 0x00001000) >> 12;
29915 immB = (value & 0x00000ffc) >> 2;
29916 immC = (value & 0x00000002) >> 1;
29917
29918 newval = md_chars_to_number (buf, THUMB_SIZE);
29919 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29920 newval |= immA;
29921 newval2 |= (immC << 11) | (immB << 1);
29922 md_number_to_chars (buf, newval, THUMB_SIZE);
29923 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
29924 }
29925 break;
29926
60f993ce
AV
29927 case BFD_RELOC_ARM_THUMB_LOOP12:
29928 if (fixP->fx_addsy
29929 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
29930 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
29931 && ARM_IS_FUNC (fixP->fx_addsy)
29932 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
29933 {
29934 /* Force a relocation for a branch 12 bits wide. */
29935 fixP->fx_done = 0;
29936 }
29937
29938 bfd_vma insn = get_thumb32_insn (buf);
1f6234a3 29939 /* le lr, <label>, le <label> or letp lr, <label> */
60f993ce 29940 if (((insn & 0xffffffff) == 0xf00fc001)
1f6234a3
AV
29941 || ((insn & 0xffffffff) == 0xf02fc001)
29942 || ((insn & 0xffffffff) == 0xf01fc001))
60f993ce
AV
29943 value = -value;
29944
29945 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
29946 as_bad_where (fixP->fx_file, fixP->fx_line,
29947 BAD_BRANCH_OFF);
29948 if (fixP->fx_done || !seg->use_rela_p)
29949 {
29950 addressT imml, immh;
29951
29952 immh = (value & 0x00000ffc) >> 2;
29953 imml = (value & 0x00000002) >> 1;
29954
29955 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
29956 newval |= (imml << 11) | (immh << 1);
29957 md_number_to_chars (buf + THUMB_SIZE, newval, THUMB_SIZE);
29958 }
29959 break;
29960
845b51d6
PB
29961 case BFD_RELOC_ARM_V4BX:
29962 /* This will need to go in the object file. */
29963 fixP->fx_done = 0;
29964 break;
29965
c19d1205
ZW
29966 case BFD_RELOC_UNUSED:
29967 default:
29968 as_bad_where (fixP->fx_file, fixP->fx_line,
29969 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
29970 }
6c43fab6
RE
29971}
29972
c19d1205
ZW
29973/* Translate internal representation of relocation info to BFD target
29974 format. */
a737bd4d 29975
c19d1205 29976arelent *
00a97672 29977tc_gen_reloc (asection *section, fixS *fixp)
a737bd4d 29978{
c19d1205
ZW
29979 arelent * reloc;
29980 bfd_reloc_code_real_type code;
a737bd4d 29981
325801bd 29982 reloc = XNEW (arelent);
a737bd4d 29983
325801bd 29984 reloc->sym_ptr_ptr = XNEW (asymbol *);
c19d1205
ZW
29985 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
29986 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
a737bd4d 29987
2fc8bdac 29988 if (fixp->fx_pcrel)
00a97672
RS
29989 {
29990 if (section->use_rela_p)
29991 fixp->fx_offset -= md_pcrel_from_section (fixp, section);
29992 else
29993 fixp->fx_offset = reloc->address;
29994 }
c19d1205 29995 reloc->addend = fixp->fx_offset;
a737bd4d 29996
c19d1205 29997 switch (fixp->fx_r_type)
a737bd4d 29998 {
c19d1205
ZW
29999 case BFD_RELOC_8:
30000 if (fixp->fx_pcrel)
30001 {
30002 code = BFD_RELOC_8_PCREL;
30003 break;
30004 }
1a0670f3 30005 /* Fall through. */
a737bd4d 30006
c19d1205
ZW
30007 case BFD_RELOC_16:
30008 if (fixp->fx_pcrel)
30009 {
30010 code = BFD_RELOC_16_PCREL;
30011 break;
30012 }
1a0670f3 30013 /* Fall through. */
6c43fab6 30014
c19d1205
ZW
30015 case BFD_RELOC_32:
30016 if (fixp->fx_pcrel)
30017 {
30018 code = BFD_RELOC_32_PCREL;
30019 break;
30020 }
1a0670f3 30021 /* Fall through. */
a737bd4d 30022
b6895b4f
PB
30023 case BFD_RELOC_ARM_MOVW:
30024 if (fixp->fx_pcrel)
30025 {
30026 code = BFD_RELOC_ARM_MOVW_PCREL;
30027 break;
30028 }
1a0670f3 30029 /* Fall through. */
b6895b4f
PB
30030
30031 case BFD_RELOC_ARM_MOVT:
30032 if (fixp->fx_pcrel)
30033 {
30034 code = BFD_RELOC_ARM_MOVT_PCREL;
30035 break;
30036 }
1a0670f3 30037 /* Fall through. */
b6895b4f
PB
30038
30039 case BFD_RELOC_ARM_THUMB_MOVW:
30040 if (fixp->fx_pcrel)
30041 {
30042 code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
30043 break;
30044 }
1a0670f3 30045 /* Fall through. */
b6895b4f
PB
30046
30047 case BFD_RELOC_ARM_THUMB_MOVT:
30048 if (fixp->fx_pcrel)
30049 {
30050 code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
30051 break;
30052 }
1a0670f3 30053 /* Fall through. */
b6895b4f 30054
c19d1205
ZW
30055 case BFD_RELOC_NONE:
30056 case BFD_RELOC_ARM_PCREL_BRANCH:
30057 case BFD_RELOC_ARM_PCREL_BLX:
30058 case BFD_RELOC_RVA:
30059 case BFD_RELOC_THUMB_PCREL_BRANCH7:
30060 case BFD_RELOC_THUMB_PCREL_BRANCH9:
30061 case BFD_RELOC_THUMB_PCREL_BRANCH12:
30062 case BFD_RELOC_THUMB_PCREL_BRANCH20:
30063 case BFD_RELOC_THUMB_PCREL_BRANCH23:
30064 case BFD_RELOC_THUMB_PCREL_BRANCH25:
c19d1205
ZW
30065 case BFD_RELOC_VTABLE_ENTRY:
30066 case BFD_RELOC_VTABLE_INHERIT:
f0927246
NC
30067#ifdef TE_PE
30068 case BFD_RELOC_32_SECREL:
30069#endif
c19d1205
ZW
30070 code = fixp->fx_r_type;
30071 break;
a737bd4d 30072
00adf2d4
JB
30073 case BFD_RELOC_THUMB_PCREL_BLX:
30074#ifdef OBJ_ELF
30075 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
30076 code = BFD_RELOC_THUMB_PCREL_BRANCH23;
30077 else
30078#endif
30079 code = BFD_RELOC_THUMB_PCREL_BLX;
30080 break;
30081
c19d1205
ZW
30082 case BFD_RELOC_ARM_LITERAL:
30083 case BFD_RELOC_ARM_HWLITERAL:
30084 /* If this is called then the a literal has
30085 been referenced across a section boundary. */
30086 as_bad_where (fixp->fx_file, fixp->fx_line,
30087 _("literal referenced across section boundary"));
30088 return NULL;
a737bd4d 30089
c19d1205 30090#ifdef OBJ_ELF
0855e32b
NS
30091 case BFD_RELOC_ARM_TLS_CALL:
30092 case BFD_RELOC_ARM_THM_TLS_CALL:
30093 case BFD_RELOC_ARM_TLS_DESCSEQ:
30094 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
c19d1205
ZW
30095 case BFD_RELOC_ARM_GOT32:
30096 case BFD_RELOC_ARM_GOTOFF:
b43420e6 30097 case BFD_RELOC_ARM_GOT_PREL:
c19d1205
ZW
30098 case BFD_RELOC_ARM_PLT32:
30099 case BFD_RELOC_ARM_TARGET1:
30100 case BFD_RELOC_ARM_ROSEGREL32:
30101 case BFD_RELOC_ARM_SBREL32:
30102 case BFD_RELOC_ARM_PREL31:
30103 case BFD_RELOC_ARM_TARGET2:
c19d1205 30104 case BFD_RELOC_ARM_TLS_LDO32:
39b41c9c
PB
30105 case BFD_RELOC_ARM_PCREL_CALL:
30106 case BFD_RELOC_ARM_PCREL_JUMP:
4962c51a
MS
30107 case BFD_RELOC_ARM_ALU_PC_G0_NC:
30108 case BFD_RELOC_ARM_ALU_PC_G0:
30109 case BFD_RELOC_ARM_ALU_PC_G1_NC:
30110 case BFD_RELOC_ARM_ALU_PC_G1:
30111 case BFD_RELOC_ARM_ALU_PC_G2:
30112 case BFD_RELOC_ARM_LDR_PC_G0:
30113 case BFD_RELOC_ARM_LDR_PC_G1:
30114 case BFD_RELOC_ARM_LDR_PC_G2:
30115 case BFD_RELOC_ARM_LDRS_PC_G0:
30116 case BFD_RELOC_ARM_LDRS_PC_G1:
30117 case BFD_RELOC_ARM_LDRS_PC_G2:
30118 case BFD_RELOC_ARM_LDC_PC_G0:
30119 case BFD_RELOC_ARM_LDC_PC_G1:
30120 case BFD_RELOC_ARM_LDC_PC_G2:
30121 case BFD_RELOC_ARM_ALU_SB_G0_NC:
30122 case BFD_RELOC_ARM_ALU_SB_G0:
30123 case BFD_RELOC_ARM_ALU_SB_G1_NC:
30124 case BFD_RELOC_ARM_ALU_SB_G1:
30125 case BFD_RELOC_ARM_ALU_SB_G2:
30126 case BFD_RELOC_ARM_LDR_SB_G0:
30127 case BFD_RELOC_ARM_LDR_SB_G1:
30128 case BFD_RELOC_ARM_LDR_SB_G2:
30129 case BFD_RELOC_ARM_LDRS_SB_G0:
30130 case BFD_RELOC_ARM_LDRS_SB_G1:
30131 case BFD_RELOC_ARM_LDRS_SB_G2:
30132 case BFD_RELOC_ARM_LDC_SB_G0:
30133 case BFD_RELOC_ARM_LDC_SB_G1:
30134 case BFD_RELOC_ARM_LDC_SB_G2:
845b51d6 30135 case BFD_RELOC_ARM_V4BX:
72d98d16
MG
30136 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
30137 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
30138 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
30139 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
188fd7ae
CL
30140 case BFD_RELOC_ARM_GOTFUNCDESC:
30141 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
30142 case BFD_RELOC_ARM_FUNCDESC:
e5d6e09e 30143 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 30144 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 30145 case BFD_RELOC_ARM_THUMB_BF13:
c19d1205
ZW
30146 code = fixp->fx_r_type;
30147 break;
a737bd4d 30148
0855e32b 30149 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205 30150 case BFD_RELOC_ARM_TLS_GD32:
5c5a4843 30151 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
75c11999 30152 case BFD_RELOC_ARM_TLS_LE32:
c19d1205 30153 case BFD_RELOC_ARM_TLS_IE32:
5c5a4843 30154 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
c19d1205 30155 case BFD_RELOC_ARM_TLS_LDM32:
5c5a4843 30156 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
c19d1205
ZW
30157 /* BFD will include the symbol's address in the addend.
30158 But we don't want that, so subtract it out again here. */
30159 if (!S_IS_COMMON (fixp->fx_addsy))
30160 reloc->addend -= (*reloc->sym_ptr_ptr)->value;
30161 code = fixp->fx_r_type;
30162 break;
30163#endif
a737bd4d 30164
c19d1205
ZW
30165 case BFD_RELOC_ARM_IMMEDIATE:
30166 as_bad_where (fixp->fx_file, fixp->fx_line,
30167 _("internal relocation (type: IMMEDIATE) not fixed up"));
30168 return NULL;
a737bd4d 30169
c19d1205
ZW
30170 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
30171 as_bad_where (fixp->fx_file, fixp->fx_line,
30172 _("ADRL used for a symbol not defined in the same file"));
30173 return NULL;
a737bd4d 30174
e12437dc 30175 case BFD_RELOC_THUMB_PCREL_BRANCH5:
f6b2b12d 30176 case BFD_RELOC_THUMB_PCREL_BFCSEL:
60f993ce 30177 case BFD_RELOC_ARM_THUMB_LOOP12:
e12437dc
AV
30178 as_bad_where (fixp->fx_file, fixp->fx_line,
30179 _("%s used for a symbol not defined in the same file"),
30180 bfd_get_reloc_code_name (fixp->fx_r_type));
30181 return NULL;
30182
c19d1205 30183 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
30184 if (section->use_rela_p)
30185 {
30186 code = fixp->fx_r_type;
30187 break;
30188 }
30189
c19d1205
ZW
30190 if (fixp->fx_addsy != NULL
30191 && !S_IS_DEFINED (fixp->fx_addsy)
30192 && S_IS_LOCAL (fixp->fx_addsy))
a737bd4d 30193 {
c19d1205
ZW
30194 as_bad_where (fixp->fx_file, fixp->fx_line,
30195 _("undefined local label `%s'"),
30196 S_GET_NAME (fixp->fx_addsy));
30197 return NULL;
a737bd4d
NC
30198 }
30199
c19d1205
ZW
30200 as_bad_where (fixp->fx_file, fixp->fx_line,
30201 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
30202 return NULL;
a737bd4d 30203
c19d1205
ZW
30204 default:
30205 {
e0471c16 30206 const char * type;
6c43fab6 30207
c19d1205
ZW
30208 switch (fixp->fx_r_type)
30209 {
30210 case BFD_RELOC_NONE: type = "NONE"; break;
30211 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
30212 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
3eb17e6b 30213 case BFD_RELOC_ARM_SMC: type = "SMC"; break;
c19d1205
ZW
30214 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
30215 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
30216 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
db187cb9 30217 case BFD_RELOC_ARM_T32_OFFSET_IMM: type = "T32_OFFSET_IMM"; break;
8f06b2d8 30218 case BFD_RELOC_ARM_T32_CP_OFF_IMM: type = "T32_CP_OFF_IMM"; break;
c19d1205
ZW
30219 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
30220 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
30221 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
30222 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
30223 default: type = _("<unknown>"); break;
30224 }
30225 as_bad_where (fixp->fx_file, fixp->fx_line,
30226 _("cannot represent %s relocation in this object file format"),
30227 type);
30228 return NULL;
30229 }
a737bd4d 30230 }
6c43fab6 30231
c19d1205
ZW
30232#ifdef OBJ_ELF
30233 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
30234 && GOT_symbol
30235 && fixp->fx_addsy == GOT_symbol)
30236 {
30237 code = BFD_RELOC_ARM_GOTPC;
30238 reloc->addend = fixp->fx_offset = reloc->address;
30239 }
30240#endif
6c43fab6 30241
c19d1205 30242 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6c43fab6 30243
c19d1205
ZW
30244 if (reloc->howto == NULL)
30245 {
30246 as_bad_where (fixp->fx_file, fixp->fx_line,
30247 _("cannot represent %s relocation in this object file format"),
30248 bfd_get_reloc_code_name (code));
30249 return NULL;
30250 }
6c43fab6 30251
c19d1205
ZW
30252 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
30253 vtable entry to be used in the relocation's section offset. */
30254 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
30255 reloc->address = fixp->fx_offset;
6c43fab6 30256
c19d1205 30257 return reloc;
6c43fab6
RE
30258}
30259
c19d1205 30260/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6c43fab6 30261
c19d1205
ZW
30262void
30263cons_fix_new_arm (fragS * frag,
30264 int where,
30265 int size,
62ebcb5c
AM
30266 expressionS * exp,
30267 bfd_reloc_code_real_type reloc)
6c43fab6 30268{
c19d1205 30269 int pcrel = 0;
6c43fab6 30270
c19d1205
ZW
30271 /* Pick a reloc.
30272 FIXME: @@ Should look at CPU word size. */
30273 switch (size)
30274 {
30275 case 1:
62ebcb5c 30276 reloc = BFD_RELOC_8;
c19d1205
ZW
30277 break;
30278 case 2:
62ebcb5c 30279 reloc = BFD_RELOC_16;
c19d1205
ZW
30280 break;
30281 case 4:
30282 default:
62ebcb5c 30283 reloc = BFD_RELOC_32;
c19d1205
ZW
30284 break;
30285 case 8:
62ebcb5c 30286 reloc = BFD_RELOC_64;
c19d1205
ZW
30287 break;
30288 }
6c43fab6 30289
f0927246
NC
30290#ifdef TE_PE
30291 if (exp->X_op == O_secrel)
30292 {
30293 exp->X_op = O_symbol;
62ebcb5c 30294 reloc = BFD_RELOC_32_SECREL;
f0927246
NC
30295 }
30296#endif
30297
62ebcb5c 30298 fix_new_exp (frag, where, size, exp, pcrel, reloc);
c19d1205 30299}
6c43fab6 30300
4343666d 30301#if defined (OBJ_COFF)
c19d1205
ZW
30302void
30303arm_validate_fix (fixS * fixP)
6c43fab6 30304{
c19d1205
ZW
30305 /* If the destination of the branch is a defined symbol which does not have
30306 the THUMB_FUNC attribute, then we must be calling a function which has
30307 the (interfacearm) attribute. We look for the Thumb entry point to that
30308 function and change the branch to refer to that function instead. */
30309 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
30310 && fixP->fx_addsy != NULL
30311 && S_IS_DEFINED (fixP->fx_addsy)
30312 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6c43fab6 30313 {
c19d1205 30314 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6c43fab6 30315 }
c19d1205
ZW
30316}
30317#endif
6c43fab6 30318
267bf995 30319
c19d1205
ZW
30320int
30321arm_force_relocation (struct fix * fixp)
30322{
30323#if defined (OBJ_COFF) && defined (TE_PE)
30324 if (fixp->fx_r_type == BFD_RELOC_RVA)
30325 return 1;
30326#endif
6c43fab6 30327
267bf995
RR
30328 /* In case we have a call or a branch to a function in ARM ISA mode from
30329 a thumb function or vice-versa force the relocation. These relocations
30330 are cleared off for some cores that might have blx and simple transformations
30331 are possible. */
30332
30333#ifdef OBJ_ELF
30334 switch (fixp->fx_r_type)
30335 {
30336 case BFD_RELOC_ARM_PCREL_JUMP:
30337 case BFD_RELOC_ARM_PCREL_CALL:
30338 case BFD_RELOC_THUMB_PCREL_BLX:
30339 if (THUMB_IS_FUNC (fixp->fx_addsy))
30340 return 1;
30341 break;
30342
30343 case BFD_RELOC_ARM_PCREL_BLX:
30344 case BFD_RELOC_THUMB_PCREL_BRANCH25:
30345 case BFD_RELOC_THUMB_PCREL_BRANCH20:
30346 case BFD_RELOC_THUMB_PCREL_BRANCH23:
30347 if (ARM_IS_FUNC (fixp->fx_addsy))
30348 return 1;
30349 break;
30350
30351 default:
30352 break;
30353 }
30354#endif
30355
b5884301
PB
30356 /* Resolve these relocations even if the symbol is extern or weak.
30357 Technically this is probably wrong due to symbol preemption.
30358 In practice these relocations do not have enough range to be useful
30359 at dynamic link time, and some code (e.g. in the Linux kernel)
30360 expects these references to be resolved. */
c19d1205
ZW
30361 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
30362 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
b5884301 30363 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM8
0110f2b8 30364 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
b5884301
PB
30365 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
30366 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2
30367 || fixp->fx_r_type == BFD_RELOC_ARM_THUMB_OFFSET
16805f35 30368 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
0110f2b8
PB
30369 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
30370 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
b5884301
PB
30371 || fixp->fx_r_type == BFD_RELOC_ARM_T32_OFFSET_IMM
30372 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12
30373 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM
30374 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM_S2)
c19d1205 30375 return 0;
a737bd4d 30376
4962c51a
MS
30377 /* Always leave these relocations for the linker. */
30378 if ((fixp->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
30379 && fixp->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
30380 || fixp->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
30381 return 1;
30382
f0291e4c
PB
30383 /* Always generate relocations against function symbols. */
30384 if (fixp->fx_r_type == BFD_RELOC_32
30385 && fixp->fx_addsy
30386 && (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION))
30387 return 1;
30388
c19d1205 30389 return generic_force_reloc (fixp);
404ff6b5
AH
30390}
30391
0ffdc86c 30392#if defined (OBJ_ELF) || defined (OBJ_COFF)
e28387c3
PB
30393/* Relocations against function names must be left unadjusted,
30394 so that the linker can use this information to generate interworking
30395 stubs. The MIPS version of this function
c19d1205
ZW
30396 also prevents relocations that are mips-16 specific, but I do not
30397 know why it does this.
404ff6b5 30398
c19d1205
ZW
30399 FIXME:
30400 There is one other problem that ought to be addressed here, but
30401 which currently is not: Taking the address of a label (rather
30402 than a function) and then later jumping to that address. Such
30403 addresses also ought to have their bottom bit set (assuming that
30404 they reside in Thumb code), but at the moment they will not. */
404ff6b5 30405
c19d1205
ZW
30406bfd_boolean
30407arm_fix_adjustable (fixS * fixP)
404ff6b5 30408{
c19d1205
ZW
30409 if (fixP->fx_addsy == NULL)
30410 return 1;
404ff6b5 30411
e28387c3
PB
30412 /* Preserve relocations against symbols with function type. */
30413 if (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION)
c921be7d 30414 return FALSE;
e28387c3 30415
c19d1205
ZW
30416 if (THUMB_IS_FUNC (fixP->fx_addsy)
30417 && fixP->fx_subsy == NULL)
c921be7d 30418 return FALSE;
a737bd4d 30419
c19d1205
ZW
30420 /* We need the symbol name for the VTABLE entries. */
30421 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
30422 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
c921be7d 30423 return FALSE;
404ff6b5 30424
c19d1205
ZW
30425 /* Don't allow symbols to be discarded on GOT related relocs. */
30426 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
30427 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
30428 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
30429 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
5c5a4843 30430 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32_FDPIC
c19d1205
ZW
30431 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
30432 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
5c5a4843 30433 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32_FDPIC
c19d1205 30434 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
5c5a4843 30435 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32_FDPIC
c19d1205 30436 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
0855e32b
NS
30437 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GOTDESC
30438 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
30439 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_CALL
30440 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
30441 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_DESCSEQ
c19d1205 30442 || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
c921be7d 30443 return FALSE;
a737bd4d 30444
4962c51a
MS
30445 /* Similarly for group relocations. */
30446 if ((fixP->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
30447 && fixP->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
30448 || fixP->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
c921be7d 30449 return FALSE;
4962c51a 30450
79947c54
CD
30451 /* MOVW/MOVT REL relocations have limited offsets, so keep the symbols. */
30452 if (fixP->fx_r_type == BFD_RELOC_ARM_MOVW
30453 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT
30454 || fixP->fx_r_type == BFD_RELOC_ARM_MOVW_PCREL
30455 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT_PCREL
30456 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
30457 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT
30458 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW_PCREL
30459 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
c921be7d 30460 return FALSE;
79947c54 30461
72d98d16
MG
30462 /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
30463 offsets, so keep these symbols. */
30464 if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
30465 && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
30466 return FALSE;
30467
c921be7d 30468 return TRUE;
a737bd4d 30469}
0ffdc86c
NC
30470#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
30471
30472#ifdef OBJ_ELF
c19d1205
ZW
30473const char *
30474elf32_arm_target_format (void)
404ff6b5 30475{
c19d1205
ZW
30476#ifdef TE_SYMBIAN
30477 return (target_big_endian
30478 ? "elf32-bigarm-symbian"
30479 : "elf32-littlearm-symbian");
30480#elif defined (TE_VXWORKS)
30481 return (target_big_endian
30482 ? "elf32-bigarm-vxworks"
30483 : "elf32-littlearm-vxworks");
b38cadfb
NC
30484#elif defined (TE_NACL)
30485 return (target_big_endian
30486 ? "elf32-bigarm-nacl"
30487 : "elf32-littlearm-nacl");
c19d1205 30488#else
18a20338
CL
30489 if (arm_fdpic)
30490 {
30491 if (target_big_endian)
30492 return "elf32-bigarm-fdpic";
30493 else
30494 return "elf32-littlearm-fdpic";
30495 }
c19d1205 30496 else
18a20338
CL
30497 {
30498 if (target_big_endian)
30499 return "elf32-bigarm";
30500 else
30501 return "elf32-littlearm";
30502 }
c19d1205 30503#endif
404ff6b5
AH
30504}
30505
c19d1205
ZW
30506void
30507armelf_frob_symbol (symbolS * symp,
30508 int * puntp)
404ff6b5 30509{
c19d1205
ZW
30510 elf_frob_symbol (symp, puntp);
30511}
30512#endif
404ff6b5 30513
c19d1205 30514/* MD interface: Finalization. */
a737bd4d 30515
c19d1205
ZW
30516void
30517arm_cleanup (void)
30518{
30519 literal_pool * pool;
a737bd4d 30520
5ee91343
AV
30521 /* Ensure that all the predication blocks are properly closed. */
30522 check_pred_blocks_finished ();
e07e6e58 30523
c19d1205
ZW
30524 for (pool = list_of_pools; pool; pool = pool->next)
30525 {
5f4273c7 30526 /* Put it at the end of the relevant section. */
c19d1205
ZW
30527 subseg_set (pool->section, pool->sub_section);
30528#ifdef OBJ_ELF
30529 arm_elf_change_section ();
30530#endif
30531 s_ltorg (0);
30532 }
404ff6b5
AH
30533}
30534
cd000bff
DJ
30535#ifdef OBJ_ELF
30536/* Remove any excess mapping symbols generated for alignment frags in
30537 SEC. We may have created a mapping symbol before a zero byte
30538 alignment; remove it if there's a mapping symbol after the
30539 alignment. */
30540static void
30541check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
30542 void *dummy ATTRIBUTE_UNUSED)
30543{
30544 segment_info_type *seginfo = seg_info (sec);
30545 fragS *fragp;
30546
30547 if (seginfo == NULL || seginfo->frchainP == NULL)
30548 return;
30549
30550 for (fragp = seginfo->frchainP->frch_root;
30551 fragp != NULL;
30552 fragp = fragp->fr_next)
30553 {
30554 symbolS *sym = fragp->tc_frag_data.last_map;
30555 fragS *next = fragp->fr_next;
30556
30557 /* Variable-sized frags have been converted to fixed size by
30558 this point. But if this was variable-sized to start with,
30559 there will be a fixed-size frag after it. So don't handle
30560 next == NULL. */
30561 if (sym == NULL || next == NULL)
30562 continue;
30563
30564 if (S_GET_VALUE (sym) < next->fr_address)
30565 /* Not at the end of this frag. */
30566 continue;
30567 know (S_GET_VALUE (sym) == next->fr_address);
30568
30569 do
30570 {
30571 if (next->tc_frag_data.first_map != NULL)
30572 {
30573 /* Next frag starts with a mapping symbol. Discard this
30574 one. */
30575 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
30576 break;
30577 }
30578
30579 if (next->fr_next == NULL)
30580 {
30581 /* This mapping symbol is at the end of the section. Discard
30582 it. */
30583 know (next->fr_fix == 0 && next->fr_var == 0);
30584 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
30585 break;
30586 }
30587
30588 /* As long as we have empty frags without any mapping symbols,
30589 keep looking. */
30590 /* If the next frag is non-empty and does not start with a
30591 mapping symbol, then this mapping symbol is required. */
30592 if (next->fr_address != next->fr_next->fr_address)
30593 break;
30594
30595 next = next->fr_next;
30596 }
30597 while (next != NULL);
30598 }
30599}
30600#endif
30601
c19d1205
ZW
30602/* Adjust the symbol table. This marks Thumb symbols as distinct from
30603 ARM ones. */
404ff6b5 30604
c19d1205
ZW
30605void
30606arm_adjust_symtab (void)
404ff6b5 30607{
c19d1205
ZW
30608#ifdef OBJ_COFF
30609 symbolS * sym;
404ff6b5 30610
c19d1205
ZW
30611 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
30612 {
30613 if (ARM_IS_THUMB (sym))
30614 {
30615 if (THUMB_IS_FUNC (sym))
30616 {
30617 /* Mark the symbol as a Thumb function. */
30618 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
30619 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
30620 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
404ff6b5 30621
c19d1205
ZW
30622 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
30623 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
30624 else
30625 as_bad (_("%s: unexpected function type: %d"),
30626 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
30627 }
30628 else switch (S_GET_STORAGE_CLASS (sym))
30629 {
30630 case C_EXT:
30631 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
30632 break;
30633 case C_STAT:
30634 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
30635 break;
30636 case C_LABEL:
30637 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
30638 break;
30639 default:
30640 /* Do nothing. */
30641 break;
30642 }
30643 }
a737bd4d 30644
c19d1205
ZW
30645 if (ARM_IS_INTERWORK (sym))
30646 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
404ff6b5 30647 }
c19d1205
ZW
30648#endif
30649#ifdef OBJ_ELF
30650 symbolS * sym;
30651 char bind;
404ff6b5 30652
c19d1205 30653 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
404ff6b5 30654 {
c19d1205
ZW
30655 if (ARM_IS_THUMB (sym))
30656 {
30657 elf_symbol_type * elf_sym;
404ff6b5 30658
c19d1205
ZW
30659 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
30660 bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
404ff6b5 30661
b0796911
PB
30662 if (! bfd_is_arm_special_symbol_name (elf_sym->symbol.name,
30663 BFD_ARM_SPECIAL_SYM_TYPE_ANY))
c19d1205
ZW
30664 {
30665 /* If it's a .thumb_func, declare it as so,
30666 otherwise tag label as .code 16. */
30667 if (THUMB_IS_FUNC (sym))
39d911fc
TP
30668 ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
30669 ST_BRANCH_TO_THUMB);
3ba67470 30670 else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
c19d1205
ZW
30671 elf_sym->internal_elf_sym.st_info =
30672 ELF_ST_INFO (bind, STT_ARM_16BIT);
30673 }
30674 }
30675 }
cd000bff
DJ
30676
30677 /* Remove any overlapping mapping symbols generated by alignment frags. */
30678 bfd_map_over_sections (stdoutput, check_mapping_symbols, (char *) 0);
709001e9
MM
30679 /* Now do generic ELF adjustments. */
30680 elf_adjust_symtab ();
c19d1205 30681#endif
404ff6b5
AH
30682}
30683
c19d1205 30684/* MD interface: Initialization. */
404ff6b5 30685
a737bd4d 30686static void
c19d1205 30687set_constant_flonums (void)
a737bd4d 30688{
c19d1205 30689 int i;
404ff6b5 30690
c19d1205
ZW
30691 for (i = 0; i < NUM_FLOAT_VALS; i++)
30692 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
30693 abort ();
a737bd4d 30694}
404ff6b5 30695
3e9e4fcf
JB
30696/* Auto-select Thumb mode if it's the only available instruction set for the
30697 given architecture. */
30698
30699static void
30700autoselect_thumb_from_cpu_variant (void)
30701{
30702 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
30703 opcode_select (16);
30704}
30705
c19d1205
ZW
30706void
30707md_begin (void)
a737bd4d 30708{
c19d1205
ZW
30709 unsigned mach;
30710 unsigned int i;
404ff6b5 30711
c19d1205
ZW
30712 if ( (arm_ops_hsh = hash_new ()) == NULL
30713 || (arm_cond_hsh = hash_new ()) == NULL
5ee91343 30714 || (arm_vcond_hsh = hash_new ()) == NULL
c19d1205
ZW
30715 || (arm_shift_hsh = hash_new ()) == NULL
30716 || (arm_psr_hsh = hash_new ()) == NULL
62b3e311 30717 || (arm_v7m_psr_hsh = hash_new ()) == NULL
c19d1205 30718 || (arm_reg_hsh = hash_new ()) == NULL
62b3e311
PB
30719 || (arm_reloc_hsh = hash_new ()) == NULL
30720 || (arm_barrier_opt_hsh = hash_new ()) == NULL)
c19d1205
ZW
30721 as_fatal (_("virtual memory exhausted"));
30722
30723 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
d3ce72d0 30724 hash_insert (arm_ops_hsh, insns[i].template_name, (void *) (insns + i));
c19d1205 30725 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
d3ce72d0 30726 hash_insert (arm_cond_hsh, conds[i].template_name, (void *) (conds + i));
5ee91343
AV
30727 for (i = 0; i < sizeof (vconds) / sizeof (struct asm_cond); i++)
30728 hash_insert (arm_vcond_hsh, vconds[i].template_name, (void *) (vconds + i));
c19d1205 30729 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
5a49b8ac 30730 hash_insert (arm_shift_hsh, shift_names[i].name, (void *) (shift_names + i));
c19d1205 30731 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 30732 hash_insert (arm_psr_hsh, psrs[i].template_name, (void *) (psrs + i));
62b3e311 30733 for (i = 0; i < sizeof (v7m_psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 30734 hash_insert (arm_v7m_psr_hsh, v7m_psrs[i].template_name,
477330fc 30735 (void *) (v7m_psrs + i));
c19d1205 30736 for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
5a49b8ac 30737 hash_insert (arm_reg_hsh, reg_names[i].name, (void *) (reg_names + i));
62b3e311
PB
30738 for (i = 0;
30739 i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
30740 i++)
d3ce72d0 30741 hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
5a49b8ac 30742 (void *) (barrier_opt_names + i));
c19d1205 30743#ifdef OBJ_ELF
3da1d841
NC
30744 for (i = 0; i < ARRAY_SIZE (reloc_names); i++)
30745 {
30746 struct reloc_entry * entry = reloc_names + i;
30747
30748 if (arm_is_eabi() && entry->reloc == BFD_RELOC_ARM_PLT32)
30749 /* This makes encode_branch() use the EABI versions of this relocation. */
30750 entry->reloc = BFD_RELOC_UNUSED;
30751
30752 hash_insert (arm_reloc_hsh, entry->name, (void *) entry);
30753 }
c19d1205
ZW
30754#endif
30755
30756 set_constant_flonums ();
404ff6b5 30757
c19d1205
ZW
30758 /* Set the cpu variant based on the command-line options. We prefer
30759 -mcpu= over -march= if both are set (as for GCC); and we prefer
30760 -mfpu= over any other way of setting the floating point unit.
30761 Use of legacy options with new options are faulted. */
e74cfd16 30762 if (legacy_cpu)
404ff6b5 30763 {
e74cfd16 30764 if (mcpu_cpu_opt || march_cpu_opt)
c19d1205
ZW
30765 as_bad (_("use of old and new-style options to set CPU type"));
30766
4d354d8b 30767 selected_arch = *legacy_cpu;
404ff6b5 30768 }
4d354d8b
TP
30769 else if (mcpu_cpu_opt)
30770 {
30771 selected_arch = *mcpu_cpu_opt;
30772 selected_ext = *mcpu_ext_opt;
30773 }
30774 else if (march_cpu_opt)
c168ce07 30775 {
4d354d8b
TP
30776 selected_arch = *march_cpu_opt;
30777 selected_ext = *march_ext_opt;
c168ce07 30778 }
4d354d8b 30779 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
404ff6b5 30780
e74cfd16 30781 if (legacy_fpu)
c19d1205 30782 {
e74cfd16 30783 if (mfpu_opt)
c19d1205 30784 as_bad (_("use of old and new-style options to set FPU type"));
03b1477f 30785
4d354d8b 30786 selected_fpu = *legacy_fpu;
03b1477f 30787 }
4d354d8b
TP
30788 else if (mfpu_opt)
30789 selected_fpu = *mfpu_opt;
30790 else
03b1477f 30791 {
45eb4c1b
NS
30792#if !(defined (EABI_DEFAULT) || defined (TE_LINUX) \
30793 || defined (TE_NetBSD) || defined (TE_VXWORKS))
39c2da32
RE
30794 /* Some environments specify a default FPU. If they don't, infer it
30795 from the processor. */
e74cfd16 30796 if (mcpu_fpu_opt)
4d354d8b 30797 selected_fpu = *mcpu_fpu_opt;
e7da50fa 30798 else if (march_fpu_opt)
4d354d8b 30799 selected_fpu = *march_fpu_opt;
39c2da32 30800#else
4d354d8b 30801 selected_fpu = fpu_default;
39c2da32 30802#endif
03b1477f
RE
30803 }
30804
4d354d8b 30805 if (ARM_FEATURE_ZERO (selected_fpu))
03b1477f 30806 {
4d354d8b
TP
30807 if (!no_cpu_selected ())
30808 selected_fpu = fpu_default;
03b1477f 30809 else
4d354d8b 30810 selected_fpu = fpu_arch_fpa;
03b1477f
RE
30811 }
30812
ee065d83 30813#ifdef CPU_DEFAULT
4d354d8b 30814 if (ARM_FEATURE_ZERO (selected_arch))
ee065d83 30815 {
4d354d8b
TP
30816 selected_arch = cpu_default;
30817 selected_cpu = selected_arch;
ee065d83 30818 }
4d354d8b 30819 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
e74cfd16 30820#else
4d354d8b
TP
30821 /* Autodection of feature mode: allow all features in cpu_variant but leave
30822 selected_cpu unset. It will be set in aeabi_set_public_attributes ()
30823 after all instruction have been processed and we can decide what CPU
30824 should be selected. */
30825 if (ARM_FEATURE_ZERO (selected_arch))
30826 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
ee065d83 30827 else
4d354d8b 30828 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 30829#endif
03b1477f 30830
3e9e4fcf
JB
30831 autoselect_thumb_from_cpu_variant ();
30832
e74cfd16 30833 arm_arch_used = thumb_arch_used = arm_arch_none;
ee065d83 30834
f17c130b 30835#if defined OBJ_COFF || defined OBJ_ELF
b99bd4ef 30836 {
7cc69913
NC
30837 unsigned int flags = 0;
30838
30839#if defined OBJ_ELF
30840 flags = meabi_flags;
d507cf36
PB
30841
30842 switch (meabi_flags)
33a392fb 30843 {
d507cf36 30844 case EF_ARM_EABI_UNKNOWN:
7cc69913 30845#endif
d507cf36
PB
30846 /* Set the flags in the private structure. */
30847 if (uses_apcs_26) flags |= F_APCS26;
30848 if (support_interwork) flags |= F_INTERWORK;
30849 if (uses_apcs_float) flags |= F_APCS_FLOAT;
c19d1205 30850 if (pic_code) flags |= F_PIC;
e74cfd16 30851 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_any_hard))
7cc69913
NC
30852 flags |= F_SOFT_FLOAT;
30853
d507cf36
PB
30854 switch (mfloat_abi_opt)
30855 {
30856 case ARM_FLOAT_ABI_SOFT:
30857 case ARM_FLOAT_ABI_SOFTFP:
30858 flags |= F_SOFT_FLOAT;
30859 break;
33a392fb 30860
d507cf36
PB
30861 case ARM_FLOAT_ABI_HARD:
30862 if (flags & F_SOFT_FLOAT)
30863 as_bad (_("hard-float conflicts with specified fpu"));
30864 break;
30865 }
03b1477f 30866
e74cfd16
PB
30867 /* Using pure-endian doubles (even if soft-float). */
30868 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
7cc69913 30869 flags |= F_VFP_FLOAT;
f17c130b 30870
fde78edd 30871#if defined OBJ_ELF
e74cfd16 30872 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_maverick))
d507cf36 30873 flags |= EF_ARM_MAVERICK_FLOAT;
d507cf36
PB
30874 break;
30875
8cb51566 30876 case EF_ARM_EABI_VER4:
3a4a14e9 30877 case EF_ARM_EABI_VER5:
c19d1205 30878 /* No additional flags to set. */
d507cf36
PB
30879 break;
30880
30881 default:
30882 abort ();
30883 }
7cc69913 30884#endif
b99bd4ef
NC
30885 bfd_set_private_flags (stdoutput, flags);
30886
30887 /* We have run out flags in the COFF header to encode the
30888 status of ATPCS support, so instead we create a dummy,
c19d1205 30889 empty, debug section called .arm.atpcs. */
b99bd4ef
NC
30890 if (atpcs)
30891 {
30892 asection * sec;
30893
30894 sec = bfd_make_section (stdoutput, ".arm.atpcs");
30895
30896 if (sec != NULL)
30897 {
fd361982
AM
30898 bfd_set_section_flags (sec, SEC_READONLY | SEC_DEBUGGING);
30899 bfd_set_section_size (sec, 0);
b99bd4ef
NC
30900 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
30901 }
30902 }
7cc69913 30903 }
f17c130b 30904#endif
b99bd4ef
NC
30905
30906 /* Record the CPU type as well. */
2d447fca
JM
30907 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
30908 mach = bfd_mach_arm_iWMMXt2;
30909 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
e16bb312 30910 mach = bfd_mach_arm_iWMMXt;
e74cfd16 30911 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
b99bd4ef 30912 mach = bfd_mach_arm_XScale;
e74cfd16 30913 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick))
fde78edd 30914 mach = bfd_mach_arm_ep9312;
e74cfd16 30915 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5e))
b99bd4ef 30916 mach = bfd_mach_arm_5TE;
e74cfd16 30917 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5))
b99bd4ef 30918 {
e74cfd16 30919 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
30920 mach = bfd_mach_arm_5T;
30921 else
30922 mach = bfd_mach_arm_5;
30923 }
e74cfd16 30924 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4))
b99bd4ef 30925 {
e74cfd16 30926 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
30927 mach = bfd_mach_arm_4T;
30928 else
30929 mach = bfd_mach_arm_4;
30930 }
e74cfd16 30931 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3m))
b99bd4ef 30932 mach = bfd_mach_arm_3M;
e74cfd16
PB
30933 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3))
30934 mach = bfd_mach_arm_3;
30935 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2s))
30936 mach = bfd_mach_arm_2a;
30937 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2))
30938 mach = bfd_mach_arm_2;
30939 else
30940 mach = bfd_mach_arm_unknown;
b99bd4ef
NC
30941
30942 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
30943}
30944
c19d1205 30945/* Command line processing. */
b99bd4ef 30946
c19d1205
ZW
30947/* md_parse_option
30948 Invocation line includes a switch not recognized by the base assembler.
30949 See if it's a processor-specific option.
b99bd4ef 30950
c19d1205
ZW
30951 This routine is somewhat complicated by the need for backwards
30952 compatibility (since older releases of gcc can't be changed).
30953 The new options try to make the interface as compatible as
30954 possible with GCC.
b99bd4ef 30955
c19d1205 30956 New options (supported) are:
b99bd4ef 30957
c19d1205
ZW
30958 -mcpu=<cpu name> Assemble for selected processor
30959 -march=<architecture name> Assemble for selected architecture
30960 -mfpu=<fpu architecture> Assemble for selected FPU.
30961 -EB/-mbig-endian Big-endian
30962 -EL/-mlittle-endian Little-endian
30963 -k Generate PIC code
30964 -mthumb Start in Thumb mode
30965 -mthumb-interwork Code supports ARM/Thumb interworking
b99bd4ef 30966
278df34e 30967 -m[no-]warn-deprecated Warn about deprecated features
8b2d793c 30968 -m[no-]warn-syms Warn when symbols match instructions
267bf995 30969
c19d1205 30970 For now we will also provide support for:
b99bd4ef 30971
c19d1205
ZW
30972 -mapcs-32 32-bit Program counter
30973 -mapcs-26 26-bit Program counter
30974 -macps-float Floats passed in FP registers
30975 -mapcs-reentrant Reentrant code
30976 -matpcs
30977 (sometime these will probably be replaced with -mapcs=<list of options>
30978 and -matpcs=<list of options>)
b99bd4ef 30979
c19d1205
ZW
30980 The remaining options are only supported for back-wards compatibility.
30981 Cpu variants, the arm part is optional:
30982 -m[arm]1 Currently not supported.
30983 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
30984 -m[arm]3 Arm 3 processor
30985 -m[arm]6[xx], Arm 6 processors
30986 -m[arm]7[xx][t][[d]m] Arm 7 processors
30987 -m[arm]8[10] Arm 8 processors
30988 -m[arm]9[20][tdmi] Arm 9 processors
30989 -mstrongarm[110[0]] StrongARM processors
30990 -mxscale XScale processors
30991 -m[arm]v[2345[t[e]]] Arm architectures
30992 -mall All (except the ARM1)
30993 FP variants:
30994 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
30995 -mfpe-old (No float load/store multiples)
30996 -mvfpxd VFP Single precision
30997 -mvfp All VFP
30998 -mno-fpu Disable all floating point instructions
b99bd4ef 30999
c19d1205
ZW
31000 The following CPU names are recognized:
31001 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
31002 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
31003 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
31004 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
31005 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
31006 arm10t arm10e, arm1020t, arm1020e, arm10200e,
31007 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
b99bd4ef 31008
c19d1205 31009 */
b99bd4ef 31010
c19d1205 31011const char * md_shortopts = "m:k";
b99bd4ef 31012
c19d1205
ZW
31013#ifdef ARM_BI_ENDIAN
31014#define OPTION_EB (OPTION_MD_BASE + 0)
31015#define OPTION_EL (OPTION_MD_BASE + 1)
b99bd4ef 31016#else
c19d1205
ZW
31017#if TARGET_BYTES_BIG_ENDIAN
31018#define OPTION_EB (OPTION_MD_BASE + 0)
b99bd4ef 31019#else
c19d1205
ZW
31020#define OPTION_EL (OPTION_MD_BASE + 1)
31021#endif
b99bd4ef 31022#endif
845b51d6 31023#define OPTION_FIX_V4BX (OPTION_MD_BASE + 2)
18a20338 31024#define OPTION_FDPIC (OPTION_MD_BASE + 3)
b99bd4ef 31025
c19d1205 31026struct option md_longopts[] =
b99bd4ef 31027{
c19d1205
ZW
31028#ifdef OPTION_EB
31029 {"EB", no_argument, NULL, OPTION_EB},
31030#endif
31031#ifdef OPTION_EL
31032 {"EL", no_argument, NULL, OPTION_EL},
b99bd4ef 31033#endif
845b51d6 31034 {"fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
18a20338
CL
31035#ifdef OBJ_ELF
31036 {"fdpic", no_argument, NULL, OPTION_FDPIC},
31037#endif
c19d1205
ZW
31038 {NULL, no_argument, NULL, 0}
31039};
b99bd4ef 31040
c19d1205 31041size_t md_longopts_size = sizeof (md_longopts);
b99bd4ef 31042
c19d1205 31043struct arm_option_table
b99bd4ef 31044{
0198d5e6
TC
31045 const char * option; /* Option name to match. */
31046 const char * help; /* Help information. */
31047 int * var; /* Variable to change. */
31048 int value; /* What to change it to. */
31049 const char * deprecated; /* If non-null, print this message. */
c19d1205 31050};
b99bd4ef 31051
c19d1205
ZW
31052struct arm_option_table arm_opts[] =
31053{
31054 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
31055 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
31056 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
31057 &support_interwork, 1, NULL},
31058 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
31059 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
31060 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
31061 1, NULL},
31062 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
31063 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
31064 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
31065 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
31066 NULL},
b99bd4ef 31067
c19d1205
ZW
31068 /* These are recognized by the assembler, but have no affect on code. */
31069 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
31070 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
278df34e
NS
31071
31072 {"mwarn-deprecated", NULL, &warn_on_deprecated, 1, NULL},
31073 {"mno-warn-deprecated", N_("do not warn on use of deprecated feature"),
31074 &warn_on_deprecated, 0, NULL},
24f19ccb
AV
31075
31076 {"mwarn-restrict-it", N_("warn about performance deprecated IT instructions"
31077 " in ARMv8-A and ARMv8-R"), &warn_on_restrict_it, 1, NULL},
31078 {"mno-warn-restrict-it", NULL, &warn_on_restrict_it, 0, NULL},
31079
8b2d793c
NC
31080 {"mwarn-syms", N_("warn about symbols that match instruction names [default]"), (int *) (& flag_warn_syms), TRUE, NULL},
31081 {"mno-warn-syms", N_("disable warnings about symobls that match instructions"), (int *) (& flag_warn_syms), FALSE, NULL},
e74cfd16
PB
31082 {NULL, NULL, NULL, 0, NULL}
31083};
31084
31085struct arm_legacy_option_table
31086{
0198d5e6
TC
31087 const char * option; /* Option name to match. */
31088 const arm_feature_set ** var; /* Variable to change. */
31089 const arm_feature_set value; /* What to change it to. */
31090 const char * deprecated; /* If non-null, print this message. */
e74cfd16 31091};
b99bd4ef 31092
e74cfd16
PB
31093const struct arm_legacy_option_table arm_legacy_opts[] =
31094{
c19d1205
ZW
31095 /* DON'T add any new processors to this list -- we want the whole list
31096 to go away... Add them to the processors table instead. */
e74cfd16
PB
31097 {"marm1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
31098 {"m1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
31099 {"marm2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
31100 {"m2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
31101 {"marm250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
31102 {"m250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
31103 {"marm3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
31104 {"m3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
31105 {"marm6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
31106 {"m6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
31107 {"marm600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
31108 {"m600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
31109 {"marm610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
31110 {"m610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
31111 {"marm620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
31112 {"m620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
31113 {"marm7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
31114 {"m7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
31115 {"marm70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
31116 {"m70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
31117 {"marm700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
31118 {"m700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
31119 {"marm700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
31120 {"m700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
31121 {"marm710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
31122 {"m710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
31123 {"marm710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
31124 {"m710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
31125 {"marm720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
31126 {"m720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
31127 {"marm7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
31128 {"m7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
31129 {"marm7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
31130 {"m7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
31131 {"marm7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
31132 {"m7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
31133 {"marm7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
31134 {"m7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
31135 {"marm7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
31136 {"m7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
31137 {"marm7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
31138 {"m7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
31139 {"marm7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
31140 {"m7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
31141 {"marm7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
31142 {"m7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
31143 {"marm7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31144 {"m7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31145 {"marm7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31146 {"m7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
31147 {"marm710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
31148 {"m710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
31149 {"marm720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
31150 {"m720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
31151 {"marm740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
31152 {"m740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
31153 {"marm8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
31154 {"m8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
31155 {"marm810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
31156 {"m810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
31157 {"marm9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
31158 {"m9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
31159 {"marm9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
31160 {"m9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
31161 {"marm920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
31162 {"m920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
31163 {"marm940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
31164 {"m940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
31165 {"mstrongarm", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
31166 {"mstrongarm110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31167 N_("use -mcpu=strongarm110")},
e74cfd16 31168 {"mstrongarm1100", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31169 N_("use -mcpu=strongarm1100")},
e74cfd16 31170 {"mstrongarm1110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 31171 N_("use -mcpu=strongarm1110")},
e74cfd16
PB
31172 {"mxscale", &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
31173 {"miwmmxt", &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
31174 {"mall", &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
7ed4c4c5 31175
c19d1205 31176 /* Architecture variants -- don't add any more to this list either. */
e74cfd16
PB
31177 {"mv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
31178 {"marmv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
31179 {"mv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
31180 {"marmv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
31181 {"mv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
31182 {"marmv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
31183 {"mv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
31184 {"marmv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
31185 {"mv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
31186 {"marmv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
31187 {"mv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
31188 {"marmv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
31189 {"mv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
31190 {"marmv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
31191 {"mv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
31192 {"marmv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
31193 {"mv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
31194 {"marmv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
7ed4c4c5 31195
c19d1205 31196 /* Floating point variants -- don't add any more to this list either. */
0198d5e6
TC
31197 {"mfpe-old", &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
31198 {"mfpa10", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
31199 {"mfpa11", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
31200 {"mno-fpu", &legacy_fpu, ARM_ARCH_NONE,
c19d1205 31201 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
7ed4c4c5 31202
e74cfd16 31203 {NULL, NULL, ARM_ARCH_NONE, NULL}
c19d1205 31204};
7ed4c4c5 31205
c19d1205 31206struct arm_cpu_option_table
7ed4c4c5 31207{
0198d5e6
TC
31208 const char * name;
31209 size_t name_len;
31210 const arm_feature_set value;
31211 const arm_feature_set ext;
c19d1205
ZW
31212 /* For some CPUs we assume an FPU unless the user explicitly sets
31213 -mfpu=... */
0198d5e6 31214 const arm_feature_set default_fpu;
ee065d83
PB
31215 /* The canonical name of the CPU, or NULL to use NAME converted to upper
31216 case. */
0198d5e6 31217 const char * canonical_name;
c19d1205 31218};
7ed4c4c5 31219
c19d1205
ZW
31220/* This list should, at a minimum, contain all the cpu names
31221 recognized by GCC. */
996b5569 31222#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
0198d5e6 31223
e74cfd16 31224static const struct arm_cpu_option_table arm_cpus[] =
c19d1205 31225{
996b5569
TP
31226 ARM_CPU_OPT ("all", NULL, ARM_ANY,
31227 ARM_ARCH_NONE,
31228 FPU_ARCH_FPA),
31229 ARM_CPU_OPT ("arm1", NULL, ARM_ARCH_V1,
31230 ARM_ARCH_NONE,
31231 FPU_ARCH_FPA),
31232 ARM_CPU_OPT ("arm2", NULL, ARM_ARCH_V2,
31233 ARM_ARCH_NONE,
31234 FPU_ARCH_FPA),
31235 ARM_CPU_OPT ("arm250", NULL, ARM_ARCH_V2S,
31236 ARM_ARCH_NONE,
31237 FPU_ARCH_FPA),
31238 ARM_CPU_OPT ("arm3", NULL, ARM_ARCH_V2S,
31239 ARM_ARCH_NONE,
31240 FPU_ARCH_FPA),
31241 ARM_CPU_OPT ("arm6", NULL, ARM_ARCH_V3,
31242 ARM_ARCH_NONE,
31243 FPU_ARCH_FPA),
31244 ARM_CPU_OPT ("arm60", NULL, ARM_ARCH_V3,
31245 ARM_ARCH_NONE,
31246 FPU_ARCH_FPA),
31247 ARM_CPU_OPT ("arm600", NULL, ARM_ARCH_V3,
31248 ARM_ARCH_NONE,
31249 FPU_ARCH_FPA),
31250 ARM_CPU_OPT ("arm610", NULL, ARM_ARCH_V3,
31251 ARM_ARCH_NONE,
31252 FPU_ARCH_FPA),
31253 ARM_CPU_OPT ("arm620", NULL, ARM_ARCH_V3,
31254 ARM_ARCH_NONE,
31255 FPU_ARCH_FPA),
31256 ARM_CPU_OPT ("arm7", NULL, ARM_ARCH_V3,
31257 ARM_ARCH_NONE,
31258 FPU_ARCH_FPA),
31259 ARM_CPU_OPT ("arm7m", NULL, ARM_ARCH_V3M,
31260 ARM_ARCH_NONE,
31261 FPU_ARCH_FPA),
31262 ARM_CPU_OPT ("arm7d", NULL, ARM_ARCH_V3,
31263 ARM_ARCH_NONE,
31264 FPU_ARCH_FPA),
31265 ARM_CPU_OPT ("arm7dm", NULL, ARM_ARCH_V3M,
31266 ARM_ARCH_NONE,
31267 FPU_ARCH_FPA),
31268 ARM_CPU_OPT ("arm7di", NULL, ARM_ARCH_V3,
31269 ARM_ARCH_NONE,
31270 FPU_ARCH_FPA),
31271 ARM_CPU_OPT ("arm7dmi", NULL, ARM_ARCH_V3M,
31272 ARM_ARCH_NONE,
31273 FPU_ARCH_FPA),
31274 ARM_CPU_OPT ("arm70", NULL, ARM_ARCH_V3,
31275 ARM_ARCH_NONE,
31276 FPU_ARCH_FPA),
31277 ARM_CPU_OPT ("arm700", NULL, ARM_ARCH_V3,
31278 ARM_ARCH_NONE,
31279 FPU_ARCH_FPA),
31280 ARM_CPU_OPT ("arm700i", NULL, ARM_ARCH_V3,
31281 ARM_ARCH_NONE,
31282 FPU_ARCH_FPA),
31283 ARM_CPU_OPT ("arm710", NULL, ARM_ARCH_V3,
31284 ARM_ARCH_NONE,
31285 FPU_ARCH_FPA),
31286 ARM_CPU_OPT ("arm710t", NULL, ARM_ARCH_V4T,
31287 ARM_ARCH_NONE,
31288 FPU_ARCH_FPA),
31289 ARM_CPU_OPT ("arm720", NULL, ARM_ARCH_V3,
31290 ARM_ARCH_NONE,
31291 FPU_ARCH_FPA),
31292 ARM_CPU_OPT ("arm720t", NULL, ARM_ARCH_V4T,
31293 ARM_ARCH_NONE,
31294 FPU_ARCH_FPA),
31295 ARM_CPU_OPT ("arm740t", NULL, ARM_ARCH_V4T,
31296 ARM_ARCH_NONE,
31297 FPU_ARCH_FPA),
31298 ARM_CPU_OPT ("arm710c", NULL, ARM_ARCH_V3,
31299 ARM_ARCH_NONE,
31300 FPU_ARCH_FPA),
31301 ARM_CPU_OPT ("arm7100", NULL, ARM_ARCH_V3,
31302 ARM_ARCH_NONE,
31303 FPU_ARCH_FPA),
31304 ARM_CPU_OPT ("arm7500", NULL, ARM_ARCH_V3,
31305 ARM_ARCH_NONE,
31306 FPU_ARCH_FPA),
31307 ARM_CPU_OPT ("arm7500fe", NULL, ARM_ARCH_V3,
31308 ARM_ARCH_NONE,
31309 FPU_ARCH_FPA),
31310 ARM_CPU_OPT ("arm7t", NULL, ARM_ARCH_V4T,
31311 ARM_ARCH_NONE,
31312 FPU_ARCH_FPA),
31313 ARM_CPU_OPT ("arm7tdmi", NULL, ARM_ARCH_V4T,
31314 ARM_ARCH_NONE,
31315 FPU_ARCH_FPA),
31316 ARM_CPU_OPT ("arm7tdmi-s", NULL, ARM_ARCH_V4T,
31317 ARM_ARCH_NONE,
31318 FPU_ARCH_FPA),
31319 ARM_CPU_OPT ("arm8", NULL, ARM_ARCH_V4,
31320 ARM_ARCH_NONE,
31321 FPU_ARCH_FPA),
31322 ARM_CPU_OPT ("arm810", NULL, ARM_ARCH_V4,
31323 ARM_ARCH_NONE,
31324 FPU_ARCH_FPA),
31325 ARM_CPU_OPT ("strongarm", NULL, ARM_ARCH_V4,
31326 ARM_ARCH_NONE,
31327 FPU_ARCH_FPA),
31328 ARM_CPU_OPT ("strongarm1", NULL, ARM_ARCH_V4,
31329 ARM_ARCH_NONE,
31330 FPU_ARCH_FPA),
31331 ARM_CPU_OPT ("strongarm110", NULL, ARM_ARCH_V4,
31332 ARM_ARCH_NONE,
31333 FPU_ARCH_FPA),
31334 ARM_CPU_OPT ("strongarm1100", NULL, ARM_ARCH_V4,
31335 ARM_ARCH_NONE,
31336 FPU_ARCH_FPA),
31337 ARM_CPU_OPT ("strongarm1110", NULL, ARM_ARCH_V4,
31338 ARM_ARCH_NONE,
31339 FPU_ARCH_FPA),
31340 ARM_CPU_OPT ("arm9", NULL, ARM_ARCH_V4T,
31341 ARM_ARCH_NONE,
31342 FPU_ARCH_FPA),
31343 ARM_CPU_OPT ("arm920", "ARM920T", ARM_ARCH_V4T,
31344 ARM_ARCH_NONE,
31345 FPU_ARCH_FPA),
31346 ARM_CPU_OPT ("arm920t", NULL, ARM_ARCH_V4T,
31347 ARM_ARCH_NONE,
31348 FPU_ARCH_FPA),
31349 ARM_CPU_OPT ("arm922t", NULL, ARM_ARCH_V4T,
31350 ARM_ARCH_NONE,
31351 FPU_ARCH_FPA),
31352 ARM_CPU_OPT ("arm940t", NULL, ARM_ARCH_V4T,
31353 ARM_ARCH_NONE,
31354 FPU_ARCH_FPA),
31355 ARM_CPU_OPT ("arm9tdmi", NULL, ARM_ARCH_V4T,
31356 ARM_ARCH_NONE,
31357 FPU_ARCH_FPA),
31358 ARM_CPU_OPT ("fa526", NULL, ARM_ARCH_V4,
31359 ARM_ARCH_NONE,
31360 FPU_ARCH_FPA),
31361 ARM_CPU_OPT ("fa626", NULL, ARM_ARCH_V4,
31362 ARM_ARCH_NONE,
31363 FPU_ARCH_FPA),
31364
c19d1205
ZW
31365 /* For V5 or later processors we default to using VFP; but the user
31366 should really set the FPU type explicitly. */
996b5569
TP
31367 ARM_CPU_OPT ("arm9e-r0", NULL, ARM_ARCH_V5TExP,
31368 ARM_ARCH_NONE,
31369 FPU_ARCH_VFP_V2),
31370 ARM_CPU_OPT ("arm9e", NULL, ARM_ARCH_V5TE,
31371 ARM_ARCH_NONE,
31372 FPU_ARCH_VFP_V2),
31373 ARM_CPU_OPT ("arm926ej", "ARM926EJ-S", ARM_ARCH_V5TEJ,
31374 ARM_ARCH_NONE,
31375 FPU_ARCH_VFP_V2),
31376 ARM_CPU_OPT ("arm926ejs", "ARM926EJ-S", ARM_ARCH_V5TEJ,
31377 ARM_ARCH_NONE,
31378 FPU_ARCH_VFP_V2),
31379 ARM_CPU_OPT ("arm926ej-s", NULL, ARM_ARCH_V5TEJ,
31380 ARM_ARCH_NONE,
31381 FPU_ARCH_VFP_V2),
31382 ARM_CPU_OPT ("arm946e-r0", NULL, ARM_ARCH_V5TExP,
31383 ARM_ARCH_NONE,
31384 FPU_ARCH_VFP_V2),
31385 ARM_CPU_OPT ("arm946e", "ARM946E-S", ARM_ARCH_V5TE,
31386 ARM_ARCH_NONE,
31387 FPU_ARCH_VFP_V2),
31388 ARM_CPU_OPT ("arm946e-s", NULL, ARM_ARCH_V5TE,
31389 ARM_ARCH_NONE,
31390 FPU_ARCH_VFP_V2),
31391 ARM_CPU_OPT ("arm966e-r0", NULL, ARM_ARCH_V5TExP,
31392 ARM_ARCH_NONE,
31393 FPU_ARCH_VFP_V2),
31394 ARM_CPU_OPT ("arm966e", "ARM966E-S", ARM_ARCH_V5TE,
31395 ARM_ARCH_NONE,
31396 FPU_ARCH_VFP_V2),
31397 ARM_CPU_OPT ("arm966e-s", NULL, ARM_ARCH_V5TE,
31398 ARM_ARCH_NONE,
31399 FPU_ARCH_VFP_V2),
31400 ARM_CPU_OPT ("arm968e-s", NULL, ARM_ARCH_V5TE,
31401 ARM_ARCH_NONE,
31402 FPU_ARCH_VFP_V2),
31403 ARM_CPU_OPT ("arm10t", NULL, ARM_ARCH_V5T,
31404 ARM_ARCH_NONE,
31405 FPU_ARCH_VFP_V1),
31406 ARM_CPU_OPT ("arm10tdmi", NULL, ARM_ARCH_V5T,
31407 ARM_ARCH_NONE,
31408 FPU_ARCH_VFP_V1),
31409 ARM_CPU_OPT ("arm10e", NULL, ARM_ARCH_V5TE,
31410 ARM_ARCH_NONE,
31411 FPU_ARCH_VFP_V2),
31412 ARM_CPU_OPT ("arm1020", "ARM1020E", ARM_ARCH_V5TE,
31413 ARM_ARCH_NONE,
31414 FPU_ARCH_VFP_V2),
31415 ARM_CPU_OPT ("arm1020t", NULL, ARM_ARCH_V5T,
31416 ARM_ARCH_NONE,
31417 FPU_ARCH_VFP_V1),
31418 ARM_CPU_OPT ("arm1020e", NULL, ARM_ARCH_V5TE,
31419 ARM_ARCH_NONE,
31420 FPU_ARCH_VFP_V2),
31421 ARM_CPU_OPT ("arm1022e", NULL, ARM_ARCH_V5TE,
31422 ARM_ARCH_NONE,
31423 FPU_ARCH_VFP_V2),
31424 ARM_CPU_OPT ("arm1026ejs", "ARM1026EJ-S", ARM_ARCH_V5TEJ,
31425 ARM_ARCH_NONE,
31426 FPU_ARCH_VFP_V2),
31427 ARM_CPU_OPT ("arm1026ej-s", NULL, ARM_ARCH_V5TEJ,
31428 ARM_ARCH_NONE,
31429 FPU_ARCH_VFP_V2),
31430 ARM_CPU_OPT ("fa606te", NULL, ARM_ARCH_V5TE,
31431 ARM_ARCH_NONE,
31432 FPU_ARCH_VFP_V2),
31433 ARM_CPU_OPT ("fa616te", NULL, ARM_ARCH_V5TE,
31434 ARM_ARCH_NONE,
31435 FPU_ARCH_VFP_V2),
31436 ARM_CPU_OPT ("fa626te", NULL, ARM_ARCH_V5TE,
31437 ARM_ARCH_NONE,
31438 FPU_ARCH_VFP_V2),
31439 ARM_CPU_OPT ("fmp626", NULL, ARM_ARCH_V5TE,
31440 ARM_ARCH_NONE,
31441 FPU_ARCH_VFP_V2),
31442 ARM_CPU_OPT ("fa726te", NULL, ARM_ARCH_V5TE,
31443 ARM_ARCH_NONE,
31444 FPU_ARCH_VFP_V2),
31445 ARM_CPU_OPT ("arm1136js", "ARM1136J-S", ARM_ARCH_V6,
31446 ARM_ARCH_NONE,
31447 FPU_NONE),
31448 ARM_CPU_OPT ("arm1136j-s", NULL, ARM_ARCH_V6,
31449 ARM_ARCH_NONE,
31450 FPU_NONE),
31451 ARM_CPU_OPT ("arm1136jfs", "ARM1136JF-S", ARM_ARCH_V6,
31452 ARM_ARCH_NONE,
31453 FPU_ARCH_VFP_V2),
31454 ARM_CPU_OPT ("arm1136jf-s", NULL, ARM_ARCH_V6,
31455 ARM_ARCH_NONE,
31456 FPU_ARCH_VFP_V2),
31457 ARM_CPU_OPT ("mpcore", "MPCore", ARM_ARCH_V6K,
31458 ARM_ARCH_NONE,
31459 FPU_ARCH_VFP_V2),
31460 ARM_CPU_OPT ("mpcorenovfp", "MPCore", ARM_ARCH_V6K,
31461 ARM_ARCH_NONE,
31462 FPU_NONE),
31463 ARM_CPU_OPT ("arm1156t2-s", NULL, ARM_ARCH_V6T2,
31464 ARM_ARCH_NONE,
31465 FPU_NONE),
31466 ARM_CPU_OPT ("arm1156t2f-s", NULL, ARM_ARCH_V6T2,
31467 ARM_ARCH_NONE,
31468 FPU_ARCH_VFP_V2),
31469 ARM_CPU_OPT ("arm1176jz-s", NULL, ARM_ARCH_V6KZ,
31470 ARM_ARCH_NONE,
31471 FPU_NONE),
31472 ARM_CPU_OPT ("arm1176jzf-s", NULL, ARM_ARCH_V6KZ,
31473 ARM_ARCH_NONE,
31474 FPU_ARCH_VFP_V2),
31475 ARM_CPU_OPT ("cortex-a5", "Cortex-A5", ARM_ARCH_V7A,
31476 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31477 FPU_NONE),
31478 ARM_CPU_OPT ("cortex-a7", "Cortex-A7", ARM_ARCH_V7VE,
31479 ARM_ARCH_NONE,
31480 FPU_ARCH_NEON_VFP_V4),
31481 ARM_CPU_OPT ("cortex-a8", "Cortex-A8", ARM_ARCH_V7A,
31482 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
31483 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
31484 ARM_CPU_OPT ("cortex-a9", "Cortex-A9", ARM_ARCH_V7A,
31485 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31486 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
31487 ARM_CPU_OPT ("cortex-a12", "Cortex-A12", ARM_ARCH_V7VE,
31488 ARM_ARCH_NONE,
31489 FPU_ARCH_NEON_VFP_V4),
31490 ARM_CPU_OPT ("cortex-a15", "Cortex-A15", ARM_ARCH_V7VE,
31491 ARM_ARCH_NONE,
31492 FPU_ARCH_NEON_VFP_V4),
31493 ARM_CPU_OPT ("cortex-a17", "Cortex-A17", ARM_ARCH_V7VE,
31494 ARM_ARCH_NONE,
31495 FPU_ARCH_NEON_VFP_V4),
31496 ARM_CPU_OPT ("cortex-a32", "Cortex-A32", ARM_ARCH_V8A,
8b301fbb 31497 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31498 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31499 ARM_CPU_OPT ("cortex-a35", "Cortex-A35", ARM_ARCH_V8A,
8b301fbb 31500 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31501 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31502 ARM_CPU_OPT ("cortex-a53", "Cortex-A53", ARM_ARCH_V8A,
8b301fbb 31503 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31504 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
31505 ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A,
31506 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 31507 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569 31508 ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A,
8b301fbb 31509 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31510 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31511 ARM_CPU_OPT ("cortex-a72", "Cortex-A72", ARM_ARCH_V8A,
8b301fbb 31512 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31513 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31514 ARM_CPU_OPT ("cortex-a73", "Cortex-A73", ARM_ARCH_V8A,
8b301fbb 31515 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31516 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
31517 ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A,
31518 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 31519 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
7ebd1359 31520 ARM_CPU_OPT ("cortex-a76", "Cortex-A76", ARM_ARCH_V8_2A,
31521 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31522 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
0535e5d7
DZ
31523 ARM_CPU_OPT ("cortex-a76ae", "Cortex-A76AE", ARM_ARCH_V8_2A,
31524 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31525 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
31526 ARM_CPU_OPT ("cortex-a77", "Cortex-A77", ARM_ARCH_V8_2A,
31527 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31528 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
ef8df4ca
KT
31529 ARM_CPU_OPT ("ares", "Ares", ARM_ARCH_V8_2A,
31530 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31531 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
31532 ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R,
31533 ARM_ARCH_NONE,
31534 FPU_NONE),
31535 ARM_CPU_OPT ("cortex-r4f", "Cortex-R4F", ARM_ARCH_V7R,
31536 ARM_ARCH_NONE,
31537 FPU_ARCH_VFP_V3D16),
31538 ARM_CPU_OPT ("cortex-r5", "Cortex-R5", ARM_ARCH_V7R,
31539 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31540 FPU_NONE),
31541 ARM_CPU_OPT ("cortex-r7", "Cortex-R7", ARM_ARCH_V7R,
31542 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31543 FPU_ARCH_VFP_V3D16),
31544 ARM_CPU_OPT ("cortex-r8", "Cortex-R8", ARM_ARCH_V7R,
31545 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
31546 FPU_ARCH_VFP_V3D16),
0cda1e19 31547 ARM_CPU_OPT ("cortex-r52", "Cortex-R52", ARM_ARCH_V8R,
8b301fbb 31548 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
0cda1e19 31549 FPU_ARCH_NEON_VFP_ARMV8),
0535e5d7
DZ
31550 ARM_CPU_OPT ("cortex-m35p", "Cortex-M35P", ARM_ARCH_V8M_MAIN,
31551 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
31552 FPU_NONE),
996b5569
TP
31553 ARM_CPU_OPT ("cortex-m33", "Cortex-M33", ARM_ARCH_V8M_MAIN,
31554 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
31555 FPU_NONE),
31556 ARM_CPU_OPT ("cortex-m23", "Cortex-M23", ARM_ARCH_V8M_BASE,
31557 ARM_ARCH_NONE,
31558 FPU_NONE),
31559 ARM_CPU_OPT ("cortex-m7", "Cortex-M7", ARM_ARCH_V7EM,
31560 ARM_ARCH_NONE,
31561 FPU_NONE),
31562 ARM_CPU_OPT ("cortex-m4", "Cortex-M4", ARM_ARCH_V7EM,
31563 ARM_ARCH_NONE,
31564 FPU_NONE),
31565 ARM_CPU_OPT ("cortex-m3", "Cortex-M3", ARM_ARCH_V7M,
31566 ARM_ARCH_NONE,
31567 FPU_NONE),
31568 ARM_CPU_OPT ("cortex-m1", "Cortex-M1", ARM_ARCH_V6SM,
31569 ARM_ARCH_NONE,
31570 FPU_NONE),
31571 ARM_CPU_OPT ("cortex-m0", "Cortex-M0", ARM_ARCH_V6SM,
31572 ARM_ARCH_NONE,
31573 FPU_NONE),
31574 ARM_CPU_OPT ("cortex-m0plus", "Cortex-M0+", ARM_ARCH_V6SM,
31575 ARM_ARCH_NONE,
31576 FPU_NONE),
31577 ARM_CPU_OPT ("exynos-m1", "Samsung Exynos M1", ARM_ARCH_V8A,
8b301fbb 31578 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569 31579 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
83f43c83
KT
31580 ARM_CPU_OPT ("neoverse-n1", "Neoverse N1", ARM_ARCH_V8_2A,
31581 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31582 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
c19d1205 31583 /* ??? XSCALE is really an architecture. */
996b5569
TP
31584 ARM_CPU_OPT ("xscale", NULL, ARM_ARCH_XSCALE,
31585 ARM_ARCH_NONE,
31586 FPU_ARCH_VFP_V2),
31587
c19d1205 31588 /* ??? iwmmxt is not a processor. */
996b5569
TP
31589 ARM_CPU_OPT ("iwmmxt", NULL, ARM_ARCH_IWMMXT,
31590 ARM_ARCH_NONE,
31591 FPU_ARCH_VFP_V2),
31592 ARM_CPU_OPT ("iwmmxt2", NULL, ARM_ARCH_IWMMXT2,
31593 ARM_ARCH_NONE,
31594 FPU_ARCH_VFP_V2),
31595 ARM_CPU_OPT ("i80200", NULL, ARM_ARCH_XSCALE,
31596 ARM_ARCH_NONE,
31597 FPU_ARCH_VFP_V2),
31598
0198d5e6 31599 /* Maverick. */
996b5569
TP
31600 ARM_CPU_OPT ("ep9312", "ARM920T",
31601 ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
31602 ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
31603
da4339ed 31604 /* Marvell processors. */
996b5569
TP
31605 ARM_CPU_OPT ("marvell-pj4", NULL, ARM_ARCH_V7A,
31606 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31607 FPU_ARCH_VFP_V3D16),
31608 ARM_CPU_OPT ("marvell-whitney", NULL, ARM_ARCH_V7A,
31609 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
31610 FPU_ARCH_NEON_VFP_V4),
da4339ed 31611
996b5569
TP
31612 /* APM X-Gene family. */
31613 ARM_CPU_OPT ("xgene1", "APM X-Gene 1", ARM_ARCH_V8A,
31614 ARM_ARCH_NONE,
31615 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31616 ARM_CPU_OPT ("xgene2", "APM X-Gene 2", ARM_ARCH_V8A,
8b301fbb 31617 ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC),
996b5569
TP
31618 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
31619
31620 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 31621};
f3bad469 31622#undef ARM_CPU_OPT
7ed4c4c5 31623
34ef62f4
AV
31624struct arm_ext_table
31625{
31626 const char * name;
31627 size_t name_len;
31628 const arm_feature_set merge;
31629 const arm_feature_set clear;
31630};
31631
c19d1205 31632struct arm_arch_option_table
7ed4c4c5 31633{
34ef62f4
AV
31634 const char * name;
31635 size_t name_len;
31636 const arm_feature_set value;
31637 const arm_feature_set default_fpu;
31638 const struct arm_ext_table * ext_table;
31639};
31640
31641/* Used to add support for +E and +noE extension. */
31642#define ARM_EXT(E, M, C) { E, sizeof (E) - 1, M, C }
31643/* Used to add support for a +E extension. */
31644#define ARM_ADD(E, M) { E, sizeof(E) - 1, M, ARM_ARCH_NONE }
31645/* Used to add support for a +noE extension. */
31646#define ARM_REMOVE(E, C) { E, sizeof(E) -1, ARM_ARCH_NONE, C }
31647
31648#define ALL_FP ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_FP16_FML, \
31649 ~0 & ~FPU_ENDIAN_PURE)
31650
31651static const struct arm_ext_table armv5te_ext_table[] =
31652{
31653 ARM_EXT ("fp", FPU_ARCH_VFP_V2, ALL_FP),
31654 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31655};
31656
31657static const struct arm_ext_table armv7_ext_table[] =
31658{
31659 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31660 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31661};
31662
31663static const struct arm_ext_table armv7ve_ext_table[] =
31664{
31665 ARM_EXT ("fp", FPU_ARCH_VFP_V4D16, ALL_FP),
31666 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16),
31667 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
31668 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31669 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
31670 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), /* Alias for +fp. */
31671 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
31672
31673 ARM_EXT ("simd", FPU_ARCH_NEON_VFP_V4,
31674 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
31675
31676 /* Aliases for +simd. */
31677 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
31678
31679 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31680 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31681 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
31682
31683 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31684};
31685
31686static const struct arm_ext_table armv7a_ext_table[] =
31687{
31688 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31689 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
31690 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
31691 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31692 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
31693 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16),
31694 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
31695
31696 ARM_EXT ("simd", FPU_ARCH_VFP_V3_PLUS_NEON_V1,
31697 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
31698
31699 /* Aliases for +simd. */
31700 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31701 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
31702
31703 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
31704 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
31705
31706 ARM_ADD ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP)),
31707 ARM_ADD ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC)),
31708 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31709};
31710
31711static const struct arm_ext_table armv7r_ext_table[] =
31712{
31713 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V3xD),
31714 ARM_ADD ("vfpv3xd", FPU_ARCH_VFP_V3xD), /* Alias for +fp.sp. */
31715 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
31716 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
31717 ARM_ADD ("vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16),
31718 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
31719 ARM_EXT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
31720 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV)),
31721 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31722};
31723
31724static const struct arm_ext_table armv7em_ext_table[] =
31725{
31726 ARM_EXT ("fp", FPU_ARCH_VFP_V4_SP_D16, ALL_FP),
31727 /* Alias for +fp, used to be known as fpv4-sp-d16. */
31728 ARM_ADD ("vfpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16),
31729 ARM_ADD ("fpv5", FPU_ARCH_VFP_V5_SP_D16),
31730 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
31731 ARM_ADD ("fpv5-d16", FPU_ARCH_VFP_V5D16),
31732 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31733};
31734
31735static const struct arm_ext_table armv8a_ext_table[] =
31736{
8b301fbb 31737 ARM_ADD ("crc", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC)),
34ef62f4
AV
31738 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
31739 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
31740 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31741
31742 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31743 should use the +simd option to turn on FP. */
31744 ARM_REMOVE ("fp", ALL_FP),
31745 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31746 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31747 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31748};
31749
31750
31751static const struct arm_ext_table armv81a_ext_table[] =
31752{
31753 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
31754 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
31755 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31756
31757 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31758 should use the +simd option to turn on FP. */
31759 ARM_REMOVE ("fp", ALL_FP),
31760 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31761 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31762 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31763};
31764
31765static const struct arm_ext_table armv82a_ext_table[] =
31766{
31767 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
31768 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_2_FP16),
31769 ARM_ADD ("fp16fml", FPU_ARCH_NEON_VFP_ARMV8_2_FP16FML),
616ce08e
MM
31770 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
31771 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
31772 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
31773 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31774 ARM_ADD ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31775
31776 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31777 should use the +simd option to turn on FP. */
31778 ARM_REMOVE ("fp", ALL_FP),
31779 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31780 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31781 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31782};
31783
31784static const struct arm_ext_table armv84a_ext_table[] =
31785{
31786 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31787 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
616ce08e
MM
31788 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
31789 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
31790 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
31791 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31792
31793 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31794 should use the +simd option to turn on FP. */
31795 ARM_REMOVE ("fp", ALL_FP),
31796 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
31797 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
31798 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31799};
31800
31801static const struct arm_ext_table armv85a_ext_table[] =
31802{
31803 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
31804 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
616ce08e
MM
31805 ARM_ADD ("bf16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_BF16)),
31806 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
34ef62f4
AV
31807 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
31808 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31809
31810 /* Armv8-a does not allow an FP implementation without SIMD, so the user
31811 should use the +simd option to turn on FP. */
31812 ARM_REMOVE ("fp", ALL_FP),
31813 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31814};
31815
aab2c27d
MM
31816static const struct arm_ext_table armv86a_ext_table[] =
31817{
616ce08e 31818 ARM_ADD ("i8mm", ARM_FEATURE_CORE_HIGH (ARM_EXT2_I8MM)),
aab2c27d
MM
31819 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31820};
31821
4934a27c
MM
31822#define CDE_EXTENSIONS \
31823 ARM_ADD ("cdecp0", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE0)), \
31824 ARM_ADD ("cdecp1", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE1)), \
31825 ARM_ADD ("cdecp2", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE2)), \
31826 ARM_ADD ("cdecp3", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE3)), \
31827 ARM_ADD ("cdecp4", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE4)), \
31828 ARM_ADD ("cdecp5", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE5)), \
31829 ARM_ADD ("cdecp6", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE6)), \
31830 ARM_ADD ("cdecp7", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CDE | ARM_EXT2_CDE7))
31831
34ef62f4
AV
31832static const struct arm_ext_table armv8m_main_ext_table[] =
31833{
92169145
AV
31834 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP),
31835 ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP)),
34ef62f4
AV
31836 ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP),
31837 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
4934a27c 31838 CDE_EXTENSIONS,
34ef62f4
AV
31839 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31840};
31841
92169145 31842
e0991585
AV
31843static const struct arm_ext_table armv8_1m_main_ext_table[] =
31844{
92169145
AV
31845 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP),
31846 ARM_FEATURE_CORE_LOW (ARM_AEXT_V8M_MAIN_DSP)),
e0991585
AV
31847 ARM_EXT ("fp",
31848 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
31849 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA),
31850 ALL_FP),
31851 ARM_ADD ("fp.dp",
31852 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
31853 FPU_VFP_V5D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
92169145 31854 ARM_EXT ("mve", ARM_FEATURE (ARM_AEXT_V8M_MAIN_DSP, ARM_EXT2_MVE, 0),
2da2eaf4 31855 ARM_FEATURE_CORE_HIGH (ARM_EXT2_MVE | ARM_EXT2_MVE_FP)),
a7ad558c 31856 ARM_ADD ("mve.fp",
92169145
AV
31857 ARM_FEATURE (ARM_AEXT_V8M_MAIN_DSP,
31858 ARM_EXT2_FP16_INST | ARM_EXT2_MVE | ARM_EXT2_MVE_FP,
2da2eaf4 31859 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
4934a27c 31860 CDE_EXTENSIONS,
e0991585
AV
31861 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
31862};
31863
4934a27c
MM
31864#undef CDE_EXTENSIONS
31865
34ef62f4
AV
31866static const struct arm_ext_table armv8r_ext_table[] =
31867{
8b301fbb 31868 ARM_ADD ("crc", ARM_FEATURE_CORE_HIGH (ARM_EXT2_CRC)),
34ef62f4
AV
31869 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
31870 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
31871 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
31872 ARM_REMOVE ("fp", ALL_FP),
31873 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V5_SP_D16),
31874 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
c19d1205 31875};
7ed4c4c5 31876
c19d1205
ZW
31877/* This list should, at a minimum, contain all the architecture names
31878 recognized by GCC. */
34ef62f4
AV
31879#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF, NULL }
31880#define ARM_ARCH_OPT2(N, V, DF, ext) \
31881 { N, sizeof (N) - 1, V, DF, ext##_ext_table }
0198d5e6 31882
e74cfd16 31883static const struct arm_arch_option_table arm_archs[] =
c19d1205 31884{
497d849d
TP
31885 ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
31886 ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
31887 ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
31888 ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
31889 ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
31890 ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
31891 ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
31892 ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
31893 ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
31894 ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
31895 ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
31896 ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
31897 ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
31898 ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
34ef62f4
AV
31899 ARM_ARCH_OPT2 ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP, armv5te),
31900 ARM_ARCH_OPT2 ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP, armv5te),
31901 ARM_ARCH_OPT2 ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP, armv5te),
31902 ARM_ARCH_OPT2 ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
31903 ARM_ARCH_OPT2 ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
31904 ARM_ARCH_OPT2 ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP, armv5te),
31905 ARM_ARCH_OPT2 ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP, armv5te),
f33026a9
MW
31906 /* The official spelling of this variant is ARMv6KZ, the name "armv6zk" is
31907 kept to preserve existing behaviour. */
34ef62f4
AV
31908 ARM_ARCH_OPT2 ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
31909 ARM_ARCH_OPT2 ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
31910 ARM_ARCH_OPT2 ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP, armv5te),
31911 ARM_ARCH_OPT2 ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP, armv5te),
31912 ARM_ARCH_OPT2 ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP, armv5te),
f33026a9
MW
31913 /* The official spelling of this variant is ARMv6KZ, the name "armv6zkt2" is
31914 kept to preserve existing behaviour. */
34ef62f4
AV
31915 ARM_ARCH_OPT2 ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
31916 ARM_ARCH_OPT2 ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
497d849d
TP
31917 ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
31918 ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
34ef62f4 31919 ARM_ARCH_OPT2 ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP, armv7),
c450d570
PB
31920 /* The official spelling of the ARMv7 profile variants is the dashed form.
31921 Accept the non-dashed form for compatibility with old toolchains. */
34ef62f4
AV
31922 ARM_ARCH_OPT2 ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
31923 ARM_ARCH_OPT2 ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP, armv7ve),
31924 ARM_ARCH_OPT2 ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 31925 ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4
AV
31926 ARM_ARCH_OPT2 ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
31927 ARM_ARCH_OPT2 ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 31928 ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4 31929 ARM_ARCH_OPT2 ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP, armv7em),
497d849d 31930 ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP),
34ef62f4
AV
31931 ARM_ARCH_OPT2 ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP,
31932 armv8m_main),
e0991585
AV
31933 ARM_ARCH_OPT2 ("armv8.1-m.main", ARM_ARCH_V8_1M_MAIN, FPU_ARCH_VFP,
31934 armv8_1m_main),
34ef62f4
AV
31935 ARM_ARCH_OPT2 ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP, armv8a),
31936 ARM_ARCH_OPT2 ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP, armv81a),
31937 ARM_ARCH_OPT2 ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP, armv82a),
31938 ARM_ARCH_OPT2 ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP, armv82a),
31939 ARM_ARCH_OPT2 ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP, armv8r),
31940 ARM_ARCH_OPT2 ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP, armv84a),
31941 ARM_ARCH_OPT2 ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP, armv85a),
aab2c27d 31942 ARM_ARCH_OPT2 ("armv8.6-a", ARM_ARCH_V8_6A, FPU_ARCH_VFP, armv86a),
497d849d
TP
31943 ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
31944 ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
31945 ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP),
34ef62f4 31946 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 31947};
f3bad469 31948#undef ARM_ARCH_OPT
7ed4c4c5 31949
69133863 31950/* ISA extensions in the co-processor and main instruction set space. */
0198d5e6 31951
69133863 31952struct arm_option_extension_value_table
c19d1205 31953{
0198d5e6
TC
31954 const char * name;
31955 size_t name_len;
31956 const arm_feature_set merge_value;
31957 const arm_feature_set clear_value;
d942732e
TP
31958 /* List of architectures for which an extension is available. ARM_ARCH_NONE
31959 indicates that an extension is available for all architectures while
31960 ARM_ANY marks an empty entry. */
0198d5e6 31961 const arm_feature_set allowed_archs[2];
c19d1205 31962};
7ed4c4c5 31963
0198d5e6
TC
31964/* The following table must be in alphabetical order with a NULL last entry. */
31965
d942732e
TP
31966#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
31967#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
0198d5e6 31968
34ef62f4
AV
31969/* DEPRECATED: Refrain from using this table to add any new extensions, instead
31970 use the context sensitive approach using arm_ext_table's. */
69133863 31971static const struct arm_option_extension_value_table arm_extensions[] =
c19d1205 31972{
8b301fbb
MI
31973 ARM_EXT_OPT ("crc", ARM_FEATURE_CORE_HIGH(ARM_EXT2_CRC),
31974 ARM_FEATURE_CORE_HIGH(ARM_EXT2_CRC),
823d2571 31975 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
bca38921 31976 ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
823d2571
TG
31977 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
31978 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
c604a79a
JW
31979 ARM_EXT_OPT ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8,
31980 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
31981 ARM_ARCH_V8_2A),
15afaa63
TP
31982 ARM_EXT_OPT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
31983 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
31984 ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
823d2571
TG
31985 ARM_EXT_OPT ("fp", FPU_ARCH_VFP_ARMV8, ARM_FEATURE_COPROC (FPU_VFP_ARMV8),
31986 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
b8ec4e87
JW
31987 ARM_EXT_OPT ("fp16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31988 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
31989 ARM_ARCH_V8_2A),
01f48020
TC
31990 ARM_EXT_OPT ("fp16fml", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
31991 | ARM_EXT2_FP16_FML),
31992 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
31993 | ARM_EXT2_FP16_FML),
31994 ARM_ARCH_V8_2A),
d942732e 31995 ARM_EXT_OPT2 ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
823d2571 31996 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
d942732e
TP
31997 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
31998 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
3d030cdb
TP
31999 /* Duplicate entry for the purpose of allowing ARMv7 to match in presence of
32000 Thumb divide instruction. Due to this having the same name as the
32001 previous entry, this will be ignored when doing command-line parsing and
32002 only considered by build attribute selection code. */
32003 ARM_EXT_OPT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
32004 ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
32005 ARM_FEATURE_CORE_LOW (ARM_EXT_V7)),
823d2571 32006 ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
d942732e 32007 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
823d2571 32008 ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
d942732e 32009 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ARCH_NONE),
823d2571 32010 ARM_EXT_OPT ("maverick", ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK),
d942732e
TP
32011 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ARCH_NONE),
32012 ARM_EXT_OPT2 ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
823d2571 32013 ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
d942732e
TP
32014 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
32015 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
823d2571
TG
32016 ARM_EXT_OPT ("os", ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
32017 ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
32018 ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
ddfded2f
MW
32019 ARM_EXT_OPT ("pan", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
32020 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
ced40572 32021 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
dad0c3bf
SD
32022 ARM_EXT_OPT ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
32023 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
32024 ARM_ARCH_V8A),
4d1464f2
MW
32025 ARM_EXT_OPT ("ras", ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
32026 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
ced40572 32027 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
643afb90
MW
32028 ARM_EXT_OPT ("rdma", FPU_ARCH_NEON_VFP_ARMV8_1,
32029 ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
ced40572 32030 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
7fadb25d
SD
32031 ARM_EXT_OPT ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
32032 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
32033 ARM_ARCH_V8A),
d942732e 32034 ARM_EXT_OPT2 ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
823d2571 32035 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
d942732e
TP
32036 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
32037 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
643afb90
MW
32038 ARM_EXT_OPT ("simd", FPU_ARCH_NEON_VFP_ARMV8,
32039 ARM_FEATURE_COPROC (FPU_NEON_ARMV8),
32040 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
823d2571
TG
32041 ARM_EXT_OPT ("virt", ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT | ARM_EXT_ADIV
32042 | ARM_EXT_DIV),
32043 ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT),
32044 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
32045 ARM_EXT_OPT ("xscale",ARM_FEATURE_COPROC (ARM_CEXT_XSCALE),
d942732e
TP
32046 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ARCH_NONE),
32047 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, { ARM_ARCH_NONE, ARM_ARCH_NONE } }
69133863 32048};
f3bad469 32049#undef ARM_EXT_OPT
69133863
MGD
32050
32051/* ISA floating-point and Advanced SIMD extensions. */
32052struct arm_option_fpu_value_table
32053{
0198d5e6
TC
32054 const char * name;
32055 const arm_feature_set value;
c19d1205 32056};
7ed4c4c5 32057
c19d1205
ZW
32058/* This list should, at a minimum, contain all the fpu names
32059 recognized by GCC. */
69133863 32060static const struct arm_option_fpu_value_table arm_fpus[] =
c19d1205
ZW
32061{
32062 {"softfpa", FPU_NONE},
32063 {"fpe", FPU_ARCH_FPE},
32064 {"fpe2", FPU_ARCH_FPE},
32065 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
32066 {"fpa", FPU_ARCH_FPA},
32067 {"fpa10", FPU_ARCH_FPA},
32068 {"fpa11", FPU_ARCH_FPA},
32069 {"arm7500fe", FPU_ARCH_FPA},
32070 {"softvfp", FPU_ARCH_VFP},
32071 {"softvfp+vfp", FPU_ARCH_VFP_V2},
32072 {"vfp", FPU_ARCH_VFP_V2},
32073 {"vfp9", FPU_ARCH_VFP_V2},
d5e0ba9c 32074 {"vfp3", FPU_ARCH_VFP_V3}, /* Undocumented, use vfpv3. */
c19d1205
ZW
32075 {"vfp10", FPU_ARCH_VFP_V2},
32076 {"vfp10-r0", FPU_ARCH_VFP_V1},
32077 {"vfpxd", FPU_ARCH_VFP_V1xD},
b1cc4aeb
PB
32078 {"vfpv2", FPU_ARCH_VFP_V2},
32079 {"vfpv3", FPU_ARCH_VFP_V3},
62f3b8c8 32080 {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16},
b1cc4aeb 32081 {"vfpv3-d16", FPU_ARCH_VFP_V3D16},
62f3b8c8
PB
32082 {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16},
32083 {"vfpv3xd", FPU_ARCH_VFP_V3xD},
32084 {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16},
c19d1205
ZW
32085 {"arm1020t", FPU_ARCH_VFP_V1},
32086 {"arm1020e", FPU_ARCH_VFP_V2},
d5e0ba9c 32087 {"arm1136jfs", FPU_ARCH_VFP_V2}, /* Undocumented, use arm1136jf-s. */
c19d1205
ZW
32088 {"arm1136jf-s", FPU_ARCH_VFP_V2},
32089 {"maverick", FPU_ARCH_MAVERICK},
d5e0ba9c 32090 {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
d3375ddd 32091 {"neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
8e79c3df 32092 {"neon-fp16", FPU_ARCH_NEON_FP16},
62f3b8c8
PB
32093 {"vfpv4", FPU_ARCH_VFP_V4},
32094 {"vfpv4-d16", FPU_ARCH_VFP_V4D16},
ada65aa3 32095 {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16},
a715796b
TG
32096 {"fpv5-d16", FPU_ARCH_VFP_V5D16},
32097 {"fpv5-sp-d16", FPU_ARCH_VFP_V5_SP_D16},
62f3b8c8 32098 {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4},
bca38921
MGD
32099 {"fp-armv8", FPU_ARCH_VFP_ARMV8},
32100 {"neon-fp-armv8", FPU_ARCH_NEON_VFP_ARMV8},
32101 {"crypto-neon-fp-armv8",
32102 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8},
d6b4b13e 32103 {"neon-fp-armv8.1", FPU_ARCH_NEON_VFP_ARMV8_1},
081e4c7d
MW
32104 {"crypto-neon-fp-armv8.1",
32105 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1},
e74cfd16
PB
32106 {NULL, ARM_ARCH_NONE}
32107};
32108
32109struct arm_option_value_table
32110{
e0471c16 32111 const char *name;
e74cfd16 32112 long value;
c19d1205 32113};
7ed4c4c5 32114
e74cfd16 32115static const struct arm_option_value_table arm_float_abis[] =
c19d1205
ZW
32116{
32117 {"hard", ARM_FLOAT_ABI_HARD},
32118 {"softfp", ARM_FLOAT_ABI_SOFTFP},
32119 {"soft", ARM_FLOAT_ABI_SOFT},
e74cfd16 32120 {NULL, 0}
c19d1205 32121};
7ed4c4c5 32122
c19d1205 32123#ifdef OBJ_ELF
3a4a14e9 32124/* We only know how to output GNU and ver 4/5 (AAELF) formats. */
e74cfd16 32125static const struct arm_option_value_table arm_eabis[] =
c19d1205
ZW
32126{
32127 {"gnu", EF_ARM_EABI_UNKNOWN},
32128 {"4", EF_ARM_EABI_VER4},
3a4a14e9 32129 {"5", EF_ARM_EABI_VER5},
e74cfd16 32130 {NULL, 0}
c19d1205
ZW
32131};
32132#endif
7ed4c4c5 32133
c19d1205
ZW
32134struct arm_long_option_table
32135{
0198d5e6 32136 const char * option; /* Substring to match. */
e0471c16 32137 const char * help; /* Help information. */
17b9d67d 32138 int (* func) (const char * subopt); /* Function to decode sub-option. */
e0471c16 32139 const char * deprecated; /* If non-null, print this message. */
c19d1205 32140};
7ed4c4c5 32141
c921be7d 32142static bfd_boolean
c168ce07 32143arm_parse_extension (const char *str, const arm_feature_set *opt_set,
34ef62f4
AV
32144 arm_feature_set *ext_set,
32145 const struct arm_ext_table *ext_table)
7ed4c4c5 32146{
69133863 32147 /* We insist on extensions being specified in alphabetical order, and with
fa94de6b
RM
32148 extensions being added before being removed. We achieve this by having
32149 the global ARM_EXTENSIONS table in alphabetical order, and using the
69133863 32150 ADDING_VALUE variable to indicate whether we are adding an extension (1)
fa94de6b 32151 or removing it (0) and only allowing it to change in the order
69133863
MGD
32152 -1 -> 1 -> 0. */
32153 const struct arm_option_extension_value_table * opt = NULL;
d942732e 32154 const arm_feature_set arm_any = ARM_ANY;
69133863
MGD
32155 int adding_value = -1;
32156
c19d1205 32157 while (str != NULL && *str != 0)
7ed4c4c5 32158 {
82b8a785 32159 const char *ext;
f3bad469 32160 size_t len;
7ed4c4c5 32161
c19d1205
ZW
32162 if (*str != '+')
32163 {
32164 as_bad (_("invalid architectural extension"));
c921be7d 32165 return FALSE;
c19d1205 32166 }
7ed4c4c5 32167
c19d1205
ZW
32168 str++;
32169 ext = strchr (str, '+');
7ed4c4c5 32170
c19d1205 32171 if (ext != NULL)
f3bad469 32172 len = ext - str;
c19d1205 32173 else
f3bad469 32174 len = strlen (str);
7ed4c4c5 32175
f3bad469 32176 if (len >= 2 && strncmp (str, "no", 2) == 0)
69133863
MGD
32177 {
32178 if (adding_value != 0)
32179 {
32180 adding_value = 0;
32181 opt = arm_extensions;
32182 }
32183
f3bad469 32184 len -= 2;
69133863
MGD
32185 str += 2;
32186 }
f3bad469 32187 else if (len > 0)
69133863
MGD
32188 {
32189 if (adding_value == -1)
32190 {
32191 adding_value = 1;
32192 opt = arm_extensions;
32193 }
32194 else if (adding_value != 1)
32195 {
32196 as_bad (_("must specify extensions to add before specifying "
32197 "those to remove"));
32198 return FALSE;
32199 }
32200 }
32201
f3bad469 32202 if (len == 0)
c19d1205
ZW
32203 {
32204 as_bad (_("missing architectural extension"));
c921be7d 32205 return FALSE;
c19d1205 32206 }
7ed4c4c5 32207
69133863
MGD
32208 gas_assert (adding_value != -1);
32209 gas_assert (opt != NULL);
32210
34ef62f4
AV
32211 if (ext_table != NULL)
32212 {
32213 const struct arm_ext_table * ext_opt = ext_table;
32214 bfd_boolean found = FALSE;
32215 for (; ext_opt->name != NULL; ext_opt++)
32216 if (ext_opt->name_len == len
32217 && strncmp (ext_opt->name, str, len) == 0)
32218 {
32219 if (adding_value)
32220 {
32221 if (ARM_FEATURE_ZERO (ext_opt->merge))
32222 /* TODO: Option not supported. When we remove the
32223 legacy table this case should error out. */
32224 continue;
32225
32226 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, ext_opt->merge);
32227 }
32228 else
32229 {
32230 if (ARM_FEATURE_ZERO (ext_opt->clear))
32231 /* TODO: Option not supported. When we remove the
32232 legacy table this case should error out. */
32233 continue;
32234 ARM_CLEAR_FEATURE (*ext_set, *ext_set, ext_opt->clear);
32235 }
32236 found = TRUE;
32237 break;
32238 }
32239 if (found)
32240 {
32241 str = ext;
32242 continue;
32243 }
32244 }
32245
69133863
MGD
32246 /* Scan over the options table trying to find an exact match. */
32247 for (; opt->name != NULL; opt++)
f3bad469 32248 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32249 {
d942732e
TP
32250 int i, nb_allowed_archs =
32251 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
69133863 32252 /* Check we can apply the extension to this architecture. */
d942732e
TP
32253 for (i = 0; i < nb_allowed_archs; i++)
32254 {
32255 /* Empty entry. */
32256 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
32257 continue;
c168ce07 32258 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set))
d942732e
TP
32259 break;
32260 }
32261 if (i == nb_allowed_archs)
69133863
MGD
32262 {
32263 as_bad (_("extension does not apply to the base architecture"));
32264 return FALSE;
32265 }
32266
32267 /* Add or remove the extension. */
32268 if (adding_value)
4d354d8b 32269 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value);
69133863 32270 else
4d354d8b 32271 ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value);
69133863 32272
3d030cdb
TP
32273 /* Allowing Thumb division instructions for ARMv7 in autodetection
32274 rely on this break so that duplicate extensions (extensions
32275 with the same name as a previous extension in the list) are not
32276 considered for command-line parsing. */
c19d1205
ZW
32277 break;
32278 }
7ed4c4c5 32279
c19d1205
ZW
32280 if (opt->name == NULL)
32281 {
69133863
MGD
32282 /* Did we fail to find an extension because it wasn't specified in
32283 alphabetical order, or because it does not exist? */
32284
32285 for (opt = arm_extensions; opt->name != NULL; opt++)
f3bad469 32286 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
69133863
MGD
32287 break;
32288
32289 if (opt->name == NULL)
32290 as_bad (_("unknown architectural extension `%s'"), str);
32291 else
32292 as_bad (_("architectural extensions must be specified in "
32293 "alphabetical order"));
32294
c921be7d 32295 return FALSE;
c19d1205 32296 }
69133863
MGD
32297 else
32298 {
32299 /* We should skip the extension we've just matched the next time
32300 round. */
32301 opt++;
32302 }
7ed4c4c5 32303
c19d1205
ZW
32304 str = ext;
32305 };
7ed4c4c5 32306
c921be7d 32307 return TRUE;
c19d1205 32308}
7ed4c4c5 32309
5312fe52
BW
32310static bfd_boolean
32311arm_parse_fp16_opt (const char *str)
32312{
32313 if (strcasecmp (str, "ieee") == 0)
32314 fp16_format = ARM_FP16_FORMAT_IEEE;
32315 else if (strcasecmp (str, "alternative") == 0)
32316 fp16_format = ARM_FP16_FORMAT_ALTERNATIVE;
32317 else
32318 {
32319 as_bad (_("unrecognised float16 format \"%s\""), str);
32320 return FALSE;
32321 }
32322
32323 return TRUE;
32324}
32325
c921be7d 32326static bfd_boolean
17b9d67d 32327arm_parse_cpu (const char *str)
7ed4c4c5 32328{
f3bad469 32329 const struct arm_cpu_option_table *opt;
82b8a785 32330 const char *ext = strchr (str, '+');
f3bad469 32331 size_t len;
7ed4c4c5 32332
c19d1205 32333 if (ext != NULL)
f3bad469 32334 len = ext - str;
7ed4c4c5 32335 else
f3bad469 32336 len = strlen (str);
7ed4c4c5 32337
f3bad469 32338 if (len == 0)
7ed4c4c5 32339 {
c19d1205 32340 as_bad (_("missing cpu name `%s'"), str);
c921be7d 32341 return FALSE;
7ed4c4c5
NC
32342 }
32343
c19d1205 32344 for (opt = arm_cpus; opt->name != NULL; opt++)
f3bad469 32345 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32346 {
c168ce07 32347 mcpu_cpu_opt = &opt->value;
4d354d8b
TP
32348 if (mcpu_ext_opt == NULL)
32349 mcpu_ext_opt = XNEW (arm_feature_set);
32350 *mcpu_ext_opt = opt->ext;
e74cfd16 32351 mcpu_fpu_opt = &opt->default_fpu;
ee065d83 32352 if (opt->canonical_name)
ef8e6722
JW
32353 {
32354 gas_assert (sizeof selected_cpu_name > strlen (opt->canonical_name));
32355 strcpy (selected_cpu_name, opt->canonical_name);
32356 }
ee065d83
PB
32357 else
32358 {
f3bad469 32359 size_t i;
c921be7d 32360
ef8e6722
JW
32361 if (len >= sizeof selected_cpu_name)
32362 len = (sizeof selected_cpu_name) - 1;
32363
f3bad469 32364 for (i = 0; i < len; i++)
ee065d83
PB
32365 selected_cpu_name[i] = TOUPPER (opt->name[i]);
32366 selected_cpu_name[i] = 0;
32367 }
7ed4c4c5 32368
c19d1205 32369 if (ext != NULL)
34ef62f4 32370 return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt, NULL);
7ed4c4c5 32371
c921be7d 32372 return TRUE;
c19d1205 32373 }
7ed4c4c5 32374
c19d1205 32375 as_bad (_("unknown cpu `%s'"), str);
c921be7d 32376 return FALSE;
7ed4c4c5
NC
32377}
32378
c921be7d 32379static bfd_boolean
17b9d67d 32380arm_parse_arch (const char *str)
7ed4c4c5 32381{
e74cfd16 32382 const struct arm_arch_option_table *opt;
82b8a785 32383 const char *ext = strchr (str, '+');
f3bad469 32384 size_t len;
7ed4c4c5 32385
c19d1205 32386 if (ext != NULL)
f3bad469 32387 len = ext - str;
7ed4c4c5 32388 else
f3bad469 32389 len = strlen (str);
7ed4c4c5 32390
f3bad469 32391 if (len == 0)
7ed4c4c5 32392 {
c19d1205 32393 as_bad (_("missing architecture name `%s'"), str);
c921be7d 32394 return FALSE;
7ed4c4c5
NC
32395 }
32396
c19d1205 32397 for (opt = arm_archs; opt->name != NULL; opt++)
f3bad469 32398 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 32399 {
e74cfd16 32400 march_cpu_opt = &opt->value;
4d354d8b
TP
32401 if (march_ext_opt == NULL)
32402 march_ext_opt = XNEW (arm_feature_set);
32403 *march_ext_opt = arm_arch_none;
e74cfd16 32404 march_fpu_opt = &opt->default_fpu;
e20f9590 32405 selected_ctx_ext_table = opt->ext_table;
5f4273c7 32406 strcpy (selected_cpu_name, opt->name);
7ed4c4c5 32407
c19d1205 32408 if (ext != NULL)
34ef62f4
AV
32409 return arm_parse_extension (ext, march_cpu_opt, march_ext_opt,
32410 opt->ext_table);
7ed4c4c5 32411
c921be7d 32412 return TRUE;
c19d1205
ZW
32413 }
32414
32415 as_bad (_("unknown architecture `%s'\n"), str);
c921be7d 32416 return FALSE;
7ed4c4c5 32417}
eb043451 32418
c921be7d 32419static bfd_boolean
17b9d67d 32420arm_parse_fpu (const char * str)
c19d1205 32421{
69133863 32422 const struct arm_option_fpu_value_table * opt;
b99bd4ef 32423
c19d1205
ZW
32424 for (opt = arm_fpus; opt->name != NULL; opt++)
32425 if (streq (opt->name, str))
32426 {
e74cfd16 32427 mfpu_opt = &opt->value;
c921be7d 32428 return TRUE;
c19d1205 32429 }
b99bd4ef 32430
c19d1205 32431 as_bad (_("unknown floating point format `%s'\n"), str);
c921be7d 32432 return FALSE;
c19d1205
ZW
32433}
32434
c921be7d 32435static bfd_boolean
17b9d67d 32436arm_parse_float_abi (const char * str)
b99bd4ef 32437{
e74cfd16 32438 const struct arm_option_value_table * opt;
b99bd4ef 32439
c19d1205
ZW
32440 for (opt = arm_float_abis; opt->name != NULL; opt++)
32441 if (streq (opt->name, str))
32442 {
32443 mfloat_abi_opt = opt->value;
c921be7d 32444 return TRUE;
c19d1205 32445 }
cc8a6dd0 32446
c19d1205 32447 as_bad (_("unknown floating point abi `%s'\n"), str);
c921be7d 32448 return FALSE;
c19d1205 32449}
b99bd4ef 32450
c19d1205 32451#ifdef OBJ_ELF
c921be7d 32452static bfd_boolean
17b9d67d 32453arm_parse_eabi (const char * str)
c19d1205 32454{
e74cfd16 32455 const struct arm_option_value_table *opt;
cc8a6dd0 32456
c19d1205
ZW
32457 for (opt = arm_eabis; opt->name != NULL; opt++)
32458 if (streq (opt->name, str))
32459 {
32460 meabi_flags = opt->value;
c921be7d 32461 return TRUE;
c19d1205
ZW
32462 }
32463 as_bad (_("unknown EABI `%s'\n"), str);
c921be7d 32464 return FALSE;
c19d1205
ZW
32465}
32466#endif
cc8a6dd0 32467
c921be7d 32468static bfd_boolean
17b9d67d 32469arm_parse_it_mode (const char * str)
e07e6e58 32470{
c921be7d 32471 bfd_boolean ret = TRUE;
e07e6e58
NC
32472
32473 if (streq ("arm", str))
32474 implicit_it_mode = IMPLICIT_IT_MODE_ARM;
32475 else if (streq ("thumb", str))
32476 implicit_it_mode = IMPLICIT_IT_MODE_THUMB;
32477 else if (streq ("always", str))
32478 implicit_it_mode = IMPLICIT_IT_MODE_ALWAYS;
32479 else if (streq ("never", str))
32480 implicit_it_mode = IMPLICIT_IT_MODE_NEVER;
32481 else
32482 {
32483 as_bad (_("unknown implicit IT mode `%s', should be "\
477330fc 32484 "arm, thumb, always, or never."), str);
c921be7d 32485 ret = FALSE;
e07e6e58
NC
32486 }
32487
32488 return ret;
32489}
32490
2e6976a8 32491static bfd_boolean
17b9d67d 32492arm_ccs_mode (const char * unused ATTRIBUTE_UNUSED)
2e6976a8
DG
32493{
32494 codecomposer_syntax = TRUE;
32495 arm_comment_chars[0] = ';';
32496 arm_line_separator_chars[0] = 0;
32497 return TRUE;
32498}
32499
c19d1205
ZW
32500struct arm_long_option_table arm_long_opts[] =
32501{
32502 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
32503 arm_parse_cpu, NULL},
32504 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
32505 arm_parse_arch, NULL},
32506 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
32507 arm_parse_fpu, NULL},
32508 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
32509 arm_parse_float_abi, NULL},
32510#ifdef OBJ_ELF
7fac0536 32511 {"meabi=", N_("<ver>\t\t assemble for eabi version <ver>"),
c19d1205
ZW
32512 arm_parse_eabi, NULL},
32513#endif
e07e6e58
NC
32514 {"mimplicit-it=", N_("<mode>\t controls implicit insertion of IT instructions"),
32515 arm_parse_it_mode, NULL},
2e6976a8
DG
32516 {"mccs", N_("\t\t\t TI CodeComposer Studio syntax compatibility mode"),
32517 arm_ccs_mode, NULL},
5312fe52
BW
32518 {"mfp16-format=",
32519 N_("[ieee|alternative]\n\
32520 set the encoding for half precision floating point "
32521 "numbers to IEEE\n\
32522 or Arm alternative format."),
32523 arm_parse_fp16_opt, NULL },
c19d1205
ZW
32524 {NULL, NULL, 0, NULL}
32525};
cc8a6dd0 32526
c19d1205 32527int
17b9d67d 32528md_parse_option (int c, const char * arg)
c19d1205
ZW
32529{
32530 struct arm_option_table *opt;
e74cfd16 32531 const struct arm_legacy_option_table *fopt;
c19d1205 32532 struct arm_long_option_table *lopt;
b99bd4ef 32533
c19d1205 32534 switch (c)
b99bd4ef 32535 {
c19d1205
ZW
32536#ifdef OPTION_EB
32537 case OPTION_EB:
32538 target_big_endian = 1;
32539 break;
32540#endif
cc8a6dd0 32541
c19d1205
ZW
32542#ifdef OPTION_EL
32543 case OPTION_EL:
32544 target_big_endian = 0;
32545 break;
32546#endif
b99bd4ef 32547
845b51d6
PB
32548 case OPTION_FIX_V4BX:
32549 fix_v4bx = TRUE;
32550 break;
32551
18a20338
CL
32552#ifdef OBJ_ELF
32553 case OPTION_FDPIC:
32554 arm_fdpic = TRUE;
32555 break;
32556#endif /* OBJ_ELF */
32557
c19d1205
ZW
32558 case 'a':
32559 /* Listing option. Just ignore these, we don't support additional
32560 ones. */
32561 return 0;
b99bd4ef 32562
c19d1205
ZW
32563 default:
32564 for (opt = arm_opts; opt->option != NULL; opt++)
32565 {
32566 if (c == opt->option[0]
32567 && ((arg == NULL && opt->option[1] == 0)
32568 || streq (arg, opt->option + 1)))
32569 {
c19d1205 32570 /* If the option is deprecated, tell the user. */
278df34e 32571 if (warn_on_deprecated && opt->deprecated != NULL)
c19d1205
ZW
32572 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
32573 arg ? arg : "", _(opt->deprecated));
b99bd4ef 32574
c19d1205
ZW
32575 if (opt->var != NULL)
32576 *opt->var = opt->value;
cc8a6dd0 32577
c19d1205
ZW
32578 return 1;
32579 }
32580 }
b99bd4ef 32581
e74cfd16
PB
32582 for (fopt = arm_legacy_opts; fopt->option != NULL; fopt++)
32583 {
32584 if (c == fopt->option[0]
32585 && ((arg == NULL && fopt->option[1] == 0)
32586 || streq (arg, fopt->option + 1)))
32587 {
e74cfd16 32588 /* If the option is deprecated, tell the user. */
278df34e 32589 if (warn_on_deprecated && fopt->deprecated != NULL)
e74cfd16
PB
32590 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
32591 arg ? arg : "", _(fopt->deprecated));
e74cfd16
PB
32592
32593 if (fopt->var != NULL)
32594 *fopt->var = &fopt->value;
32595
32596 return 1;
32597 }
32598 }
32599
c19d1205
ZW
32600 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
32601 {
32602 /* These options are expected to have an argument. */
32603 if (c == lopt->option[0]
32604 && arg != NULL
32605 && strncmp (arg, lopt->option + 1,
32606 strlen (lopt->option + 1)) == 0)
32607 {
c19d1205 32608 /* If the option is deprecated, tell the user. */
278df34e 32609 if (warn_on_deprecated && lopt->deprecated != NULL)
c19d1205
ZW
32610 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
32611 _(lopt->deprecated));
b99bd4ef 32612
c19d1205
ZW
32613 /* Call the sup-option parser. */
32614 return lopt->func (arg + strlen (lopt->option) - 1);
32615 }
32616 }
a737bd4d 32617
c19d1205
ZW
32618 return 0;
32619 }
a394c00f 32620
c19d1205
ZW
32621 return 1;
32622}
a394c00f 32623
c19d1205
ZW
32624void
32625md_show_usage (FILE * fp)
a394c00f 32626{
c19d1205
ZW
32627 struct arm_option_table *opt;
32628 struct arm_long_option_table *lopt;
a394c00f 32629
c19d1205 32630 fprintf (fp, _(" ARM-specific assembler options:\n"));
a394c00f 32631
c19d1205
ZW
32632 for (opt = arm_opts; opt->option != NULL; opt++)
32633 if (opt->help != NULL)
32634 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
a394c00f 32635
c19d1205
ZW
32636 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
32637 if (lopt->help != NULL)
32638 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
a394c00f 32639
c19d1205
ZW
32640#ifdef OPTION_EB
32641 fprintf (fp, _("\
32642 -EB assemble code for a big-endian cpu\n"));
a394c00f
NC
32643#endif
32644
c19d1205
ZW
32645#ifdef OPTION_EL
32646 fprintf (fp, _("\
32647 -EL assemble code for a little-endian cpu\n"));
a737bd4d 32648#endif
845b51d6
PB
32649
32650 fprintf (fp, _("\
32651 --fix-v4bx Allow BX in ARMv4 code\n"));
18a20338
CL
32652
32653#ifdef OBJ_ELF
32654 fprintf (fp, _("\
32655 --fdpic generate an FDPIC object file\n"));
32656#endif /* OBJ_ELF */
c19d1205 32657}
ee065d83 32658
ee065d83 32659#ifdef OBJ_ELF
0198d5e6 32660
62b3e311
PB
32661typedef struct
32662{
32663 int val;
32664 arm_feature_set flags;
32665} cpu_arch_ver_table;
32666
2c6b98ea
TP
32667/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
32668 chronologically for architectures, with an exception for ARMv6-M and
32669 ARMv6S-M due to legacy reasons. No new architecture should have a
32670 special case. This allows for build attribute selection results to be
32671 stable when new architectures are added. */
62b3e311
PB
32672static const cpu_arch_ver_table cpu_arch_ver[] =
32673{
031254f2
AV
32674 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V1},
32675 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2},
32676 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2S},
32677 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3},
32678 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3M},
32679 {TAG_CPU_ARCH_V4, ARM_ARCH_V4xM},
32680 {TAG_CPU_ARCH_V4, ARM_ARCH_V4},
32681 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4TxM},
32682 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4T},
32683 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5xM},
32684 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5},
32685 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5TxM},
32686 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5T},
32687 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TExP},
32688 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TE},
32689 {TAG_CPU_ARCH_V5TEJ, ARM_ARCH_V5TEJ},
32690 {TAG_CPU_ARCH_V6, ARM_ARCH_V6},
32691 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6Z},
32692 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6KZ},
32693 {TAG_CPU_ARCH_V6K, ARM_ARCH_V6K},
32694 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6T2},
32695 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KT2},
32696 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6ZT2},
32697 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KZT2},
2c6b98ea
TP
32698
32699 /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
32700 always selected build attributes to match those of ARMv6-M
32701 (resp. ARMv6S-M). However, due to these architectures being a strict
32702 subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
32703 would be selected when fully respecting chronology of architectures.
32704 It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
32705 move them before ARMv7 architectures. */
031254f2
AV
32706 {TAG_CPU_ARCH_V6_M, ARM_ARCH_V6M},
32707 {TAG_CPU_ARCH_V6S_M, ARM_ARCH_V6SM},
32708
32709 {TAG_CPU_ARCH_V7, ARM_ARCH_V7},
32710 {TAG_CPU_ARCH_V7, ARM_ARCH_V7A},
32711 {TAG_CPU_ARCH_V7, ARM_ARCH_V7R},
32712 {TAG_CPU_ARCH_V7, ARM_ARCH_V7M},
32713 {TAG_CPU_ARCH_V7, ARM_ARCH_V7VE},
32714 {TAG_CPU_ARCH_V7E_M, ARM_ARCH_V7EM},
32715 {TAG_CPU_ARCH_V8, ARM_ARCH_V8A},
32716 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_1A},
32717 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_2A},
32718 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_3A},
32719 {TAG_CPU_ARCH_V8M_BASE, ARM_ARCH_V8M_BASE},
32720 {TAG_CPU_ARCH_V8M_MAIN, ARM_ARCH_V8M_MAIN},
32721 {TAG_CPU_ARCH_V8R, ARM_ARCH_V8R},
32722 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_4A},
32723 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_5A},
32724 {TAG_CPU_ARCH_V8_1M_MAIN, ARM_ARCH_V8_1M_MAIN},
aab2c27d
MM
32725 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_6A},
32726 {-1, ARM_ARCH_NONE}
62b3e311
PB
32727};
32728
ee3c0378 32729/* Set an attribute if it has not already been set by the user. */
0198d5e6 32730
ee3c0378
AS
32731static void
32732aeabi_set_attribute_int (int tag, int value)
32733{
32734 if (tag < 1
32735 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
32736 || !attributes_set_explicitly[tag])
32737 bfd_elf_add_proc_attr_int (stdoutput, tag, value);
32738}
32739
32740static void
32741aeabi_set_attribute_string (int tag, const char *value)
32742{
32743 if (tag < 1
32744 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
32745 || !attributes_set_explicitly[tag])
32746 bfd_elf_add_proc_attr_string (stdoutput, tag, value);
32747}
32748
2c6b98ea
TP
32749/* Return whether features in the *NEEDED feature set are available via
32750 extensions for the architecture whose feature set is *ARCH_FSET. */
0198d5e6 32751
2c6b98ea
TP
32752static bfd_boolean
32753have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
32754 const arm_feature_set *needed)
32755{
32756 int i, nb_allowed_archs;
32757 arm_feature_set ext_fset;
32758 const struct arm_option_extension_value_table *opt;
32759
32760 ext_fset = arm_arch_none;
32761 for (opt = arm_extensions; opt->name != NULL; opt++)
32762 {
32763 /* Extension does not provide any feature we need. */
32764 if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
32765 continue;
32766
32767 nb_allowed_archs =
32768 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
32769 for (i = 0; i < nb_allowed_archs; i++)
32770 {
32771 /* Empty entry. */
32772 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
32773 break;
32774
32775 /* Extension is available, add it. */
32776 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
32777 ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
32778 }
32779 }
32780
32781 /* Can we enable all features in *needed? */
32782 return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
32783}
32784
32785/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
32786 a given architecture feature set *ARCH_EXT_FSET including extension feature
32787 set *EXT_FSET. Selection logic used depend on EXACT_MATCH:
32788 - if true, check for an exact match of the architecture modulo extensions;
32789 - otherwise, select build attribute value of the first superset
32790 architecture released so that results remains stable when new architectures
32791 are added.
32792 For -march/-mcpu=all the build attribute value of the most featureful
32793 architecture is returned. Tag_CPU_arch_profile result is returned in
32794 PROFILE. */
0198d5e6 32795
2c6b98ea
TP
32796static int
32797get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
32798 const arm_feature_set *ext_fset,
32799 char *profile, int exact_match)
32800{
32801 arm_feature_set arch_fset;
32802 const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
32803
32804 /* Select most featureful architecture with all its extensions if building
32805 for -march=all as the feature sets used to set build attributes. */
32806 if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
32807 {
32808 /* Force revisiting of decision for each new architecture. */
031254f2 32809 gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V8_1M_MAIN);
2c6b98ea
TP
32810 *profile = 'A';
32811 return TAG_CPU_ARCH_V8;
32812 }
32813
32814 ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
32815
32816 for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
32817 {
32818 arm_feature_set known_arch_fset;
32819
32820 ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
32821 if (exact_match)
32822 {
32823 /* Base architecture match user-specified architecture and
32824 extensions, eg. ARMv6S-M matching -march=armv6-m+os. */
32825 if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
32826 {
32827 p_ver_ret = p_ver;
32828 goto found;
32829 }
32830 /* Base architecture match user-specified architecture only
32831 (eg. ARMv6-M in the same case as above). Record it in case we
32832 find a match with above condition. */
32833 else if (p_ver_ret == NULL
32834 && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
32835 p_ver_ret = p_ver;
32836 }
32837 else
32838 {
32839
32840 /* Architecture has all features wanted. */
32841 if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
32842 {
32843 arm_feature_set added_fset;
32844
32845 /* Compute features added by this architecture over the one
32846 recorded in p_ver_ret. */
32847 if (p_ver_ret != NULL)
32848 ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
32849 p_ver_ret->flags);
32850 /* First architecture that match incl. with extensions, or the
32851 only difference in features over the recorded match is
32852 features that were optional and are now mandatory. */
32853 if (p_ver_ret == NULL
32854 || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
32855 {
32856 p_ver_ret = p_ver;
32857 goto found;
32858 }
32859 }
32860 else if (p_ver_ret == NULL)
32861 {
32862 arm_feature_set needed_ext_fset;
32863
32864 ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
32865
32866 /* Architecture has all features needed when using some
32867 extensions. Record it and continue searching in case there
32868 exist an architecture providing all needed features without
32869 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
32870 OS extension). */
32871 if (have_ext_for_needed_feat_p (&known_arch_fset,
32872 &needed_ext_fset))
32873 p_ver_ret = p_ver;
32874 }
32875 }
32876 }
32877
32878 if (p_ver_ret == NULL)
32879 return -1;
32880
dc1e8a47 32881 found:
2c6b98ea 32882 /* Tag_CPU_arch_profile. */
164446e0
AF
32883 if (!ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8r)
32884 && (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
32885 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
32886 || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
32887 && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only))))
2c6b98ea 32888 *profile = 'A';
164446e0
AF
32889 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r)
32890 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8r))
2c6b98ea
TP
32891 *profile = 'R';
32892 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
32893 *profile = 'M';
32894 else
32895 *profile = '\0';
32896 return p_ver_ret->val;
32897}
32898
ee065d83 32899/* Set the public EABI object attributes. */
0198d5e6 32900
c168ce07 32901static void
ee065d83
PB
32902aeabi_set_public_attributes (void)
32903{
b90d5ba0 32904 char profile = '\0';
2c6b98ea 32905 int arch = -1;
90ec0d68 32906 int virt_sec = 0;
bca38921 32907 int fp16_optional = 0;
2c6b98ea
TP
32908 int skip_exact_match = 0;
32909 arm_feature_set flags, flags_arch, flags_ext;
ee065d83 32910
54bab281
TP
32911 /* Autodetection mode, choose the architecture based the instructions
32912 actually used. */
32913 if (no_cpu_selected ())
32914 {
32915 ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
ddd7f988 32916
54bab281
TP
32917 if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
32918 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
ddd7f988 32919
54bab281
TP
32920 if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
32921 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
ddd7f988 32922
54bab281 32923 /* Code run during relaxation relies on selected_cpu being set. */
4d354d8b
TP
32924 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
32925 flags_ext = arm_arch_none;
32926 ARM_CLEAR_FEATURE (selected_arch, flags_arch, flags_ext);
32927 selected_ext = flags_ext;
54bab281
TP
32928 selected_cpu = flags;
32929 }
32930 /* Otherwise, choose the architecture based on the capabilities of the
32931 requested cpu. */
32932 else
4d354d8b
TP
32933 {
32934 ARM_MERGE_FEATURE_SETS (flags_arch, selected_arch, selected_ext);
32935 ARM_CLEAR_FEATURE (flags_arch, flags_arch, fpu_any);
32936 flags_ext = selected_ext;
32937 flags = selected_cpu;
32938 }
32939 ARM_MERGE_FEATURE_SETS (flags, flags, selected_fpu);
7f78eb34 32940
ddd7f988 32941 /* Allow the user to override the reported architecture. */
4d354d8b 32942 if (!ARM_FEATURE_ZERO (selected_object_arch))
7a1d4c38 32943 {
4d354d8b 32944 ARM_CLEAR_FEATURE (flags_arch, selected_object_arch, fpu_any);
2c6b98ea 32945 flags_ext = arm_arch_none;
7a1d4c38 32946 }
2c6b98ea 32947 else
4d354d8b 32948 skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
2c6b98ea
TP
32949
32950 /* When this function is run again after relaxation has happened there is no
32951 way to determine whether an architecture or CPU was specified by the user:
32952 - selected_cpu is set above for relaxation to work;
32953 - march_cpu_opt is not set if only -mcpu or .cpu is used;
32954 - mcpu_cpu_opt is set to arm_arch_any for autodetection.
32955 Therefore, if not in -march=all case we first try an exact match and fall
32956 back to autodetection. */
32957 if (!skip_exact_match)
32958 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
32959 if (arch == -1)
32960 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
32961 if (arch == -1)
32962 as_bad (_("no architecture contains all the instructions used\n"));
9e3c6df6 32963
ee065d83
PB
32964 /* Tag_CPU_name. */
32965 if (selected_cpu_name[0])
32966 {
91d6fa6a 32967 char *q;
ee065d83 32968
91d6fa6a
NC
32969 q = selected_cpu_name;
32970 if (strncmp (q, "armv", 4) == 0)
ee065d83
PB
32971 {
32972 int i;
5f4273c7 32973
91d6fa6a
NC
32974 q += 4;
32975 for (i = 0; q[i]; i++)
32976 q[i] = TOUPPER (q[i]);
ee065d83 32977 }
91d6fa6a 32978 aeabi_set_attribute_string (Tag_CPU_name, q);
ee065d83 32979 }
62f3b8c8 32980
ee065d83 32981 /* Tag_CPU_arch. */
ee3c0378 32982 aeabi_set_attribute_int (Tag_CPU_arch, arch);
62f3b8c8 32983
62b3e311 32984 /* Tag_CPU_arch_profile. */
69239280
MGD
32985 if (profile != '\0')
32986 aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
62f3b8c8 32987
15afaa63 32988 /* Tag_DSP_extension. */
4d354d8b 32989 if (ARM_CPU_HAS_FEATURE (selected_ext, arm_ext_dsp))
6c290d53 32990 aeabi_set_attribute_int (Tag_DSP_extension, 1);
15afaa63 32991
2c6b98ea 32992 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
ee065d83 32993 /* Tag_ARM_ISA_use. */
ee3c0378 32994 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
2c6b98ea 32995 || ARM_FEATURE_ZERO (flags_arch))
ee3c0378 32996 aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
62f3b8c8 32997
ee065d83 32998 /* Tag_THUMB_ISA_use. */
ee3c0378 32999 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
2c6b98ea 33000 || ARM_FEATURE_ZERO (flags_arch))
4ed7ed8d
TP
33001 {
33002 int thumb_isa_use;
33003
33004 if (!ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
16a1fa25 33005 && ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only))
4ed7ed8d
TP
33006 thumb_isa_use = 3;
33007 else if (ARM_CPU_HAS_FEATURE (flags, arm_arch_t2))
33008 thumb_isa_use = 2;
33009 else
33010 thumb_isa_use = 1;
33011 aeabi_set_attribute_int (Tag_THUMB_ISA_use, thumb_isa_use);
33012 }
62f3b8c8 33013
ee065d83 33014 /* Tag_VFP_arch. */
a715796b
TG
33015 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_armv8xd))
33016 aeabi_set_attribute_int (Tag_VFP_arch,
33017 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
33018 ? 7 : 8);
bca38921 33019 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_fma))
62f3b8c8
PB
33020 aeabi_set_attribute_int (Tag_VFP_arch,
33021 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
33022 ? 5 : 6);
33023 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32))
bca38921
MGD
33024 {
33025 fp16_optional = 1;
33026 aeabi_set_attribute_int (Tag_VFP_arch, 3);
33027 }
ada65aa3 33028 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v3xd))
bca38921
MGD
33029 {
33030 aeabi_set_attribute_int (Tag_VFP_arch, 4);
33031 fp16_optional = 1;
33032 }
ee3c0378
AS
33033 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v2))
33034 aeabi_set_attribute_int (Tag_VFP_arch, 2);
33035 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1)
477330fc 33036 || ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd))
ee3c0378 33037 aeabi_set_attribute_int (Tag_VFP_arch, 1);
62f3b8c8 33038
4547cb56
NC
33039 /* Tag_ABI_HardFP_use. */
33040 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd)
33041 && !ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1))
33042 aeabi_set_attribute_int (Tag_ABI_HardFP_use, 1);
33043
ee065d83 33044 /* Tag_WMMX_arch. */
ee3c0378
AS
33045 if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt2))
33046 aeabi_set_attribute_int (Tag_WMMX_arch, 2);
33047 else if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt))
33048 aeabi_set_attribute_int (Tag_WMMX_arch, 1);
62f3b8c8 33049
ee3c0378 33050 /* Tag_Advanced_SIMD_arch (formerly Tag_NEON_arch). */
9411fd44
MW
33051 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v8_1))
33052 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 4);
33053 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_armv8))
bca38921
MGD
33054 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 3);
33055 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v1))
33056 {
33057 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_fma))
33058 {
33059 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 2);
33060 }
33061 else
33062 {
33063 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 1);
33064 fp16_optional = 1;
33065 }
33066 }
fa94de6b 33067
a7ad558c
AV
33068 if (ARM_CPU_HAS_FEATURE (flags, mve_fp_ext))
33069 aeabi_set_attribute_int (Tag_MVE_arch, 2);
33070 else if (ARM_CPU_HAS_FEATURE (flags, mve_ext))
33071 aeabi_set_attribute_int (Tag_MVE_arch, 1);
33072
ee3c0378 33073 /* Tag_VFP_HP_extension (formerly Tag_NEON_FP16_arch). */
bca38921 33074 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_fp16) && fp16_optional)
ee3c0378 33075 aeabi_set_attribute_int (Tag_VFP_HP_extension, 1);
4547cb56 33076
69239280
MGD
33077 /* Tag_DIV_use.
33078
33079 We set Tag_DIV_use to two when integer divide instructions have been used
33080 in ARM state, or when Thumb integer divide instructions have been used,
33081 but we have no architecture profile set, nor have we any ARM instructions.
33082
4ed7ed8d
TP
33083 For ARMv8-A and ARMv8-M we set the tag to 0 as integer divide is implied
33084 by the base architecture.
bca38921 33085
69239280 33086 For new architectures we will have to check these tests. */
031254f2 33087 gas_assert (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
4ed7ed8d
TP
33088 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
33089 || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
bca38921
MGD
33090 aeabi_set_attribute_int (Tag_DIV_use, 0);
33091 else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_adiv)
33092 || (profile == '\0'
33093 && ARM_CPU_HAS_FEATURE (flags, arm_ext_div)
33094 && !ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any)))
eea54501 33095 aeabi_set_attribute_int (Tag_DIV_use, 2);
60e5ef9f
MGD
33096
33097 /* Tag_MP_extension_use. */
33098 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_mp))
33099 aeabi_set_attribute_int (Tag_MPextension_use, 1);
f4c65163
MGD
33100
33101 /* Tag Virtualization_use. */
33102 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_sec))
90ec0d68
MGD
33103 virt_sec |= 1;
33104 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_virt))
33105 virt_sec |= 2;
33106 if (virt_sec != 0)
33107 aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
5312fe52
BW
33108
33109 if (fp16_format != ARM_FP16_FORMAT_DEFAULT)
33110 aeabi_set_attribute_int (Tag_ABI_FP_16bit_format, fp16_format);
ee065d83
PB
33111}
33112
c168ce07
TP
33113/* Post relaxation hook. Recompute ARM attributes now that relaxation is
33114 finished and free extension feature bits which will not be used anymore. */
0198d5e6 33115
c168ce07
TP
33116void
33117arm_md_post_relax (void)
33118{
33119 aeabi_set_public_attributes ();
4d354d8b
TP
33120 XDELETE (mcpu_ext_opt);
33121 mcpu_ext_opt = NULL;
33122 XDELETE (march_ext_opt);
33123 march_ext_opt = NULL;
c168ce07
TP
33124}
33125
104d59d1 33126/* Add the default contents for the .ARM.attributes section. */
0198d5e6 33127
ee065d83
PB
33128void
33129arm_md_end (void)
33130{
ee065d83
PB
33131 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
33132 return;
33133
33134 aeabi_set_public_attributes ();
ee065d83 33135}
8463be01 33136#endif /* OBJ_ELF */
ee065d83 33137
ee065d83
PB
33138/* Parse a .cpu directive. */
33139
33140static void
33141s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
33142{
e74cfd16 33143 const struct arm_cpu_option_table *opt;
ee065d83
PB
33144 char *name;
33145 char saved_char;
33146
33147 name = input_line_pointer;
5f4273c7 33148 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
33149 input_line_pointer++;
33150 saved_char = *input_line_pointer;
33151 *input_line_pointer = 0;
33152
33153 /* Skip the first "all" entry. */
33154 for (opt = arm_cpus + 1; opt->name != NULL; opt++)
33155 if (streq (opt->name, name))
33156 {
4d354d8b
TP
33157 selected_arch = opt->value;
33158 selected_ext = opt->ext;
33159 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
ee065d83 33160 if (opt->canonical_name)
5f4273c7 33161 strcpy (selected_cpu_name, opt->canonical_name);
ee065d83
PB
33162 else
33163 {
33164 int i;
33165 for (i = 0; opt->name[i]; i++)
33166 selected_cpu_name[i] = TOUPPER (opt->name[i]);
f3bad469 33167
ee065d83
PB
33168 selected_cpu_name[i] = 0;
33169 }
4d354d8b
TP
33170 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
33171
ee065d83
PB
33172 *input_line_pointer = saved_char;
33173 demand_empty_rest_of_line ();
33174 return;
33175 }
33176 as_bad (_("unknown cpu `%s'"), name);
33177 *input_line_pointer = saved_char;
33178 ignore_rest_of_line ();
33179}
33180
ee065d83
PB
33181/* Parse a .arch directive. */
33182
33183static void
33184s_arm_arch (int ignored ATTRIBUTE_UNUSED)
33185{
e74cfd16 33186 const struct arm_arch_option_table *opt;
ee065d83
PB
33187 char saved_char;
33188 char *name;
33189
33190 name = input_line_pointer;
5f4273c7 33191 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
33192 input_line_pointer++;
33193 saved_char = *input_line_pointer;
33194 *input_line_pointer = 0;
33195
33196 /* Skip the first "all" entry. */
33197 for (opt = arm_archs + 1; opt->name != NULL; opt++)
33198 if (streq (opt->name, name))
33199 {
4d354d8b 33200 selected_arch = opt->value;
0e7aaa72 33201 selected_ctx_ext_table = opt->ext_table;
4d354d8b
TP
33202 selected_ext = arm_arch_none;
33203 selected_cpu = selected_arch;
5f4273c7 33204 strcpy (selected_cpu_name, opt->name);
4d354d8b 33205 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
33206 *input_line_pointer = saved_char;
33207 demand_empty_rest_of_line ();
33208 return;
33209 }
33210
33211 as_bad (_("unknown architecture `%s'\n"), name);
33212 *input_line_pointer = saved_char;
33213 ignore_rest_of_line ();
33214}
33215
7a1d4c38
PB
33216/* Parse a .object_arch directive. */
33217
33218static void
33219s_arm_object_arch (int ignored ATTRIBUTE_UNUSED)
33220{
33221 const struct arm_arch_option_table *opt;
33222 char saved_char;
33223 char *name;
33224
33225 name = input_line_pointer;
5f4273c7 33226 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
7a1d4c38
PB
33227 input_line_pointer++;
33228 saved_char = *input_line_pointer;
33229 *input_line_pointer = 0;
33230
33231 /* Skip the first "all" entry. */
33232 for (opt = arm_archs + 1; opt->name != NULL; opt++)
33233 if (streq (opt->name, name))
33234 {
4d354d8b 33235 selected_object_arch = opt->value;
7a1d4c38
PB
33236 *input_line_pointer = saved_char;
33237 demand_empty_rest_of_line ();
33238 return;
33239 }
33240
33241 as_bad (_("unknown architecture `%s'\n"), name);
33242 *input_line_pointer = saved_char;
33243 ignore_rest_of_line ();
33244}
33245
69133863
MGD
33246/* Parse a .arch_extension directive. */
33247
33248static void
33249s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
33250{
33251 const struct arm_option_extension_value_table *opt;
33252 char saved_char;
33253 char *name;
33254 int adding_value = 1;
33255
33256 name = input_line_pointer;
33257 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
33258 input_line_pointer++;
33259 saved_char = *input_line_pointer;
33260 *input_line_pointer = 0;
33261
33262 if (strlen (name) >= 2
33263 && strncmp (name, "no", 2) == 0)
33264 {
33265 adding_value = 0;
33266 name += 2;
33267 }
33268
e20f9590
MI
33269 /* Check the context specific extension table */
33270 if (selected_ctx_ext_table)
33271 {
33272 const struct arm_ext_table * ext_opt;
33273 for (ext_opt = selected_ctx_ext_table; ext_opt->name != NULL; ext_opt++)
33274 {
33275 if (streq (ext_opt->name, name))
33276 {
33277 if (adding_value)
33278 {
33279 if (ARM_FEATURE_ZERO (ext_opt->merge))
33280 /* TODO: Option not supported. When we remove the
33281 legacy table this case should error out. */
33282 continue;
33283 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
33284 ext_opt->merge);
33285 }
33286 else
33287 ARM_CLEAR_FEATURE (selected_ext, selected_ext, ext_opt->clear);
33288
33289 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
33290 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
33291 *input_line_pointer = saved_char;
33292 demand_empty_rest_of_line ();
33293 return;
33294 }
33295 }
33296 }
33297
69133863
MGD
33298 for (opt = arm_extensions; opt->name != NULL; opt++)
33299 if (streq (opt->name, name))
33300 {
d942732e
TP
33301 int i, nb_allowed_archs =
33302 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[i]);
33303 for (i = 0; i < nb_allowed_archs; i++)
33304 {
33305 /* Empty entry. */
4d354d8b 33306 if (ARM_CPU_IS_ANY (opt->allowed_archs[i]))
d942732e 33307 continue;
4d354d8b 33308 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], selected_arch))
d942732e
TP
33309 break;
33310 }
33311
33312 if (i == nb_allowed_archs)
69133863
MGD
33313 {
33314 as_bad (_("architectural extension `%s' is not allowed for the "
33315 "current base architecture"), name);
33316 break;
33317 }
33318
33319 if (adding_value)
4d354d8b 33320 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
5a70a223 33321 opt->merge_value);
69133863 33322 else
4d354d8b 33323 ARM_CLEAR_FEATURE (selected_ext, selected_ext, opt->clear_value);
69133863 33324
4d354d8b
TP
33325 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
33326 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
69133863
MGD
33327 *input_line_pointer = saved_char;
33328 demand_empty_rest_of_line ();
3d030cdb
TP
33329 /* Allowing Thumb division instructions for ARMv7 in autodetection rely
33330 on this return so that duplicate extensions (extensions with the
33331 same name as a previous extension in the list) are not considered
33332 for command-line parsing. */
69133863
MGD
33333 return;
33334 }
33335
33336 if (opt->name == NULL)
e673710a 33337 as_bad (_("unknown architecture extension `%s'\n"), name);
69133863
MGD
33338
33339 *input_line_pointer = saved_char;
33340 ignore_rest_of_line ();
33341}
33342
ee065d83
PB
33343/* Parse a .fpu directive. */
33344
33345static void
33346s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
33347{
69133863 33348 const struct arm_option_fpu_value_table *opt;
ee065d83
PB
33349 char saved_char;
33350 char *name;
33351
33352 name = input_line_pointer;
5f4273c7 33353 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
33354 input_line_pointer++;
33355 saved_char = *input_line_pointer;
33356 *input_line_pointer = 0;
5f4273c7 33357
ee065d83
PB
33358 for (opt = arm_fpus; opt->name != NULL; opt++)
33359 if (streq (opt->name, name))
33360 {
4d354d8b 33361 selected_fpu = opt->value;
f4399880 33362 ARM_CLEAR_FEATURE (selected_cpu, selected_cpu, fpu_any);
4d354d8b
TP
33363#ifndef CPU_DEFAULT
33364 if (no_cpu_selected ())
33365 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
33366 else
33367#endif
33368 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
33369 *input_line_pointer = saved_char;
33370 demand_empty_rest_of_line ();
33371 return;
33372 }
33373
33374 as_bad (_("unknown floating point format `%s'\n"), name);
33375 *input_line_pointer = saved_char;
33376 ignore_rest_of_line ();
33377}
ee065d83 33378
794ba86a 33379/* Copy symbol information. */
f31fef98 33380
794ba86a
DJ
33381void
33382arm_copy_symbol_attributes (symbolS *dest, symbolS *src)
33383{
33384 ARM_GET_FLAG (dest) = ARM_GET_FLAG (src);
33385}
e04befd0 33386
f31fef98 33387#ifdef OBJ_ELF
e04befd0
AS
33388/* Given a symbolic attribute NAME, return the proper integer value.
33389 Returns -1 if the attribute is not known. */
f31fef98 33390
e04befd0
AS
33391int
33392arm_convert_symbolic_attribute (const char *name)
33393{
f31fef98
NC
33394 static const struct
33395 {
33396 const char * name;
33397 const int tag;
33398 }
33399 attribute_table[] =
33400 {
33401 /* When you modify this table you should
33402 also modify the list in doc/c-arm.texi. */
e04befd0 33403#define T(tag) {#tag, tag}
f31fef98
NC
33404 T (Tag_CPU_raw_name),
33405 T (Tag_CPU_name),
33406 T (Tag_CPU_arch),
33407 T (Tag_CPU_arch_profile),
33408 T (Tag_ARM_ISA_use),
33409 T (Tag_THUMB_ISA_use),
75375b3e 33410 T (Tag_FP_arch),
f31fef98
NC
33411 T (Tag_VFP_arch),
33412 T (Tag_WMMX_arch),
33413 T (Tag_Advanced_SIMD_arch),
33414 T (Tag_PCS_config),
33415 T (Tag_ABI_PCS_R9_use),
33416 T (Tag_ABI_PCS_RW_data),
33417 T (Tag_ABI_PCS_RO_data),
33418 T (Tag_ABI_PCS_GOT_use),
33419 T (Tag_ABI_PCS_wchar_t),
33420 T (Tag_ABI_FP_rounding),
33421 T (Tag_ABI_FP_denormal),
33422 T (Tag_ABI_FP_exceptions),
33423 T (Tag_ABI_FP_user_exceptions),
33424 T (Tag_ABI_FP_number_model),
75375b3e 33425 T (Tag_ABI_align_needed),
f31fef98 33426 T (Tag_ABI_align8_needed),
75375b3e 33427 T (Tag_ABI_align_preserved),
f31fef98
NC
33428 T (Tag_ABI_align8_preserved),
33429 T (Tag_ABI_enum_size),
33430 T (Tag_ABI_HardFP_use),
33431 T (Tag_ABI_VFP_args),
33432 T (Tag_ABI_WMMX_args),
33433 T (Tag_ABI_optimization_goals),
33434 T (Tag_ABI_FP_optimization_goals),
33435 T (Tag_compatibility),
33436 T (Tag_CPU_unaligned_access),
75375b3e 33437 T (Tag_FP_HP_extension),
f31fef98
NC
33438 T (Tag_VFP_HP_extension),
33439 T (Tag_ABI_FP_16bit_format),
cd21e546
MGD
33440 T (Tag_MPextension_use),
33441 T (Tag_DIV_use),
f31fef98
NC
33442 T (Tag_nodefaults),
33443 T (Tag_also_compatible_with),
33444 T (Tag_conformance),
33445 T (Tag_T2EE_use),
33446 T (Tag_Virtualization_use),
15afaa63 33447 T (Tag_DSP_extension),
a7ad558c 33448 T (Tag_MVE_arch),
cd21e546 33449 /* We deliberately do not include Tag_MPextension_use_legacy. */
e04befd0 33450#undef T
f31fef98 33451 };
e04befd0
AS
33452 unsigned int i;
33453
33454 if (name == NULL)
33455 return -1;
33456
f31fef98 33457 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
c921be7d 33458 if (streq (name, attribute_table[i].name))
e04befd0
AS
33459 return attribute_table[i].tag;
33460
33461 return -1;
33462}
267bf995 33463
93ef582d
NC
33464/* Apply sym value for relocations only in the case that they are for
33465 local symbols in the same segment as the fixup and you have the
33466 respective architectural feature for blx and simple switches. */
0198d5e6 33467
267bf995 33468int
93ef582d 33469arm_apply_sym_value (struct fix * fixP, segT this_seg)
267bf995
RR
33470{
33471 if (fixP->fx_addsy
33472 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
93ef582d
NC
33473 /* PR 17444: If the local symbol is in a different section then a reloc
33474 will always be generated for it, so applying the symbol value now
33475 will result in a double offset being stored in the relocation. */
33476 && (S_GET_SEGMENT (fixP->fx_addsy) == this_seg)
34e77a92 33477 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE))
267bf995
RR
33478 {
33479 switch (fixP->fx_r_type)
33480 {
33481 case BFD_RELOC_ARM_PCREL_BLX:
33482 case BFD_RELOC_THUMB_PCREL_BRANCH23:
33483 if (ARM_IS_FUNC (fixP->fx_addsy))
33484 return 1;
33485 break;
33486
33487 case BFD_RELOC_ARM_PCREL_CALL:
33488 case BFD_RELOC_THUMB_PCREL_BLX:
33489 if (THUMB_IS_FUNC (fixP->fx_addsy))
93ef582d 33490 return 1;
267bf995
RR
33491 break;
33492
33493 default:
33494 break;
33495 }
33496
33497 }
33498 return 0;
33499}
f31fef98 33500#endif /* OBJ_ELF */
This page took 6.220995 seconds and 4 git commands to generate.