[PATCH 22/57][Arm][GAS] Add support for MVE instructions: vmlaldav, vmlalv, vmlsldav...
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
CommitLineData
b99bd4ef 1/* tc-arm.c -- Assemble for the ARM
82704155 2 Copyright (C) 1994-2019 Free Software Foundation, Inc.
b99bd4ef
NC
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
22d9c8c5 5 Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
34920d91
NC
6 Cirrus coprocessor fixes by Petko Manolov (petkan@nucleusys.com)
7 Cirrus coprocessor fixes by Vladimir Ivanov (vladitx@nucleusys.com)
b99bd4ef
NC
8
9 This file is part of GAS, the GNU Assembler.
10
11 GAS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
ec2655a6 13 the Free Software Foundation; either version 3, or (at your option)
b99bd4ef
NC
14 any later version.
15
16 GAS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
c19d1205 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b99bd4ef
NC
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with GAS; see the file COPYING. If not, write to the Free
699d2810
NC
23 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
24 02110-1301, USA. */
b99bd4ef 25
42a68e18 26#include "as.h"
5287ad62 27#include <limits.h>
037e8744 28#include <stdarg.h>
c19d1205 29#define NO_RELOC 0
3882b010 30#include "safe-ctype.h"
b99bd4ef
NC
31#include "subsegs.h"
32#include "obstack.h"
3da1d841 33#include "libiberty.h"
f263249b
RE
34#include "opcode/arm.h"
35
b99bd4ef
NC
36#ifdef OBJ_ELF
37#include "elf/arm.h"
a394c00f 38#include "dw2gencfi.h"
b99bd4ef
NC
39#endif
40
f0927246
NC
41#include "dwarf2dbg.h"
42
7ed4c4c5
NC
43#ifdef OBJ_ELF
44/* Must be at least the size of the largest unwind opcode (currently two). */
45#define ARM_OPCODE_CHUNK_SIZE 8
46
47/* This structure holds the unwinding state. */
48
49static struct
50{
c19d1205
ZW
51 symbolS * proc_start;
52 symbolS * table_entry;
53 symbolS * personality_routine;
54 int personality_index;
7ed4c4c5 55 /* The segment containing the function. */
c19d1205
ZW
56 segT saved_seg;
57 subsegT saved_subseg;
7ed4c4c5
NC
58 /* Opcodes generated from this function. */
59 unsigned char * opcodes;
c19d1205
ZW
60 int opcode_count;
61 int opcode_alloc;
7ed4c4c5 62 /* The number of bytes pushed to the stack. */
c19d1205 63 offsetT frame_size;
7ed4c4c5
NC
64 /* We don't add stack adjustment opcodes immediately so that we can merge
65 multiple adjustments. We can also omit the final adjustment
66 when using a frame pointer. */
c19d1205 67 offsetT pending_offset;
7ed4c4c5 68 /* These two fields are set by both unwind_movsp and unwind_setfp. They
c19d1205
ZW
69 hold the reg+offset to use when restoring sp from a frame pointer. */
70 offsetT fp_offset;
71 int fp_reg;
7ed4c4c5 72 /* Nonzero if an unwind_setfp directive has been seen. */
c19d1205 73 unsigned fp_used:1;
7ed4c4c5 74 /* Nonzero if the last opcode restores sp from fp_reg. */
c19d1205 75 unsigned sp_restored:1;
7ed4c4c5
NC
76} unwind;
77
18a20338
CL
78/* Whether --fdpic was given. */
79static int arm_fdpic;
80
8b1ad454
NC
81#endif /* OBJ_ELF */
82
4962c51a
MS
83/* Results from operand parsing worker functions. */
84
85typedef enum
86{
87 PARSE_OPERAND_SUCCESS,
88 PARSE_OPERAND_FAIL,
89 PARSE_OPERAND_FAIL_NO_BACKTRACK
90} parse_operand_result;
91
33a392fb
PB
92enum arm_float_abi
93{
94 ARM_FLOAT_ABI_HARD,
95 ARM_FLOAT_ABI_SOFTFP,
96 ARM_FLOAT_ABI_SOFT
97};
98
c19d1205 99/* Types of processor to assemble for. */
b99bd4ef 100#ifndef CPU_DEFAULT
8a59fff3 101/* The code that was here used to select a default CPU depending on compiler
fa94de6b 102 pre-defines which were only present when doing native builds, thus
8a59fff3
MGD
103 changing gas' default behaviour depending upon the build host.
104
105 If you have a target that requires a default CPU option then the you
106 should define CPU_DEFAULT here. */
b99bd4ef
NC
107#endif
108
109#ifndef FPU_DEFAULT
c820d418
MM
110# ifdef TE_LINUX
111# define FPU_DEFAULT FPU_ARCH_FPA
112# elif defined (TE_NetBSD)
113# ifdef OBJ_ELF
114# define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, but VFP order. */
115# else
116 /* Legacy a.out format. */
117# define FPU_DEFAULT FPU_ARCH_FPA /* Soft-float, but FPA order. */
118# endif
4e7fd91e
PB
119# elif defined (TE_VXWORKS)
120# define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, VFP order. */
c820d418
MM
121# else
122 /* For backwards compatibility, default to FPA. */
123# define FPU_DEFAULT FPU_ARCH_FPA
124# endif
125#endif /* ifndef FPU_DEFAULT */
b99bd4ef 126
c19d1205 127#define streq(a, b) (strcmp (a, b) == 0)
b99bd4ef 128
4d354d8b
TP
129/* Current set of feature bits available (CPU+FPU). Different from
130 selected_cpu + selected_fpu in case of autodetection since the CPU
131 feature bits are then all set. */
e74cfd16 132static arm_feature_set cpu_variant;
4d354d8b
TP
133/* Feature bits used in each execution state. Used to set build attribute
134 (in particular Tag_*_ISA_use) in CPU autodetection mode. */
e74cfd16
PB
135static arm_feature_set arm_arch_used;
136static arm_feature_set thumb_arch_used;
b99bd4ef 137
b99bd4ef 138/* Flags stored in private area of BFD structure. */
c19d1205
ZW
139static int uses_apcs_26 = FALSE;
140static int atpcs = FALSE;
b34976b6
AM
141static int support_interwork = FALSE;
142static int uses_apcs_float = FALSE;
c19d1205 143static int pic_code = FALSE;
845b51d6 144static int fix_v4bx = FALSE;
278df34e
NS
145/* Warn on using deprecated features. */
146static int warn_on_deprecated = TRUE;
147
2e6976a8
DG
148/* Understand CodeComposer Studio assembly syntax. */
149bfd_boolean codecomposer_syntax = FALSE;
03b1477f
RE
150
151/* Variables that we set while parsing command-line options. Once all
152 options have been read we re-process these values to set the real
153 assembly flags. */
4d354d8b
TP
154
155/* CPU and FPU feature bits set for legacy CPU and FPU options (eg. -marm1
156 instead of -mcpu=arm1). */
157static const arm_feature_set *legacy_cpu = NULL;
158static const arm_feature_set *legacy_fpu = NULL;
159
160/* CPU, extension and FPU feature bits selected by -mcpu. */
161static const arm_feature_set *mcpu_cpu_opt = NULL;
162static arm_feature_set *mcpu_ext_opt = NULL;
163static const arm_feature_set *mcpu_fpu_opt = NULL;
164
165/* CPU, extension and FPU feature bits selected by -march. */
166static const arm_feature_set *march_cpu_opt = NULL;
167static arm_feature_set *march_ext_opt = NULL;
168static const arm_feature_set *march_fpu_opt = NULL;
169
170/* Feature bits selected by -mfpu. */
171static const arm_feature_set *mfpu_opt = NULL;
e74cfd16
PB
172
173/* Constants for known architecture features. */
174static const arm_feature_set fpu_default = FPU_DEFAULT;
f85d59c3 175static const arm_feature_set fpu_arch_vfp_v1 ATTRIBUTE_UNUSED = FPU_ARCH_VFP_V1;
e74cfd16 176static const arm_feature_set fpu_arch_vfp_v2 = FPU_ARCH_VFP_V2;
f85d59c3
KT
177static const arm_feature_set fpu_arch_vfp_v3 ATTRIBUTE_UNUSED = FPU_ARCH_VFP_V3;
178static const arm_feature_set fpu_arch_neon_v1 ATTRIBUTE_UNUSED = FPU_ARCH_NEON_V1;
e74cfd16
PB
179static const arm_feature_set fpu_arch_fpa = FPU_ARCH_FPA;
180static const arm_feature_set fpu_any_hard = FPU_ANY_HARD;
69c9e028 181#ifdef OBJ_ELF
e74cfd16 182static const arm_feature_set fpu_arch_maverick = FPU_ARCH_MAVERICK;
69c9e028 183#endif
e74cfd16
PB
184static const arm_feature_set fpu_endian_pure = FPU_ARCH_ENDIAN_PURE;
185
186#ifdef CPU_DEFAULT
187static const arm_feature_set cpu_default = CPU_DEFAULT;
188#endif
189
823d2571 190static const arm_feature_set arm_ext_v1 = ARM_FEATURE_CORE_LOW (ARM_EXT_V1);
4070243b 191static const arm_feature_set arm_ext_v2 = ARM_FEATURE_CORE_LOW (ARM_EXT_V2);
823d2571
TG
192static const arm_feature_set arm_ext_v2s = ARM_FEATURE_CORE_LOW (ARM_EXT_V2S);
193static const arm_feature_set arm_ext_v3 = ARM_FEATURE_CORE_LOW (ARM_EXT_V3);
194static const arm_feature_set arm_ext_v3m = ARM_FEATURE_CORE_LOW (ARM_EXT_V3M);
195static const arm_feature_set arm_ext_v4 = ARM_FEATURE_CORE_LOW (ARM_EXT_V4);
196static const arm_feature_set arm_ext_v4t = ARM_FEATURE_CORE_LOW (ARM_EXT_V4T);
197static const arm_feature_set arm_ext_v5 = ARM_FEATURE_CORE_LOW (ARM_EXT_V5);
e74cfd16 198static const arm_feature_set arm_ext_v4t_5 =
823d2571
TG
199 ARM_FEATURE_CORE_LOW (ARM_EXT_V4T | ARM_EXT_V5);
200static const arm_feature_set arm_ext_v5t = ARM_FEATURE_CORE_LOW (ARM_EXT_V5T);
201static const arm_feature_set arm_ext_v5e = ARM_FEATURE_CORE_LOW (ARM_EXT_V5E);
202static const arm_feature_set arm_ext_v5exp = ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP);
203static const arm_feature_set arm_ext_v5j = ARM_FEATURE_CORE_LOW (ARM_EXT_V5J);
204static const arm_feature_set arm_ext_v6 = ARM_FEATURE_CORE_LOW (ARM_EXT_V6);
205static const arm_feature_set arm_ext_v6k = ARM_FEATURE_CORE_LOW (ARM_EXT_V6K);
206static const arm_feature_set arm_ext_v6t2 = ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2);
55e8aae7
SP
207/* Only for compatability of hint instructions. */
208static const arm_feature_set arm_ext_v6k_v6t2 =
209 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K | ARM_EXT_V6T2);
823d2571
TG
210static const arm_feature_set arm_ext_v6_notm =
211 ARM_FEATURE_CORE_LOW (ARM_EXT_V6_NOTM);
212static const arm_feature_set arm_ext_v6_dsp =
213 ARM_FEATURE_CORE_LOW (ARM_EXT_V6_DSP);
214static const arm_feature_set arm_ext_barrier =
215 ARM_FEATURE_CORE_LOW (ARM_EXT_BARRIER);
216static const arm_feature_set arm_ext_msr =
217 ARM_FEATURE_CORE_LOW (ARM_EXT_THUMB_MSR);
218static const arm_feature_set arm_ext_div = ARM_FEATURE_CORE_LOW (ARM_EXT_DIV);
219static const arm_feature_set arm_ext_v7 = ARM_FEATURE_CORE_LOW (ARM_EXT_V7);
220static const arm_feature_set arm_ext_v7a = ARM_FEATURE_CORE_LOW (ARM_EXT_V7A);
221static const arm_feature_set arm_ext_v7r = ARM_FEATURE_CORE_LOW (ARM_EXT_V7R);
69c9e028 222#ifdef OBJ_ELF
e7d39ed3 223static const arm_feature_set ATTRIBUTE_UNUSED arm_ext_v7m = ARM_FEATURE_CORE_LOW (ARM_EXT_V7M);
69c9e028 224#endif
823d2571 225static const arm_feature_set arm_ext_v8 = ARM_FEATURE_CORE_LOW (ARM_EXT_V8);
7e806470 226static const arm_feature_set arm_ext_m =
173205ca 227 ARM_FEATURE_CORE (ARM_EXT_V6M | ARM_EXT_V7M,
16a1fa25 228 ARM_EXT2_V8M | ARM_EXT2_V8M_MAIN);
823d2571
TG
229static const arm_feature_set arm_ext_mp = ARM_FEATURE_CORE_LOW (ARM_EXT_MP);
230static const arm_feature_set arm_ext_sec = ARM_FEATURE_CORE_LOW (ARM_EXT_SEC);
231static const arm_feature_set arm_ext_os = ARM_FEATURE_CORE_LOW (ARM_EXT_OS);
232static const arm_feature_set arm_ext_adiv = ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV);
233static const arm_feature_set arm_ext_virt = ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT);
ddfded2f 234static const arm_feature_set arm_ext_pan = ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN);
4ed7ed8d 235static const arm_feature_set arm_ext_v8m = ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M);
16a1fa25
TP
236static const arm_feature_set arm_ext_v8m_main =
237 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M_MAIN);
e12437dc
AV
238static const arm_feature_set arm_ext_v8_1m_main =
239ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN);
16a1fa25
TP
240/* Instructions in ARMv8-M only found in M profile architectures. */
241static const arm_feature_set arm_ext_v8m_m_only =
242 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M | ARM_EXT2_V8M_MAIN);
ff8646ee
TP
243static const arm_feature_set arm_ext_v6t2_v8m =
244 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M);
4ed7ed8d
TP
245/* Instructions shared between ARMv8-A and ARMv8-M. */
246static const arm_feature_set arm_ext_atomics =
247 ARM_FEATURE_CORE_HIGH (ARM_EXT2_ATOMICS);
69c9e028 248#ifdef OBJ_ELF
15afaa63
TP
249/* DSP instructions Tag_DSP_extension refers to. */
250static const arm_feature_set arm_ext_dsp =
251 ARM_FEATURE_CORE_LOW (ARM_EXT_V5E | ARM_EXT_V5ExP | ARM_EXT_V6_DSP);
69c9e028 252#endif
4d1464f2
MW
253static const arm_feature_set arm_ext_ras =
254 ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS);
b8ec4e87
JW
255/* FP16 instructions. */
256static const arm_feature_set arm_ext_fp16 =
257 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST);
01f48020
TC
258static const arm_feature_set arm_ext_fp16_fml =
259 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_FML);
dec41383
JW
260static const arm_feature_set arm_ext_v8_2 =
261 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_2A);
49e8a725
SN
262static const arm_feature_set arm_ext_v8_3 =
263 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A);
7fadb25d
SD
264static const arm_feature_set arm_ext_sb =
265 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB);
dad0c3bf
SD
266static const arm_feature_set arm_ext_predres =
267 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES);
e74cfd16
PB
268
269static const arm_feature_set arm_arch_any = ARM_ANY;
49fa50ef 270#ifdef OBJ_ELF
2c6b98ea 271static const arm_feature_set fpu_any = FPU_ANY;
49fa50ef 272#endif
f85d59c3 273static const arm_feature_set arm_arch_full ATTRIBUTE_UNUSED = ARM_FEATURE (-1, -1, -1);
e74cfd16
PB
274static const arm_feature_set arm_arch_t2 = ARM_ARCH_THUMB2;
275static const arm_feature_set arm_arch_none = ARM_ARCH_NONE;
276
2d447fca 277static const arm_feature_set arm_cext_iwmmxt2 =
823d2571 278 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2);
e74cfd16 279static const arm_feature_set arm_cext_iwmmxt =
823d2571 280 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT);
e74cfd16 281static const arm_feature_set arm_cext_xscale =
823d2571 282 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE);
e74cfd16 283static const arm_feature_set arm_cext_maverick =
823d2571
TG
284 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK);
285static const arm_feature_set fpu_fpa_ext_v1 =
286 ARM_FEATURE_COPROC (FPU_FPA_EXT_V1);
287static const arm_feature_set fpu_fpa_ext_v2 =
288 ARM_FEATURE_COPROC (FPU_FPA_EXT_V2);
e74cfd16 289static const arm_feature_set fpu_vfp_ext_v1xd =
823d2571
TG
290 ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD);
291static const arm_feature_set fpu_vfp_ext_v1 =
292 ARM_FEATURE_COPROC (FPU_VFP_EXT_V1);
293static const arm_feature_set fpu_vfp_ext_v2 =
294 ARM_FEATURE_COPROC (FPU_VFP_EXT_V2);
295static const arm_feature_set fpu_vfp_ext_v3xd =
296 ARM_FEATURE_COPROC (FPU_VFP_EXT_V3xD);
297static const arm_feature_set fpu_vfp_ext_v3 =
298 ARM_FEATURE_COPROC (FPU_VFP_EXT_V3);
b1cc4aeb 299static const arm_feature_set fpu_vfp_ext_d32 =
823d2571
TG
300 ARM_FEATURE_COPROC (FPU_VFP_EXT_D32);
301static const arm_feature_set fpu_neon_ext_v1 =
302 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1);
5287ad62 303static const arm_feature_set fpu_vfp_v3_or_neon_ext =
823d2571 304 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_VFP_EXT_V3);
a7ad558c
AV
305static const arm_feature_set mve_ext =
306 ARM_FEATURE_COPROC (FPU_MVE);
307static const arm_feature_set mve_fp_ext =
308 ARM_FEATURE_COPROC (FPU_MVE_FP);
69c9e028 309#ifdef OBJ_ELF
823d2571
TG
310static const arm_feature_set fpu_vfp_fp16 =
311 ARM_FEATURE_COPROC (FPU_VFP_EXT_FP16);
312static const arm_feature_set fpu_neon_ext_fma =
313 ARM_FEATURE_COPROC (FPU_NEON_EXT_FMA);
69c9e028 314#endif
823d2571
TG
315static const arm_feature_set fpu_vfp_ext_fma =
316 ARM_FEATURE_COPROC (FPU_VFP_EXT_FMA);
bca38921 317static const arm_feature_set fpu_vfp_ext_armv8 =
823d2571 318 ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8);
a715796b 319static const arm_feature_set fpu_vfp_ext_armv8xd =
823d2571 320 ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8xD);
bca38921 321static const arm_feature_set fpu_neon_ext_armv8 =
823d2571 322 ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8);
bca38921 323static const arm_feature_set fpu_crypto_ext_armv8 =
823d2571 324 ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8);
dd5181d5 325static const arm_feature_set crc_ext_armv8 =
823d2571 326 ARM_FEATURE_COPROC (CRC_EXT_ARMV8);
d6b4b13e 327static const arm_feature_set fpu_neon_ext_v8_1 =
643afb90 328 ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA);
c604a79a
JW
329static const arm_feature_set fpu_neon_ext_dotprod =
330 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD);
e74cfd16 331
33a392fb 332static int mfloat_abi_opt = -1;
4d354d8b
TP
333/* Architecture feature bits selected by the last -mcpu/-march or .cpu/.arch
334 directive. */
335static arm_feature_set selected_arch = ARM_ARCH_NONE;
336/* Extension feature bits selected by the last -mcpu/-march or .arch_extension
337 directive. */
338static arm_feature_set selected_ext = ARM_ARCH_NONE;
339/* Feature bits selected by the last -mcpu/-march or by the combination of the
340 last .cpu/.arch directive .arch_extension directives since that
341 directive. */
e74cfd16 342static arm_feature_set selected_cpu = ARM_ARCH_NONE;
4d354d8b
TP
343/* FPU feature bits selected by the last -mfpu or .fpu directive. */
344static arm_feature_set selected_fpu = FPU_NONE;
345/* Feature bits selected by the last .object_arch directive. */
346static arm_feature_set selected_object_arch = ARM_ARCH_NONE;
ee065d83 347/* Must be long enough to hold any of the names in arm_cpus. */
ef8e6722 348static char selected_cpu_name[20];
8d67f500 349
aacf0b33
KT
350extern FLONUM_TYPE generic_floating_point_number;
351
8d67f500
NC
352/* Return if no cpu was selected on command-line. */
353static bfd_boolean
354no_cpu_selected (void)
355{
823d2571 356 return ARM_FEATURE_EQUAL (selected_cpu, arm_arch_none);
8d67f500
NC
357}
358
7cc69913 359#ifdef OBJ_ELF
deeaaff8
DJ
360# ifdef EABI_DEFAULT
361static int meabi_flags = EABI_DEFAULT;
362# else
d507cf36 363static int meabi_flags = EF_ARM_EABI_UNKNOWN;
deeaaff8 364# endif
e1da3f5b 365
ee3c0378
AS
366static int attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
367
e1da3f5b 368bfd_boolean
5f4273c7 369arm_is_eabi (void)
e1da3f5b
PB
370{
371 return (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4);
372}
7cc69913 373#endif
b99bd4ef 374
b99bd4ef 375#ifdef OBJ_ELF
c19d1205 376/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
b99bd4ef
NC
377symbolS * GOT_symbol;
378#endif
379
b99bd4ef
NC
380/* 0: assemble for ARM,
381 1: assemble for Thumb,
382 2: assemble for Thumb even though target CPU does not support thumb
383 instructions. */
384static int thumb_mode = 0;
8dc2430f
NC
385/* A value distinct from the possible values for thumb_mode that we
386 can use to record whether thumb_mode has been copied into the
387 tc_frag_data field of a frag. */
388#define MODE_RECORDED (1 << 4)
b99bd4ef 389
e07e6e58
NC
390/* Specifies the intrinsic IT insn behavior mode. */
391enum implicit_it_mode
392{
393 IMPLICIT_IT_MODE_NEVER = 0x00,
394 IMPLICIT_IT_MODE_ARM = 0x01,
395 IMPLICIT_IT_MODE_THUMB = 0x02,
396 IMPLICIT_IT_MODE_ALWAYS = (IMPLICIT_IT_MODE_ARM | IMPLICIT_IT_MODE_THUMB)
397};
398static int implicit_it_mode = IMPLICIT_IT_MODE_ARM;
399
c19d1205
ZW
400/* If unified_syntax is true, we are processing the new unified
401 ARM/Thumb syntax. Important differences from the old ARM mode:
402
403 - Immediate operands do not require a # prefix.
404 - Conditional affixes always appear at the end of the
405 instruction. (For backward compatibility, those instructions
406 that formerly had them in the middle, continue to accept them
407 there.)
408 - The IT instruction may appear, and if it does is validated
409 against subsequent conditional affixes. It does not generate
410 machine code.
411
412 Important differences from the old Thumb mode:
413
414 - Immediate operands do not require a # prefix.
415 - Most of the V6T2 instructions are only available in unified mode.
416 - The .N and .W suffixes are recognized and honored (it is an error
417 if they cannot be honored).
418 - All instructions set the flags if and only if they have an 's' affix.
419 - Conditional affixes may be used. They are validated against
420 preceding IT instructions. Unlike ARM mode, you cannot use a
421 conditional affix except in the scope of an IT instruction. */
422
423static bfd_boolean unified_syntax = FALSE;
b99bd4ef 424
bacebabc
RM
425/* An immediate operand can start with #, and ld*, st*, pld operands
426 can contain [ and ]. We need to tell APP not to elide whitespace
477330fc
RM
427 before a [, which can appear as the first operand for pld.
428 Likewise, a { can appear as the first operand for push, pop, vld*, etc. */
429const char arm_symbol_chars[] = "#[]{}";
bacebabc 430
5287ad62
JB
431enum neon_el_type
432{
dcbf9037 433 NT_invtype,
5287ad62
JB
434 NT_untyped,
435 NT_integer,
436 NT_float,
437 NT_poly,
438 NT_signed,
dcbf9037 439 NT_unsigned
5287ad62
JB
440};
441
442struct neon_type_el
443{
444 enum neon_el_type type;
445 unsigned size;
446};
447
448#define NEON_MAX_TYPE_ELS 4
449
450struct neon_type
451{
452 struct neon_type_el el[NEON_MAX_TYPE_ELS];
453 unsigned elems;
454};
455
5ee91343 456enum pred_instruction_type
e07e6e58 457{
5ee91343
AV
458 OUTSIDE_PRED_INSN,
459 INSIDE_VPT_INSN,
e07e6e58
NC
460 INSIDE_IT_INSN,
461 INSIDE_IT_LAST_INSN,
462 IF_INSIDE_IT_LAST_INSN, /* Either outside or inside;
477330fc 463 if inside, should be the last one. */
e07e6e58 464 NEUTRAL_IT_INSN, /* This could be either inside or outside,
477330fc 465 i.e. BKPT and NOP. */
5ee91343
AV
466 IT_INSN, /* The IT insn has been parsed. */
467 VPT_INSN, /* The VPT/VPST insn has been parsed. */
35c228db 468 MVE_OUTSIDE_PRED_INSN , /* Instruction to indicate a MVE instruction without
5ee91343 469 a predication code. */
35c228db 470 MVE_UNPREDICABLE_INSN /* MVE instruction that is non-predicable. */
e07e6e58
NC
471};
472
ad6cec43
MGD
473/* The maximum number of operands we need. */
474#define ARM_IT_MAX_OPERANDS 6
e2b0ab59 475#define ARM_IT_MAX_RELOCS 3
ad6cec43 476
b99bd4ef
NC
477struct arm_it
478{
c19d1205 479 const char * error;
b99bd4ef 480 unsigned long instruction;
c19d1205
ZW
481 int size;
482 int size_req;
483 int cond;
037e8744
JB
484 /* "uncond_value" is set to the value in place of the conditional field in
485 unconditional versions of the instruction, or -1 if nothing is
486 appropriate. */
487 int uncond_value;
5287ad62 488 struct neon_type vectype;
88714cb8
DG
489 /* This does not indicate an actual NEON instruction, only that
490 the mnemonic accepts neon-style type suffixes. */
491 int is_neon;
0110f2b8
PB
492 /* Set to the opcode if the instruction needs relaxation.
493 Zero if the instruction is not relaxed. */
494 unsigned long relax;
b99bd4ef
NC
495 struct
496 {
497 bfd_reloc_code_real_type type;
c19d1205
ZW
498 expressionS exp;
499 int pc_rel;
e2b0ab59 500 } relocs[ARM_IT_MAX_RELOCS];
b99bd4ef 501
5ee91343 502 enum pred_instruction_type pred_insn_type;
e07e6e58 503
c19d1205
ZW
504 struct
505 {
506 unsigned reg;
ca3f61f7 507 signed int imm;
dcbf9037 508 struct neon_type_el vectype;
ca3f61f7
NC
509 unsigned present : 1; /* Operand present. */
510 unsigned isreg : 1; /* Operand was a register. */
f5f10c66
AV
511 unsigned immisreg : 2; /* .imm field is a second register.
512 0: imm, 1: gpr, 2: MVE Q-register. */
57785aa2
AV
513 unsigned isscalar : 2; /* Operand is a (SIMD) scalar:
514 0) not scalar,
515 1) Neon scalar,
516 2) MVE scalar. */
5287ad62 517 unsigned immisalign : 1; /* Immediate is an alignment specifier. */
c96612cc 518 unsigned immisfloat : 1; /* Immediate was parsed as a float. */
5287ad62
JB
519 /* Note: we abuse "regisimm" to mean "is Neon register" in VMOV
520 instructions. This allows us to disambiguate ARM <-> vector insns. */
521 unsigned regisimm : 1; /* 64-bit immediate, reg forms high 32 bits. */
037e8744 522 unsigned isvec : 1; /* Is a single, double or quad VFP/Neon reg. */
5ee91343 523 unsigned isquad : 1; /* Operand is SIMD quad register. */
037e8744 524 unsigned issingle : 1; /* Operand is VFP single-precision register. */
1b883319 525 unsigned iszr : 1; /* Operand is ZR register. */
ca3f61f7
NC
526 unsigned hasreloc : 1; /* Operand has relocation suffix. */
527 unsigned writeback : 1; /* Operand has trailing ! */
528 unsigned preind : 1; /* Preindexed address. */
529 unsigned postind : 1; /* Postindexed address. */
530 unsigned negative : 1; /* Index register was negated. */
531 unsigned shifted : 1; /* Shift applied to operation. */
532 unsigned shift_kind : 3; /* Shift operation (enum shift_kind). */
ad6cec43 533 } operands[ARM_IT_MAX_OPERANDS];
b99bd4ef
NC
534};
535
c19d1205 536static struct arm_it inst;
b99bd4ef
NC
537
538#define NUM_FLOAT_VALS 8
539
05d2d07e 540const char * fp_const[] =
b99bd4ef
NC
541{
542 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
543};
544
b99bd4ef
NC
545LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
546
547#define FAIL (-1)
548#define SUCCESS (0)
549
550#define SUFF_S 1
551#define SUFF_D 2
552#define SUFF_E 3
553#define SUFF_P 4
554
c19d1205
ZW
555#define CP_T_X 0x00008000
556#define CP_T_Y 0x00400000
b99bd4ef 557
c19d1205
ZW
558#define CONDS_BIT 0x00100000
559#define LOAD_BIT 0x00100000
b99bd4ef
NC
560
561#define DOUBLE_LOAD_FLAG 0x00000001
562
563struct asm_cond
564{
d3ce72d0 565 const char * template_name;
c921be7d 566 unsigned long value;
b99bd4ef
NC
567};
568
c19d1205 569#define COND_ALWAYS 0xE
b99bd4ef 570
b99bd4ef
NC
571struct asm_psr
572{
d3ce72d0 573 const char * template_name;
c921be7d 574 unsigned long field;
b99bd4ef
NC
575};
576
62b3e311
PB
577struct asm_barrier_opt
578{
e797f7e0
MGD
579 const char * template_name;
580 unsigned long value;
581 const arm_feature_set arch;
62b3e311
PB
582};
583
2d2255b5 584/* The bit that distinguishes CPSR and SPSR. */
b99bd4ef
NC
585#define SPSR_BIT (1 << 22)
586
c19d1205
ZW
587/* The individual PSR flag bits. */
588#define PSR_c (1 << 16)
589#define PSR_x (1 << 17)
590#define PSR_s (1 << 18)
591#define PSR_f (1 << 19)
b99bd4ef 592
c19d1205 593struct reloc_entry
bfae80f2 594{
0198d5e6 595 const char * name;
c921be7d 596 bfd_reloc_code_real_type reloc;
bfae80f2
RE
597};
598
5287ad62 599enum vfp_reg_pos
bfae80f2 600{
5287ad62
JB
601 VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn,
602 VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
bfae80f2
RE
603};
604
605enum vfp_ldstm_type
606{
607 VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
608};
609
dcbf9037
JB
610/* Bits for DEFINED field in neon_typed_alias. */
611#define NTA_HASTYPE 1
612#define NTA_HASINDEX 2
613
614struct neon_typed_alias
615{
c921be7d
NC
616 unsigned char defined;
617 unsigned char index;
618 struct neon_type_el eltype;
dcbf9037
JB
619};
620
c19d1205 621/* ARM register categories. This includes coprocessor numbers and various
5aa75429
TP
622 architecture extensions' registers. Each entry should have an error message
623 in reg_expected_msgs below. */
c19d1205 624enum arm_reg_type
bfae80f2 625{
c19d1205
ZW
626 REG_TYPE_RN,
627 REG_TYPE_CP,
628 REG_TYPE_CN,
629 REG_TYPE_FN,
630 REG_TYPE_VFS,
631 REG_TYPE_VFD,
5287ad62 632 REG_TYPE_NQ,
037e8744 633 REG_TYPE_VFSD,
5287ad62 634 REG_TYPE_NDQ,
dec41383 635 REG_TYPE_NSD,
037e8744 636 REG_TYPE_NSDQ,
c19d1205
ZW
637 REG_TYPE_VFC,
638 REG_TYPE_MVF,
639 REG_TYPE_MVD,
640 REG_TYPE_MVFX,
641 REG_TYPE_MVDX,
642 REG_TYPE_MVAX,
5ee91343 643 REG_TYPE_MQ,
c19d1205
ZW
644 REG_TYPE_DSPSC,
645 REG_TYPE_MMXWR,
646 REG_TYPE_MMXWC,
647 REG_TYPE_MMXWCG,
648 REG_TYPE_XSCALE,
5ee91343 649 REG_TYPE_RNB,
1b883319 650 REG_TYPE_ZR
bfae80f2
RE
651};
652
dcbf9037
JB
653/* Structure for a hash table entry for a register.
654 If TYPE is REG_TYPE_VFD or REG_TYPE_NQ, the NEON field can point to extra
655 information which states whether a vector type or index is specified (for a
656 register alias created with .dn or .qn). Otherwise NEON should be NULL. */
6c43fab6
RE
657struct reg_entry
658{
c921be7d 659 const char * name;
90ec0d68 660 unsigned int number;
c921be7d
NC
661 unsigned char type;
662 unsigned char builtin;
663 struct neon_typed_alias * neon;
6c43fab6
RE
664};
665
c19d1205 666/* Diagnostics used when we don't get a register of the expected type. */
c921be7d 667const char * const reg_expected_msgs[] =
c19d1205 668{
5aa75429
TP
669 [REG_TYPE_RN] = N_("ARM register expected"),
670 [REG_TYPE_CP] = N_("bad or missing co-processor number"),
671 [REG_TYPE_CN] = N_("co-processor register expected"),
672 [REG_TYPE_FN] = N_("FPA register expected"),
673 [REG_TYPE_VFS] = N_("VFP single precision register expected"),
674 [REG_TYPE_VFD] = N_("VFP/Neon double precision register expected"),
675 [REG_TYPE_NQ] = N_("Neon quad precision register expected"),
676 [REG_TYPE_VFSD] = N_("VFP single or double precision register expected"),
677 [REG_TYPE_NDQ] = N_("Neon double or quad precision register expected"),
678 [REG_TYPE_NSD] = N_("Neon single or double precision register expected"),
679 [REG_TYPE_NSDQ] = N_("VFP single, double or Neon quad precision register"
680 " expected"),
681 [REG_TYPE_VFC] = N_("VFP system register expected"),
682 [REG_TYPE_MVF] = N_("Maverick MVF register expected"),
683 [REG_TYPE_MVD] = N_("Maverick MVD register expected"),
684 [REG_TYPE_MVFX] = N_("Maverick MVFX register expected"),
685 [REG_TYPE_MVDX] = N_("Maverick MVDX register expected"),
686 [REG_TYPE_MVAX] = N_("Maverick MVAX register expected"),
687 [REG_TYPE_DSPSC] = N_("Maverick DSPSC register expected"),
688 [REG_TYPE_MMXWR] = N_("iWMMXt data register expected"),
689 [REG_TYPE_MMXWC] = N_("iWMMXt control register expected"),
690 [REG_TYPE_MMXWCG] = N_("iWMMXt scalar register expected"),
691 [REG_TYPE_XSCALE] = N_("XScale accumulator register expected"),
5ee91343 692 [REG_TYPE_MQ] = N_("MVE vector register expected"),
5aa75429 693 [REG_TYPE_RNB] = N_("")
6c43fab6
RE
694};
695
c19d1205 696/* Some well known registers that we refer to directly elsewhere. */
bd340a04 697#define REG_R12 12
c19d1205
ZW
698#define REG_SP 13
699#define REG_LR 14
700#define REG_PC 15
404ff6b5 701
b99bd4ef
NC
702/* ARM instructions take 4bytes in the object file, Thumb instructions
703 take 2: */
c19d1205 704#define INSN_SIZE 4
b99bd4ef
NC
705
706struct asm_opcode
707{
708 /* Basic string to match. */
d3ce72d0 709 const char * template_name;
c19d1205
ZW
710
711 /* Parameters to instruction. */
5be8be5d 712 unsigned int operands[8];
c19d1205
ZW
713
714 /* Conditional tag - see opcode_lookup. */
715 unsigned int tag : 4;
b99bd4ef
NC
716
717 /* Basic instruction code. */
a302e574 718 unsigned int avalue;
b99bd4ef 719
c19d1205
ZW
720 /* Thumb-format instruction code. */
721 unsigned int tvalue;
b99bd4ef 722
90e4755a 723 /* Which architecture variant provides this instruction. */
c921be7d
NC
724 const arm_feature_set * avariant;
725 const arm_feature_set * tvariant;
c19d1205
ZW
726
727 /* Function to call to encode instruction in ARM format. */
728 void (* aencode) (void);
b99bd4ef 729
c19d1205
ZW
730 /* Function to call to encode instruction in Thumb format. */
731 void (* tencode) (void);
5ee91343
AV
732
733 /* Indicates whether this instruction may be vector predicated. */
734 unsigned int mayBeVecPred : 1;
b99bd4ef
NC
735};
736
a737bd4d
NC
737/* Defines for various bits that we will want to toggle. */
738#define INST_IMMEDIATE 0x02000000
739#define OFFSET_REG 0x02000000
c19d1205 740#define HWOFFSET_IMM 0x00400000
a737bd4d
NC
741#define SHIFT_BY_REG 0x00000010
742#define PRE_INDEX 0x01000000
743#define INDEX_UP 0x00800000
744#define WRITE_BACK 0x00200000
745#define LDM_TYPE_2_OR_3 0x00400000
a028a6f5 746#define CPSI_MMOD 0x00020000
90e4755a 747
a737bd4d
NC
748#define LITERAL_MASK 0xf000f000
749#define OPCODE_MASK 0xfe1fffff
750#define V4_STR_BIT 0x00000020
8335d6aa 751#define VLDR_VMOV_SAME 0x0040f000
90e4755a 752
efd81785
PB
753#define T2_SUBS_PC_LR 0xf3de8f00
754
a737bd4d 755#define DATA_OP_SHIFT 21
bada4342 756#define SBIT_SHIFT 20
90e4755a 757
ef8d22e6
PB
758#define T2_OPCODE_MASK 0xfe1fffff
759#define T2_DATA_OP_SHIFT 21
bada4342 760#define T2_SBIT_SHIFT 20
ef8d22e6 761
6530b175
NC
762#define A_COND_MASK 0xf0000000
763#define A_PUSH_POP_OP_MASK 0x0fff0000
764
765/* Opcodes for pushing/poping registers to/from the stack. */
766#define A1_OPCODE_PUSH 0x092d0000
767#define A2_OPCODE_PUSH 0x052d0004
768#define A2_OPCODE_POP 0x049d0004
769
a737bd4d
NC
770/* Codes to distinguish the arithmetic instructions. */
771#define OPCODE_AND 0
772#define OPCODE_EOR 1
773#define OPCODE_SUB 2
774#define OPCODE_RSB 3
775#define OPCODE_ADD 4
776#define OPCODE_ADC 5
777#define OPCODE_SBC 6
778#define OPCODE_RSC 7
779#define OPCODE_TST 8
780#define OPCODE_TEQ 9
781#define OPCODE_CMP 10
782#define OPCODE_CMN 11
783#define OPCODE_ORR 12
784#define OPCODE_MOV 13
785#define OPCODE_BIC 14
786#define OPCODE_MVN 15
90e4755a 787
ef8d22e6
PB
788#define T2_OPCODE_AND 0
789#define T2_OPCODE_BIC 1
790#define T2_OPCODE_ORR 2
791#define T2_OPCODE_ORN 3
792#define T2_OPCODE_EOR 4
793#define T2_OPCODE_ADD 8
794#define T2_OPCODE_ADC 10
795#define T2_OPCODE_SBC 11
796#define T2_OPCODE_SUB 13
797#define T2_OPCODE_RSB 14
798
a737bd4d
NC
799#define T_OPCODE_MUL 0x4340
800#define T_OPCODE_TST 0x4200
801#define T_OPCODE_CMN 0x42c0
802#define T_OPCODE_NEG 0x4240
803#define T_OPCODE_MVN 0x43c0
90e4755a 804
a737bd4d
NC
805#define T_OPCODE_ADD_R3 0x1800
806#define T_OPCODE_SUB_R3 0x1a00
807#define T_OPCODE_ADD_HI 0x4400
808#define T_OPCODE_ADD_ST 0xb000
809#define T_OPCODE_SUB_ST 0xb080
810#define T_OPCODE_ADD_SP 0xa800
811#define T_OPCODE_ADD_PC 0xa000
812#define T_OPCODE_ADD_I8 0x3000
813#define T_OPCODE_SUB_I8 0x3800
814#define T_OPCODE_ADD_I3 0x1c00
815#define T_OPCODE_SUB_I3 0x1e00
b99bd4ef 816
a737bd4d
NC
817#define T_OPCODE_ASR_R 0x4100
818#define T_OPCODE_LSL_R 0x4080
c19d1205
ZW
819#define T_OPCODE_LSR_R 0x40c0
820#define T_OPCODE_ROR_R 0x41c0
a737bd4d
NC
821#define T_OPCODE_ASR_I 0x1000
822#define T_OPCODE_LSL_I 0x0000
823#define T_OPCODE_LSR_I 0x0800
b99bd4ef 824
a737bd4d
NC
825#define T_OPCODE_MOV_I8 0x2000
826#define T_OPCODE_CMP_I8 0x2800
827#define T_OPCODE_CMP_LR 0x4280
828#define T_OPCODE_MOV_HR 0x4600
829#define T_OPCODE_CMP_HR 0x4500
b99bd4ef 830
a737bd4d
NC
831#define T_OPCODE_LDR_PC 0x4800
832#define T_OPCODE_LDR_SP 0x9800
833#define T_OPCODE_STR_SP 0x9000
834#define T_OPCODE_LDR_IW 0x6800
835#define T_OPCODE_STR_IW 0x6000
836#define T_OPCODE_LDR_IH 0x8800
837#define T_OPCODE_STR_IH 0x8000
838#define T_OPCODE_LDR_IB 0x7800
839#define T_OPCODE_STR_IB 0x7000
840#define T_OPCODE_LDR_RW 0x5800
841#define T_OPCODE_STR_RW 0x5000
842#define T_OPCODE_LDR_RH 0x5a00
843#define T_OPCODE_STR_RH 0x5200
844#define T_OPCODE_LDR_RB 0x5c00
845#define T_OPCODE_STR_RB 0x5400
c9b604bd 846
a737bd4d
NC
847#define T_OPCODE_PUSH 0xb400
848#define T_OPCODE_POP 0xbc00
b99bd4ef 849
2fc8bdac 850#define T_OPCODE_BRANCH 0xe000
b99bd4ef 851
a737bd4d 852#define THUMB_SIZE 2 /* Size of thumb instruction. */
a737bd4d 853#define THUMB_PP_PC_LR 0x0100
c19d1205 854#define THUMB_LOAD_BIT 0x0800
53365c0d 855#define THUMB2_LOAD_BIT 0x00100000
c19d1205 856
5ee91343 857#define BAD_SYNTAX _("syntax error")
c19d1205 858#define BAD_ARGS _("bad arguments to instruction")
fdfde340 859#define BAD_SP _("r13 not allowed here")
c19d1205 860#define BAD_PC _("r15 not allowed here")
a302e574
AV
861#define BAD_ODD _("Odd register not allowed here")
862#define BAD_EVEN _("Even register not allowed here")
c19d1205
ZW
863#define BAD_COND _("instruction cannot be conditional")
864#define BAD_OVERLAP _("registers may not be the same")
865#define BAD_HIREG _("lo register required")
866#define BAD_THUMB32 _("instruction not supported in Thumb16 mode")
35c228db 867#define BAD_ADDR_MODE _("instruction does not accept this addressing mode")
dfa9f0d5 868#define BAD_BRANCH _("branch must be last instruction in IT block")
e12437dc 869#define BAD_BRANCH_OFF _("branch out of range or not a multiple of 2")
dfa9f0d5 870#define BAD_NOT_IT _("instruction not allowed in IT block")
5ee91343 871#define BAD_NOT_VPT _("instruction missing MVE vector predication code")
037e8744 872#define BAD_FPU _("selected FPU does not support instruction")
e07e6e58 873#define BAD_OUT_IT _("thumb conditional instruction should be in IT block")
5ee91343
AV
874#define BAD_OUT_VPT \
875 _("vector predicated instruction should be in VPT/VPST block")
e07e6e58 876#define BAD_IT_COND _("incorrect condition in IT block")
5ee91343 877#define BAD_VPT_COND _("incorrect condition in VPT/VPST block")
e07e6e58 878#define BAD_IT_IT _("IT falling in the range of a previous IT block")
921e5f0a 879#define MISSING_FNSTART _("missing .fnstart before unwinding directive")
5be8be5d
DG
880#define BAD_PC_ADDRESSING \
881 _("cannot use register index with PC-relative addressing")
882#define BAD_PC_WRITEBACK \
883 _("cannot use writeback with PC-relative addressing")
9db2f6b4
RL
884#define BAD_RANGE _("branch out of range")
885#define BAD_FP16 _("selected processor does not support fp16 instruction")
dd5181d5 886#define UNPRED_REG(R) _("using " R " results in unpredictable behaviour")
a9f02af8 887#define THUMB1_RELOC_ONLY _("relocation valid in thumb1 code only")
5ee91343
AV
888#define MVE_NOT_IT _("Warning: instruction is UNPREDICTABLE in an IT " \
889 "block")
890#define MVE_NOT_VPT _("Warning: instruction is UNPREDICTABLE in a VPT " \
891 "block")
892#define MVE_BAD_PC _("Warning: instruction is UNPREDICTABLE with PC" \
893 " operand")
894#define MVE_BAD_SP _("Warning: instruction is UNPREDICTABLE with SP" \
895 " operand")
a302e574 896#define BAD_SIMD_TYPE _("bad type in SIMD instruction")
886e1c73
AV
897#define BAD_MVE_AUTO \
898 _("GAS auto-detection mode and -march=all is deprecated for MVE, please" \
899 " use a valid -march or -mcpu option.")
900#define BAD_MVE_SRCDEST _("Warning: 32-bit element size and same destination "\
901 "and source operands makes instruction UNPREDICTABLE")
35c228db 902#define BAD_EL_TYPE _("bad element type for instruction")
1b883319 903#define MVE_BAD_QREG _("MVE vector register Q[0..7] expected")
c19d1205 904
c921be7d
NC
905static struct hash_control * arm_ops_hsh;
906static struct hash_control * arm_cond_hsh;
5ee91343 907static struct hash_control * arm_vcond_hsh;
c921be7d
NC
908static struct hash_control * arm_shift_hsh;
909static struct hash_control * arm_psr_hsh;
910static struct hash_control * arm_v7m_psr_hsh;
911static struct hash_control * arm_reg_hsh;
912static struct hash_control * arm_reloc_hsh;
913static struct hash_control * arm_barrier_opt_hsh;
b99bd4ef 914
b99bd4ef
NC
915/* Stuff needed to resolve the label ambiguity
916 As:
917 ...
918 label: <insn>
919 may differ from:
920 ...
921 label:
5f4273c7 922 <insn> */
b99bd4ef
NC
923
924symbolS * last_label_seen;
b34976b6 925static int label_is_thumb_function_name = FALSE;
e07e6e58 926
3d0c9500
NC
927/* Literal pool structure. Held on a per-section
928 and per-sub-section basis. */
a737bd4d 929
c19d1205 930#define MAX_LITERAL_POOL_SIZE 1024
3d0c9500 931typedef struct literal_pool
b99bd4ef 932{
c921be7d
NC
933 expressionS literals [MAX_LITERAL_POOL_SIZE];
934 unsigned int next_free_entry;
935 unsigned int id;
936 symbolS * symbol;
937 segT section;
938 subsegT sub_section;
a8040cf2
NC
939#ifdef OBJ_ELF
940 struct dwarf2_line_info locs [MAX_LITERAL_POOL_SIZE];
941#endif
c921be7d 942 struct literal_pool * next;
8335d6aa 943 unsigned int alignment;
3d0c9500 944} literal_pool;
b99bd4ef 945
3d0c9500
NC
946/* Pointer to a linked list of literal pools. */
947literal_pool * list_of_pools = NULL;
e27ec89e 948
2e6976a8
DG
949typedef enum asmfunc_states
950{
951 OUTSIDE_ASMFUNC,
952 WAITING_ASMFUNC_NAME,
953 WAITING_ENDASMFUNC
954} asmfunc_states;
955
956static asmfunc_states asmfunc_state = OUTSIDE_ASMFUNC;
957
e07e6e58 958#ifdef OBJ_ELF
5ee91343 959# define now_pred seg_info (now_seg)->tc_segment_info_data.current_pred
e07e6e58 960#else
5ee91343 961static struct current_pred now_pred;
e07e6e58
NC
962#endif
963
964static inline int
5ee91343 965now_pred_compatible (int cond)
e07e6e58 966{
5ee91343 967 return (cond & ~1) == (now_pred.cc & ~1);
e07e6e58
NC
968}
969
970static inline int
971conditional_insn (void)
972{
973 return inst.cond != COND_ALWAYS;
974}
975
5ee91343 976static int in_pred_block (void);
e07e6e58 977
5ee91343 978static int handle_pred_state (void);
e07e6e58
NC
979
980static void force_automatic_it_block_close (void);
981
c921be7d
NC
982static void it_fsm_post_encode (void);
983
5ee91343 984#define set_pred_insn_type(type) \
e07e6e58
NC
985 do \
986 { \
5ee91343
AV
987 inst.pred_insn_type = type; \
988 if (handle_pred_state () == FAIL) \
477330fc 989 return; \
e07e6e58
NC
990 } \
991 while (0)
992
5ee91343 993#define set_pred_insn_type_nonvoid(type, failret) \
c921be7d
NC
994 do \
995 { \
5ee91343
AV
996 inst.pred_insn_type = type; \
997 if (handle_pred_state () == FAIL) \
477330fc 998 return failret; \
c921be7d
NC
999 } \
1000 while(0)
1001
5ee91343 1002#define set_pred_insn_type_last() \
e07e6e58
NC
1003 do \
1004 { \
1005 if (inst.cond == COND_ALWAYS) \
5ee91343 1006 set_pred_insn_type (IF_INSIDE_IT_LAST_INSN); \
e07e6e58 1007 else \
5ee91343 1008 set_pred_insn_type (INSIDE_IT_LAST_INSN); \
e07e6e58
NC
1009 } \
1010 while (0)
1011
c19d1205 1012/* Pure syntax. */
b99bd4ef 1013
c19d1205
ZW
1014/* This array holds the chars that always start a comment. If the
1015 pre-processor is disabled, these aren't very useful. */
2e6976a8 1016char arm_comment_chars[] = "@";
3d0c9500 1017
c19d1205
ZW
1018/* This array holds the chars that only start a comment at the beginning of
1019 a line. If the line seems to have the form '# 123 filename'
1020 .line and .file directives will appear in the pre-processed output. */
1021/* Note that input_file.c hand checks for '#' at the beginning of the
1022 first line of the input file. This is because the compiler outputs
1023 #NO_APP at the beginning of its output. */
1024/* Also note that comments like this one will always work. */
1025const char line_comment_chars[] = "#";
3d0c9500 1026
2e6976a8 1027char arm_line_separator_chars[] = ";";
b99bd4ef 1028
c19d1205
ZW
1029/* Chars that can be used to separate mant
1030 from exp in floating point numbers. */
1031const char EXP_CHARS[] = "eE";
3d0c9500 1032
c19d1205
ZW
1033/* Chars that mean this number is a floating point constant. */
1034/* As in 0f12.456 */
1035/* or 0d1.2345e12 */
b99bd4ef 1036
c19d1205 1037const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
3d0c9500 1038
c19d1205
ZW
1039/* Prefix characters that indicate the start of an immediate
1040 value. */
1041#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
3d0c9500 1042
c19d1205
ZW
1043/* Separator character handling. */
1044
1045#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
1046
1047static inline int
1048skip_past_char (char ** str, char c)
1049{
8ab8155f
NC
1050 /* PR gas/14987: Allow for whitespace before the expected character. */
1051 skip_whitespace (*str);
427d0db6 1052
c19d1205
ZW
1053 if (**str == c)
1054 {
1055 (*str)++;
1056 return SUCCESS;
3d0c9500 1057 }
c19d1205
ZW
1058 else
1059 return FAIL;
1060}
c921be7d 1061
c19d1205 1062#define skip_past_comma(str) skip_past_char (str, ',')
3d0c9500 1063
c19d1205
ZW
1064/* Arithmetic expressions (possibly involving symbols). */
1065
1066/* Return TRUE if anything in the expression is a bignum. */
1067
0198d5e6 1068static bfd_boolean
c19d1205
ZW
1069walk_no_bignums (symbolS * sp)
1070{
1071 if (symbol_get_value_expression (sp)->X_op == O_big)
0198d5e6 1072 return TRUE;
c19d1205
ZW
1073
1074 if (symbol_get_value_expression (sp)->X_add_symbol)
3d0c9500 1075 {
c19d1205
ZW
1076 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
1077 || (symbol_get_value_expression (sp)->X_op_symbol
1078 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
3d0c9500
NC
1079 }
1080
0198d5e6 1081 return FALSE;
3d0c9500
NC
1082}
1083
0198d5e6 1084static bfd_boolean in_my_get_expression = FALSE;
c19d1205
ZW
1085
1086/* Third argument to my_get_expression. */
1087#define GE_NO_PREFIX 0
1088#define GE_IMM_PREFIX 1
1089#define GE_OPT_PREFIX 2
5287ad62
JB
1090/* This is a bit of a hack. Use an optional prefix, and also allow big (64-bit)
1091 immediates, as can be used in Neon VMVN and VMOV immediate instructions. */
1092#define GE_OPT_PREFIX_BIG 3
a737bd4d 1093
b99bd4ef 1094static int
c19d1205 1095my_get_expression (expressionS * ep, char ** str, int prefix_mode)
b99bd4ef 1096{
c19d1205 1097 char * save_in;
b99bd4ef 1098
c19d1205
ZW
1099 /* In unified syntax, all prefixes are optional. */
1100 if (unified_syntax)
5287ad62 1101 prefix_mode = (prefix_mode == GE_OPT_PREFIX_BIG) ? prefix_mode
477330fc 1102 : GE_OPT_PREFIX;
b99bd4ef 1103
c19d1205 1104 switch (prefix_mode)
b99bd4ef 1105 {
c19d1205
ZW
1106 case GE_NO_PREFIX: break;
1107 case GE_IMM_PREFIX:
1108 if (!is_immediate_prefix (**str))
1109 {
1110 inst.error = _("immediate expression requires a # prefix");
1111 return FAIL;
1112 }
1113 (*str)++;
1114 break;
1115 case GE_OPT_PREFIX:
5287ad62 1116 case GE_OPT_PREFIX_BIG:
c19d1205
ZW
1117 if (is_immediate_prefix (**str))
1118 (*str)++;
1119 break;
0198d5e6
TC
1120 default:
1121 abort ();
c19d1205 1122 }
b99bd4ef 1123
c19d1205 1124 memset (ep, 0, sizeof (expressionS));
b99bd4ef 1125
c19d1205
ZW
1126 save_in = input_line_pointer;
1127 input_line_pointer = *str;
0198d5e6 1128 in_my_get_expression = TRUE;
2ac93be7 1129 expression (ep);
0198d5e6 1130 in_my_get_expression = FALSE;
c19d1205 1131
f86adc07 1132 if (ep->X_op == O_illegal || ep->X_op == O_absent)
b99bd4ef 1133 {
f86adc07 1134 /* We found a bad or missing expression in md_operand(). */
c19d1205
ZW
1135 *str = input_line_pointer;
1136 input_line_pointer = save_in;
1137 if (inst.error == NULL)
f86adc07
NS
1138 inst.error = (ep->X_op == O_absent
1139 ? _("missing expression") :_("bad expression"));
c19d1205
ZW
1140 return 1;
1141 }
b99bd4ef 1142
c19d1205
ZW
1143 /* Get rid of any bignums now, so that we don't generate an error for which
1144 we can't establish a line number later on. Big numbers are never valid
1145 in instructions, which is where this routine is always called. */
5287ad62
JB
1146 if (prefix_mode != GE_OPT_PREFIX_BIG
1147 && (ep->X_op == O_big
477330fc 1148 || (ep->X_add_symbol
5287ad62 1149 && (walk_no_bignums (ep->X_add_symbol)
477330fc 1150 || (ep->X_op_symbol
5287ad62 1151 && walk_no_bignums (ep->X_op_symbol))))))
c19d1205
ZW
1152 {
1153 inst.error = _("invalid constant");
1154 *str = input_line_pointer;
1155 input_line_pointer = save_in;
1156 return 1;
1157 }
b99bd4ef 1158
c19d1205
ZW
1159 *str = input_line_pointer;
1160 input_line_pointer = save_in;
0198d5e6 1161 return SUCCESS;
b99bd4ef
NC
1162}
1163
c19d1205
ZW
1164/* Turn a string in input_line_pointer into a floating point constant
1165 of type TYPE, and store the appropriate bytes in *LITP. The number
1166 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1167 returned, or NULL on OK.
b99bd4ef 1168
c19d1205
ZW
1169 Note that fp constants aren't represent in the normal way on the ARM.
1170 In big endian mode, things are as expected. However, in little endian
1171 mode fp constants are big-endian word-wise, and little-endian byte-wise
1172 within the words. For example, (double) 1.1 in big endian mode is
1173 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
1174 the byte sequence 99 99 f1 3f 9a 99 99 99.
b99bd4ef 1175
c19d1205 1176 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
b99bd4ef 1177
6d4af3c2 1178const char *
c19d1205
ZW
1179md_atof (int type, char * litP, int * sizeP)
1180{
1181 int prec;
1182 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1183 char *t;
1184 int i;
b99bd4ef 1185
c19d1205
ZW
1186 switch (type)
1187 {
1188 case 'f':
1189 case 'F':
1190 case 's':
1191 case 'S':
1192 prec = 2;
1193 break;
b99bd4ef 1194
c19d1205
ZW
1195 case 'd':
1196 case 'D':
1197 case 'r':
1198 case 'R':
1199 prec = 4;
1200 break;
b99bd4ef 1201
c19d1205
ZW
1202 case 'x':
1203 case 'X':
499ac353 1204 prec = 5;
c19d1205 1205 break;
b99bd4ef 1206
c19d1205
ZW
1207 case 'p':
1208 case 'P':
499ac353 1209 prec = 5;
c19d1205 1210 break;
a737bd4d 1211
c19d1205
ZW
1212 default:
1213 *sizeP = 0;
499ac353 1214 return _("Unrecognized or unsupported floating point constant");
c19d1205 1215 }
b99bd4ef 1216
c19d1205
ZW
1217 t = atof_ieee (input_line_pointer, type, words);
1218 if (t)
1219 input_line_pointer = t;
499ac353 1220 *sizeP = prec * sizeof (LITTLENUM_TYPE);
b99bd4ef 1221
c19d1205
ZW
1222 if (target_big_endian)
1223 {
1224 for (i = 0; i < prec; i++)
1225 {
499ac353
NC
1226 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1227 litP += sizeof (LITTLENUM_TYPE);
c19d1205
ZW
1228 }
1229 }
1230 else
1231 {
e74cfd16 1232 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
c19d1205
ZW
1233 for (i = prec - 1; i >= 0; i--)
1234 {
499ac353
NC
1235 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1236 litP += sizeof (LITTLENUM_TYPE);
c19d1205
ZW
1237 }
1238 else
1239 /* For a 4 byte float the order of elements in `words' is 1 0.
1240 For an 8 byte float the order is 1 0 3 2. */
1241 for (i = 0; i < prec; i += 2)
1242 {
499ac353
NC
1243 md_number_to_chars (litP, (valueT) words[i + 1],
1244 sizeof (LITTLENUM_TYPE));
1245 md_number_to_chars (litP + sizeof (LITTLENUM_TYPE),
1246 (valueT) words[i], sizeof (LITTLENUM_TYPE));
1247 litP += 2 * sizeof (LITTLENUM_TYPE);
c19d1205
ZW
1248 }
1249 }
b99bd4ef 1250
499ac353 1251 return NULL;
c19d1205 1252}
b99bd4ef 1253
c19d1205
ZW
1254/* We handle all bad expressions here, so that we can report the faulty
1255 instruction in the error message. */
0198d5e6 1256
c19d1205 1257void
91d6fa6a 1258md_operand (expressionS * exp)
c19d1205
ZW
1259{
1260 if (in_my_get_expression)
91d6fa6a 1261 exp->X_op = O_illegal;
b99bd4ef
NC
1262}
1263
c19d1205 1264/* Immediate values. */
b99bd4ef 1265
0198d5e6 1266#ifdef OBJ_ELF
c19d1205
ZW
1267/* Generic immediate-value read function for use in directives.
1268 Accepts anything that 'expression' can fold to a constant.
1269 *val receives the number. */
0198d5e6 1270
c19d1205
ZW
1271static int
1272immediate_for_directive (int *val)
b99bd4ef 1273{
c19d1205
ZW
1274 expressionS exp;
1275 exp.X_op = O_illegal;
b99bd4ef 1276
c19d1205
ZW
1277 if (is_immediate_prefix (*input_line_pointer))
1278 {
1279 input_line_pointer++;
1280 expression (&exp);
1281 }
b99bd4ef 1282
c19d1205
ZW
1283 if (exp.X_op != O_constant)
1284 {
1285 as_bad (_("expected #constant"));
1286 ignore_rest_of_line ();
1287 return FAIL;
1288 }
1289 *val = exp.X_add_number;
1290 return SUCCESS;
b99bd4ef 1291}
c19d1205 1292#endif
b99bd4ef 1293
c19d1205 1294/* Register parsing. */
b99bd4ef 1295
c19d1205
ZW
1296/* Generic register parser. CCP points to what should be the
1297 beginning of a register name. If it is indeed a valid register
1298 name, advance CCP over it and return the reg_entry structure;
1299 otherwise return NULL. Does not issue diagnostics. */
1300
1301static struct reg_entry *
1302arm_reg_parse_multi (char **ccp)
b99bd4ef 1303{
c19d1205
ZW
1304 char *start = *ccp;
1305 char *p;
1306 struct reg_entry *reg;
b99bd4ef 1307
477330fc
RM
1308 skip_whitespace (start);
1309
c19d1205
ZW
1310#ifdef REGISTER_PREFIX
1311 if (*start != REGISTER_PREFIX)
01cfc07f 1312 return NULL;
c19d1205
ZW
1313 start++;
1314#endif
1315#ifdef OPTIONAL_REGISTER_PREFIX
1316 if (*start == OPTIONAL_REGISTER_PREFIX)
1317 start++;
1318#endif
b99bd4ef 1319
c19d1205
ZW
1320 p = start;
1321 if (!ISALPHA (*p) || !is_name_beginner (*p))
1322 return NULL;
b99bd4ef 1323
c19d1205
ZW
1324 do
1325 p++;
1326 while (ISALPHA (*p) || ISDIGIT (*p) || *p == '_');
1327
1328 reg = (struct reg_entry *) hash_find_n (arm_reg_hsh, start, p - start);
1329
1330 if (!reg)
1331 return NULL;
1332
1333 *ccp = p;
1334 return reg;
b99bd4ef
NC
1335}
1336
1337static int
dcbf9037 1338arm_reg_alt_syntax (char **ccp, char *start, struct reg_entry *reg,
477330fc 1339 enum arm_reg_type type)
b99bd4ef 1340{
c19d1205
ZW
1341 /* Alternative syntaxes are accepted for a few register classes. */
1342 switch (type)
1343 {
1344 case REG_TYPE_MVF:
1345 case REG_TYPE_MVD:
1346 case REG_TYPE_MVFX:
1347 case REG_TYPE_MVDX:
1348 /* Generic coprocessor register names are allowed for these. */
79134647 1349 if (reg && reg->type == REG_TYPE_CN)
c19d1205
ZW
1350 return reg->number;
1351 break;
69b97547 1352
c19d1205
ZW
1353 case REG_TYPE_CP:
1354 /* For backward compatibility, a bare number is valid here. */
1355 {
1356 unsigned long processor = strtoul (start, ccp, 10);
1357 if (*ccp != start && processor <= 15)
1358 return processor;
1359 }
1a0670f3 1360 /* Fall through. */
6057a28f 1361
c19d1205
ZW
1362 case REG_TYPE_MMXWC:
1363 /* WC includes WCG. ??? I'm not sure this is true for all
1364 instructions that take WC registers. */
79134647 1365 if (reg && reg->type == REG_TYPE_MMXWCG)
c19d1205 1366 return reg->number;
6057a28f 1367 break;
c19d1205 1368
6057a28f 1369 default:
c19d1205 1370 break;
6057a28f
NC
1371 }
1372
dcbf9037
JB
1373 return FAIL;
1374}
1375
1376/* As arm_reg_parse_multi, but the register must be of type TYPE, and the
1377 return value is the register number or FAIL. */
1378
1379static int
1380arm_reg_parse (char **ccp, enum arm_reg_type type)
1381{
1382 char *start = *ccp;
1383 struct reg_entry *reg = arm_reg_parse_multi (ccp);
1384 int ret;
1385
1386 /* Do not allow a scalar (reg+index) to parse as a register. */
1387 if (reg && reg->neon && (reg->neon->defined & NTA_HASINDEX))
1388 return FAIL;
1389
1390 if (reg && reg->type == type)
1391 return reg->number;
1392
1393 if ((ret = arm_reg_alt_syntax (ccp, start, reg, type)) != FAIL)
1394 return ret;
1395
c19d1205
ZW
1396 *ccp = start;
1397 return FAIL;
1398}
69b97547 1399
dcbf9037
JB
1400/* Parse a Neon type specifier. *STR should point at the leading '.'
1401 character. Does no verification at this stage that the type fits the opcode
1402 properly. E.g.,
1403
1404 .i32.i32.s16
1405 .s32.f32
1406 .u16
1407
1408 Can all be legally parsed by this function.
1409
1410 Fills in neon_type struct pointer with parsed information, and updates STR
1411 to point after the parsed type specifier. Returns SUCCESS if this was a legal
1412 type, FAIL if not. */
1413
1414static int
1415parse_neon_type (struct neon_type *type, char **str)
1416{
1417 char *ptr = *str;
1418
1419 if (type)
1420 type->elems = 0;
1421
1422 while (type->elems < NEON_MAX_TYPE_ELS)
1423 {
1424 enum neon_el_type thistype = NT_untyped;
1425 unsigned thissize = -1u;
1426
1427 if (*ptr != '.')
1428 break;
1429
1430 ptr++;
1431
1432 /* Just a size without an explicit type. */
1433 if (ISDIGIT (*ptr))
1434 goto parsesize;
1435
1436 switch (TOLOWER (*ptr))
1437 {
1438 case 'i': thistype = NT_integer; break;
1439 case 'f': thistype = NT_float; break;
1440 case 'p': thistype = NT_poly; break;
1441 case 's': thistype = NT_signed; break;
1442 case 'u': thistype = NT_unsigned; break;
477330fc
RM
1443 case 'd':
1444 thistype = NT_float;
1445 thissize = 64;
1446 ptr++;
1447 goto done;
dcbf9037
JB
1448 default:
1449 as_bad (_("unexpected character `%c' in type specifier"), *ptr);
1450 return FAIL;
1451 }
1452
1453 ptr++;
1454
1455 /* .f is an abbreviation for .f32. */
1456 if (thistype == NT_float && !ISDIGIT (*ptr))
1457 thissize = 32;
1458 else
1459 {
1460 parsesize:
1461 thissize = strtoul (ptr, &ptr, 10);
1462
1463 if (thissize != 8 && thissize != 16 && thissize != 32
477330fc
RM
1464 && thissize != 64)
1465 {
1466 as_bad (_("bad size %d in type specifier"), thissize);
dcbf9037
JB
1467 return FAIL;
1468 }
1469 }
1470
037e8744 1471 done:
dcbf9037 1472 if (type)
477330fc
RM
1473 {
1474 type->el[type->elems].type = thistype;
dcbf9037
JB
1475 type->el[type->elems].size = thissize;
1476 type->elems++;
1477 }
1478 }
1479
1480 /* Empty/missing type is not a successful parse. */
1481 if (type->elems == 0)
1482 return FAIL;
1483
1484 *str = ptr;
1485
1486 return SUCCESS;
1487}
1488
1489/* Errors may be set multiple times during parsing or bit encoding
1490 (particularly in the Neon bits), but usually the earliest error which is set
1491 will be the most meaningful. Avoid overwriting it with later (cascading)
1492 errors by calling this function. */
1493
1494static void
1495first_error (const char *err)
1496{
1497 if (!inst.error)
1498 inst.error = err;
1499}
1500
1501/* Parse a single type, e.g. ".s32", leading period included. */
1502static int
1503parse_neon_operand_type (struct neon_type_el *vectype, char **ccp)
1504{
1505 char *str = *ccp;
1506 struct neon_type optype;
1507
1508 if (*str == '.')
1509 {
1510 if (parse_neon_type (&optype, &str) == SUCCESS)
477330fc
RM
1511 {
1512 if (optype.elems == 1)
1513 *vectype = optype.el[0];
1514 else
1515 {
1516 first_error (_("only one type should be specified for operand"));
1517 return FAIL;
1518 }
1519 }
dcbf9037 1520 else
477330fc
RM
1521 {
1522 first_error (_("vector type expected"));
1523 return FAIL;
1524 }
dcbf9037
JB
1525 }
1526 else
1527 return FAIL;
5f4273c7 1528
dcbf9037 1529 *ccp = str;
5f4273c7 1530
dcbf9037
JB
1531 return SUCCESS;
1532}
1533
1534/* Special meanings for indices (which have a range of 0-7), which will fit into
1535 a 4-bit integer. */
1536
1537#define NEON_ALL_LANES 15
1538#define NEON_INTERLEAVE_LANES 14
1539
5ee91343
AV
1540/* Record a use of the given feature. */
1541static void
1542record_feature_use (const arm_feature_set *feature)
1543{
1544 if (thumb_mode)
1545 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, *feature);
1546 else
1547 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, *feature);
1548}
1549
1550/* If the given feature available in the selected CPU, mark it as used.
1551 Returns TRUE iff feature is available. */
1552static bfd_boolean
1553mark_feature_used (const arm_feature_set *feature)
1554{
886e1c73
AV
1555
1556 /* Do not support the use of MVE only instructions when in auto-detection or
1557 -march=all. */
1558 if (((feature == &mve_ext) || (feature == &mve_fp_ext))
1559 && ARM_CPU_IS_ANY (cpu_variant))
1560 {
1561 first_error (BAD_MVE_AUTO);
1562 return FALSE;
1563 }
5ee91343
AV
1564 /* Ensure the option is valid on the current architecture. */
1565 if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
1566 return FALSE;
1567
1568 /* Add the appropriate architecture feature for the barrier option used.
1569 */
1570 record_feature_use (feature);
1571
1572 return TRUE;
1573}
1574
dcbf9037
JB
1575/* Parse either a register or a scalar, with an optional type. Return the
1576 register number, and optionally fill in the actual type of the register
1577 when multiple alternatives were given (NEON_TYPE_NDQ) in *RTYPE, and
1578 type/index information in *TYPEINFO. */
1579
1580static int
1581parse_typed_reg_or_scalar (char **ccp, enum arm_reg_type type,
477330fc
RM
1582 enum arm_reg_type *rtype,
1583 struct neon_typed_alias *typeinfo)
dcbf9037
JB
1584{
1585 char *str = *ccp;
1586 struct reg_entry *reg = arm_reg_parse_multi (&str);
1587 struct neon_typed_alias atype;
1588 struct neon_type_el parsetype;
1589
1590 atype.defined = 0;
1591 atype.index = -1;
1592 atype.eltype.type = NT_invtype;
1593 atype.eltype.size = -1;
1594
1595 /* Try alternate syntax for some types of register. Note these are mutually
1596 exclusive with the Neon syntax extensions. */
1597 if (reg == NULL)
1598 {
1599 int altreg = arm_reg_alt_syntax (&str, *ccp, reg, type);
1600 if (altreg != FAIL)
477330fc 1601 *ccp = str;
dcbf9037 1602 if (typeinfo)
477330fc 1603 *typeinfo = atype;
dcbf9037
JB
1604 return altreg;
1605 }
1606
037e8744
JB
1607 /* Undo polymorphism when a set of register types may be accepted. */
1608 if ((type == REG_TYPE_NDQ
1609 && (reg->type == REG_TYPE_NQ || reg->type == REG_TYPE_VFD))
1610 || (type == REG_TYPE_VFSD
477330fc 1611 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
037e8744 1612 || (type == REG_TYPE_NSDQ
477330fc
RM
1613 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD
1614 || reg->type == REG_TYPE_NQ))
dec41383
JW
1615 || (type == REG_TYPE_NSD
1616 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
f512f76f
NC
1617 || (type == REG_TYPE_MMXWC
1618 && (reg->type == REG_TYPE_MMXWCG)))
21d799b5 1619 type = (enum arm_reg_type) reg->type;
dcbf9037 1620
5ee91343
AV
1621 if (type == REG_TYPE_MQ)
1622 {
1623 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
1624 return FAIL;
1625
1626 if (!reg || reg->type != REG_TYPE_NQ)
1627 return FAIL;
1628
1629 if (reg->number > 14 && !mark_feature_used (&fpu_vfp_ext_d32))
1630 {
1631 first_error (_("expected MVE register [q0..q7]"));
1632 return FAIL;
1633 }
1634 type = REG_TYPE_NQ;
1635 }
1636 else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
1637 && (type == REG_TYPE_NQ))
1638 return FAIL;
1639
1640
dcbf9037
JB
1641 if (type != reg->type)
1642 return FAIL;
1643
1644 if (reg->neon)
1645 atype = *reg->neon;
5f4273c7 1646
dcbf9037
JB
1647 if (parse_neon_operand_type (&parsetype, &str) == SUCCESS)
1648 {
1649 if ((atype.defined & NTA_HASTYPE) != 0)
477330fc
RM
1650 {
1651 first_error (_("can't redefine type for operand"));
1652 return FAIL;
1653 }
dcbf9037
JB
1654 atype.defined |= NTA_HASTYPE;
1655 atype.eltype = parsetype;
1656 }
5f4273c7 1657
dcbf9037
JB
1658 if (skip_past_char (&str, '[') == SUCCESS)
1659 {
dec41383
JW
1660 if (type != REG_TYPE_VFD
1661 && !(type == REG_TYPE_VFS
57785aa2
AV
1662 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_2))
1663 && !(type == REG_TYPE_NQ
1664 && ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)))
477330fc 1665 {
57785aa2
AV
1666 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
1667 first_error (_("only D and Q registers may be indexed"));
1668 else
1669 first_error (_("only D registers may be indexed"));
477330fc
RM
1670 return FAIL;
1671 }
5f4273c7 1672
dcbf9037 1673 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
1674 {
1675 first_error (_("can't change index for operand"));
1676 return FAIL;
1677 }
dcbf9037
JB
1678
1679 atype.defined |= NTA_HASINDEX;
1680
1681 if (skip_past_char (&str, ']') == SUCCESS)
477330fc 1682 atype.index = NEON_ALL_LANES;
dcbf9037 1683 else
477330fc
RM
1684 {
1685 expressionS exp;
dcbf9037 1686
477330fc 1687 my_get_expression (&exp, &str, GE_NO_PREFIX);
dcbf9037 1688
477330fc
RM
1689 if (exp.X_op != O_constant)
1690 {
1691 first_error (_("constant expression required"));
1692 return FAIL;
1693 }
dcbf9037 1694
477330fc
RM
1695 if (skip_past_char (&str, ']') == FAIL)
1696 return FAIL;
dcbf9037 1697
477330fc
RM
1698 atype.index = exp.X_add_number;
1699 }
dcbf9037 1700 }
5f4273c7 1701
dcbf9037
JB
1702 if (typeinfo)
1703 *typeinfo = atype;
5f4273c7 1704
dcbf9037
JB
1705 if (rtype)
1706 *rtype = type;
5f4273c7 1707
dcbf9037 1708 *ccp = str;
5f4273c7 1709
dcbf9037
JB
1710 return reg->number;
1711}
1712
efd6b359 1713/* Like arm_reg_parse, but also allow the following extra features:
dcbf9037
JB
1714 - If RTYPE is non-zero, return the (possibly restricted) type of the
1715 register (e.g. Neon double or quad reg when either has been requested).
1716 - If this is a Neon vector type with additional type information, fill
1717 in the struct pointed to by VECTYPE (if non-NULL).
5f4273c7 1718 This function will fault on encountering a scalar. */
dcbf9037
JB
1719
1720static int
1721arm_typed_reg_parse (char **ccp, enum arm_reg_type type,
477330fc 1722 enum arm_reg_type *rtype, struct neon_type_el *vectype)
dcbf9037
JB
1723{
1724 struct neon_typed_alias atype;
1725 char *str = *ccp;
1726 int reg = parse_typed_reg_or_scalar (&str, type, rtype, &atype);
1727
1728 if (reg == FAIL)
1729 return FAIL;
1730
0855e32b
NS
1731 /* Do not allow regname(... to parse as a register. */
1732 if (*str == '(')
1733 return FAIL;
1734
dcbf9037
JB
1735 /* Do not allow a scalar (reg+index) to parse as a register. */
1736 if ((atype.defined & NTA_HASINDEX) != 0)
1737 {
1738 first_error (_("register operand expected, but got scalar"));
1739 return FAIL;
1740 }
1741
1742 if (vectype)
1743 *vectype = atype.eltype;
1744
1745 *ccp = str;
1746
1747 return reg;
1748}
1749
1750#define NEON_SCALAR_REG(X) ((X) >> 4)
1751#define NEON_SCALAR_INDEX(X) ((X) & 15)
1752
5287ad62
JB
1753/* Parse a Neon scalar. Most of the time when we're parsing a scalar, we don't
1754 have enough information to be able to do a good job bounds-checking. So, we
1755 just do easy checks here, and do further checks later. */
1756
1757static int
57785aa2
AV
1758parse_scalar (char **ccp, int elsize, struct neon_type_el *type, enum
1759 arm_reg_type reg_type)
5287ad62 1760{
dcbf9037 1761 int reg;
5287ad62 1762 char *str = *ccp;
dcbf9037 1763 struct neon_typed_alias atype;
57785aa2 1764 unsigned reg_size;
5f4273c7 1765
dec41383 1766 reg = parse_typed_reg_or_scalar (&str, reg_type, NULL, &atype);
5f4273c7 1767
57785aa2
AV
1768 switch (reg_type)
1769 {
1770 case REG_TYPE_VFS:
1771 reg_size = 32;
1772 break;
1773 case REG_TYPE_VFD:
1774 reg_size = 64;
1775 break;
1776 case REG_TYPE_MQ:
1777 reg_size = 128;
1778 break;
1779 default:
1780 gas_assert (0);
1781 return FAIL;
1782 }
1783
dcbf9037 1784 if (reg == FAIL || (atype.defined & NTA_HASINDEX) == 0)
5287ad62 1785 return FAIL;
5f4273c7 1786
57785aa2 1787 if (reg_type != REG_TYPE_MQ && atype.index == NEON_ALL_LANES)
5287ad62 1788 {
dcbf9037 1789 first_error (_("scalar must have an index"));
5287ad62
JB
1790 return FAIL;
1791 }
57785aa2 1792 else if (atype.index >= reg_size / elsize)
5287ad62 1793 {
dcbf9037 1794 first_error (_("scalar index out of range"));
5287ad62
JB
1795 return FAIL;
1796 }
5f4273c7 1797
dcbf9037
JB
1798 if (type)
1799 *type = atype.eltype;
5f4273c7 1800
5287ad62 1801 *ccp = str;
5f4273c7 1802
dcbf9037 1803 return reg * 16 + atype.index;
5287ad62
JB
1804}
1805
4b5a202f
AV
1806/* Types of registers in a list. */
1807
1808enum reg_list_els
1809{
1810 REGLIST_RN,
1811 REGLIST_CLRM,
1812 REGLIST_VFP_S,
efd6b359 1813 REGLIST_VFP_S_VPR,
4b5a202f 1814 REGLIST_VFP_D,
efd6b359 1815 REGLIST_VFP_D_VPR,
4b5a202f
AV
1816 REGLIST_NEON_D
1817};
1818
c19d1205 1819/* Parse an ARM register list. Returns the bitmask, or FAIL. */
e07e6e58 1820
c19d1205 1821static long
4b5a202f 1822parse_reg_list (char ** strp, enum reg_list_els etype)
c19d1205 1823{
4b5a202f
AV
1824 char *str = *strp;
1825 long range = 0;
1826 int another_range;
1827
1828 gas_assert (etype == REGLIST_RN || etype == REGLIST_CLRM);
a737bd4d 1829
c19d1205
ZW
1830 /* We come back here if we get ranges concatenated by '+' or '|'. */
1831 do
6057a28f 1832 {
477330fc
RM
1833 skip_whitespace (str);
1834
c19d1205 1835 another_range = 0;
a737bd4d 1836
c19d1205
ZW
1837 if (*str == '{')
1838 {
1839 int in_range = 0;
1840 int cur_reg = -1;
a737bd4d 1841
c19d1205
ZW
1842 str++;
1843 do
1844 {
1845 int reg;
4b5a202f
AV
1846 const char apsr_str[] = "apsr";
1847 int apsr_str_len = strlen (apsr_str);
6057a28f 1848
4b5a202f
AV
1849 reg = arm_reg_parse (&str, REGLIST_RN);
1850 if (etype == REGLIST_CLRM)
c19d1205 1851 {
4b5a202f
AV
1852 if (reg == REG_SP || reg == REG_PC)
1853 reg = FAIL;
1854 else if (reg == FAIL
1855 && !strncasecmp (str, apsr_str, apsr_str_len)
1856 && !ISALPHA (*(str + apsr_str_len)))
1857 {
1858 reg = 15;
1859 str += apsr_str_len;
1860 }
1861
1862 if (reg == FAIL)
1863 {
1864 first_error (_("r0-r12, lr or APSR expected"));
1865 return FAIL;
1866 }
1867 }
1868 else /* etype == REGLIST_RN. */
1869 {
1870 if (reg == FAIL)
1871 {
1872 first_error (_(reg_expected_msgs[REGLIST_RN]));
1873 return FAIL;
1874 }
c19d1205 1875 }
a737bd4d 1876
c19d1205
ZW
1877 if (in_range)
1878 {
1879 int i;
a737bd4d 1880
c19d1205
ZW
1881 if (reg <= cur_reg)
1882 {
dcbf9037 1883 first_error (_("bad range in register list"));
c19d1205
ZW
1884 return FAIL;
1885 }
40a18ebd 1886
c19d1205
ZW
1887 for (i = cur_reg + 1; i < reg; i++)
1888 {
1889 if (range & (1 << i))
1890 as_tsktsk
1891 (_("Warning: duplicated register (r%d) in register list"),
1892 i);
1893 else
1894 range |= 1 << i;
1895 }
1896 in_range = 0;
1897 }
a737bd4d 1898
c19d1205
ZW
1899 if (range & (1 << reg))
1900 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
1901 reg);
1902 else if (reg <= cur_reg)
1903 as_tsktsk (_("Warning: register range not in ascending order"));
a737bd4d 1904
c19d1205
ZW
1905 range |= 1 << reg;
1906 cur_reg = reg;
1907 }
1908 while (skip_past_comma (&str) != FAIL
1909 || (in_range = 1, *str++ == '-'));
1910 str--;
a737bd4d 1911
d996d970 1912 if (skip_past_char (&str, '}') == FAIL)
c19d1205 1913 {
dcbf9037 1914 first_error (_("missing `}'"));
c19d1205
ZW
1915 return FAIL;
1916 }
1917 }
4b5a202f 1918 else if (etype == REGLIST_RN)
c19d1205 1919 {
91d6fa6a 1920 expressionS exp;
40a18ebd 1921
91d6fa6a 1922 if (my_get_expression (&exp, &str, GE_NO_PREFIX))
c19d1205 1923 return FAIL;
40a18ebd 1924
91d6fa6a 1925 if (exp.X_op == O_constant)
c19d1205 1926 {
91d6fa6a
NC
1927 if (exp.X_add_number
1928 != (exp.X_add_number & 0x0000ffff))
c19d1205
ZW
1929 {
1930 inst.error = _("invalid register mask");
1931 return FAIL;
1932 }
a737bd4d 1933
91d6fa6a 1934 if ((range & exp.X_add_number) != 0)
c19d1205 1935 {
91d6fa6a 1936 int regno = range & exp.X_add_number;
a737bd4d 1937
c19d1205
ZW
1938 regno &= -regno;
1939 regno = (1 << regno) - 1;
1940 as_tsktsk
1941 (_("Warning: duplicated register (r%d) in register list"),
1942 regno);
1943 }
a737bd4d 1944
91d6fa6a 1945 range |= exp.X_add_number;
c19d1205
ZW
1946 }
1947 else
1948 {
e2b0ab59 1949 if (inst.relocs[0].type != 0)
c19d1205
ZW
1950 {
1951 inst.error = _("expression too complex");
1952 return FAIL;
1953 }
a737bd4d 1954
e2b0ab59
AV
1955 memcpy (&inst.relocs[0].exp, &exp, sizeof (expressionS));
1956 inst.relocs[0].type = BFD_RELOC_ARM_MULTI;
1957 inst.relocs[0].pc_rel = 0;
c19d1205
ZW
1958 }
1959 }
a737bd4d 1960
c19d1205
ZW
1961 if (*str == '|' || *str == '+')
1962 {
1963 str++;
1964 another_range = 1;
1965 }
a737bd4d 1966 }
c19d1205 1967 while (another_range);
a737bd4d 1968
c19d1205
ZW
1969 *strp = str;
1970 return range;
a737bd4d
NC
1971}
1972
c19d1205
ZW
1973/* Parse a VFP register list. If the string is invalid return FAIL.
1974 Otherwise return the number of registers, and set PBASE to the first
5287ad62
JB
1975 register. Parses registers of type ETYPE.
1976 If REGLIST_NEON_D is used, several syntax enhancements are enabled:
1977 - Q registers can be used to specify pairs of D registers
1978 - { } can be omitted from around a singleton register list
477330fc
RM
1979 FIXME: This is not implemented, as it would require backtracking in
1980 some cases, e.g.:
1981 vtbl.8 d3,d4,d5
1982 This could be done (the meaning isn't really ambiguous), but doesn't
1983 fit in well with the current parsing framework.
dcbf9037
JB
1984 - 32 D registers may be used (also true for VFPv3).
1985 FIXME: Types are ignored in these register lists, which is probably a
1986 bug. */
6057a28f 1987
c19d1205 1988static int
efd6b359
AV
1989parse_vfp_reg_list (char **ccp, unsigned int *pbase, enum reg_list_els etype,
1990 bfd_boolean *partial_match)
6057a28f 1991{
037e8744 1992 char *str = *ccp;
c19d1205
ZW
1993 int base_reg;
1994 int new_base;
21d799b5 1995 enum arm_reg_type regtype = (enum arm_reg_type) 0;
5287ad62 1996 int max_regs = 0;
c19d1205
ZW
1997 int count = 0;
1998 int warned = 0;
1999 unsigned long mask = 0;
a737bd4d 2000 int i;
efd6b359
AV
2001 bfd_boolean vpr_seen = FALSE;
2002 bfd_boolean expect_vpr =
2003 (etype == REGLIST_VFP_S_VPR) || (etype == REGLIST_VFP_D_VPR);
6057a28f 2004
477330fc 2005 if (skip_past_char (&str, '{') == FAIL)
5287ad62
JB
2006 {
2007 inst.error = _("expecting {");
2008 return FAIL;
2009 }
6057a28f 2010
5287ad62 2011 switch (etype)
c19d1205 2012 {
5287ad62 2013 case REGLIST_VFP_S:
efd6b359 2014 case REGLIST_VFP_S_VPR:
c19d1205
ZW
2015 regtype = REG_TYPE_VFS;
2016 max_regs = 32;
5287ad62 2017 break;
5f4273c7 2018
5287ad62 2019 case REGLIST_VFP_D:
efd6b359 2020 case REGLIST_VFP_D_VPR:
5287ad62 2021 regtype = REG_TYPE_VFD;
b7fc2769 2022 break;
5f4273c7 2023
b7fc2769
JB
2024 case REGLIST_NEON_D:
2025 regtype = REG_TYPE_NDQ;
2026 break;
4b5a202f
AV
2027
2028 default:
2029 gas_assert (0);
b7fc2769
JB
2030 }
2031
efd6b359 2032 if (etype != REGLIST_VFP_S && etype != REGLIST_VFP_S_VPR)
b7fc2769 2033 {
b1cc4aeb
PB
2034 /* VFPv3 allows 32 D registers, except for the VFPv3-D16 variant. */
2035 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
2036 {
2037 max_regs = 32;
2038 if (thumb_mode)
2039 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
2040 fpu_vfp_ext_d32);
2041 else
2042 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
2043 fpu_vfp_ext_d32);
2044 }
5287ad62 2045 else
477330fc 2046 max_regs = 16;
c19d1205 2047 }
6057a28f 2048
c19d1205 2049 base_reg = max_regs;
efd6b359 2050 *partial_match = FALSE;
a737bd4d 2051
c19d1205
ZW
2052 do
2053 {
5287ad62 2054 int setmask = 1, addregs = 1;
efd6b359
AV
2055 const char vpr_str[] = "vpr";
2056 int vpr_str_len = strlen (vpr_str);
dcbf9037 2057
037e8744 2058 new_base = arm_typed_reg_parse (&str, regtype, &regtype, NULL);
dcbf9037 2059
efd6b359
AV
2060 if (expect_vpr)
2061 {
2062 if (new_base == FAIL
2063 && !strncasecmp (str, vpr_str, vpr_str_len)
2064 && !ISALPHA (*(str + vpr_str_len))
2065 && !vpr_seen)
2066 {
2067 vpr_seen = TRUE;
2068 str += vpr_str_len;
2069 if (count == 0)
2070 base_reg = 0; /* Canonicalize VPR only on d0 with 0 regs. */
2071 }
2072 else if (vpr_seen)
2073 {
2074 first_error (_("VPR expected last"));
2075 return FAIL;
2076 }
2077 else if (new_base == FAIL)
2078 {
2079 if (regtype == REG_TYPE_VFS)
2080 first_error (_("VFP single precision register or VPR "
2081 "expected"));
2082 else /* regtype == REG_TYPE_VFD. */
2083 first_error (_("VFP/Neon double precision register or VPR "
2084 "expected"));
2085 return FAIL;
2086 }
2087 }
2088 else if (new_base == FAIL)
a737bd4d 2089 {
dcbf9037 2090 first_error (_(reg_expected_msgs[regtype]));
c19d1205
ZW
2091 return FAIL;
2092 }
5f4273c7 2093
efd6b359
AV
2094 *partial_match = TRUE;
2095 if (vpr_seen)
2096 continue;
2097
b7fc2769 2098 if (new_base >= max_regs)
477330fc
RM
2099 {
2100 first_error (_("register out of range in list"));
2101 return FAIL;
2102 }
5f4273c7 2103
5287ad62
JB
2104 /* Note: a value of 2 * n is returned for the register Q<n>. */
2105 if (regtype == REG_TYPE_NQ)
477330fc
RM
2106 {
2107 setmask = 3;
2108 addregs = 2;
2109 }
5287ad62 2110
c19d1205
ZW
2111 if (new_base < base_reg)
2112 base_reg = new_base;
a737bd4d 2113
5287ad62 2114 if (mask & (setmask << new_base))
c19d1205 2115 {
dcbf9037 2116 first_error (_("invalid register list"));
c19d1205 2117 return FAIL;
a737bd4d 2118 }
a737bd4d 2119
efd6b359 2120 if ((mask >> new_base) != 0 && ! warned && !vpr_seen)
c19d1205
ZW
2121 {
2122 as_tsktsk (_("register list not in ascending order"));
2123 warned = 1;
2124 }
0bbf2aa4 2125
5287ad62
JB
2126 mask |= setmask << new_base;
2127 count += addregs;
0bbf2aa4 2128
037e8744 2129 if (*str == '-') /* We have the start of a range expression */
c19d1205
ZW
2130 {
2131 int high_range;
0bbf2aa4 2132
037e8744 2133 str++;
0bbf2aa4 2134
037e8744 2135 if ((high_range = arm_typed_reg_parse (&str, regtype, NULL, NULL))
477330fc 2136 == FAIL)
c19d1205
ZW
2137 {
2138 inst.error = gettext (reg_expected_msgs[regtype]);
2139 return FAIL;
2140 }
0bbf2aa4 2141
477330fc
RM
2142 if (high_range >= max_regs)
2143 {
2144 first_error (_("register out of range in list"));
2145 return FAIL;
2146 }
b7fc2769 2147
477330fc
RM
2148 if (regtype == REG_TYPE_NQ)
2149 high_range = high_range + 1;
5287ad62 2150
c19d1205
ZW
2151 if (high_range <= new_base)
2152 {
2153 inst.error = _("register range not in ascending order");
2154 return FAIL;
2155 }
0bbf2aa4 2156
5287ad62 2157 for (new_base += addregs; new_base <= high_range; new_base += addregs)
0bbf2aa4 2158 {
5287ad62 2159 if (mask & (setmask << new_base))
0bbf2aa4 2160 {
c19d1205
ZW
2161 inst.error = _("invalid register list");
2162 return FAIL;
0bbf2aa4 2163 }
c19d1205 2164
5287ad62
JB
2165 mask |= setmask << new_base;
2166 count += addregs;
0bbf2aa4 2167 }
0bbf2aa4 2168 }
0bbf2aa4 2169 }
037e8744 2170 while (skip_past_comma (&str) != FAIL);
0bbf2aa4 2171
037e8744 2172 str++;
0bbf2aa4 2173
c19d1205 2174 /* Sanity check -- should have raised a parse error above. */
efd6b359 2175 if ((!vpr_seen && count == 0) || count > max_regs)
c19d1205
ZW
2176 abort ();
2177
2178 *pbase = base_reg;
2179
efd6b359
AV
2180 if (expect_vpr && !vpr_seen)
2181 {
2182 first_error (_("VPR expected last"));
2183 return FAIL;
2184 }
2185
c19d1205
ZW
2186 /* Final test -- the registers must be consecutive. */
2187 mask >>= base_reg;
2188 for (i = 0; i < count; i++)
2189 {
2190 if ((mask & (1u << i)) == 0)
2191 {
2192 inst.error = _("non-contiguous register range");
2193 return FAIL;
2194 }
2195 }
2196
037e8744
JB
2197 *ccp = str;
2198
c19d1205 2199 return count;
b99bd4ef
NC
2200}
2201
dcbf9037
JB
2202/* True if two alias types are the same. */
2203
c921be7d 2204static bfd_boolean
dcbf9037
JB
2205neon_alias_types_same (struct neon_typed_alias *a, struct neon_typed_alias *b)
2206{
2207 if (!a && !b)
c921be7d 2208 return TRUE;
5f4273c7 2209
dcbf9037 2210 if (!a || !b)
c921be7d 2211 return FALSE;
dcbf9037
JB
2212
2213 if (a->defined != b->defined)
c921be7d 2214 return FALSE;
5f4273c7 2215
dcbf9037
JB
2216 if ((a->defined & NTA_HASTYPE) != 0
2217 && (a->eltype.type != b->eltype.type
477330fc 2218 || a->eltype.size != b->eltype.size))
c921be7d 2219 return FALSE;
dcbf9037
JB
2220
2221 if ((a->defined & NTA_HASINDEX) != 0
2222 && (a->index != b->index))
c921be7d 2223 return FALSE;
5f4273c7 2224
c921be7d 2225 return TRUE;
dcbf9037
JB
2226}
2227
5287ad62
JB
2228/* Parse element/structure lists for Neon VLD<n> and VST<n> instructions.
2229 The base register is put in *PBASE.
dcbf9037 2230 The lane (or one of the NEON_*_LANES constants) is placed in bits [3:0] of
5287ad62
JB
2231 the return value.
2232 The register stride (minus one) is put in bit 4 of the return value.
dcbf9037
JB
2233 Bits [6:5] encode the list length (minus one).
2234 The type of the list elements is put in *ELTYPE, if non-NULL. */
5287ad62 2235
5287ad62 2236#define NEON_LANE(X) ((X) & 0xf)
dcbf9037 2237#define NEON_REG_STRIDE(X) ((((X) >> 4) & 1) + 1)
5287ad62
JB
2238#define NEON_REGLIST_LENGTH(X) ((((X) >> 5) & 3) + 1)
2239
2240static int
dcbf9037 2241parse_neon_el_struct_list (char **str, unsigned *pbase,
35c228db 2242 int mve,
477330fc 2243 struct neon_type_el *eltype)
5287ad62
JB
2244{
2245 char *ptr = *str;
2246 int base_reg = -1;
2247 int reg_incr = -1;
2248 int count = 0;
2249 int lane = -1;
2250 int leading_brace = 0;
2251 enum arm_reg_type rtype = REG_TYPE_NDQ;
35c228db
AV
2252 const char *const incr_error = mve ? _("register stride must be 1") :
2253 _("register stride must be 1 or 2");
20203fb9 2254 const char *const type_error = _("mismatched element/structure types in list");
dcbf9037 2255 struct neon_typed_alias firsttype;
f85d59c3
KT
2256 firsttype.defined = 0;
2257 firsttype.eltype.type = NT_invtype;
2258 firsttype.eltype.size = -1;
2259 firsttype.index = -1;
5f4273c7 2260
5287ad62
JB
2261 if (skip_past_char (&ptr, '{') == SUCCESS)
2262 leading_brace = 1;
5f4273c7 2263
5287ad62
JB
2264 do
2265 {
dcbf9037 2266 struct neon_typed_alias atype;
35c228db
AV
2267 if (mve)
2268 rtype = REG_TYPE_MQ;
dcbf9037
JB
2269 int getreg = parse_typed_reg_or_scalar (&ptr, rtype, &rtype, &atype);
2270
5287ad62 2271 if (getreg == FAIL)
477330fc
RM
2272 {
2273 first_error (_(reg_expected_msgs[rtype]));
2274 return FAIL;
2275 }
5f4273c7 2276
5287ad62 2277 if (base_reg == -1)
477330fc
RM
2278 {
2279 base_reg = getreg;
2280 if (rtype == REG_TYPE_NQ)
2281 {
2282 reg_incr = 1;
2283 }
2284 firsttype = atype;
2285 }
5287ad62 2286 else if (reg_incr == -1)
477330fc
RM
2287 {
2288 reg_incr = getreg - base_reg;
2289 if (reg_incr < 1 || reg_incr > 2)
2290 {
2291 first_error (_(incr_error));
2292 return FAIL;
2293 }
2294 }
5287ad62 2295 else if (getreg != base_reg + reg_incr * count)
477330fc
RM
2296 {
2297 first_error (_(incr_error));
2298 return FAIL;
2299 }
dcbf9037 2300
c921be7d 2301 if (! neon_alias_types_same (&atype, &firsttype))
477330fc
RM
2302 {
2303 first_error (_(type_error));
2304 return FAIL;
2305 }
5f4273c7 2306
5287ad62 2307 /* Handle Dn-Dm or Qn-Qm syntax. Can only be used with non-indexed list
477330fc 2308 modes. */
5287ad62 2309 if (ptr[0] == '-')
477330fc
RM
2310 {
2311 struct neon_typed_alias htype;
2312 int hireg, dregs = (rtype == REG_TYPE_NQ) ? 2 : 1;
2313 if (lane == -1)
2314 lane = NEON_INTERLEAVE_LANES;
2315 else if (lane != NEON_INTERLEAVE_LANES)
2316 {
2317 first_error (_(type_error));
2318 return FAIL;
2319 }
2320 if (reg_incr == -1)
2321 reg_incr = 1;
2322 else if (reg_incr != 1)
2323 {
2324 first_error (_("don't use Rn-Rm syntax with non-unit stride"));
2325 return FAIL;
2326 }
2327 ptr++;
2328 hireg = parse_typed_reg_or_scalar (&ptr, rtype, NULL, &htype);
2329 if (hireg == FAIL)
2330 {
2331 first_error (_(reg_expected_msgs[rtype]));
2332 return FAIL;
2333 }
2334 if (! neon_alias_types_same (&htype, &firsttype))
2335 {
2336 first_error (_(type_error));
2337 return FAIL;
2338 }
2339 count += hireg + dregs - getreg;
2340 continue;
2341 }
5f4273c7 2342
5287ad62
JB
2343 /* If we're using Q registers, we can't use [] or [n] syntax. */
2344 if (rtype == REG_TYPE_NQ)
477330fc
RM
2345 {
2346 count += 2;
2347 continue;
2348 }
5f4273c7 2349
dcbf9037 2350 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
2351 {
2352 if (lane == -1)
2353 lane = atype.index;
2354 else if (lane != atype.index)
2355 {
2356 first_error (_(type_error));
2357 return FAIL;
2358 }
2359 }
5287ad62 2360 else if (lane == -1)
477330fc 2361 lane = NEON_INTERLEAVE_LANES;
5287ad62 2362 else if (lane != NEON_INTERLEAVE_LANES)
477330fc
RM
2363 {
2364 first_error (_(type_error));
2365 return FAIL;
2366 }
5287ad62
JB
2367 count++;
2368 }
2369 while ((count != 1 || leading_brace) && skip_past_comma (&ptr) != FAIL);
5f4273c7 2370
5287ad62
JB
2371 /* No lane set by [x]. We must be interleaving structures. */
2372 if (lane == -1)
2373 lane = NEON_INTERLEAVE_LANES;
5f4273c7 2374
5287ad62 2375 /* Sanity check. */
35c228db 2376 if (lane == -1 || base_reg == -1 || count < 1 || (!mve && count > 4)
5287ad62
JB
2377 || (count > 1 && reg_incr == -1))
2378 {
dcbf9037 2379 first_error (_("error parsing element/structure list"));
5287ad62
JB
2380 return FAIL;
2381 }
2382
2383 if ((count > 1 || leading_brace) && skip_past_char (&ptr, '}') == FAIL)
2384 {
dcbf9037 2385 first_error (_("expected }"));
5287ad62
JB
2386 return FAIL;
2387 }
5f4273c7 2388
5287ad62
JB
2389 if (reg_incr == -1)
2390 reg_incr = 1;
2391
dcbf9037
JB
2392 if (eltype)
2393 *eltype = firsttype.eltype;
2394
5287ad62
JB
2395 *pbase = base_reg;
2396 *str = ptr;
5f4273c7 2397
5287ad62
JB
2398 return lane | ((reg_incr - 1) << 4) | ((count - 1) << 5);
2399}
2400
c19d1205
ZW
2401/* Parse an explicit relocation suffix on an expression. This is
2402 either nothing, or a word in parentheses. Note that if !OBJ_ELF,
2403 arm_reloc_hsh contains no entries, so this function can only
2404 succeed if there is no () after the word. Returns -1 on error,
2405 BFD_RELOC_UNUSED if there wasn't any suffix. */
3da1d841 2406
c19d1205
ZW
2407static int
2408parse_reloc (char **str)
b99bd4ef 2409{
c19d1205
ZW
2410 struct reloc_entry *r;
2411 char *p, *q;
b99bd4ef 2412
c19d1205
ZW
2413 if (**str != '(')
2414 return BFD_RELOC_UNUSED;
b99bd4ef 2415
c19d1205
ZW
2416 p = *str + 1;
2417 q = p;
2418
2419 while (*q && *q != ')' && *q != ',')
2420 q++;
2421 if (*q != ')')
2422 return -1;
2423
21d799b5
NC
2424 if ((r = (struct reloc_entry *)
2425 hash_find_n (arm_reloc_hsh, p, q - p)) == NULL)
c19d1205
ZW
2426 return -1;
2427
2428 *str = q + 1;
2429 return r->reloc;
b99bd4ef
NC
2430}
2431
c19d1205
ZW
2432/* Directives: register aliases. */
2433
dcbf9037 2434static struct reg_entry *
90ec0d68 2435insert_reg_alias (char *str, unsigned number, int type)
b99bd4ef 2436{
d3ce72d0 2437 struct reg_entry *new_reg;
c19d1205 2438 const char *name;
b99bd4ef 2439
d3ce72d0 2440 if ((new_reg = (struct reg_entry *) hash_find (arm_reg_hsh, str)) != 0)
c19d1205 2441 {
d3ce72d0 2442 if (new_reg->builtin)
c19d1205 2443 as_warn (_("ignoring attempt to redefine built-in register '%s'"), str);
b99bd4ef 2444
c19d1205
ZW
2445 /* Only warn about a redefinition if it's not defined as the
2446 same register. */
d3ce72d0 2447 else if (new_reg->number != number || new_reg->type != type)
c19d1205 2448 as_warn (_("ignoring redefinition of register alias '%s'"), str);
69b97547 2449
d929913e 2450 return NULL;
c19d1205 2451 }
b99bd4ef 2452
c19d1205 2453 name = xstrdup (str);
325801bd 2454 new_reg = XNEW (struct reg_entry);
b99bd4ef 2455
d3ce72d0
NC
2456 new_reg->name = name;
2457 new_reg->number = number;
2458 new_reg->type = type;
2459 new_reg->builtin = FALSE;
2460 new_reg->neon = NULL;
b99bd4ef 2461
d3ce72d0 2462 if (hash_insert (arm_reg_hsh, name, (void *) new_reg))
c19d1205 2463 abort ();
5f4273c7 2464
d3ce72d0 2465 return new_reg;
dcbf9037
JB
2466}
2467
2468static void
2469insert_neon_reg_alias (char *str, int number, int type,
477330fc 2470 struct neon_typed_alias *atype)
dcbf9037
JB
2471{
2472 struct reg_entry *reg = insert_reg_alias (str, number, type);
5f4273c7 2473
dcbf9037
JB
2474 if (!reg)
2475 {
2476 first_error (_("attempt to redefine typed alias"));
2477 return;
2478 }
5f4273c7 2479
dcbf9037
JB
2480 if (atype)
2481 {
325801bd 2482 reg->neon = XNEW (struct neon_typed_alias);
dcbf9037
JB
2483 *reg->neon = *atype;
2484 }
c19d1205 2485}
b99bd4ef 2486
c19d1205 2487/* Look for the .req directive. This is of the form:
b99bd4ef 2488
c19d1205 2489 new_register_name .req existing_register_name
b99bd4ef 2490
c19d1205 2491 If we find one, or if it looks sufficiently like one that we want to
d929913e 2492 handle any error here, return TRUE. Otherwise return FALSE. */
b99bd4ef 2493
d929913e 2494static bfd_boolean
c19d1205
ZW
2495create_register_alias (char * newname, char *p)
2496{
2497 struct reg_entry *old;
2498 char *oldname, *nbuf;
2499 size_t nlen;
b99bd4ef 2500
c19d1205
ZW
2501 /* The input scrubber ensures that whitespace after the mnemonic is
2502 collapsed to single spaces. */
2503 oldname = p;
2504 if (strncmp (oldname, " .req ", 6) != 0)
d929913e 2505 return FALSE;
b99bd4ef 2506
c19d1205
ZW
2507 oldname += 6;
2508 if (*oldname == '\0')
d929913e 2509 return FALSE;
b99bd4ef 2510
21d799b5 2511 old = (struct reg_entry *) hash_find (arm_reg_hsh, oldname);
c19d1205 2512 if (!old)
b99bd4ef 2513 {
c19d1205 2514 as_warn (_("unknown register '%s' -- .req ignored"), oldname);
d929913e 2515 return TRUE;
b99bd4ef
NC
2516 }
2517
c19d1205
ZW
2518 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2519 the desired alias name, and p points to its end. If not, then
2520 the desired alias name is in the global original_case_string. */
2521#ifdef TC_CASE_SENSITIVE
2522 nlen = p - newname;
2523#else
2524 newname = original_case_string;
2525 nlen = strlen (newname);
2526#endif
b99bd4ef 2527
29a2809e 2528 nbuf = xmemdup0 (newname, nlen);
b99bd4ef 2529
c19d1205
ZW
2530 /* Create aliases under the new name as stated; an all-lowercase
2531 version of the new name; and an all-uppercase version of the new
2532 name. */
d929913e
NC
2533 if (insert_reg_alias (nbuf, old->number, old->type) != NULL)
2534 {
2535 for (p = nbuf; *p; p++)
2536 *p = TOUPPER (*p);
c19d1205 2537
d929913e
NC
2538 if (strncmp (nbuf, newname, nlen))
2539 {
2540 /* If this attempt to create an additional alias fails, do not bother
2541 trying to create the all-lower case alias. We will fail and issue
2542 a second, duplicate error message. This situation arises when the
2543 programmer does something like:
2544 foo .req r0
2545 Foo .req r1
2546 The second .req creates the "Foo" alias but then fails to create
5f4273c7 2547 the artificial FOO alias because it has already been created by the
d929913e
NC
2548 first .req. */
2549 if (insert_reg_alias (nbuf, old->number, old->type) == NULL)
e1fa0163
NC
2550 {
2551 free (nbuf);
2552 return TRUE;
2553 }
d929913e 2554 }
c19d1205 2555
d929913e
NC
2556 for (p = nbuf; *p; p++)
2557 *p = TOLOWER (*p);
c19d1205 2558
d929913e
NC
2559 if (strncmp (nbuf, newname, nlen))
2560 insert_reg_alias (nbuf, old->number, old->type);
2561 }
c19d1205 2562
e1fa0163 2563 free (nbuf);
d929913e 2564 return TRUE;
b99bd4ef
NC
2565}
2566
dcbf9037
JB
2567/* Create a Neon typed/indexed register alias using directives, e.g.:
2568 X .dn d5.s32[1]
2569 Y .qn 6.s16
2570 Z .dn d7
2571 T .dn Z[0]
2572 These typed registers can be used instead of the types specified after the
2573 Neon mnemonic, so long as all operands given have types. Types can also be
2574 specified directly, e.g.:
5f4273c7 2575 vadd d0.s32, d1.s32, d2.s32 */
dcbf9037 2576
c921be7d 2577static bfd_boolean
dcbf9037
JB
2578create_neon_reg_alias (char *newname, char *p)
2579{
2580 enum arm_reg_type basetype;
2581 struct reg_entry *basereg;
2582 struct reg_entry mybasereg;
2583 struct neon_type ntype;
2584 struct neon_typed_alias typeinfo;
12d6b0b7 2585 char *namebuf, *nameend ATTRIBUTE_UNUSED;
dcbf9037 2586 int namelen;
5f4273c7 2587
dcbf9037
JB
2588 typeinfo.defined = 0;
2589 typeinfo.eltype.type = NT_invtype;
2590 typeinfo.eltype.size = -1;
2591 typeinfo.index = -1;
5f4273c7 2592
dcbf9037 2593 nameend = p;
5f4273c7 2594
dcbf9037
JB
2595 if (strncmp (p, " .dn ", 5) == 0)
2596 basetype = REG_TYPE_VFD;
2597 else if (strncmp (p, " .qn ", 5) == 0)
2598 basetype = REG_TYPE_NQ;
2599 else
c921be7d 2600 return FALSE;
5f4273c7 2601
dcbf9037 2602 p += 5;
5f4273c7 2603
dcbf9037 2604 if (*p == '\0')
c921be7d 2605 return FALSE;
5f4273c7 2606
dcbf9037
JB
2607 basereg = arm_reg_parse_multi (&p);
2608
2609 if (basereg && basereg->type != basetype)
2610 {
2611 as_bad (_("bad type for register"));
c921be7d 2612 return FALSE;
dcbf9037
JB
2613 }
2614
2615 if (basereg == NULL)
2616 {
2617 expressionS exp;
2618 /* Try parsing as an integer. */
2619 my_get_expression (&exp, &p, GE_NO_PREFIX);
2620 if (exp.X_op != O_constant)
477330fc
RM
2621 {
2622 as_bad (_("expression must be constant"));
2623 return FALSE;
2624 }
dcbf9037
JB
2625 basereg = &mybasereg;
2626 basereg->number = (basetype == REG_TYPE_NQ) ? exp.X_add_number * 2
477330fc 2627 : exp.X_add_number;
dcbf9037
JB
2628 basereg->neon = 0;
2629 }
2630
2631 if (basereg->neon)
2632 typeinfo = *basereg->neon;
2633
2634 if (parse_neon_type (&ntype, &p) == SUCCESS)
2635 {
2636 /* We got a type. */
2637 if (typeinfo.defined & NTA_HASTYPE)
477330fc
RM
2638 {
2639 as_bad (_("can't redefine the type of a register alias"));
2640 return FALSE;
2641 }
5f4273c7 2642
dcbf9037
JB
2643 typeinfo.defined |= NTA_HASTYPE;
2644 if (ntype.elems != 1)
477330fc
RM
2645 {
2646 as_bad (_("you must specify a single type only"));
2647 return FALSE;
2648 }
dcbf9037
JB
2649 typeinfo.eltype = ntype.el[0];
2650 }
5f4273c7 2651
dcbf9037
JB
2652 if (skip_past_char (&p, '[') == SUCCESS)
2653 {
2654 expressionS exp;
2655 /* We got a scalar index. */
5f4273c7 2656
dcbf9037 2657 if (typeinfo.defined & NTA_HASINDEX)
477330fc
RM
2658 {
2659 as_bad (_("can't redefine the index of a scalar alias"));
2660 return FALSE;
2661 }
5f4273c7 2662
dcbf9037 2663 my_get_expression (&exp, &p, GE_NO_PREFIX);
5f4273c7 2664
dcbf9037 2665 if (exp.X_op != O_constant)
477330fc
RM
2666 {
2667 as_bad (_("scalar index must be constant"));
2668 return FALSE;
2669 }
5f4273c7 2670
dcbf9037
JB
2671 typeinfo.defined |= NTA_HASINDEX;
2672 typeinfo.index = exp.X_add_number;
5f4273c7 2673
dcbf9037 2674 if (skip_past_char (&p, ']') == FAIL)
477330fc
RM
2675 {
2676 as_bad (_("expecting ]"));
2677 return FALSE;
2678 }
dcbf9037
JB
2679 }
2680
15735687
NS
2681 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2682 the desired alias name, and p points to its end. If not, then
2683 the desired alias name is in the global original_case_string. */
2684#ifdef TC_CASE_SENSITIVE
dcbf9037 2685 namelen = nameend - newname;
15735687
NS
2686#else
2687 newname = original_case_string;
2688 namelen = strlen (newname);
2689#endif
2690
29a2809e 2691 namebuf = xmemdup0 (newname, namelen);
5f4273c7 2692
dcbf9037 2693 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2694 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2695
dcbf9037
JB
2696 /* Insert name in all uppercase. */
2697 for (p = namebuf; *p; p++)
2698 *p = TOUPPER (*p);
5f4273c7 2699
dcbf9037
JB
2700 if (strncmp (namebuf, newname, namelen))
2701 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2702 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2703
dcbf9037
JB
2704 /* Insert name in all lowercase. */
2705 for (p = namebuf; *p; p++)
2706 *p = TOLOWER (*p);
5f4273c7 2707
dcbf9037
JB
2708 if (strncmp (namebuf, newname, namelen))
2709 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2710 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2711
e1fa0163 2712 free (namebuf);
c921be7d 2713 return TRUE;
dcbf9037
JB
2714}
2715
c19d1205
ZW
2716/* Should never be called, as .req goes between the alias and the
2717 register name, not at the beginning of the line. */
c921be7d 2718
b99bd4ef 2719static void
c19d1205 2720s_req (int a ATTRIBUTE_UNUSED)
b99bd4ef 2721{
c19d1205
ZW
2722 as_bad (_("invalid syntax for .req directive"));
2723}
b99bd4ef 2724
dcbf9037
JB
2725static void
2726s_dn (int a ATTRIBUTE_UNUSED)
2727{
2728 as_bad (_("invalid syntax for .dn directive"));
2729}
2730
2731static void
2732s_qn (int a ATTRIBUTE_UNUSED)
2733{
2734 as_bad (_("invalid syntax for .qn directive"));
2735}
2736
c19d1205
ZW
2737/* The .unreq directive deletes an alias which was previously defined
2738 by .req. For example:
b99bd4ef 2739
c19d1205
ZW
2740 my_alias .req r11
2741 .unreq my_alias */
b99bd4ef
NC
2742
2743static void
c19d1205 2744s_unreq (int a ATTRIBUTE_UNUSED)
b99bd4ef 2745{
c19d1205
ZW
2746 char * name;
2747 char saved_char;
b99bd4ef 2748
c19d1205
ZW
2749 name = input_line_pointer;
2750
2751 while (*input_line_pointer != 0
2752 && *input_line_pointer != ' '
2753 && *input_line_pointer != '\n')
2754 ++input_line_pointer;
2755
2756 saved_char = *input_line_pointer;
2757 *input_line_pointer = 0;
2758
2759 if (!*name)
2760 as_bad (_("invalid syntax for .unreq directive"));
2761 else
2762 {
21d799b5 2763 struct reg_entry *reg = (struct reg_entry *) hash_find (arm_reg_hsh,
477330fc 2764 name);
c19d1205
ZW
2765
2766 if (!reg)
2767 as_bad (_("unknown register alias '%s'"), name);
2768 else if (reg->builtin)
a1727c1a 2769 as_warn (_("ignoring attempt to use .unreq on fixed register name: '%s'"),
c19d1205
ZW
2770 name);
2771 else
2772 {
d929913e
NC
2773 char * p;
2774 char * nbuf;
2775
db0bc284 2776 hash_delete (arm_reg_hsh, name, FALSE);
c19d1205 2777 free ((char *) reg->name);
477330fc
RM
2778 if (reg->neon)
2779 free (reg->neon);
c19d1205 2780 free (reg);
d929913e
NC
2781
2782 /* Also locate the all upper case and all lower case versions.
2783 Do not complain if we cannot find one or the other as it
2784 was probably deleted above. */
5f4273c7 2785
d929913e
NC
2786 nbuf = strdup (name);
2787 for (p = nbuf; *p; p++)
2788 *p = TOUPPER (*p);
21d799b5 2789 reg = (struct reg_entry *) hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2790 if (reg)
2791 {
db0bc284 2792 hash_delete (arm_reg_hsh, nbuf, FALSE);
d929913e
NC
2793 free ((char *) reg->name);
2794 if (reg->neon)
2795 free (reg->neon);
2796 free (reg);
2797 }
2798
2799 for (p = nbuf; *p; p++)
2800 *p = TOLOWER (*p);
21d799b5 2801 reg = (struct reg_entry *) hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2802 if (reg)
2803 {
db0bc284 2804 hash_delete (arm_reg_hsh, nbuf, FALSE);
d929913e
NC
2805 free ((char *) reg->name);
2806 if (reg->neon)
2807 free (reg->neon);
2808 free (reg);
2809 }
2810
2811 free (nbuf);
c19d1205
ZW
2812 }
2813 }
b99bd4ef 2814
c19d1205 2815 *input_line_pointer = saved_char;
b99bd4ef
NC
2816 demand_empty_rest_of_line ();
2817}
2818
c19d1205
ZW
2819/* Directives: Instruction set selection. */
2820
2821#ifdef OBJ_ELF
2822/* This code is to handle mapping symbols as defined in the ARM ELF spec.
2823 (See "Mapping symbols", section 4.5.5, ARM AAELF version 1.0).
2824 Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
2825 and $d has type STT_OBJECT (BSF_OBJECT flag). Now all three are untyped. */
2826
cd000bff
DJ
2827/* Create a new mapping symbol for the transition to STATE. */
2828
2829static void
2830make_mapping_symbol (enum mstate state, valueT value, fragS *frag)
b99bd4ef 2831{
a737bd4d 2832 symbolS * symbolP;
c19d1205
ZW
2833 const char * symname;
2834 int type;
b99bd4ef 2835
c19d1205 2836 switch (state)
b99bd4ef 2837 {
c19d1205
ZW
2838 case MAP_DATA:
2839 symname = "$d";
2840 type = BSF_NO_FLAGS;
2841 break;
2842 case MAP_ARM:
2843 symname = "$a";
2844 type = BSF_NO_FLAGS;
2845 break;
2846 case MAP_THUMB:
2847 symname = "$t";
2848 type = BSF_NO_FLAGS;
2849 break;
c19d1205
ZW
2850 default:
2851 abort ();
2852 }
2853
cd000bff 2854 symbolP = symbol_new (symname, now_seg, value, frag);
c19d1205
ZW
2855 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2856
2857 switch (state)
2858 {
2859 case MAP_ARM:
2860 THUMB_SET_FUNC (symbolP, 0);
2861 ARM_SET_THUMB (symbolP, 0);
2862 ARM_SET_INTERWORK (symbolP, support_interwork);
2863 break;
2864
2865 case MAP_THUMB:
2866 THUMB_SET_FUNC (symbolP, 1);
2867 ARM_SET_THUMB (symbolP, 1);
2868 ARM_SET_INTERWORK (symbolP, support_interwork);
2869 break;
2870
2871 case MAP_DATA:
2872 default:
cd000bff
DJ
2873 break;
2874 }
2875
2876 /* Save the mapping symbols for future reference. Also check that
2877 we do not place two mapping symbols at the same offset within a
2878 frag. We'll handle overlap between frags in
2de7820f
JZ
2879 check_mapping_symbols.
2880
2881 If .fill or other data filling directive generates zero sized data,
2882 the mapping symbol for the following code will have the same value
2883 as the one generated for the data filling directive. In this case,
2884 we replace the old symbol with the new one at the same address. */
cd000bff
DJ
2885 if (value == 0)
2886 {
2de7820f
JZ
2887 if (frag->tc_frag_data.first_map != NULL)
2888 {
2889 know (S_GET_VALUE (frag->tc_frag_data.first_map) == 0);
2890 symbol_remove (frag->tc_frag_data.first_map, &symbol_rootP, &symbol_lastP);
2891 }
cd000bff
DJ
2892 frag->tc_frag_data.first_map = symbolP;
2893 }
2894 if (frag->tc_frag_data.last_map != NULL)
0f020cef
JZ
2895 {
2896 know (S_GET_VALUE (frag->tc_frag_data.last_map) <= S_GET_VALUE (symbolP));
0f020cef
JZ
2897 if (S_GET_VALUE (frag->tc_frag_data.last_map) == S_GET_VALUE (symbolP))
2898 symbol_remove (frag->tc_frag_data.last_map, &symbol_rootP, &symbol_lastP);
2899 }
cd000bff
DJ
2900 frag->tc_frag_data.last_map = symbolP;
2901}
2902
2903/* We must sometimes convert a region marked as code to data during
2904 code alignment, if an odd number of bytes have to be padded. The
2905 code mapping symbol is pushed to an aligned address. */
2906
2907static void
2908insert_data_mapping_symbol (enum mstate state,
2909 valueT value, fragS *frag, offsetT bytes)
2910{
2911 /* If there was already a mapping symbol, remove it. */
2912 if (frag->tc_frag_data.last_map != NULL
2913 && S_GET_VALUE (frag->tc_frag_data.last_map) == frag->fr_address + value)
2914 {
2915 symbolS *symp = frag->tc_frag_data.last_map;
2916
2917 if (value == 0)
2918 {
2919 know (frag->tc_frag_data.first_map == symp);
2920 frag->tc_frag_data.first_map = NULL;
2921 }
2922 frag->tc_frag_data.last_map = NULL;
2923 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
c19d1205 2924 }
cd000bff
DJ
2925
2926 make_mapping_symbol (MAP_DATA, value, frag);
2927 make_mapping_symbol (state, value + bytes, frag);
2928}
2929
2930static void mapping_state_2 (enum mstate state, int max_chars);
2931
2932/* Set the mapping state to STATE. Only call this when about to
2933 emit some STATE bytes to the file. */
2934
4e9aaefb 2935#define TRANSITION(from, to) (mapstate == (from) && state == (to))
cd000bff
DJ
2936void
2937mapping_state (enum mstate state)
2938{
940b5ce0
DJ
2939 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
2940
cd000bff
DJ
2941 if (mapstate == state)
2942 /* The mapping symbol has already been emitted.
2943 There is nothing else to do. */
2944 return;
49c62a33
NC
2945
2946 if (state == MAP_ARM || state == MAP_THUMB)
2947 /* PR gas/12931
2948 All ARM instructions require 4-byte alignment.
2949 (Almost) all Thumb instructions require 2-byte alignment.
2950
2951 When emitting instructions into any section, mark the section
2952 appropriately.
2953
2954 Some Thumb instructions are alignment-sensitive modulo 4 bytes,
2955 but themselves require 2-byte alignment; this applies to some
33eaf5de 2956 PC- relative forms. However, these cases will involve implicit
49c62a33
NC
2957 literal pool generation or an explicit .align >=2, both of
2958 which will cause the section to me marked with sufficient
2959 alignment. Thus, we don't handle those cases here. */
2960 record_alignment (now_seg, state == MAP_ARM ? 2 : 1);
2961
2962 if (TRANSITION (MAP_UNDEFINED, MAP_DATA))
4e9aaefb 2963 /* This case will be evaluated later. */
cd000bff 2964 return;
cd000bff
DJ
2965
2966 mapping_state_2 (state, 0);
cd000bff
DJ
2967}
2968
2969/* Same as mapping_state, but MAX_CHARS bytes have already been
2970 allocated. Put the mapping symbol that far back. */
2971
2972static void
2973mapping_state_2 (enum mstate state, int max_chars)
2974{
940b5ce0
DJ
2975 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
2976
2977 if (!SEG_NORMAL (now_seg))
2978 return;
2979
cd000bff
DJ
2980 if (mapstate == state)
2981 /* The mapping symbol has already been emitted.
2982 There is nothing else to do. */
2983 return;
2984
4e9aaefb
SA
2985 if (TRANSITION (MAP_UNDEFINED, MAP_ARM)
2986 || TRANSITION (MAP_UNDEFINED, MAP_THUMB))
2987 {
2988 struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
2989 const int add_symbol = (frag_now != frag_first) || (frag_now_fix () > 0);
2990
2991 if (add_symbol)
2992 make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
2993 }
2994
cd000bff
DJ
2995 seg_info (now_seg)->tc_segment_info_data.mapstate = state;
2996 make_mapping_symbol (state, (valueT) frag_now_fix () - max_chars, frag_now);
c19d1205 2997}
4e9aaefb 2998#undef TRANSITION
c19d1205 2999#else
d3106081
NS
3000#define mapping_state(x) ((void)0)
3001#define mapping_state_2(x, y) ((void)0)
c19d1205
ZW
3002#endif
3003
3004/* Find the real, Thumb encoded start of a Thumb function. */
3005
4343666d 3006#ifdef OBJ_COFF
c19d1205
ZW
3007static symbolS *
3008find_real_start (symbolS * symbolP)
3009{
3010 char * real_start;
3011 const char * name = S_GET_NAME (symbolP);
3012 symbolS * new_target;
3013
3014 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
3015#define STUB_NAME ".real_start_of"
3016
3017 if (name == NULL)
3018 abort ();
3019
37f6032b
ZW
3020 /* The compiler may generate BL instructions to local labels because
3021 it needs to perform a branch to a far away location. These labels
3022 do not have a corresponding ".real_start_of" label. We check
3023 both for S_IS_LOCAL and for a leading dot, to give a way to bypass
3024 the ".real_start_of" convention for nonlocal branches. */
3025 if (S_IS_LOCAL (symbolP) || name[0] == '.')
c19d1205
ZW
3026 return symbolP;
3027
e1fa0163 3028 real_start = concat (STUB_NAME, name, NULL);
c19d1205 3029 new_target = symbol_find (real_start);
e1fa0163 3030 free (real_start);
c19d1205
ZW
3031
3032 if (new_target == NULL)
3033 {
bd3ba5d1 3034 as_warn (_("Failed to find real start of function: %s\n"), name);
c19d1205
ZW
3035 new_target = symbolP;
3036 }
3037
c19d1205
ZW
3038 return new_target;
3039}
4343666d 3040#endif
c19d1205
ZW
3041
3042static void
3043opcode_select (int width)
3044{
3045 switch (width)
3046 {
3047 case 16:
3048 if (! thumb_mode)
3049 {
e74cfd16 3050 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
c19d1205
ZW
3051 as_bad (_("selected processor does not support THUMB opcodes"));
3052
3053 thumb_mode = 1;
3054 /* No need to force the alignment, since we will have been
3055 coming from ARM mode, which is word-aligned. */
3056 record_alignment (now_seg, 1);
3057 }
c19d1205
ZW
3058 break;
3059
3060 case 32:
3061 if (thumb_mode)
3062 {
e74cfd16 3063 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205
ZW
3064 as_bad (_("selected processor does not support ARM opcodes"));
3065
3066 thumb_mode = 0;
3067
3068 if (!need_pass_2)
3069 frag_align (2, 0, 0);
3070
3071 record_alignment (now_seg, 1);
3072 }
c19d1205
ZW
3073 break;
3074
3075 default:
3076 as_bad (_("invalid instruction size selected (%d)"), width);
3077 }
3078}
3079
3080static void
3081s_arm (int ignore ATTRIBUTE_UNUSED)
3082{
3083 opcode_select (32);
3084 demand_empty_rest_of_line ();
3085}
3086
3087static void
3088s_thumb (int ignore ATTRIBUTE_UNUSED)
3089{
3090 opcode_select (16);
3091 demand_empty_rest_of_line ();
3092}
3093
3094static void
3095s_code (int unused ATTRIBUTE_UNUSED)
3096{
3097 int temp;
3098
3099 temp = get_absolute_expression ();
3100 switch (temp)
3101 {
3102 case 16:
3103 case 32:
3104 opcode_select (temp);
3105 break;
3106
3107 default:
3108 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3109 }
3110}
3111
3112static void
3113s_force_thumb (int ignore ATTRIBUTE_UNUSED)
3114{
3115 /* If we are not already in thumb mode go into it, EVEN if
3116 the target processor does not support thumb instructions.
3117 This is used by gcc/config/arm/lib1funcs.asm for example
3118 to compile interworking support functions even if the
3119 target processor should not support interworking. */
3120 if (! thumb_mode)
3121 {
3122 thumb_mode = 2;
3123 record_alignment (now_seg, 1);
3124 }
3125
3126 demand_empty_rest_of_line ();
3127}
3128
3129static void
3130s_thumb_func (int ignore ATTRIBUTE_UNUSED)
3131{
3132 s_thumb (0);
3133
3134 /* The following label is the name/address of the start of a Thumb function.
3135 We need to know this for the interworking support. */
3136 label_is_thumb_function_name = TRUE;
3137}
3138
3139/* Perform a .set directive, but also mark the alias as
3140 being a thumb function. */
3141
3142static void
3143s_thumb_set (int equiv)
3144{
3145 /* XXX the following is a duplicate of the code for s_set() in read.c
3146 We cannot just call that code as we need to get at the symbol that
3147 is created. */
3148 char * name;
3149 char delim;
3150 char * end_name;
3151 symbolS * symbolP;
3152
3153 /* Especial apologies for the random logic:
3154 This just grew, and could be parsed much more simply!
3155 Dean - in haste. */
d02603dc 3156 delim = get_symbol_name (& name);
c19d1205 3157 end_name = input_line_pointer;
d02603dc 3158 (void) restore_line_pointer (delim);
c19d1205
ZW
3159
3160 if (*input_line_pointer != ',')
3161 {
3162 *end_name = 0;
3163 as_bad (_("expected comma after name \"%s\""), name);
b99bd4ef
NC
3164 *end_name = delim;
3165 ignore_rest_of_line ();
3166 return;
3167 }
3168
3169 input_line_pointer++;
3170 *end_name = 0;
3171
3172 if (name[0] == '.' && name[1] == '\0')
3173 {
3174 /* XXX - this should not happen to .thumb_set. */
3175 abort ();
3176 }
3177
3178 if ((symbolP = symbol_find (name)) == NULL
3179 && (symbolP = md_undefined_symbol (name)) == NULL)
3180 {
3181#ifndef NO_LISTING
3182 /* When doing symbol listings, play games with dummy fragments living
3183 outside the normal fragment chain to record the file and line info
c19d1205 3184 for this symbol. */
b99bd4ef
NC
3185 if (listing & LISTING_SYMBOLS)
3186 {
3187 extern struct list_info_struct * listing_tail;
21d799b5 3188 fragS * dummy_frag = (fragS * ) xmalloc (sizeof (fragS));
b99bd4ef
NC
3189
3190 memset (dummy_frag, 0, sizeof (fragS));
3191 dummy_frag->fr_type = rs_fill;
3192 dummy_frag->line = listing_tail;
3193 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3194 dummy_frag->fr_symbol = symbolP;
3195 }
3196 else
3197#endif
3198 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3199
3200#ifdef OBJ_COFF
3201 /* "set" symbols are local unless otherwise specified. */
3202 SF_SET_LOCAL (symbolP);
3203#endif /* OBJ_COFF */
3204 } /* Make a new symbol. */
3205
3206 symbol_table_insert (symbolP);
3207
3208 * end_name = delim;
3209
3210 if (equiv
3211 && S_IS_DEFINED (symbolP)
3212 && S_GET_SEGMENT (symbolP) != reg_section)
3213 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3214
3215 pseudo_set (symbolP);
3216
3217 demand_empty_rest_of_line ();
3218
c19d1205 3219 /* XXX Now we come to the Thumb specific bit of code. */
b99bd4ef
NC
3220
3221 THUMB_SET_FUNC (symbolP, 1);
3222 ARM_SET_THUMB (symbolP, 1);
3223#if defined OBJ_ELF || defined OBJ_COFF
3224 ARM_SET_INTERWORK (symbolP, support_interwork);
3225#endif
3226}
3227
c19d1205 3228/* Directives: Mode selection. */
b99bd4ef 3229
c19d1205
ZW
3230/* .syntax [unified|divided] - choose the new unified syntax
3231 (same for Arm and Thumb encoding, modulo slight differences in what
3232 can be represented) or the old divergent syntax for each mode. */
b99bd4ef 3233static void
c19d1205 3234s_syntax (int unused ATTRIBUTE_UNUSED)
b99bd4ef 3235{
c19d1205
ZW
3236 char *name, delim;
3237
d02603dc 3238 delim = get_symbol_name (& name);
c19d1205
ZW
3239
3240 if (!strcasecmp (name, "unified"))
3241 unified_syntax = TRUE;
3242 else if (!strcasecmp (name, "divided"))
3243 unified_syntax = FALSE;
3244 else
3245 {
3246 as_bad (_("unrecognized syntax mode \"%s\""), name);
3247 return;
3248 }
d02603dc 3249 (void) restore_line_pointer (delim);
b99bd4ef
NC
3250 demand_empty_rest_of_line ();
3251}
3252
c19d1205
ZW
3253/* Directives: sectioning and alignment. */
3254
c19d1205
ZW
3255static void
3256s_bss (int ignore ATTRIBUTE_UNUSED)
b99bd4ef 3257{
c19d1205
ZW
3258 /* We don't support putting frags in the BSS segment, we fake it by
3259 marking in_bss, then looking at s_skip for clues. */
3260 subseg_set (bss_section, 0);
3261 demand_empty_rest_of_line ();
cd000bff
DJ
3262
3263#ifdef md_elf_section_change_hook
3264 md_elf_section_change_hook ();
3265#endif
c19d1205 3266}
b99bd4ef 3267
c19d1205
ZW
3268static void
3269s_even (int ignore ATTRIBUTE_UNUSED)
3270{
3271 /* Never make frag if expect extra pass. */
3272 if (!need_pass_2)
3273 frag_align (1, 0, 0);
b99bd4ef 3274
c19d1205 3275 record_alignment (now_seg, 1);
b99bd4ef 3276
c19d1205 3277 demand_empty_rest_of_line ();
b99bd4ef
NC
3278}
3279
2e6976a8
DG
3280/* Directives: CodeComposer Studio. */
3281
3282/* .ref (for CodeComposer Studio syntax only). */
3283static void
3284s_ccs_ref (int unused ATTRIBUTE_UNUSED)
3285{
3286 if (codecomposer_syntax)
3287 ignore_rest_of_line ();
3288 else
3289 as_bad (_(".ref pseudo-op only available with -mccs flag."));
3290}
3291
3292/* If name is not NULL, then it is used for marking the beginning of a
2b0f3761 3293 function, whereas if it is NULL then it means the function end. */
2e6976a8
DG
3294static void
3295asmfunc_debug (const char * name)
3296{
3297 static const char * last_name = NULL;
3298
3299 if (name != NULL)
3300 {
3301 gas_assert (last_name == NULL);
3302 last_name = name;
3303
3304 if (debug_type == DEBUG_STABS)
3305 stabs_generate_asm_func (name, name);
3306 }
3307 else
3308 {
3309 gas_assert (last_name != NULL);
3310
3311 if (debug_type == DEBUG_STABS)
3312 stabs_generate_asm_endfunc (last_name, last_name);
3313
3314 last_name = NULL;
3315 }
3316}
3317
3318static void
3319s_ccs_asmfunc (int unused ATTRIBUTE_UNUSED)
3320{
3321 if (codecomposer_syntax)
3322 {
3323 switch (asmfunc_state)
3324 {
3325 case OUTSIDE_ASMFUNC:
3326 asmfunc_state = WAITING_ASMFUNC_NAME;
3327 break;
3328
3329 case WAITING_ASMFUNC_NAME:
3330 as_bad (_(".asmfunc repeated."));
3331 break;
3332
3333 case WAITING_ENDASMFUNC:
3334 as_bad (_(".asmfunc without function."));
3335 break;
3336 }
3337 demand_empty_rest_of_line ();
3338 }
3339 else
3340 as_bad (_(".asmfunc pseudo-op only available with -mccs flag."));
3341}
3342
3343static void
3344s_ccs_endasmfunc (int unused ATTRIBUTE_UNUSED)
3345{
3346 if (codecomposer_syntax)
3347 {
3348 switch (asmfunc_state)
3349 {
3350 case OUTSIDE_ASMFUNC:
3351 as_bad (_(".endasmfunc without a .asmfunc."));
3352 break;
3353
3354 case WAITING_ASMFUNC_NAME:
3355 as_bad (_(".endasmfunc without function."));
3356 break;
3357
3358 case WAITING_ENDASMFUNC:
3359 asmfunc_state = OUTSIDE_ASMFUNC;
3360 asmfunc_debug (NULL);
3361 break;
3362 }
3363 demand_empty_rest_of_line ();
3364 }
3365 else
3366 as_bad (_(".endasmfunc pseudo-op only available with -mccs flag."));
3367}
3368
3369static void
3370s_ccs_def (int name)
3371{
3372 if (codecomposer_syntax)
3373 s_globl (name);
3374 else
3375 as_bad (_(".def pseudo-op only available with -mccs flag."));
3376}
3377
c19d1205 3378/* Directives: Literal pools. */
a737bd4d 3379
c19d1205
ZW
3380static literal_pool *
3381find_literal_pool (void)
a737bd4d 3382{
c19d1205 3383 literal_pool * pool;
a737bd4d 3384
c19d1205 3385 for (pool = list_of_pools; pool != NULL; pool = pool->next)
a737bd4d 3386 {
c19d1205
ZW
3387 if (pool->section == now_seg
3388 && pool->sub_section == now_subseg)
3389 break;
a737bd4d
NC
3390 }
3391
c19d1205 3392 return pool;
a737bd4d
NC
3393}
3394
c19d1205
ZW
3395static literal_pool *
3396find_or_make_literal_pool (void)
a737bd4d 3397{
c19d1205
ZW
3398 /* Next literal pool ID number. */
3399 static unsigned int latest_pool_num = 1;
3400 literal_pool * pool;
a737bd4d 3401
c19d1205 3402 pool = find_literal_pool ();
a737bd4d 3403
c19d1205 3404 if (pool == NULL)
a737bd4d 3405 {
c19d1205 3406 /* Create a new pool. */
325801bd 3407 pool = XNEW (literal_pool);
c19d1205
ZW
3408 if (! pool)
3409 return NULL;
a737bd4d 3410
c19d1205
ZW
3411 pool->next_free_entry = 0;
3412 pool->section = now_seg;
3413 pool->sub_section = now_subseg;
3414 pool->next = list_of_pools;
3415 pool->symbol = NULL;
8335d6aa 3416 pool->alignment = 2;
c19d1205
ZW
3417
3418 /* Add it to the list. */
3419 list_of_pools = pool;
a737bd4d 3420 }
a737bd4d 3421
c19d1205
ZW
3422 /* New pools, and emptied pools, will have a NULL symbol. */
3423 if (pool->symbol == NULL)
a737bd4d 3424 {
c19d1205
ZW
3425 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
3426 (valueT) 0, &zero_address_frag);
3427 pool->id = latest_pool_num ++;
a737bd4d
NC
3428 }
3429
c19d1205
ZW
3430 /* Done. */
3431 return pool;
a737bd4d
NC
3432}
3433
c19d1205 3434/* Add the literal in the global 'inst'
5f4273c7 3435 structure to the relevant literal pool. */
b99bd4ef
NC
3436
3437static int
8335d6aa 3438add_to_lit_pool (unsigned int nbytes)
b99bd4ef 3439{
8335d6aa
JW
3440#define PADDING_SLOT 0x1
3441#define LIT_ENTRY_SIZE_MASK 0xFF
c19d1205 3442 literal_pool * pool;
8335d6aa
JW
3443 unsigned int entry, pool_size = 0;
3444 bfd_boolean padding_slot_p = FALSE;
e56c722b 3445 unsigned imm1 = 0;
8335d6aa
JW
3446 unsigned imm2 = 0;
3447
3448 if (nbytes == 8)
3449 {
3450 imm1 = inst.operands[1].imm;
3451 imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
e2b0ab59 3452 : inst.relocs[0].exp.X_unsigned ? 0
2569ceb0 3453 : ((bfd_int64_t) inst.operands[1].imm) >> 32);
8335d6aa
JW
3454 if (target_big_endian)
3455 {
3456 imm1 = imm2;
3457 imm2 = inst.operands[1].imm;
3458 }
3459 }
b99bd4ef 3460
c19d1205
ZW
3461 pool = find_or_make_literal_pool ();
3462
3463 /* Check if this literal value is already in the pool. */
3464 for (entry = 0; entry < pool->next_free_entry; entry ++)
b99bd4ef 3465 {
8335d6aa
JW
3466 if (nbytes == 4)
3467 {
e2b0ab59
AV
3468 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3469 && (inst.relocs[0].exp.X_op == O_constant)
8335d6aa 3470 && (pool->literals[entry].X_add_number
e2b0ab59 3471 == inst.relocs[0].exp.X_add_number)
8335d6aa
JW
3472 && (pool->literals[entry].X_md == nbytes)
3473 && (pool->literals[entry].X_unsigned
e2b0ab59 3474 == inst.relocs[0].exp.X_unsigned))
8335d6aa
JW
3475 break;
3476
e2b0ab59
AV
3477 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3478 && (inst.relocs[0].exp.X_op == O_symbol)
8335d6aa 3479 && (pool->literals[entry].X_add_number
e2b0ab59 3480 == inst.relocs[0].exp.X_add_number)
8335d6aa 3481 && (pool->literals[entry].X_add_symbol
e2b0ab59 3482 == inst.relocs[0].exp.X_add_symbol)
8335d6aa 3483 && (pool->literals[entry].X_op_symbol
e2b0ab59 3484 == inst.relocs[0].exp.X_op_symbol)
8335d6aa
JW
3485 && (pool->literals[entry].X_md == nbytes))
3486 break;
3487 }
3488 else if ((nbytes == 8)
3489 && !(pool_size & 0x7)
3490 && ((entry + 1) != pool->next_free_entry)
3491 && (pool->literals[entry].X_op == O_constant)
19f2f6a9 3492 && (pool->literals[entry].X_add_number == (offsetT) imm1)
8335d6aa 3493 && (pool->literals[entry].X_unsigned
e2b0ab59 3494 == inst.relocs[0].exp.X_unsigned)
8335d6aa 3495 && (pool->literals[entry + 1].X_op == O_constant)
19f2f6a9 3496 && (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
8335d6aa 3497 && (pool->literals[entry + 1].X_unsigned
e2b0ab59 3498 == inst.relocs[0].exp.X_unsigned))
c19d1205
ZW
3499 break;
3500
8335d6aa
JW
3501 padding_slot_p = ((pool->literals[entry].X_md >> 8) == PADDING_SLOT);
3502 if (padding_slot_p && (nbytes == 4))
c19d1205 3503 break;
8335d6aa
JW
3504
3505 pool_size += 4;
b99bd4ef
NC
3506 }
3507
c19d1205
ZW
3508 /* Do we need to create a new entry? */
3509 if (entry == pool->next_free_entry)
3510 {
3511 if (entry >= MAX_LITERAL_POOL_SIZE)
3512 {
3513 inst.error = _("literal pool overflow");
3514 return FAIL;
3515 }
3516
8335d6aa
JW
3517 if (nbytes == 8)
3518 {
3519 /* For 8-byte entries, we align to an 8-byte boundary,
3520 and split it into two 4-byte entries, because on 32-bit
3521 host, 8-byte constants are treated as big num, thus
3522 saved in "generic_bignum" which will be overwritten
3523 by later assignments.
3524
3525 We also need to make sure there is enough space for
3526 the split.
3527
3528 We also check to make sure the literal operand is a
3529 constant number. */
e2b0ab59
AV
3530 if (!(inst.relocs[0].exp.X_op == O_constant
3531 || inst.relocs[0].exp.X_op == O_big))
8335d6aa
JW
3532 {
3533 inst.error = _("invalid type for literal pool");
3534 return FAIL;
3535 }
3536 else if (pool_size & 0x7)
3537 {
3538 if ((entry + 2) >= MAX_LITERAL_POOL_SIZE)
3539 {
3540 inst.error = _("literal pool overflow");
3541 return FAIL;
3542 }
3543
e2b0ab59 3544 pool->literals[entry] = inst.relocs[0].exp;
a6684f0d 3545 pool->literals[entry].X_op = O_constant;
8335d6aa
JW
3546 pool->literals[entry].X_add_number = 0;
3547 pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
3548 pool->next_free_entry += 1;
3549 pool_size += 4;
3550 }
3551 else if ((entry + 1) >= MAX_LITERAL_POOL_SIZE)
3552 {
3553 inst.error = _("literal pool overflow");
3554 return FAIL;
3555 }
3556
e2b0ab59 3557 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3558 pool->literals[entry].X_op = O_constant;
3559 pool->literals[entry].X_add_number = imm1;
e2b0ab59 3560 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa 3561 pool->literals[entry++].X_md = 4;
e2b0ab59 3562 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3563 pool->literals[entry].X_op = O_constant;
3564 pool->literals[entry].X_add_number = imm2;
e2b0ab59 3565 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa
JW
3566 pool->literals[entry].X_md = 4;
3567 pool->alignment = 3;
3568 pool->next_free_entry += 1;
3569 }
3570 else
3571 {
e2b0ab59 3572 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3573 pool->literals[entry].X_md = 4;
3574 }
3575
a8040cf2
NC
3576#ifdef OBJ_ELF
3577 /* PR ld/12974: Record the location of the first source line to reference
3578 this entry in the literal pool. If it turns out during linking that the
3579 symbol does not exist we will be able to give an accurate line number for
3580 the (first use of the) missing reference. */
3581 if (debug_type == DEBUG_DWARF2)
3582 dwarf2_where (pool->locs + entry);
3583#endif
c19d1205
ZW
3584 pool->next_free_entry += 1;
3585 }
8335d6aa
JW
3586 else if (padding_slot_p)
3587 {
e2b0ab59 3588 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3589 pool->literals[entry].X_md = nbytes;
3590 }
b99bd4ef 3591
e2b0ab59
AV
3592 inst.relocs[0].exp.X_op = O_symbol;
3593 inst.relocs[0].exp.X_add_number = pool_size;
3594 inst.relocs[0].exp.X_add_symbol = pool->symbol;
b99bd4ef 3595
c19d1205 3596 return SUCCESS;
b99bd4ef
NC
3597}
3598
2e6976a8 3599bfd_boolean
2e57ce7b 3600tc_start_label_without_colon (void)
2e6976a8
DG
3601{
3602 bfd_boolean ret = TRUE;
3603
3604 if (codecomposer_syntax && asmfunc_state == WAITING_ASMFUNC_NAME)
3605 {
2e57ce7b 3606 const char *label = input_line_pointer;
2e6976a8
DG
3607
3608 while (!is_end_of_line[(int) label[-1]])
3609 --label;
3610
3611 if (*label == '.')
3612 {
3613 as_bad (_("Invalid label '%s'"), label);
3614 ret = FALSE;
3615 }
3616
3617 asmfunc_debug (label);
3618
3619 asmfunc_state = WAITING_ENDASMFUNC;
3620 }
3621
3622 return ret;
3623}
3624
c19d1205 3625/* Can't use symbol_new here, so have to create a symbol and then at
33eaf5de 3626 a later date assign it a value. That's what these functions do. */
e16bb312 3627
c19d1205
ZW
3628static void
3629symbol_locate (symbolS * symbolP,
3630 const char * name, /* It is copied, the caller can modify. */
3631 segT segment, /* Segment identifier (SEG_<something>). */
3632 valueT valu, /* Symbol value. */
3633 fragS * frag) /* Associated fragment. */
3634{
e57e6ddc 3635 size_t name_length;
c19d1205 3636 char * preserved_copy_of_name;
e16bb312 3637
c19d1205
ZW
3638 name_length = strlen (name) + 1; /* +1 for \0. */
3639 obstack_grow (&notes, name, name_length);
21d799b5 3640 preserved_copy_of_name = (char *) obstack_finish (&notes);
e16bb312 3641
c19d1205
ZW
3642#ifdef tc_canonicalize_symbol_name
3643 preserved_copy_of_name =
3644 tc_canonicalize_symbol_name (preserved_copy_of_name);
3645#endif
b99bd4ef 3646
c19d1205 3647 S_SET_NAME (symbolP, preserved_copy_of_name);
b99bd4ef 3648
c19d1205
ZW
3649 S_SET_SEGMENT (symbolP, segment);
3650 S_SET_VALUE (symbolP, valu);
3651 symbol_clear_list_pointers (symbolP);
b99bd4ef 3652
c19d1205 3653 symbol_set_frag (symbolP, frag);
b99bd4ef 3654
c19d1205
ZW
3655 /* Link to end of symbol chain. */
3656 {
3657 extern int symbol_table_frozen;
b99bd4ef 3658
c19d1205
ZW
3659 if (symbol_table_frozen)
3660 abort ();
3661 }
b99bd4ef 3662
c19d1205 3663 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
b99bd4ef 3664
c19d1205 3665 obj_symbol_new_hook (symbolP);
b99bd4ef 3666
c19d1205
ZW
3667#ifdef tc_symbol_new_hook
3668 tc_symbol_new_hook (symbolP);
3669#endif
3670
3671#ifdef DEBUG_SYMS
3672 verify_symbol_chain (symbol_rootP, symbol_lastP);
3673#endif /* DEBUG_SYMS */
b99bd4ef
NC
3674}
3675
c19d1205
ZW
3676static void
3677s_ltorg (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 3678{
c19d1205
ZW
3679 unsigned int entry;
3680 literal_pool * pool;
3681 char sym_name[20];
b99bd4ef 3682
c19d1205
ZW
3683 pool = find_literal_pool ();
3684 if (pool == NULL
3685 || pool->symbol == NULL
3686 || pool->next_free_entry == 0)
3687 return;
b99bd4ef 3688
c19d1205
ZW
3689 /* Align pool as you have word accesses.
3690 Only make a frag if we have to. */
3691 if (!need_pass_2)
8335d6aa 3692 frag_align (pool->alignment, 0, 0);
b99bd4ef 3693
c19d1205 3694 record_alignment (now_seg, 2);
b99bd4ef 3695
aaca88ef 3696#ifdef OBJ_ELF
47fc6e36
WN
3697 seg_info (now_seg)->tc_segment_info_data.mapstate = MAP_DATA;
3698 make_mapping_symbol (MAP_DATA, (valueT) frag_now_fix (), frag_now);
aaca88ef 3699#endif
c19d1205 3700 sprintf (sym_name, "$$lit_\002%x", pool->id);
b99bd4ef 3701
c19d1205
ZW
3702 symbol_locate (pool->symbol, sym_name, now_seg,
3703 (valueT) frag_now_fix (), frag_now);
3704 symbol_table_insert (pool->symbol);
b99bd4ef 3705
c19d1205 3706 ARM_SET_THUMB (pool->symbol, thumb_mode);
b99bd4ef 3707
c19d1205
ZW
3708#if defined OBJ_COFF || defined OBJ_ELF
3709 ARM_SET_INTERWORK (pool->symbol, support_interwork);
3710#endif
6c43fab6 3711
c19d1205 3712 for (entry = 0; entry < pool->next_free_entry; entry ++)
a8040cf2
NC
3713 {
3714#ifdef OBJ_ELF
3715 if (debug_type == DEBUG_DWARF2)
3716 dwarf2_gen_line_info (frag_now_fix (), pool->locs + entry);
3717#endif
3718 /* First output the expression in the instruction to the pool. */
8335d6aa
JW
3719 emit_expr (&(pool->literals[entry]),
3720 pool->literals[entry].X_md & LIT_ENTRY_SIZE_MASK);
a8040cf2 3721 }
b99bd4ef 3722
c19d1205
ZW
3723 /* Mark the pool as empty. */
3724 pool->next_free_entry = 0;
3725 pool->symbol = NULL;
b99bd4ef
NC
3726}
3727
c19d1205
ZW
3728#ifdef OBJ_ELF
3729/* Forward declarations for functions below, in the MD interface
3730 section. */
3731static void fix_new_arm (fragS *, int, short, expressionS *, int, int);
3732static valueT create_unwind_entry (int);
3733static void start_unwind_section (const segT, int);
3734static void add_unwind_opcode (valueT, int);
3735static void flush_pending_unwind (void);
b99bd4ef 3736
c19d1205 3737/* Directives: Data. */
b99bd4ef 3738
c19d1205
ZW
3739static void
3740s_arm_elf_cons (int nbytes)
3741{
3742 expressionS exp;
b99bd4ef 3743
c19d1205
ZW
3744#ifdef md_flush_pending_output
3745 md_flush_pending_output ();
3746#endif
b99bd4ef 3747
c19d1205 3748 if (is_it_end_of_statement ())
b99bd4ef 3749 {
c19d1205
ZW
3750 demand_empty_rest_of_line ();
3751 return;
b99bd4ef
NC
3752 }
3753
c19d1205
ZW
3754#ifdef md_cons_align
3755 md_cons_align (nbytes);
3756#endif
b99bd4ef 3757
c19d1205
ZW
3758 mapping_state (MAP_DATA);
3759 do
b99bd4ef 3760 {
c19d1205
ZW
3761 int reloc;
3762 char *base = input_line_pointer;
b99bd4ef 3763
c19d1205 3764 expression (& exp);
b99bd4ef 3765
c19d1205
ZW
3766 if (exp.X_op != O_symbol)
3767 emit_expr (&exp, (unsigned int) nbytes);
3768 else
3769 {
3770 char *before_reloc = input_line_pointer;
3771 reloc = parse_reloc (&input_line_pointer);
3772 if (reloc == -1)
3773 {
3774 as_bad (_("unrecognized relocation suffix"));
3775 ignore_rest_of_line ();
3776 return;
3777 }
3778 else if (reloc == BFD_RELOC_UNUSED)
3779 emit_expr (&exp, (unsigned int) nbytes);
3780 else
3781 {
21d799b5 3782 reloc_howto_type *howto = (reloc_howto_type *)
477330fc
RM
3783 bfd_reloc_type_lookup (stdoutput,
3784 (bfd_reloc_code_real_type) reloc);
c19d1205 3785 int size = bfd_get_reloc_size (howto);
b99bd4ef 3786
2fc8bdac
ZW
3787 if (reloc == BFD_RELOC_ARM_PLT32)
3788 {
3789 as_bad (_("(plt) is only valid on branch targets"));
3790 reloc = BFD_RELOC_UNUSED;
3791 size = 0;
3792 }
3793
c19d1205 3794 if (size > nbytes)
992a06ee
AM
3795 as_bad (ngettext ("%s relocations do not fit in %d byte",
3796 "%s relocations do not fit in %d bytes",
3797 nbytes),
c19d1205
ZW
3798 howto->name, nbytes);
3799 else
3800 {
3801 /* We've parsed an expression stopping at O_symbol.
3802 But there may be more expression left now that we
3803 have parsed the relocation marker. Parse it again.
3804 XXX Surely there is a cleaner way to do this. */
3805 char *p = input_line_pointer;
3806 int offset;
325801bd 3807 char *save_buf = XNEWVEC (char, input_line_pointer - base);
e1fa0163 3808
c19d1205
ZW
3809 memcpy (save_buf, base, input_line_pointer - base);
3810 memmove (base + (input_line_pointer - before_reloc),
3811 base, before_reloc - base);
3812
3813 input_line_pointer = base + (input_line_pointer-before_reloc);
3814 expression (&exp);
3815 memcpy (base, save_buf, p - base);
3816
3817 offset = nbytes - size;
4b1a927e
AM
3818 p = frag_more (nbytes);
3819 memset (p, 0, nbytes);
c19d1205 3820 fix_new_exp (frag_now, p - frag_now->fr_literal + offset,
21d799b5 3821 size, &exp, 0, (enum bfd_reloc_code_real) reloc);
e1fa0163 3822 free (save_buf);
c19d1205
ZW
3823 }
3824 }
3825 }
b99bd4ef 3826 }
c19d1205 3827 while (*input_line_pointer++ == ',');
b99bd4ef 3828
c19d1205
ZW
3829 /* Put terminator back into stream. */
3830 input_line_pointer --;
3831 demand_empty_rest_of_line ();
b99bd4ef
NC
3832}
3833
c921be7d
NC
3834/* Emit an expression containing a 32-bit thumb instruction.
3835 Implementation based on put_thumb32_insn. */
3836
3837static void
3838emit_thumb32_expr (expressionS * exp)
3839{
3840 expressionS exp_high = *exp;
3841
3842 exp_high.X_add_number = (unsigned long)exp_high.X_add_number >> 16;
3843 emit_expr (& exp_high, (unsigned int) THUMB_SIZE);
3844 exp->X_add_number &= 0xffff;
3845 emit_expr (exp, (unsigned int) THUMB_SIZE);
3846}
3847
3848/* Guess the instruction size based on the opcode. */
3849
3850static int
3851thumb_insn_size (int opcode)
3852{
3853 if ((unsigned int) opcode < 0xe800u)
3854 return 2;
3855 else if ((unsigned int) opcode >= 0xe8000000u)
3856 return 4;
3857 else
3858 return 0;
3859}
3860
3861static bfd_boolean
3862emit_insn (expressionS *exp, int nbytes)
3863{
3864 int size = 0;
3865
3866 if (exp->X_op == O_constant)
3867 {
3868 size = nbytes;
3869
3870 if (size == 0)
3871 size = thumb_insn_size (exp->X_add_number);
3872
3873 if (size != 0)
3874 {
3875 if (size == 2 && (unsigned int)exp->X_add_number > 0xffffu)
3876 {
3877 as_bad (_(".inst.n operand too big. "\
3878 "Use .inst.w instead"));
3879 size = 0;
3880 }
3881 else
3882 {
5ee91343
AV
3883 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
3884 set_pred_insn_type_nonvoid (OUTSIDE_PRED_INSN, 0);
c921be7d 3885 else
5ee91343 3886 set_pred_insn_type_nonvoid (NEUTRAL_IT_INSN, 0);
c921be7d
NC
3887
3888 if (thumb_mode && (size > THUMB_SIZE) && !target_big_endian)
3889 emit_thumb32_expr (exp);
3890 else
3891 emit_expr (exp, (unsigned int) size);
3892
3893 it_fsm_post_encode ();
3894 }
3895 }
3896 else
3897 as_bad (_("cannot determine Thumb instruction size. " \
3898 "Use .inst.n/.inst.w instead"));
3899 }
3900 else
3901 as_bad (_("constant expression required"));
3902
3903 return (size != 0);
3904}
3905
3906/* Like s_arm_elf_cons but do not use md_cons_align and
3907 set the mapping state to MAP_ARM/MAP_THUMB. */
3908
3909static void
3910s_arm_elf_inst (int nbytes)
3911{
3912 if (is_it_end_of_statement ())
3913 {
3914 demand_empty_rest_of_line ();
3915 return;
3916 }
3917
3918 /* Calling mapping_state () here will not change ARM/THUMB,
3919 but will ensure not to be in DATA state. */
3920
3921 if (thumb_mode)
3922 mapping_state (MAP_THUMB);
3923 else
3924 {
3925 if (nbytes != 0)
3926 {
3927 as_bad (_("width suffixes are invalid in ARM mode"));
3928 ignore_rest_of_line ();
3929 return;
3930 }
3931
3932 nbytes = 4;
3933
3934 mapping_state (MAP_ARM);
3935 }
3936
3937 do
3938 {
3939 expressionS exp;
3940
3941 expression (& exp);
3942
3943 if (! emit_insn (& exp, nbytes))
3944 {
3945 ignore_rest_of_line ();
3946 return;
3947 }
3948 }
3949 while (*input_line_pointer++ == ',');
3950
3951 /* Put terminator back into stream. */
3952 input_line_pointer --;
3953 demand_empty_rest_of_line ();
3954}
b99bd4ef 3955
c19d1205 3956/* Parse a .rel31 directive. */
b99bd4ef 3957
c19d1205
ZW
3958static void
3959s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
3960{
3961 expressionS exp;
3962 char *p;
3963 valueT highbit;
b99bd4ef 3964
c19d1205
ZW
3965 highbit = 0;
3966 if (*input_line_pointer == '1')
3967 highbit = 0x80000000;
3968 else if (*input_line_pointer != '0')
3969 as_bad (_("expected 0 or 1"));
b99bd4ef 3970
c19d1205
ZW
3971 input_line_pointer++;
3972 if (*input_line_pointer != ',')
3973 as_bad (_("missing comma"));
3974 input_line_pointer++;
b99bd4ef 3975
c19d1205
ZW
3976#ifdef md_flush_pending_output
3977 md_flush_pending_output ();
3978#endif
b99bd4ef 3979
c19d1205
ZW
3980#ifdef md_cons_align
3981 md_cons_align (4);
3982#endif
b99bd4ef 3983
c19d1205 3984 mapping_state (MAP_DATA);
b99bd4ef 3985
c19d1205 3986 expression (&exp);
b99bd4ef 3987
c19d1205
ZW
3988 p = frag_more (4);
3989 md_number_to_chars (p, highbit, 4);
3990 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
3991 BFD_RELOC_ARM_PREL31);
b99bd4ef 3992
c19d1205 3993 demand_empty_rest_of_line ();
b99bd4ef
NC
3994}
3995
c19d1205 3996/* Directives: AEABI stack-unwind tables. */
b99bd4ef 3997
c19d1205 3998/* Parse an unwind_fnstart directive. Simply records the current location. */
b99bd4ef 3999
c19d1205
ZW
4000static void
4001s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
4002{
4003 demand_empty_rest_of_line ();
921e5f0a
PB
4004 if (unwind.proc_start)
4005 {
c921be7d 4006 as_bad (_("duplicate .fnstart directive"));
921e5f0a
PB
4007 return;
4008 }
4009
c19d1205
ZW
4010 /* Mark the start of the function. */
4011 unwind.proc_start = expr_build_dot ();
b99bd4ef 4012
c19d1205
ZW
4013 /* Reset the rest of the unwind info. */
4014 unwind.opcode_count = 0;
4015 unwind.table_entry = NULL;
4016 unwind.personality_routine = NULL;
4017 unwind.personality_index = -1;
4018 unwind.frame_size = 0;
4019 unwind.fp_offset = 0;
fdfde340 4020 unwind.fp_reg = REG_SP;
c19d1205
ZW
4021 unwind.fp_used = 0;
4022 unwind.sp_restored = 0;
4023}
b99bd4ef 4024
b99bd4ef 4025
c19d1205
ZW
4026/* Parse a handlerdata directive. Creates the exception handling table entry
4027 for the function. */
b99bd4ef 4028
c19d1205
ZW
4029static void
4030s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
4031{
4032 demand_empty_rest_of_line ();
921e5f0a 4033 if (!unwind.proc_start)
c921be7d 4034 as_bad (MISSING_FNSTART);
921e5f0a 4035
c19d1205 4036 if (unwind.table_entry)
6decc662 4037 as_bad (_("duplicate .handlerdata directive"));
f02232aa 4038
c19d1205
ZW
4039 create_unwind_entry (1);
4040}
a737bd4d 4041
c19d1205 4042/* Parse an unwind_fnend directive. Generates the index table entry. */
b99bd4ef 4043
c19d1205
ZW
4044static void
4045s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
4046{
4047 long where;
4048 char *ptr;
4049 valueT val;
940b5ce0 4050 unsigned int marked_pr_dependency;
f02232aa 4051
c19d1205 4052 demand_empty_rest_of_line ();
f02232aa 4053
921e5f0a
PB
4054 if (!unwind.proc_start)
4055 {
c921be7d 4056 as_bad (_(".fnend directive without .fnstart"));
921e5f0a
PB
4057 return;
4058 }
4059
c19d1205
ZW
4060 /* Add eh table entry. */
4061 if (unwind.table_entry == NULL)
4062 val = create_unwind_entry (0);
4063 else
4064 val = 0;
f02232aa 4065
c19d1205
ZW
4066 /* Add index table entry. This is two words. */
4067 start_unwind_section (unwind.saved_seg, 1);
4068 frag_align (2, 0, 0);
4069 record_alignment (now_seg, 2);
b99bd4ef 4070
c19d1205 4071 ptr = frag_more (8);
5011093d 4072 memset (ptr, 0, 8);
c19d1205 4073 where = frag_now_fix () - 8;
f02232aa 4074
c19d1205
ZW
4075 /* Self relative offset of the function start. */
4076 fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
4077 BFD_RELOC_ARM_PREL31);
f02232aa 4078
c19d1205
ZW
4079 /* Indicate dependency on EHABI-defined personality routines to the
4080 linker, if it hasn't been done already. */
940b5ce0
DJ
4081 marked_pr_dependency
4082 = seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency;
c19d1205
ZW
4083 if (unwind.personality_index >= 0 && unwind.personality_index < 3
4084 && !(marked_pr_dependency & (1 << unwind.personality_index)))
4085 {
5f4273c7
NC
4086 static const char *const name[] =
4087 {
4088 "__aeabi_unwind_cpp_pr0",
4089 "__aeabi_unwind_cpp_pr1",
4090 "__aeabi_unwind_cpp_pr2"
4091 };
c19d1205
ZW
4092 symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
4093 fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
c19d1205 4094 seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
940b5ce0 4095 |= 1 << unwind.personality_index;
c19d1205 4096 }
f02232aa 4097
c19d1205
ZW
4098 if (val)
4099 /* Inline exception table entry. */
4100 md_number_to_chars (ptr + 4, val, 4);
4101 else
4102 /* Self relative offset of the table entry. */
4103 fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
4104 BFD_RELOC_ARM_PREL31);
f02232aa 4105
c19d1205
ZW
4106 /* Restore the original section. */
4107 subseg_set (unwind.saved_seg, unwind.saved_subseg);
921e5f0a
PB
4108
4109 unwind.proc_start = NULL;
c19d1205 4110}
f02232aa 4111
f02232aa 4112
c19d1205 4113/* Parse an unwind_cantunwind directive. */
b99bd4ef 4114
c19d1205
ZW
4115static void
4116s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
4117{
4118 demand_empty_rest_of_line ();
921e5f0a 4119 if (!unwind.proc_start)
c921be7d 4120 as_bad (MISSING_FNSTART);
921e5f0a 4121
c19d1205
ZW
4122 if (unwind.personality_routine || unwind.personality_index != -1)
4123 as_bad (_("personality routine specified for cantunwind frame"));
b99bd4ef 4124
c19d1205
ZW
4125 unwind.personality_index = -2;
4126}
b99bd4ef 4127
b99bd4ef 4128
c19d1205 4129/* Parse a personalityindex directive. */
b99bd4ef 4130
c19d1205
ZW
4131static void
4132s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
4133{
4134 expressionS exp;
b99bd4ef 4135
921e5f0a 4136 if (!unwind.proc_start)
c921be7d 4137 as_bad (MISSING_FNSTART);
921e5f0a 4138
c19d1205
ZW
4139 if (unwind.personality_routine || unwind.personality_index != -1)
4140 as_bad (_("duplicate .personalityindex directive"));
b99bd4ef 4141
c19d1205 4142 expression (&exp);
b99bd4ef 4143
c19d1205
ZW
4144 if (exp.X_op != O_constant
4145 || exp.X_add_number < 0 || exp.X_add_number > 15)
b99bd4ef 4146 {
c19d1205
ZW
4147 as_bad (_("bad personality routine number"));
4148 ignore_rest_of_line ();
4149 return;
b99bd4ef
NC
4150 }
4151
c19d1205 4152 unwind.personality_index = exp.X_add_number;
b99bd4ef 4153
c19d1205
ZW
4154 demand_empty_rest_of_line ();
4155}
e16bb312 4156
e16bb312 4157
c19d1205 4158/* Parse a personality directive. */
e16bb312 4159
c19d1205
ZW
4160static void
4161s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
4162{
4163 char *name, *p, c;
a737bd4d 4164
921e5f0a 4165 if (!unwind.proc_start)
c921be7d 4166 as_bad (MISSING_FNSTART);
921e5f0a 4167
c19d1205
ZW
4168 if (unwind.personality_routine || unwind.personality_index != -1)
4169 as_bad (_("duplicate .personality directive"));
a737bd4d 4170
d02603dc 4171 c = get_symbol_name (& name);
c19d1205 4172 p = input_line_pointer;
d02603dc
NC
4173 if (c == '"')
4174 ++ input_line_pointer;
c19d1205
ZW
4175 unwind.personality_routine = symbol_find_or_make (name);
4176 *p = c;
4177 demand_empty_rest_of_line ();
4178}
e16bb312 4179
e16bb312 4180
c19d1205 4181/* Parse a directive saving core registers. */
e16bb312 4182
c19d1205
ZW
4183static void
4184s_arm_unwind_save_core (void)
e16bb312 4185{
c19d1205
ZW
4186 valueT op;
4187 long range;
4188 int n;
e16bb312 4189
4b5a202f 4190 range = parse_reg_list (&input_line_pointer, REGLIST_RN);
c19d1205 4191 if (range == FAIL)
e16bb312 4192 {
c19d1205
ZW
4193 as_bad (_("expected register list"));
4194 ignore_rest_of_line ();
4195 return;
4196 }
e16bb312 4197
c19d1205 4198 demand_empty_rest_of_line ();
e16bb312 4199
c19d1205
ZW
4200 /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
4201 into .unwind_save {..., sp...}. We aren't bothered about the value of
4202 ip because it is clobbered by calls. */
4203 if (unwind.sp_restored && unwind.fp_reg == 12
4204 && (range & 0x3000) == 0x1000)
4205 {
4206 unwind.opcode_count--;
4207 unwind.sp_restored = 0;
4208 range = (range | 0x2000) & ~0x1000;
4209 unwind.pending_offset = 0;
4210 }
e16bb312 4211
01ae4198
DJ
4212 /* Pop r4-r15. */
4213 if (range & 0xfff0)
c19d1205 4214 {
01ae4198
DJ
4215 /* See if we can use the short opcodes. These pop a block of up to 8
4216 registers starting with r4, plus maybe r14. */
4217 for (n = 0; n < 8; n++)
4218 {
4219 /* Break at the first non-saved register. */
4220 if ((range & (1 << (n + 4))) == 0)
4221 break;
4222 }
4223 /* See if there are any other bits set. */
4224 if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
4225 {
4226 /* Use the long form. */
4227 op = 0x8000 | ((range >> 4) & 0xfff);
4228 add_unwind_opcode (op, 2);
4229 }
0dd132b6 4230 else
01ae4198
DJ
4231 {
4232 /* Use the short form. */
4233 if (range & 0x4000)
4234 op = 0xa8; /* Pop r14. */
4235 else
4236 op = 0xa0; /* Do not pop r14. */
4237 op |= (n - 1);
4238 add_unwind_opcode (op, 1);
4239 }
c19d1205 4240 }
0dd132b6 4241
c19d1205
ZW
4242 /* Pop r0-r3. */
4243 if (range & 0xf)
4244 {
4245 op = 0xb100 | (range & 0xf);
4246 add_unwind_opcode (op, 2);
0dd132b6
NC
4247 }
4248
c19d1205
ZW
4249 /* Record the number of bytes pushed. */
4250 for (n = 0; n < 16; n++)
4251 {
4252 if (range & (1 << n))
4253 unwind.frame_size += 4;
4254 }
0dd132b6
NC
4255}
4256
c19d1205
ZW
4257
4258/* Parse a directive saving FPA registers. */
b99bd4ef
NC
4259
4260static void
c19d1205 4261s_arm_unwind_save_fpa (int reg)
b99bd4ef 4262{
c19d1205
ZW
4263 expressionS exp;
4264 int num_regs;
4265 valueT op;
b99bd4ef 4266
c19d1205
ZW
4267 /* Get Number of registers to transfer. */
4268 if (skip_past_comma (&input_line_pointer) != FAIL)
4269 expression (&exp);
4270 else
4271 exp.X_op = O_illegal;
b99bd4ef 4272
c19d1205 4273 if (exp.X_op != O_constant)
b99bd4ef 4274 {
c19d1205
ZW
4275 as_bad (_("expected , <constant>"));
4276 ignore_rest_of_line ();
b99bd4ef
NC
4277 return;
4278 }
4279
c19d1205
ZW
4280 num_regs = exp.X_add_number;
4281
4282 if (num_regs < 1 || num_regs > 4)
b99bd4ef 4283 {
c19d1205
ZW
4284 as_bad (_("number of registers must be in the range [1:4]"));
4285 ignore_rest_of_line ();
b99bd4ef
NC
4286 return;
4287 }
4288
c19d1205 4289 demand_empty_rest_of_line ();
b99bd4ef 4290
c19d1205
ZW
4291 if (reg == 4)
4292 {
4293 /* Short form. */
4294 op = 0xb4 | (num_regs - 1);
4295 add_unwind_opcode (op, 1);
4296 }
b99bd4ef
NC
4297 else
4298 {
c19d1205
ZW
4299 /* Long form. */
4300 op = 0xc800 | (reg << 4) | (num_regs - 1);
4301 add_unwind_opcode (op, 2);
b99bd4ef 4302 }
c19d1205 4303 unwind.frame_size += num_regs * 12;
b99bd4ef
NC
4304}
4305
c19d1205 4306
fa073d69
MS
4307/* Parse a directive saving VFP registers for ARMv6 and above. */
4308
4309static void
4310s_arm_unwind_save_vfp_armv6 (void)
4311{
4312 int count;
4313 unsigned int start;
4314 valueT op;
4315 int num_vfpv3_regs = 0;
4316 int num_regs_below_16;
efd6b359 4317 bfd_boolean partial_match;
fa073d69 4318
efd6b359
AV
4319 count = parse_vfp_reg_list (&input_line_pointer, &start, REGLIST_VFP_D,
4320 &partial_match);
fa073d69
MS
4321 if (count == FAIL)
4322 {
4323 as_bad (_("expected register list"));
4324 ignore_rest_of_line ();
4325 return;
4326 }
4327
4328 demand_empty_rest_of_line ();
4329
4330 /* We always generate FSTMD/FLDMD-style unwinding opcodes (rather
4331 than FSTMX/FLDMX-style ones). */
4332
4333 /* Generate opcode for (VFPv3) registers numbered in the range 16 .. 31. */
4334 if (start >= 16)
4335 num_vfpv3_regs = count;
4336 else if (start + count > 16)
4337 num_vfpv3_regs = start + count - 16;
4338
4339 if (num_vfpv3_regs > 0)
4340 {
4341 int start_offset = start > 16 ? start - 16 : 0;
4342 op = 0xc800 | (start_offset << 4) | (num_vfpv3_regs - 1);
4343 add_unwind_opcode (op, 2);
4344 }
4345
4346 /* Generate opcode for registers numbered in the range 0 .. 15. */
4347 num_regs_below_16 = num_vfpv3_regs > 0 ? 16 - (int) start : count;
9c2799c2 4348 gas_assert (num_regs_below_16 + num_vfpv3_regs == count);
fa073d69
MS
4349 if (num_regs_below_16 > 0)
4350 {
4351 op = 0xc900 | (start << 4) | (num_regs_below_16 - 1);
4352 add_unwind_opcode (op, 2);
4353 }
4354
4355 unwind.frame_size += count * 8;
4356}
4357
4358
4359/* Parse a directive saving VFP registers for pre-ARMv6. */
b99bd4ef
NC
4360
4361static void
c19d1205 4362s_arm_unwind_save_vfp (void)
b99bd4ef 4363{
c19d1205 4364 int count;
ca3f61f7 4365 unsigned int reg;
c19d1205 4366 valueT op;
efd6b359 4367 bfd_boolean partial_match;
b99bd4ef 4368
efd6b359
AV
4369 count = parse_vfp_reg_list (&input_line_pointer, &reg, REGLIST_VFP_D,
4370 &partial_match);
c19d1205 4371 if (count == FAIL)
b99bd4ef 4372 {
c19d1205
ZW
4373 as_bad (_("expected register list"));
4374 ignore_rest_of_line ();
b99bd4ef
NC
4375 return;
4376 }
4377
c19d1205 4378 demand_empty_rest_of_line ();
b99bd4ef 4379
c19d1205 4380 if (reg == 8)
b99bd4ef 4381 {
c19d1205
ZW
4382 /* Short form. */
4383 op = 0xb8 | (count - 1);
4384 add_unwind_opcode (op, 1);
b99bd4ef 4385 }
c19d1205 4386 else
b99bd4ef 4387 {
c19d1205
ZW
4388 /* Long form. */
4389 op = 0xb300 | (reg << 4) | (count - 1);
4390 add_unwind_opcode (op, 2);
b99bd4ef 4391 }
c19d1205
ZW
4392 unwind.frame_size += count * 8 + 4;
4393}
b99bd4ef 4394
b99bd4ef 4395
c19d1205
ZW
4396/* Parse a directive saving iWMMXt data registers. */
4397
4398static void
4399s_arm_unwind_save_mmxwr (void)
4400{
4401 int reg;
4402 int hi_reg;
4403 int i;
4404 unsigned mask = 0;
4405 valueT op;
b99bd4ef 4406
c19d1205
ZW
4407 if (*input_line_pointer == '{')
4408 input_line_pointer++;
b99bd4ef 4409
c19d1205 4410 do
b99bd4ef 4411 {
dcbf9037 4412 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
b99bd4ef 4413
c19d1205 4414 if (reg == FAIL)
b99bd4ef 4415 {
9b7132d3 4416 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205 4417 goto error;
b99bd4ef
NC
4418 }
4419
c19d1205
ZW
4420 if (mask >> reg)
4421 as_tsktsk (_("register list not in ascending order"));
4422 mask |= 1 << reg;
b99bd4ef 4423
c19d1205
ZW
4424 if (*input_line_pointer == '-')
4425 {
4426 input_line_pointer++;
dcbf9037 4427 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
c19d1205
ZW
4428 if (hi_reg == FAIL)
4429 {
9b7132d3 4430 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205
ZW
4431 goto error;
4432 }
4433 else if (reg >= hi_reg)
4434 {
4435 as_bad (_("bad register range"));
4436 goto error;
4437 }
4438 for (; reg < hi_reg; reg++)
4439 mask |= 1 << reg;
4440 }
4441 }
4442 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4443
d996d970 4444 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4445
c19d1205 4446 demand_empty_rest_of_line ();
b99bd4ef 4447
708587a4 4448 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4449 the list. */
4450 flush_pending_unwind ();
b99bd4ef 4451
c19d1205 4452 for (i = 0; i < 16; i++)
b99bd4ef 4453 {
c19d1205
ZW
4454 if (mask & (1 << i))
4455 unwind.frame_size += 8;
b99bd4ef
NC
4456 }
4457
c19d1205
ZW
4458 /* Attempt to combine with a previous opcode. We do this because gcc
4459 likes to output separate unwind directives for a single block of
4460 registers. */
4461 if (unwind.opcode_count > 0)
b99bd4ef 4462 {
c19d1205
ZW
4463 i = unwind.opcodes[unwind.opcode_count - 1];
4464 if ((i & 0xf8) == 0xc0)
4465 {
4466 i &= 7;
4467 /* Only merge if the blocks are contiguous. */
4468 if (i < 6)
4469 {
4470 if ((mask & 0xfe00) == (1 << 9))
4471 {
4472 mask |= ((1 << (i + 11)) - 1) & 0xfc00;
4473 unwind.opcode_count--;
4474 }
4475 }
4476 else if (i == 6 && unwind.opcode_count >= 2)
4477 {
4478 i = unwind.opcodes[unwind.opcode_count - 2];
4479 reg = i >> 4;
4480 i &= 0xf;
b99bd4ef 4481
c19d1205
ZW
4482 op = 0xffff << (reg - 1);
4483 if (reg > 0
87a1fd79 4484 && ((mask & op) == (1u << (reg - 1))))
c19d1205
ZW
4485 {
4486 op = (1 << (reg + i + 1)) - 1;
4487 op &= ~((1 << reg) - 1);
4488 mask |= op;
4489 unwind.opcode_count -= 2;
4490 }
4491 }
4492 }
b99bd4ef
NC
4493 }
4494
c19d1205
ZW
4495 hi_reg = 15;
4496 /* We want to generate opcodes in the order the registers have been
4497 saved, ie. descending order. */
4498 for (reg = 15; reg >= -1; reg--)
b99bd4ef 4499 {
c19d1205
ZW
4500 /* Save registers in blocks. */
4501 if (reg < 0
4502 || !(mask & (1 << reg)))
4503 {
4504 /* We found an unsaved reg. Generate opcodes to save the
5f4273c7 4505 preceding block. */
c19d1205
ZW
4506 if (reg != hi_reg)
4507 {
4508 if (reg == 9)
4509 {
4510 /* Short form. */
4511 op = 0xc0 | (hi_reg - 10);
4512 add_unwind_opcode (op, 1);
4513 }
4514 else
4515 {
4516 /* Long form. */
4517 op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
4518 add_unwind_opcode (op, 2);
4519 }
4520 }
4521 hi_reg = reg - 1;
4522 }
b99bd4ef
NC
4523 }
4524
c19d1205
ZW
4525 return;
4526error:
4527 ignore_rest_of_line ();
b99bd4ef
NC
4528}
4529
4530static void
c19d1205 4531s_arm_unwind_save_mmxwcg (void)
b99bd4ef 4532{
c19d1205
ZW
4533 int reg;
4534 int hi_reg;
4535 unsigned mask = 0;
4536 valueT op;
b99bd4ef 4537
c19d1205
ZW
4538 if (*input_line_pointer == '{')
4539 input_line_pointer++;
b99bd4ef 4540
477330fc
RM
4541 skip_whitespace (input_line_pointer);
4542
c19d1205 4543 do
b99bd4ef 4544 {
dcbf9037 4545 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
b99bd4ef 4546
c19d1205
ZW
4547 if (reg == FAIL)
4548 {
9b7132d3 4549 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4550 goto error;
4551 }
b99bd4ef 4552
c19d1205
ZW
4553 reg -= 8;
4554 if (mask >> reg)
4555 as_tsktsk (_("register list not in ascending order"));
4556 mask |= 1 << reg;
b99bd4ef 4557
c19d1205
ZW
4558 if (*input_line_pointer == '-')
4559 {
4560 input_line_pointer++;
dcbf9037 4561 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
c19d1205
ZW
4562 if (hi_reg == FAIL)
4563 {
9b7132d3 4564 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4565 goto error;
4566 }
4567 else if (reg >= hi_reg)
4568 {
4569 as_bad (_("bad register range"));
4570 goto error;
4571 }
4572 for (; reg < hi_reg; reg++)
4573 mask |= 1 << reg;
4574 }
b99bd4ef 4575 }
c19d1205 4576 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4577
d996d970 4578 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4579
c19d1205
ZW
4580 demand_empty_rest_of_line ();
4581
708587a4 4582 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4583 the list. */
4584 flush_pending_unwind ();
b99bd4ef 4585
c19d1205 4586 for (reg = 0; reg < 16; reg++)
b99bd4ef 4587 {
c19d1205
ZW
4588 if (mask & (1 << reg))
4589 unwind.frame_size += 4;
b99bd4ef 4590 }
c19d1205
ZW
4591 op = 0xc700 | mask;
4592 add_unwind_opcode (op, 2);
4593 return;
4594error:
4595 ignore_rest_of_line ();
b99bd4ef
NC
4596}
4597
c19d1205 4598
fa073d69
MS
4599/* Parse an unwind_save directive.
4600 If the argument is non-zero, this is a .vsave directive. */
c19d1205 4601
b99bd4ef 4602static void
fa073d69 4603s_arm_unwind_save (int arch_v6)
b99bd4ef 4604{
c19d1205
ZW
4605 char *peek;
4606 struct reg_entry *reg;
4607 bfd_boolean had_brace = FALSE;
b99bd4ef 4608
921e5f0a 4609 if (!unwind.proc_start)
c921be7d 4610 as_bad (MISSING_FNSTART);
921e5f0a 4611
c19d1205
ZW
4612 /* Figure out what sort of save we have. */
4613 peek = input_line_pointer;
b99bd4ef 4614
c19d1205 4615 if (*peek == '{')
b99bd4ef 4616 {
c19d1205
ZW
4617 had_brace = TRUE;
4618 peek++;
b99bd4ef
NC
4619 }
4620
c19d1205 4621 reg = arm_reg_parse_multi (&peek);
b99bd4ef 4622
c19d1205 4623 if (!reg)
b99bd4ef 4624 {
c19d1205
ZW
4625 as_bad (_("register expected"));
4626 ignore_rest_of_line ();
b99bd4ef
NC
4627 return;
4628 }
4629
c19d1205 4630 switch (reg->type)
b99bd4ef 4631 {
c19d1205
ZW
4632 case REG_TYPE_FN:
4633 if (had_brace)
4634 {
4635 as_bad (_("FPA .unwind_save does not take a register list"));
4636 ignore_rest_of_line ();
4637 return;
4638 }
93ac2687 4639 input_line_pointer = peek;
c19d1205 4640 s_arm_unwind_save_fpa (reg->number);
b99bd4ef 4641 return;
c19d1205 4642
1f5afe1c
NC
4643 case REG_TYPE_RN:
4644 s_arm_unwind_save_core ();
4645 return;
4646
fa073d69
MS
4647 case REG_TYPE_VFD:
4648 if (arch_v6)
477330fc 4649 s_arm_unwind_save_vfp_armv6 ();
fa073d69 4650 else
477330fc 4651 s_arm_unwind_save_vfp ();
fa073d69 4652 return;
1f5afe1c
NC
4653
4654 case REG_TYPE_MMXWR:
4655 s_arm_unwind_save_mmxwr ();
4656 return;
4657
4658 case REG_TYPE_MMXWCG:
4659 s_arm_unwind_save_mmxwcg ();
4660 return;
c19d1205
ZW
4661
4662 default:
4663 as_bad (_(".unwind_save does not support this kind of register"));
4664 ignore_rest_of_line ();
b99bd4ef 4665 }
c19d1205 4666}
b99bd4ef 4667
b99bd4ef 4668
c19d1205
ZW
4669/* Parse an unwind_movsp directive. */
4670
4671static void
4672s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
4673{
4674 int reg;
4675 valueT op;
4fa3602b 4676 int offset;
c19d1205 4677
921e5f0a 4678 if (!unwind.proc_start)
c921be7d 4679 as_bad (MISSING_FNSTART);
921e5f0a 4680
dcbf9037 4681 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205 4682 if (reg == FAIL)
b99bd4ef 4683 {
9b7132d3 4684 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_RN]));
c19d1205 4685 ignore_rest_of_line ();
b99bd4ef
NC
4686 return;
4687 }
4fa3602b
PB
4688
4689 /* Optional constant. */
4690 if (skip_past_comma (&input_line_pointer) != FAIL)
4691 {
4692 if (immediate_for_directive (&offset) == FAIL)
4693 return;
4694 }
4695 else
4696 offset = 0;
4697
c19d1205 4698 demand_empty_rest_of_line ();
b99bd4ef 4699
c19d1205 4700 if (reg == REG_SP || reg == REG_PC)
b99bd4ef 4701 {
c19d1205 4702 as_bad (_("SP and PC not permitted in .unwind_movsp directive"));
b99bd4ef
NC
4703 return;
4704 }
4705
c19d1205
ZW
4706 if (unwind.fp_reg != REG_SP)
4707 as_bad (_("unexpected .unwind_movsp directive"));
b99bd4ef 4708
c19d1205
ZW
4709 /* Generate opcode to restore the value. */
4710 op = 0x90 | reg;
4711 add_unwind_opcode (op, 1);
4712
4713 /* Record the information for later. */
4714 unwind.fp_reg = reg;
4fa3602b 4715 unwind.fp_offset = unwind.frame_size - offset;
c19d1205 4716 unwind.sp_restored = 1;
b05fe5cf
ZW
4717}
4718
c19d1205
ZW
4719/* Parse an unwind_pad directive. */
4720
b05fe5cf 4721static void
c19d1205 4722s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
b05fe5cf 4723{
c19d1205 4724 int offset;
b05fe5cf 4725
921e5f0a 4726 if (!unwind.proc_start)
c921be7d 4727 as_bad (MISSING_FNSTART);
921e5f0a 4728
c19d1205
ZW
4729 if (immediate_for_directive (&offset) == FAIL)
4730 return;
b99bd4ef 4731
c19d1205
ZW
4732 if (offset & 3)
4733 {
4734 as_bad (_("stack increment must be multiple of 4"));
4735 ignore_rest_of_line ();
4736 return;
4737 }
b99bd4ef 4738
c19d1205
ZW
4739 /* Don't generate any opcodes, just record the details for later. */
4740 unwind.frame_size += offset;
4741 unwind.pending_offset += offset;
4742
4743 demand_empty_rest_of_line ();
4744}
4745
4746/* Parse an unwind_setfp directive. */
4747
4748static void
4749s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 4750{
c19d1205
ZW
4751 int sp_reg;
4752 int fp_reg;
4753 int offset;
4754
921e5f0a 4755 if (!unwind.proc_start)
c921be7d 4756 as_bad (MISSING_FNSTART);
921e5f0a 4757
dcbf9037 4758 fp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205
ZW
4759 if (skip_past_comma (&input_line_pointer) == FAIL)
4760 sp_reg = FAIL;
4761 else
dcbf9037 4762 sp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
b99bd4ef 4763
c19d1205
ZW
4764 if (fp_reg == FAIL || sp_reg == FAIL)
4765 {
4766 as_bad (_("expected <reg>, <reg>"));
4767 ignore_rest_of_line ();
4768 return;
4769 }
b99bd4ef 4770
c19d1205
ZW
4771 /* Optional constant. */
4772 if (skip_past_comma (&input_line_pointer) != FAIL)
4773 {
4774 if (immediate_for_directive (&offset) == FAIL)
4775 return;
4776 }
4777 else
4778 offset = 0;
a737bd4d 4779
c19d1205 4780 demand_empty_rest_of_line ();
a737bd4d 4781
fdfde340 4782 if (sp_reg != REG_SP && sp_reg != unwind.fp_reg)
a737bd4d 4783 {
c19d1205
ZW
4784 as_bad (_("register must be either sp or set by a previous"
4785 "unwind_movsp directive"));
4786 return;
a737bd4d
NC
4787 }
4788
c19d1205
ZW
4789 /* Don't generate any opcodes, just record the information for later. */
4790 unwind.fp_reg = fp_reg;
4791 unwind.fp_used = 1;
fdfde340 4792 if (sp_reg == REG_SP)
c19d1205
ZW
4793 unwind.fp_offset = unwind.frame_size - offset;
4794 else
4795 unwind.fp_offset -= offset;
a737bd4d
NC
4796}
4797
c19d1205
ZW
4798/* Parse an unwind_raw directive. */
4799
4800static void
4801s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
a737bd4d 4802{
c19d1205 4803 expressionS exp;
708587a4 4804 /* This is an arbitrary limit. */
c19d1205
ZW
4805 unsigned char op[16];
4806 int count;
a737bd4d 4807
921e5f0a 4808 if (!unwind.proc_start)
c921be7d 4809 as_bad (MISSING_FNSTART);
921e5f0a 4810
c19d1205
ZW
4811 expression (&exp);
4812 if (exp.X_op == O_constant
4813 && skip_past_comma (&input_line_pointer) != FAIL)
a737bd4d 4814 {
c19d1205
ZW
4815 unwind.frame_size += exp.X_add_number;
4816 expression (&exp);
4817 }
4818 else
4819 exp.X_op = O_illegal;
a737bd4d 4820
c19d1205
ZW
4821 if (exp.X_op != O_constant)
4822 {
4823 as_bad (_("expected <offset>, <opcode>"));
4824 ignore_rest_of_line ();
4825 return;
4826 }
a737bd4d 4827
c19d1205 4828 count = 0;
a737bd4d 4829
c19d1205
ZW
4830 /* Parse the opcode. */
4831 for (;;)
4832 {
4833 if (count >= 16)
4834 {
4835 as_bad (_("unwind opcode too long"));
4836 ignore_rest_of_line ();
a737bd4d 4837 }
c19d1205 4838 if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
a737bd4d 4839 {
c19d1205
ZW
4840 as_bad (_("invalid unwind opcode"));
4841 ignore_rest_of_line ();
4842 return;
a737bd4d 4843 }
c19d1205 4844 op[count++] = exp.X_add_number;
a737bd4d 4845
c19d1205
ZW
4846 /* Parse the next byte. */
4847 if (skip_past_comma (&input_line_pointer) == FAIL)
4848 break;
a737bd4d 4849
c19d1205
ZW
4850 expression (&exp);
4851 }
b99bd4ef 4852
c19d1205
ZW
4853 /* Add the opcode bytes in reverse order. */
4854 while (count--)
4855 add_unwind_opcode (op[count], 1);
b99bd4ef 4856
c19d1205 4857 demand_empty_rest_of_line ();
b99bd4ef 4858}
ee065d83
PB
4859
4860
4861/* Parse a .eabi_attribute directive. */
4862
4863static void
4864s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
4865{
0420f52b 4866 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
ee3c0378 4867
3076e594 4868 if (tag >= 0 && tag < NUM_KNOWN_OBJ_ATTRIBUTES)
ee3c0378 4869 attributes_set_explicitly[tag] = 1;
ee065d83
PB
4870}
4871
0855e32b
NS
4872/* Emit a tls fix for the symbol. */
4873
4874static void
4875s_arm_tls_descseq (int ignored ATTRIBUTE_UNUSED)
4876{
4877 char *p;
4878 expressionS exp;
4879#ifdef md_flush_pending_output
4880 md_flush_pending_output ();
4881#endif
4882
4883#ifdef md_cons_align
4884 md_cons_align (4);
4885#endif
4886
4887 /* Since we're just labelling the code, there's no need to define a
4888 mapping symbol. */
4889 expression (&exp);
4890 p = obstack_next_free (&frchain_now->frch_obstack);
4891 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
4892 thumb_mode ? BFD_RELOC_ARM_THM_TLS_DESCSEQ
4893 : BFD_RELOC_ARM_TLS_DESCSEQ);
4894}
cdf9ccec 4895#endif /* OBJ_ELF */
0855e32b 4896
ee065d83 4897static void s_arm_arch (int);
7a1d4c38 4898static void s_arm_object_arch (int);
ee065d83
PB
4899static void s_arm_cpu (int);
4900static void s_arm_fpu (int);
69133863 4901static void s_arm_arch_extension (int);
b99bd4ef 4902
f0927246
NC
4903#ifdef TE_PE
4904
4905static void
5f4273c7 4906pe_directive_secrel (int dummy ATTRIBUTE_UNUSED)
f0927246
NC
4907{
4908 expressionS exp;
4909
4910 do
4911 {
4912 expression (&exp);
4913 if (exp.X_op == O_symbol)
4914 exp.X_op = O_secrel;
4915
4916 emit_expr (&exp, 4);
4917 }
4918 while (*input_line_pointer++ == ',');
4919
4920 input_line_pointer--;
4921 demand_empty_rest_of_line ();
4922}
4923#endif /* TE_PE */
4924
c19d1205
ZW
4925/* This table describes all the machine specific pseudo-ops the assembler
4926 has to support. The fields are:
4927 pseudo-op name without dot
4928 function to call to execute this pseudo-op
4929 Integer arg to pass to the function. */
b99bd4ef 4930
c19d1205 4931const pseudo_typeS md_pseudo_table[] =
b99bd4ef 4932{
c19d1205
ZW
4933 /* Never called because '.req' does not start a line. */
4934 { "req", s_req, 0 },
dcbf9037
JB
4935 /* Following two are likewise never called. */
4936 { "dn", s_dn, 0 },
4937 { "qn", s_qn, 0 },
c19d1205
ZW
4938 { "unreq", s_unreq, 0 },
4939 { "bss", s_bss, 0 },
db2ed2e0 4940 { "align", s_align_ptwo, 2 },
c19d1205
ZW
4941 { "arm", s_arm, 0 },
4942 { "thumb", s_thumb, 0 },
4943 { "code", s_code, 0 },
4944 { "force_thumb", s_force_thumb, 0 },
4945 { "thumb_func", s_thumb_func, 0 },
4946 { "thumb_set", s_thumb_set, 0 },
4947 { "even", s_even, 0 },
4948 { "ltorg", s_ltorg, 0 },
4949 { "pool", s_ltorg, 0 },
4950 { "syntax", s_syntax, 0 },
8463be01
PB
4951 { "cpu", s_arm_cpu, 0 },
4952 { "arch", s_arm_arch, 0 },
7a1d4c38 4953 { "object_arch", s_arm_object_arch, 0 },
8463be01 4954 { "fpu", s_arm_fpu, 0 },
69133863 4955 { "arch_extension", s_arm_arch_extension, 0 },
c19d1205 4956#ifdef OBJ_ELF
c921be7d
NC
4957 { "word", s_arm_elf_cons, 4 },
4958 { "long", s_arm_elf_cons, 4 },
4959 { "inst.n", s_arm_elf_inst, 2 },
4960 { "inst.w", s_arm_elf_inst, 4 },
4961 { "inst", s_arm_elf_inst, 0 },
4962 { "rel31", s_arm_rel31, 0 },
c19d1205
ZW
4963 { "fnstart", s_arm_unwind_fnstart, 0 },
4964 { "fnend", s_arm_unwind_fnend, 0 },
4965 { "cantunwind", s_arm_unwind_cantunwind, 0 },
4966 { "personality", s_arm_unwind_personality, 0 },
4967 { "personalityindex", s_arm_unwind_personalityindex, 0 },
4968 { "handlerdata", s_arm_unwind_handlerdata, 0 },
4969 { "save", s_arm_unwind_save, 0 },
fa073d69 4970 { "vsave", s_arm_unwind_save, 1 },
c19d1205
ZW
4971 { "movsp", s_arm_unwind_movsp, 0 },
4972 { "pad", s_arm_unwind_pad, 0 },
4973 { "setfp", s_arm_unwind_setfp, 0 },
4974 { "unwind_raw", s_arm_unwind_raw, 0 },
ee065d83 4975 { "eabi_attribute", s_arm_eabi_attribute, 0 },
0855e32b 4976 { "tlsdescseq", s_arm_tls_descseq, 0 },
c19d1205
ZW
4977#else
4978 { "word", cons, 4},
f0927246
NC
4979
4980 /* These are used for dwarf. */
4981 {"2byte", cons, 2},
4982 {"4byte", cons, 4},
4983 {"8byte", cons, 8},
4984 /* These are used for dwarf2. */
68d20676 4985 { "file", dwarf2_directive_file, 0 },
f0927246
NC
4986 { "loc", dwarf2_directive_loc, 0 },
4987 { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
c19d1205
ZW
4988#endif
4989 { "extend", float_cons, 'x' },
4990 { "ldouble", float_cons, 'x' },
4991 { "packed", float_cons, 'p' },
f0927246
NC
4992#ifdef TE_PE
4993 {"secrel32", pe_directive_secrel, 0},
4994#endif
2e6976a8
DG
4995
4996 /* These are for compatibility with CodeComposer Studio. */
4997 {"ref", s_ccs_ref, 0},
4998 {"def", s_ccs_def, 0},
4999 {"asmfunc", s_ccs_asmfunc, 0},
5000 {"endasmfunc", s_ccs_endasmfunc, 0},
5001
c19d1205
ZW
5002 { 0, 0, 0 }
5003};
5004\f
5005/* Parser functions used exclusively in instruction operands. */
b99bd4ef 5006
c19d1205
ZW
5007/* Generic immediate-value read function for use in insn parsing.
5008 STR points to the beginning of the immediate (the leading #);
5009 VAL receives the value; if the value is outside [MIN, MAX]
5010 issue an error. PREFIX_OPT is true if the immediate prefix is
5011 optional. */
b99bd4ef 5012
c19d1205
ZW
5013static int
5014parse_immediate (char **str, int *val, int min, int max,
5015 bfd_boolean prefix_opt)
5016{
5017 expressionS exp;
0198d5e6 5018
c19d1205
ZW
5019 my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
5020 if (exp.X_op != O_constant)
b99bd4ef 5021 {
c19d1205
ZW
5022 inst.error = _("constant expression required");
5023 return FAIL;
5024 }
b99bd4ef 5025
c19d1205
ZW
5026 if (exp.X_add_number < min || exp.X_add_number > max)
5027 {
5028 inst.error = _("immediate value out of range");
5029 return FAIL;
5030 }
b99bd4ef 5031
c19d1205
ZW
5032 *val = exp.X_add_number;
5033 return SUCCESS;
5034}
b99bd4ef 5035
5287ad62 5036/* Less-generic immediate-value read function with the possibility of loading a
036dc3f7 5037 big (64-bit) immediate, as required by Neon VMOV, VMVN and logic immediate
5287ad62
JB
5038 instructions. Puts the result directly in inst.operands[i]. */
5039
5040static int
8335d6aa
JW
5041parse_big_immediate (char **str, int i, expressionS *in_exp,
5042 bfd_boolean allow_symbol_p)
5287ad62
JB
5043{
5044 expressionS exp;
8335d6aa 5045 expressionS *exp_p = in_exp ? in_exp : &exp;
5287ad62
JB
5046 char *ptr = *str;
5047
8335d6aa 5048 my_get_expression (exp_p, &ptr, GE_OPT_PREFIX_BIG);
5287ad62 5049
8335d6aa 5050 if (exp_p->X_op == O_constant)
036dc3f7 5051 {
8335d6aa 5052 inst.operands[i].imm = exp_p->X_add_number & 0xffffffff;
036dc3f7
PB
5053 /* If we're on a 64-bit host, then a 64-bit number can be returned using
5054 O_constant. We have to be careful not to break compilation for
5055 32-bit X_add_number, though. */
8335d6aa 5056 if ((exp_p->X_add_number & ~(offsetT)(0xffffffffU)) != 0)
036dc3f7 5057 {
8335d6aa
JW
5058 /* X >> 32 is illegal if sizeof (exp_p->X_add_number) == 4. */
5059 inst.operands[i].reg = (((exp_p->X_add_number >> 16) >> 16)
5060 & 0xffffffff);
036dc3f7
PB
5061 inst.operands[i].regisimm = 1;
5062 }
5063 }
8335d6aa
JW
5064 else if (exp_p->X_op == O_big
5065 && LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 32)
5287ad62
JB
5066 {
5067 unsigned parts = 32 / LITTLENUM_NUMBER_OF_BITS, j, idx = 0;
95b75c01 5068
5287ad62 5069 /* Bignums have their least significant bits in
477330fc
RM
5070 generic_bignum[0]. Make sure we put 32 bits in imm and
5071 32 bits in reg, in a (hopefully) portable way. */
9c2799c2 5072 gas_assert (parts != 0);
95b75c01
NC
5073
5074 /* Make sure that the number is not too big.
5075 PR 11972: Bignums can now be sign-extended to the
5076 size of a .octa so check that the out of range bits
5077 are all zero or all one. */
8335d6aa 5078 if (LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 64)
95b75c01
NC
5079 {
5080 LITTLENUM_TYPE m = -1;
5081
5082 if (generic_bignum[parts * 2] != 0
5083 && generic_bignum[parts * 2] != m)
5084 return FAIL;
5085
8335d6aa 5086 for (j = parts * 2 + 1; j < (unsigned) exp_p->X_add_number; j++)
95b75c01
NC
5087 if (generic_bignum[j] != generic_bignum[j-1])
5088 return FAIL;
5089 }
5090
5287ad62
JB
5091 inst.operands[i].imm = 0;
5092 for (j = 0; j < parts; j++, idx++)
477330fc
RM
5093 inst.operands[i].imm |= generic_bignum[idx]
5094 << (LITTLENUM_NUMBER_OF_BITS * j);
5287ad62
JB
5095 inst.operands[i].reg = 0;
5096 for (j = 0; j < parts; j++, idx++)
477330fc
RM
5097 inst.operands[i].reg |= generic_bignum[idx]
5098 << (LITTLENUM_NUMBER_OF_BITS * j);
5287ad62
JB
5099 inst.operands[i].regisimm = 1;
5100 }
8335d6aa 5101 else if (!(exp_p->X_op == O_symbol && allow_symbol_p))
5287ad62 5102 return FAIL;
5f4273c7 5103
5287ad62
JB
5104 *str = ptr;
5105
5106 return SUCCESS;
5107}
5108
c19d1205
ZW
5109/* Returns the pseudo-register number of an FPA immediate constant,
5110 or FAIL if there isn't a valid constant here. */
b99bd4ef 5111
c19d1205
ZW
5112static int
5113parse_fpa_immediate (char ** str)
5114{
5115 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5116 char * save_in;
5117 expressionS exp;
5118 int i;
5119 int j;
b99bd4ef 5120
c19d1205
ZW
5121 /* First try and match exact strings, this is to guarantee
5122 that some formats will work even for cross assembly. */
b99bd4ef 5123
c19d1205
ZW
5124 for (i = 0; fp_const[i]; i++)
5125 {
5126 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
b99bd4ef 5127 {
c19d1205 5128 char *start = *str;
b99bd4ef 5129
c19d1205
ZW
5130 *str += strlen (fp_const[i]);
5131 if (is_end_of_line[(unsigned char) **str])
5132 return i + 8;
5133 *str = start;
5134 }
5135 }
b99bd4ef 5136
c19d1205
ZW
5137 /* Just because we didn't get a match doesn't mean that the constant
5138 isn't valid, just that it is in a format that we don't
5139 automatically recognize. Try parsing it with the standard
5140 expression routines. */
b99bd4ef 5141
c19d1205 5142 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
b99bd4ef 5143
c19d1205
ZW
5144 /* Look for a raw floating point number. */
5145 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5146 && is_end_of_line[(unsigned char) *save_in])
5147 {
5148 for (i = 0; i < NUM_FLOAT_VALS; i++)
5149 {
5150 for (j = 0; j < MAX_LITTLENUMS; j++)
b99bd4ef 5151 {
c19d1205
ZW
5152 if (words[j] != fp_values[i][j])
5153 break;
b99bd4ef
NC
5154 }
5155
c19d1205 5156 if (j == MAX_LITTLENUMS)
b99bd4ef 5157 {
c19d1205
ZW
5158 *str = save_in;
5159 return i + 8;
b99bd4ef
NC
5160 }
5161 }
5162 }
b99bd4ef 5163
c19d1205
ZW
5164 /* Try and parse a more complex expression, this will probably fail
5165 unless the code uses a floating point prefix (eg "0f"). */
5166 save_in = input_line_pointer;
5167 input_line_pointer = *str;
5168 if (expression (&exp) == absolute_section
5169 && exp.X_op == O_big
5170 && exp.X_add_number < 0)
5171 {
5172 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5173 Ditto for 15. */
ba592044
AM
5174#define X_PRECISION 5
5175#define E_PRECISION 15L
5176 if (gen_to_words (words, X_PRECISION, E_PRECISION) == 0)
c19d1205
ZW
5177 {
5178 for (i = 0; i < NUM_FLOAT_VALS; i++)
5179 {
5180 for (j = 0; j < MAX_LITTLENUMS; j++)
5181 {
5182 if (words[j] != fp_values[i][j])
5183 break;
5184 }
b99bd4ef 5185
c19d1205
ZW
5186 if (j == MAX_LITTLENUMS)
5187 {
5188 *str = input_line_pointer;
5189 input_line_pointer = save_in;
5190 return i + 8;
5191 }
5192 }
5193 }
b99bd4ef
NC
5194 }
5195
c19d1205
ZW
5196 *str = input_line_pointer;
5197 input_line_pointer = save_in;
5198 inst.error = _("invalid FPA immediate expression");
5199 return FAIL;
b99bd4ef
NC
5200}
5201
136da414
JB
5202/* Returns 1 if a number has "quarter-precision" float format
5203 0baBbbbbbc defgh000 00000000 00000000. */
5204
5205static int
5206is_quarter_float (unsigned imm)
5207{
5208 int bs = (imm & 0x20000000) ? 0x3e000000 : 0x40000000;
5209 return (imm & 0x7ffff) == 0 && ((imm & 0x7e000000) ^ bs) == 0;
5210}
5211
aacf0b33
KT
5212
5213/* Detect the presence of a floating point or integer zero constant,
5214 i.e. #0.0 or #0. */
5215
5216static bfd_boolean
5217parse_ifimm_zero (char **in)
5218{
5219 int error_code;
5220
5221 if (!is_immediate_prefix (**in))
3c6452ae
TP
5222 {
5223 /* In unified syntax, all prefixes are optional. */
5224 if (!unified_syntax)
5225 return FALSE;
5226 }
5227 else
5228 ++*in;
0900a05b
JW
5229
5230 /* Accept #0x0 as a synonym for #0. */
5231 if (strncmp (*in, "0x", 2) == 0)
5232 {
5233 int val;
5234 if (parse_immediate (in, &val, 0, 0, TRUE) == FAIL)
5235 return FALSE;
5236 return TRUE;
5237 }
5238
aacf0b33
KT
5239 error_code = atof_generic (in, ".", EXP_CHARS,
5240 &generic_floating_point_number);
5241
5242 if (!error_code
5243 && generic_floating_point_number.sign == '+'
5244 && (generic_floating_point_number.low
5245 > generic_floating_point_number.leader))
5246 return TRUE;
5247
5248 return FALSE;
5249}
5250
136da414
JB
5251/* Parse an 8-bit "quarter-precision" floating point number of the form:
5252 0baBbbbbbc defgh000 00000000 00000000.
c96612cc
JB
5253 The zero and minus-zero cases need special handling, since they can't be
5254 encoded in the "quarter-precision" float format, but can nonetheless be
5255 loaded as integer constants. */
136da414
JB
5256
5257static unsigned
5258parse_qfloat_immediate (char **ccp, int *immed)
5259{
5260 char *str = *ccp;
c96612cc 5261 char *fpnum;
136da414 5262 LITTLENUM_TYPE words[MAX_LITTLENUMS];
c96612cc 5263 int found_fpchar = 0;
5f4273c7 5264
136da414 5265 skip_past_char (&str, '#');
5f4273c7 5266
c96612cc
JB
5267 /* We must not accidentally parse an integer as a floating-point number. Make
5268 sure that the value we parse is not an integer by checking for special
5269 characters '.' or 'e'.
5270 FIXME: This is a horrible hack, but doing better is tricky because type
5271 information isn't in a very usable state at parse time. */
5272 fpnum = str;
5273 skip_whitespace (fpnum);
5274
5275 if (strncmp (fpnum, "0x", 2) == 0)
5276 return FAIL;
5277 else
5278 {
5279 for (; *fpnum != '\0' && *fpnum != ' ' && *fpnum != '\n'; fpnum++)
477330fc
RM
5280 if (*fpnum == '.' || *fpnum == 'e' || *fpnum == 'E')
5281 {
5282 found_fpchar = 1;
5283 break;
5284 }
c96612cc
JB
5285
5286 if (!found_fpchar)
477330fc 5287 return FAIL;
c96612cc 5288 }
5f4273c7 5289
136da414
JB
5290 if ((str = atof_ieee (str, 's', words)) != NULL)
5291 {
5292 unsigned fpword = 0;
5293 int i;
5f4273c7 5294
136da414
JB
5295 /* Our FP word must be 32 bits (single-precision FP). */
5296 for (i = 0; i < 32 / LITTLENUM_NUMBER_OF_BITS; i++)
477330fc
RM
5297 {
5298 fpword <<= LITTLENUM_NUMBER_OF_BITS;
5299 fpword |= words[i];
5300 }
5f4273c7 5301
c96612cc 5302 if (is_quarter_float (fpword) || (fpword & 0x7fffffff) == 0)
477330fc 5303 *immed = fpword;
136da414 5304 else
477330fc 5305 return FAIL;
136da414
JB
5306
5307 *ccp = str;
5f4273c7 5308
136da414
JB
5309 return SUCCESS;
5310 }
5f4273c7 5311
136da414
JB
5312 return FAIL;
5313}
5314
c19d1205
ZW
5315/* Shift operands. */
5316enum shift_kind
b99bd4ef 5317{
f5f10c66 5318 SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX, SHIFT_UXTW
c19d1205 5319};
b99bd4ef 5320
c19d1205
ZW
5321struct asm_shift_name
5322{
5323 const char *name;
5324 enum shift_kind kind;
5325};
b99bd4ef 5326
c19d1205
ZW
5327/* Third argument to parse_shift. */
5328enum parse_shift_mode
5329{
5330 NO_SHIFT_RESTRICT, /* Any kind of shift is accepted. */
5331 SHIFT_IMMEDIATE, /* Shift operand must be an immediate. */
5332 SHIFT_LSL_OR_ASR_IMMEDIATE, /* Shift must be LSL or ASR immediate. */
5333 SHIFT_ASR_IMMEDIATE, /* Shift must be ASR immediate. */
5334 SHIFT_LSL_IMMEDIATE, /* Shift must be LSL immediate. */
f5f10c66 5335 SHIFT_UXTW_IMMEDIATE /* Shift must be UXTW immediate. */
c19d1205 5336};
b99bd4ef 5337
c19d1205
ZW
5338/* Parse a <shift> specifier on an ARM data processing instruction.
5339 This has three forms:
b99bd4ef 5340
c19d1205
ZW
5341 (LSL|LSR|ASL|ASR|ROR) Rs
5342 (LSL|LSR|ASL|ASR|ROR) #imm
5343 RRX
b99bd4ef 5344
c19d1205
ZW
5345 Note that ASL is assimilated to LSL in the instruction encoding, and
5346 RRX to ROR #0 (which cannot be written as such). */
b99bd4ef 5347
c19d1205
ZW
5348static int
5349parse_shift (char **str, int i, enum parse_shift_mode mode)
b99bd4ef 5350{
c19d1205
ZW
5351 const struct asm_shift_name *shift_name;
5352 enum shift_kind shift;
5353 char *s = *str;
5354 char *p = s;
5355 int reg;
b99bd4ef 5356
c19d1205
ZW
5357 for (p = *str; ISALPHA (*p); p++)
5358 ;
b99bd4ef 5359
c19d1205 5360 if (p == *str)
b99bd4ef 5361 {
c19d1205
ZW
5362 inst.error = _("shift expression expected");
5363 return FAIL;
b99bd4ef
NC
5364 }
5365
21d799b5 5366 shift_name = (const struct asm_shift_name *) hash_find_n (arm_shift_hsh, *str,
477330fc 5367 p - *str);
c19d1205
ZW
5368
5369 if (shift_name == NULL)
b99bd4ef 5370 {
c19d1205
ZW
5371 inst.error = _("shift expression expected");
5372 return FAIL;
b99bd4ef
NC
5373 }
5374
c19d1205 5375 shift = shift_name->kind;
b99bd4ef 5376
c19d1205
ZW
5377 switch (mode)
5378 {
5379 case NO_SHIFT_RESTRICT:
f5f10c66
AV
5380 case SHIFT_IMMEDIATE:
5381 if (shift == SHIFT_UXTW)
5382 {
5383 inst.error = _("'UXTW' not allowed here");
5384 return FAIL;
5385 }
5386 break;
b99bd4ef 5387
c19d1205
ZW
5388 case SHIFT_LSL_OR_ASR_IMMEDIATE:
5389 if (shift != SHIFT_LSL && shift != SHIFT_ASR)
5390 {
5391 inst.error = _("'LSL' or 'ASR' required");
5392 return FAIL;
5393 }
5394 break;
b99bd4ef 5395
c19d1205
ZW
5396 case SHIFT_LSL_IMMEDIATE:
5397 if (shift != SHIFT_LSL)
5398 {
5399 inst.error = _("'LSL' required");
5400 return FAIL;
5401 }
5402 break;
b99bd4ef 5403
c19d1205
ZW
5404 case SHIFT_ASR_IMMEDIATE:
5405 if (shift != SHIFT_ASR)
5406 {
5407 inst.error = _("'ASR' required");
5408 return FAIL;
5409 }
5410 break;
f5f10c66
AV
5411 case SHIFT_UXTW_IMMEDIATE:
5412 if (shift != SHIFT_UXTW)
5413 {
5414 inst.error = _("'UXTW' required");
5415 return FAIL;
5416 }
5417 break;
b99bd4ef 5418
c19d1205
ZW
5419 default: abort ();
5420 }
b99bd4ef 5421
c19d1205
ZW
5422 if (shift != SHIFT_RRX)
5423 {
5424 /* Whitespace can appear here if the next thing is a bare digit. */
5425 skip_whitespace (p);
b99bd4ef 5426
c19d1205 5427 if (mode == NO_SHIFT_RESTRICT
dcbf9037 5428 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5429 {
5430 inst.operands[i].imm = reg;
5431 inst.operands[i].immisreg = 1;
5432 }
e2b0ab59 5433 else if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
c19d1205
ZW
5434 return FAIL;
5435 }
5436 inst.operands[i].shift_kind = shift;
5437 inst.operands[i].shifted = 1;
5438 *str = p;
5439 return SUCCESS;
b99bd4ef
NC
5440}
5441
c19d1205 5442/* Parse a <shifter_operand> for an ARM data processing instruction:
b99bd4ef 5443
c19d1205
ZW
5444 #<immediate>
5445 #<immediate>, <rotate>
5446 <Rm>
5447 <Rm>, <shift>
b99bd4ef 5448
c19d1205
ZW
5449 where <shift> is defined by parse_shift above, and <rotate> is a
5450 multiple of 2 between 0 and 30. Validation of immediate operands
55cf6793 5451 is deferred to md_apply_fix. */
b99bd4ef 5452
c19d1205
ZW
5453static int
5454parse_shifter_operand (char **str, int i)
5455{
5456 int value;
91d6fa6a 5457 expressionS exp;
b99bd4ef 5458
dcbf9037 5459 if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5460 {
5461 inst.operands[i].reg = value;
5462 inst.operands[i].isreg = 1;
b99bd4ef 5463
c19d1205 5464 /* parse_shift will override this if appropriate */
e2b0ab59
AV
5465 inst.relocs[0].exp.X_op = O_constant;
5466 inst.relocs[0].exp.X_add_number = 0;
b99bd4ef 5467
c19d1205
ZW
5468 if (skip_past_comma (str) == FAIL)
5469 return SUCCESS;
b99bd4ef 5470
c19d1205
ZW
5471 /* Shift operation on register. */
5472 return parse_shift (str, i, NO_SHIFT_RESTRICT);
b99bd4ef
NC
5473 }
5474
e2b0ab59 5475 if (my_get_expression (&inst.relocs[0].exp, str, GE_IMM_PREFIX))
c19d1205 5476 return FAIL;
b99bd4ef 5477
c19d1205 5478 if (skip_past_comma (str) == SUCCESS)
b99bd4ef 5479 {
c19d1205 5480 /* #x, y -- ie explicit rotation by Y. */
91d6fa6a 5481 if (my_get_expression (&exp, str, GE_NO_PREFIX))
c19d1205 5482 return FAIL;
b99bd4ef 5483
e2b0ab59 5484 if (exp.X_op != O_constant || inst.relocs[0].exp.X_op != O_constant)
c19d1205
ZW
5485 {
5486 inst.error = _("constant expression expected");
5487 return FAIL;
5488 }
b99bd4ef 5489
91d6fa6a 5490 value = exp.X_add_number;
c19d1205
ZW
5491 if (value < 0 || value > 30 || value % 2 != 0)
5492 {
5493 inst.error = _("invalid rotation");
5494 return FAIL;
5495 }
e2b0ab59
AV
5496 if (inst.relocs[0].exp.X_add_number < 0
5497 || inst.relocs[0].exp.X_add_number > 255)
c19d1205
ZW
5498 {
5499 inst.error = _("invalid constant");
5500 return FAIL;
5501 }
09d92015 5502
a415b1cd 5503 /* Encode as specified. */
e2b0ab59 5504 inst.operands[i].imm = inst.relocs[0].exp.X_add_number | value << 7;
a415b1cd 5505 return SUCCESS;
09d92015
MM
5506 }
5507
e2b0ab59
AV
5508 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
5509 inst.relocs[0].pc_rel = 0;
c19d1205 5510 return SUCCESS;
09d92015
MM
5511}
5512
4962c51a
MS
5513/* Group relocation information. Each entry in the table contains the
5514 textual name of the relocation as may appear in assembler source
5515 and must end with a colon.
5516 Along with this textual name are the relocation codes to be used if
5517 the corresponding instruction is an ALU instruction (ADD or SUB only),
5518 an LDR, an LDRS, or an LDC. */
5519
5520struct group_reloc_table_entry
5521{
5522 const char *name;
5523 int alu_code;
5524 int ldr_code;
5525 int ldrs_code;
5526 int ldc_code;
5527};
5528
5529typedef enum
5530{
5531 /* Varieties of non-ALU group relocation. */
5532
5533 GROUP_LDR,
5534 GROUP_LDRS,
35c228db
AV
5535 GROUP_LDC,
5536 GROUP_MVE
4962c51a
MS
5537} group_reloc_type;
5538
5539static struct group_reloc_table_entry group_reloc_table[] =
5540 { /* Program counter relative: */
5541 { "pc_g0_nc",
5542 BFD_RELOC_ARM_ALU_PC_G0_NC, /* ALU */
5543 0, /* LDR */
5544 0, /* LDRS */
5545 0 }, /* LDC */
5546 { "pc_g0",
5547 BFD_RELOC_ARM_ALU_PC_G0, /* ALU */
5548 BFD_RELOC_ARM_LDR_PC_G0, /* LDR */
5549 BFD_RELOC_ARM_LDRS_PC_G0, /* LDRS */
5550 BFD_RELOC_ARM_LDC_PC_G0 }, /* LDC */
5551 { "pc_g1_nc",
5552 BFD_RELOC_ARM_ALU_PC_G1_NC, /* ALU */
5553 0, /* LDR */
5554 0, /* LDRS */
5555 0 }, /* LDC */
5556 { "pc_g1",
5557 BFD_RELOC_ARM_ALU_PC_G1, /* ALU */
5558 BFD_RELOC_ARM_LDR_PC_G1, /* LDR */
5559 BFD_RELOC_ARM_LDRS_PC_G1, /* LDRS */
5560 BFD_RELOC_ARM_LDC_PC_G1 }, /* LDC */
5561 { "pc_g2",
5562 BFD_RELOC_ARM_ALU_PC_G2, /* ALU */
5563 BFD_RELOC_ARM_LDR_PC_G2, /* LDR */
5564 BFD_RELOC_ARM_LDRS_PC_G2, /* LDRS */
5565 BFD_RELOC_ARM_LDC_PC_G2 }, /* LDC */
5566 /* Section base relative */
5567 { "sb_g0_nc",
5568 BFD_RELOC_ARM_ALU_SB_G0_NC, /* ALU */
5569 0, /* LDR */
5570 0, /* LDRS */
5571 0 }, /* LDC */
5572 { "sb_g0",
5573 BFD_RELOC_ARM_ALU_SB_G0, /* ALU */
5574 BFD_RELOC_ARM_LDR_SB_G0, /* LDR */
5575 BFD_RELOC_ARM_LDRS_SB_G0, /* LDRS */
5576 BFD_RELOC_ARM_LDC_SB_G0 }, /* LDC */
5577 { "sb_g1_nc",
5578 BFD_RELOC_ARM_ALU_SB_G1_NC, /* ALU */
5579 0, /* LDR */
5580 0, /* LDRS */
5581 0 }, /* LDC */
5582 { "sb_g1",
5583 BFD_RELOC_ARM_ALU_SB_G1, /* ALU */
5584 BFD_RELOC_ARM_LDR_SB_G1, /* LDR */
5585 BFD_RELOC_ARM_LDRS_SB_G1, /* LDRS */
5586 BFD_RELOC_ARM_LDC_SB_G1 }, /* LDC */
5587 { "sb_g2",
5588 BFD_RELOC_ARM_ALU_SB_G2, /* ALU */
5589 BFD_RELOC_ARM_LDR_SB_G2, /* LDR */
5590 BFD_RELOC_ARM_LDRS_SB_G2, /* LDRS */
72d98d16
MG
5591 BFD_RELOC_ARM_LDC_SB_G2 }, /* LDC */
5592 /* Absolute thumb alu relocations. */
5593 { "lower0_7",
5594 BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,/* ALU. */
5595 0, /* LDR. */
5596 0, /* LDRS. */
5597 0 }, /* LDC. */
5598 { "lower8_15",
5599 BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,/* ALU. */
5600 0, /* LDR. */
5601 0, /* LDRS. */
5602 0 }, /* LDC. */
5603 { "upper0_7",
5604 BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,/* ALU. */
5605 0, /* LDR. */
5606 0, /* LDRS. */
5607 0 }, /* LDC. */
5608 { "upper8_15",
5609 BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,/* ALU. */
5610 0, /* LDR. */
5611 0, /* LDRS. */
5612 0 } }; /* LDC. */
4962c51a
MS
5613
5614/* Given the address of a pointer pointing to the textual name of a group
5615 relocation as may appear in assembler source, attempt to find its details
5616 in group_reloc_table. The pointer will be updated to the character after
5617 the trailing colon. On failure, FAIL will be returned; SUCCESS
5618 otherwise. On success, *entry will be updated to point at the relevant
5619 group_reloc_table entry. */
5620
5621static int
5622find_group_reloc_table_entry (char **str, struct group_reloc_table_entry **out)
5623{
5624 unsigned int i;
5625 for (i = 0; i < ARRAY_SIZE (group_reloc_table); i++)
5626 {
5627 int length = strlen (group_reloc_table[i].name);
5628
5f4273c7
NC
5629 if (strncasecmp (group_reloc_table[i].name, *str, length) == 0
5630 && (*str)[length] == ':')
477330fc
RM
5631 {
5632 *out = &group_reloc_table[i];
5633 *str += (length + 1);
5634 return SUCCESS;
5635 }
4962c51a
MS
5636 }
5637
5638 return FAIL;
5639}
5640
5641/* Parse a <shifter_operand> for an ARM data processing instruction
5642 (as for parse_shifter_operand) where group relocations are allowed:
5643
5644 #<immediate>
5645 #<immediate>, <rotate>
5646 #:<group_reloc>:<expression>
5647 <Rm>
5648 <Rm>, <shift>
5649
5650 where <group_reloc> is one of the strings defined in group_reloc_table.
5651 The hashes are optional.
5652
5653 Everything else is as for parse_shifter_operand. */
5654
5655static parse_operand_result
5656parse_shifter_operand_group_reloc (char **str, int i)
5657{
5658 /* Determine if we have the sequence of characters #: or just :
5659 coming next. If we do, then we check for a group relocation.
5660 If we don't, punt the whole lot to parse_shifter_operand. */
5661
5662 if (((*str)[0] == '#' && (*str)[1] == ':')
5663 || (*str)[0] == ':')
5664 {
5665 struct group_reloc_table_entry *entry;
5666
5667 if ((*str)[0] == '#')
477330fc 5668 (*str) += 2;
4962c51a 5669 else
477330fc 5670 (*str)++;
4962c51a
MS
5671
5672 /* Try to parse a group relocation. Anything else is an error. */
5673 if (find_group_reloc_table_entry (str, &entry) == FAIL)
477330fc
RM
5674 {
5675 inst.error = _("unknown group relocation");
5676 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5677 }
4962c51a
MS
5678
5679 /* We now have the group relocation table entry corresponding to
477330fc 5680 the name in the assembler source. Next, we parse the expression. */
e2b0ab59 5681 if (my_get_expression (&inst.relocs[0].exp, str, GE_NO_PREFIX))
477330fc 5682 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
4962c51a
MS
5683
5684 /* Record the relocation type (always the ALU variant here). */
e2b0ab59
AV
5685 inst.relocs[0].type = (bfd_reloc_code_real_type) entry->alu_code;
5686 gas_assert (inst.relocs[0].type != 0);
4962c51a
MS
5687
5688 return PARSE_OPERAND_SUCCESS;
5689 }
5690 else
5691 return parse_shifter_operand (str, i) == SUCCESS
477330fc 5692 ? PARSE_OPERAND_SUCCESS : PARSE_OPERAND_FAIL;
4962c51a
MS
5693
5694 /* Never reached. */
5695}
5696
8e560766
MGD
5697/* Parse a Neon alignment expression. Information is written to
5698 inst.operands[i]. We assume the initial ':' has been skipped.
fa94de6b 5699
8e560766
MGD
5700 align .imm = align << 8, .immisalign=1, .preind=0 */
5701static parse_operand_result
5702parse_neon_alignment (char **str, int i)
5703{
5704 char *p = *str;
5705 expressionS exp;
5706
5707 my_get_expression (&exp, &p, GE_NO_PREFIX);
5708
5709 if (exp.X_op != O_constant)
5710 {
5711 inst.error = _("alignment must be constant");
5712 return PARSE_OPERAND_FAIL;
5713 }
5714
5715 inst.operands[i].imm = exp.X_add_number << 8;
5716 inst.operands[i].immisalign = 1;
5717 /* Alignments are not pre-indexes. */
5718 inst.operands[i].preind = 0;
5719
5720 *str = p;
5721 return PARSE_OPERAND_SUCCESS;
5722}
5723
c19d1205 5724/* Parse all forms of an ARM address expression. Information is written
e2b0ab59 5725 to inst.operands[i] and/or inst.relocs[0].
09d92015 5726
c19d1205 5727 Preindexed addressing (.preind=1):
09d92015 5728
e2b0ab59 5729 [Rn, #offset] .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5730 [Rn, +/-Rm] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5731 [Rn, +/-Rm, shift] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5732 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5733
c19d1205 5734 These three may have a trailing ! which causes .writeback to be set also.
09d92015 5735
c19d1205 5736 Postindexed addressing (.postind=1, .writeback=1):
09d92015 5737
e2b0ab59 5738 [Rn], #offset .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5739 [Rn], +/-Rm .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5740 [Rn], +/-Rm, shift .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5741 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5742
c19d1205 5743 Unindexed addressing (.preind=0, .postind=0):
09d92015 5744
c19d1205 5745 [Rn], {option} .reg=Rn .imm=option .immisreg=0
09d92015 5746
c19d1205 5747 Other:
09d92015 5748
c19d1205 5749 [Rn]{!} shorthand for [Rn,#0]{!}
e2b0ab59
AV
5750 =immediate .isreg=0 .relocs[0].exp=immediate
5751 label .reg=PC .relocs[0].pc_rel=1 .relocs[0].exp=label
09d92015 5752
c19d1205 5753 It is the caller's responsibility to check for addressing modes not
e2b0ab59 5754 supported by the instruction, and to set inst.relocs[0].type. */
c19d1205 5755
4962c51a
MS
5756static parse_operand_result
5757parse_address_main (char **str, int i, int group_relocations,
477330fc 5758 group_reloc_type group_type)
09d92015 5759{
c19d1205
ZW
5760 char *p = *str;
5761 int reg;
09d92015 5762
c19d1205 5763 if (skip_past_char (&p, '[') == FAIL)
09d92015 5764 {
c19d1205
ZW
5765 if (skip_past_char (&p, '=') == FAIL)
5766 {
974da60d 5767 /* Bare address - translate to PC-relative offset. */
e2b0ab59 5768 inst.relocs[0].pc_rel = 1;
c19d1205
ZW
5769 inst.operands[i].reg = REG_PC;
5770 inst.operands[i].isreg = 1;
5771 inst.operands[i].preind = 1;
09d92015 5772
e2b0ab59 5773 if (my_get_expression (&inst.relocs[0].exp, &p, GE_OPT_PREFIX_BIG))
8335d6aa
JW
5774 return PARSE_OPERAND_FAIL;
5775 }
e2b0ab59 5776 else if (parse_big_immediate (&p, i, &inst.relocs[0].exp,
8335d6aa 5777 /*allow_symbol_p=*/TRUE))
4962c51a 5778 return PARSE_OPERAND_FAIL;
09d92015 5779
c19d1205 5780 *str = p;
4962c51a 5781 return PARSE_OPERAND_SUCCESS;
09d92015
MM
5782 }
5783
8ab8155f
NC
5784 /* PR gas/14887: Allow for whitespace after the opening bracket. */
5785 skip_whitespace (p);
5786
f5f10c66
AV
5787 if (group_type == GROUP_MVE)
5788 {
5789 enum arm_reg_type rtype = REG_TYPE_MQ;
5790 struct neon_type_el et;
5791 if ((reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
5792 {
5793 inst.operands[i].isquad = 1;
5794 }
5795 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
5796 {
5797 inst.error = BAD_ADDR_MODE;
5798 return PARSE_OPERAND_FAIL;
5799 }
5800 }
5801 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
09d92015 5802 {
35c228db
AV
5803 if (group_type == GROUP_MVE)
5804 inst.error = BAD_ADDR_MODE;
5805 else
5806 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
4962c51a 5807 return PARSE_OPERAND_FAIL;
09d92015 5808 }
c19d1205
ZW
5809 inst.operands[i].reg = reg;
5810 inst.operands[i].isreg = 1;
09d92015 5811
c19d1205 5812 if (skip_past_comma (&p) == SUCCESS)
09d92015 5813 {
c19d1205 5814 inst.operands[i].preind = 1;
09d92015 5815
c19d1205
ZW
5816 if (*p == '+') p++;
5817 else if (*p == '-') p++, inst.operands[i].negative = 1;
5818
f5f10c66
AV
5819 enum arm_reg_type rtype = REG_TYPE_MQ;
5820 struct neon_type_el et;
5821 if (group_type == GROUP_MVE
5822 && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
5823 {
5824 inst.operands[i].immisreg = 2;
5825 inst.operands[i].imm = reg;
5826
5827 if (skip_past_comma (&p) == SUCCESS)
5828 {
5829 if (parse_shift (&p, i, SHIFT_UXTW_IMMEDIATE) == SUCCESS)
5830 {
5831 inst.operands[i].imm |= inst.relocs[0].exp.X_add_number << 5;
5832 inst.relocs[0].exp.X_add_number = 0;
5833 }
5834 else
5835 return PARSE_OPERAND_FAIL;
5836 }
5837 }
5838 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
09d92015 5839 {
c19d1205
ZW
5840 inst.operands[i].imm = reg;
5841 inst.operands[i].immisreg = 1;
5842
5843 if (skip_past_comma (&p) == SUCCESS)
5844 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 5845 return PARSE_OPERAND_FAIL;
c19d1205 5846 }
5287ad62 5847 else if (skip_past_char (&p, ':') == SUCCESS)
8e560766
MGD
5848 {
5849 /* FIXME: '@' should be used here, but it's filtered out by generic
5850 code before we get to see it here. This may be subject to
5851 change. */
5852 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 5853
8e560766
MGD
5854 if (result != PARSE_OPERAND_SUCCESS)
5855 return result;
5856 }
c19d1205
ZW
5857 else
5858 {
5859 if (inst.operands[i].negative)
5860 {
5861 inst.operands[i].negative = 0;
5862 p--;
5863 }
4962c51a 5864
5f4273c7
NC
5865 if (group_relocations
5866 && ((*p == '#' && *(p + 1) == ':') || *p == ':'))
4962c51a
MS
5867 {
5868 struct group_reloc_table_entry *entry;
5869
477330fc
RM
5870 /* Skip over the #: or : sequence. */
5871 if (*p == '#')
5872 p += 2;
5873 else
5874 p++;
4962c51a
MS
5875
5876 /* Try to parse a group relocation. Anything else is an
477330fc 5877 error. */
4962c51a
MS
5878 if (find_group_reloc_table_entry (&p, &entry) == FAIL)
5879 {
5880 inst.error = _("unknown group relocation");
5881 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5882 }
5883
5884 /* We now have the group relocation table entry corresponding to
5885 the name in the assembler source. Next, we parse the
477330fc 5886 expression. */
e2b0ab59 5887 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
4962c51a
MS
5888 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5889
5890 /* Record the relocation type. */
477330fc
RM
5891 switch (group_type)
5892 {
5893 case GROUP_LDR:
e2b0ab59
AV
5894 inst.relocs[0].type
5895 = (bfd_reloc_code_real_type) entry->ldr_code;
477330fc 5896 break;
4962c51a 5897
477330fc 5898 case GROUP_LDRS:
e2b0ab59
AV
5899 inst.relocs[0].type
5900 = (bfd_reloc_code_real_type) entry->ldrs_code;
477330fc 5901 break;
4962c51a 5902
477330fc 5903 case GROUP_LDC:
e2b0ab59
AV
5904 inst.relocs[0].type
5905 = (bfd_reloc_code_real_type) entry->ldc_code;
477330fc 5906 break;
4962c51a 5907
477330fc
RM
5908 default:
5909 gas_assert (0);
5910 }
4962c51a 5911
e2b0ab59 5912 if (inst.relocs[0].type == 0)
4962c51a
MS
5913 {
5914 inst.error = _("this group relocation is not allowed on this instruction");
5915 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5916 }
477330fc
RM
5917 }
5918 else
26d97720
NS
5919 {
5920 char *q = p;
0198d5e6 5921
e2b0ab59 5922 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
26d97720
NS
5923 return PARSE_OPERAND_FAIL;
5924 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
5925 if (inst.relocs[0].exp.X_op == O_constant
5926 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
5927 {
5928 skip_whitespace (q);
5929 if (*q == '#')
5930 {
5931 q++;
5932 skip_whitespace (q);
5933 }
5934 if (*q == '-')
5935 inst.operands[i].negative = 1;
5936 }
5937 }
09d92015
MM
5938 }
5939 }
8e560766
MGD
5940 else if (skip_past_char (&p, ':') == SUCCESS)
5941 {
5942 /* FIXME: '@' should be used here, but it's filtered out by generic code
5943 before we get to see it here. This may be subject to change. */
5944 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 5945
8e560766
MGD
5946 if (result != PARSE_OPERAND_SUCCESS)
5947 return result;
5948 }
09d92015 5949
c19d1205 5950 if (skip_past_char (&p, ']') == FAIL)
09d92015 5951 {
c19d1205 5952 inst.error = _("']' expected");
4962c51a 5953 return PARSE_OPERAND_FAIL;
09d92015
MM
5954 }
5955
c19d1205
ZW
5956 if (skip_past_char (&p, '!') == SUCCESS)
5957 inst.operands[i].writeback = 1;
09d92015 5958
c19d1205 5959 else if (skip_past_comma (&p) == SUCCESS)
09d92015 5960 {
c19d1205
ZW
5961 if (skip_past_char (&p, '{') == SUCCESS)
5962 {
5963 /* [Rn], {expr} - unindexed, with option */
5964 if (parse_immediate (&p, &inst.operands[i].imm,
ca3f61f7 5965 0, 255, TRUE) == FAIL)
4962c51a 5966 return PARSE_OPERAND_FAIL;
09d92015 5967
c19d1205
ZW
5968 if (skip_past_char (&p, '}') == FAIL)
5969 {
5970 inst.error = _("'}' expected at end of 'option' field");
4962c51a 5971 return PARSE_OPERAND_FAIL;
c19d1205
ZW
5972 }
5973 if (inst.operands[i].preind)
5974 {
5975 inst.error = _("cannot combine index with option");
4962c51a 5976 return PARSE_OPERAND_FAIL;
c19d1205
ZW
5977 }
5978 *str = p;
4962c51a 5979 return PARSE_OPERAND_SUCCESS;
09d92015 5980 }
c19d1205
ZW
5981 else
5982 {
5983 inst.operands[i].postind = 1;
5984 inst.operands[i].writeback = 1;
09d92015 5985
c19d1205
ZW
5986 if (inst.operands[i].preind)
5987 {
5988 inst.error = _("cannot combine pre- and post-indexing");
4962c51a 5989 return PARSE_OPERAND_FAIL;
c19d1205 5990 }
09d92015 5991
c19d1205
ZW
5992 if (*p == '+') p++;
5993 else if (*p == '-') p++, inst.operands[i].negative = 1;
a737bd4d 5994
f5f10c66
AV
5995 enum arm_reg_type rtype = REG_TYPE_MQ;
5996 struct neon_type_el et;
5997 if (group_type == GROUP_MVE
5998 && (reg = arm_typed_reg_parse (&p, rtype, &rtype, &et)) != FAIL)
5999 {
6000 inst.operands[i].immisreg = 2;
6001 inst.operands[i].imm = reg;
6002 }
6003 else if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205 6004 {
477330fc
RM
6005 /* We might be using the immediate for alignment already. If we
6006 are, OR the register number into the low-order bits. */
6007 if (inst.operands[i].immisalign)
6008 inst.operands[i].imm |= reg;
6009 else
6010 inst.operands[i].imm = reg;
c19d1205 6011 inst.operands[i].immisreg = 1;
a737bd4d 6012
c19d1205
ZW
6013 if (skip_past_comma (&p) == SUCCESS)
6014 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 6015 return PARSE_OPERAND_FAIL;
c19d1205
ZW
6016 }
6017 else
6018 {
26d97720 6019 char *q = p;
0198d5e6 6020
c19d1205
ZW
6021 if (inst.operands[i].negative)
6022 {
6023 inst.operands[i].negative = 0;
6024 p--;
6025 }
e2b0ab59 6026 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
4962c51a 6027 return PARSE_OPERAND_FAIL;
26d97720 6028 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
6029 if (inst.relocs[0].exp.X_op == O_constant
6030 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
6031 {
6032 skip_whitespace (q);
6033 if (*q == '#')
6034 {
6035 q++;
6036 skip_whitespace (q);
6037 }
6038 if (*q == '-')
6039 inst.operands[i].negative = 1;
6040 }
c19d1205
ZW
6041 }
6042 }
a737bd4d
NC
6043 }
6044
c19d1205
ZW
6045 /* If at this point neither .preind nor .postind is set, we have a
6046 bare [Rn]{!}, which is shorthand for [Rn,#0]{!}. */
6047 if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
6048 {
6049 inst.operands[i].preind = 1;
e2b0ab59
AV
6050 inst.relocs[0].exp.X_op = O_constant;
6051 inst.relocs[0].exp.X_add_number = 0;
c19d1205
ZW
6052 }
6053 *str = p;
4962c51a
MS
6054 return PARSE_OPERAND_SUCCESS;
6055}
6056
6057static int
6058parse_address (char **str, int i)
6059{
21d799b5 6060 return parse_address_main (str, i, 0, GROUP_LDR) == PARSE_OPERAND_SUCCESS
477330fc 6061 ? SUCCESS : FAIL;
4962c51a
MS
6062}
6063
6064static parse_operand_result
6065parse_address_group_reloc (char **str, int i, group_reloc_type type)
6066{
6067 return parse_address_main (str, i, 1, type);
a737bd4d
NC
6068}
6069
b6895b4f
PB
6070/* Parse an operand for a MOVW or MOVT instruction. */
6071static int
6072parse_half (char **str)
6073{
6074 char * p;
5f4273c7 6075
b6895b4f
PB
6076 p = *str;
6077 skip_past_char (&p, '#');
5f4273c7 6078 if (strncasecmp (p, ":lower16:", 9) == 0)
e2b0ab59 6079 inst.relocs[0].type = BFD_RELOC_ARM_MOVW;
b6895b4f 6080 else if (strncasecmp (p, ":upper16:", 9) == 0)
e2b0ab59 6081 inst.relocs[0].type = BFD_RELOC_ARM_MOVT;
b6895b4f 6082
e2b0ab59 6083 if (inst.relocs[0].type != BFD_RELOC_UNUSED)
b6895b4f
PB
6084 {
6085 p += 9;
5f4273c7 6086 skip_whitespace (p);
b6895b4f
PB
6087 }
6088
e2b0ab59 6089 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
b6895b4f
PB
6090 return FAIL;
6091
e2b0ab59 6092 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 6093 {
e2b0ab59 6094 if (inst.relocs[0].exp.X_op != O_constant)
b6895b4f
PB
6095 {
6096 inst.error = _("constant expression expected");
6097 return FAIL;
6098 }
e2b0ab59
AV
6099 if (inst.relocs[0].exp.X_add_number < 0
6100 || inst.relocs[0].exp.X_add_number > 0xffff)
b6895b4f
PB
6101 {
6102 inst.error = _("immediate value out of range");
6103 return FAIL;
6104 }
6105 }
6106 *str = p;
6107 return SUCCESS;
6108}
6109
c19d1205 6110/* Miscellaneous. */
a737bd4d 6111
c19d1205
ZW
6112/* Parse a PSR flag operand. The value returned is FAIL on syntax error,
6113 or a bitmask suitable to be or-ed into the ARM msr instruction. */
6114static int
d2cd1205 6115parse_psr (char **str, bfd_boolean lhs)
09d92015 6116{
c19d1205
ZW
6117 char *p;
6118 unsigned long psr_field;
62b3e311
PB
6119 const struct asm_psr *psr;
6120 char *start;
d2cd1205 6121 bfd_boolean is_apsr = FALSE;
ac7f631b 6122 bfd_boolean m_profile = ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m);
09d92015 6123
a4482bb6
NC
6124 /* PR gas/12698: If the user has specified -march=all then m_profile will
6125 be TRUE, but we want to ignore it in this case as we are building for any
6126 CPU type, including non-m variants. */
823d2571 6127 if (ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
a4482bb6
NC
6128 m_profile = FALSE;
6129
c19d1205
ZW
6130 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
6131 feature for ease of use and backwards compatibility. */
6132 p = *str;
62b3e311 6133 if (strncasecmp (p, "SPSR", 4) == 0)
d2cd1205
JB
6134 {
6135 if (m_profile)
6136 goto unsupported_psr;
fa94de6b 6137
d2cd1205
JB
6138 psr_field = SPSR_BIT;
6139 }
6140 else if (strncasecmp (p, "CPSR", 4) == 0)
6141 {
6142 if (m_profile)
6143 goto unsupported_psr;
6144
6145 psr_field = 0;
6146 }
6147 else if (strncasecmp (p, "APSR", 4) == 0)
6148 {
6149 /* APSR[_<bits>] can be used as a synonym for CPSR[_<flags>] on ARMv7-A
6150 and ARMv7-R architecture CPUs. */
6151 is_apsr = TRUE;
6152 psr_field = 0;
6153 }
6154 else if (m_profile)
62b3e311
PB
6155 {
6156 start = p;
6157 do
6158 p++;
6159 while (ISALNUM (*p) || *p == '_');
6160
d2cd1205
JB
6161 if (strncasecmp (start, "iapsr", 5) == 0
6162 || strncasecmp (start, "eapsr", 5) == 0
6163 || strncasecmp (start, "xpsr", 4) == 0
6164 || strncasecmp (start, "psr", 3) == 0)
6165 p = start + strcspn (start, "rR") + 1;
6166
21d799b5 6167 psr = (const struct asm_psr *) hash_find_n (arm_v7m_psr_hsh, start,
477330fc 6168 p - start);
d2cd1205 6169
62b3e311
PB
6170 if (!psr)
6171 return FAIL;
09d92015 6172
d2cd1205
JB
6173 /* If APSR is being written, a bitfield may be specified. Note that
6174 APSR itself is handled above. */
6175 if (psr->field <= 3)
6176 {
6177 psr_field = psr->field;
6178 is_apsr = TRUE;
6179 goto check_suffix;
6180 }
6181
62b3e311 6182 *str = p;
d2cd1205
JB
6183 /* M-profile MSR instructions have the mask field set to "10", except
6184 *PSR variants which modify APSR, which may use a different mask (and
6185 have been handled already). Do that by setting the PSR_f field
6186 here. */
6187 return psr->field | (lhs ? PSR_f : 0);
62b3e311 6188 }
d2cd1205
JB
6189 else
6190 goto unsupported_psr;
09d92015 6191
62b3e311 6192 p += 4;
d2cd1205 6193check_suffix:
c19d1205
ZW
6194 if (*p == '_')
6195 {
6196 /* A suffix follows. */
c19d1205
ZW
6197 p++;
6198 start = p;
a737bd4d 6199
c19d1205
ZW
6200 do
6201 p++;
6202 while (ISALNUM (*p) || *p == '_');
a737bd4d 6203
d2cd1205
JB
6204 if (is_apsr)
6205 {
6206 /* APSR uses a notation for bits, rather than fields. */
6207 unsigned int nzcvq_bits = 0;
6208 unsigned int g_bit = 0;
6209 char *bit;
fa94de6b 6210
d2cd1205
JB
6211 for (bit = start; bit != p; bit++)
6212 {
6213 switch (TOLOWER (*bit))
477330fc 6214 {
d2cd1205
JB
6215 case 'n':
6216 nzcvq_bits |= (nzcvq_bits & 0x01) ? 0x20 : 0x01;
6217 break;
6218
6219 case 'z':
6220 nzcvq_bits |= (nzcvq_bits & 0x02) ? 0x20 : 0x02;
6221 break;
6222
6223 case 'c':
6224 nzcvq_bits |= (nzcvq_bits & 0x04) ? 0x20 : 0x04;
6225 break;
6226
6227 case 'v':
6228 nzcvq_bits |= (nzcvq_bits & 0x08) ? 0x20 : 0x08;
6229 break;
fa94de6b 6230
d2cd1205
JB
6231 case 'q':
6232 nzcvq_bits |= (nzcvq_bits & 0x10) ? 0x20 : 0x10;
6233 break;
fa94de6b 6234
d2cd1205
JB
6235 case 'g':
6236 g_bit |= (g_bit & 0x1) ? 0x2 : 0x1;
6237 break;
fa94de6b 6238
d2cd1205
JB
6239 default:
6240 inst.error = _("unexpected bit specified after APSR");
6241 return FAIL;
6242 }
6243 }
fa94de6b 6244
d2cd1205
JB
6245 if (nzcvq_bits == 0x1f)
6246 psr_field |= PSR_f;
fa94de6b 6247
d2cd1205
JB
6248 if (g_bit == 0x1)
6249 {
6250 if (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp))
477330fc 6251 {
d2cd1205
JB
6252 inst.error = _("selected processor does not "
6253 "support DSP extension");
6254 return FAIL;
6255 }
6256
6257 psr_field |= PSR_s;
6258 }
fa94de6b 6259
d2cd1205
JB
6260 if ((nzcvq_bits & 0x20) != 0
6261 || (nzcvq_bits != 0x1f && nzcvq_bits != 0)
6262 || (g_bit & 0x2) != 0)
6263 {
6264 inst.error = _("bad bitmask specified after APSR");
6265 return FAIL;
6266 }
6267 }
6268 else
477330fc 6269 {
d2cd1205 6270 psr = (const struct asm_psr *) hash_find_n (arm_psr_hsh, start,
477330fc 6271 p - start);
d2cd1205 6272 if (!psr)
477330fc 6273 goto error;
a737bd4d 6274
d2cd1205
JB
6275 psr_field |= psr->field;
6276 }
a737bd4d 6277 }
c19d1205 6278 else
a737bd4d 6279 {
c19d1205
ZW
6280 if (ISALNUM (*p))
6281 goto error; /* Garbage after "[CS]PSR". */
6282
d2cd1205 6283 /* Unadorned APSR is equivalent to APSR_nzcvq/CPSR_f (for writes). This
477330fc 6284 is deprecated, but allow it anyway. */
d2cd1205
JB
6285 if (is_apsr && lhs)
6286 {
6287 psr_field |= PSR_f;
6288 as_tsktsk (_("writing to APSR without specifying a bitmask is "
6289 "deprecated"));
6290 }
6291 else if (!m_profile)
6292 /* These bits are never right for M-profile devices: don't set them
6293 (only code paths which read/write APSR reach here). */
6294 psr_field |= (PSR_c | PSR_f);
a737bd4d 6295 }
c19d1205
ZW
6296 *str = p;
6297 return psr_field;
a737bd4d 6298
d2cd1205
JB
6299 unsupported_psr:
6300 inst.error = _("selected processor does not support requested special "
6301 "purpose register");
6302 return FAIL;
6303
c19d1205
ZW
6304 error:
6305 inst.error = _("flag for {c}psr instruction expected");
6306 return FAIL;
a737bd4d
NC
6307}
6308
32c36c3c
AV
6309static int
6310parse_sys_vldr_vstr (char **str)
6311{
6312 unsigned i;
6313 int val = FAIL;
6314 struct {
6315 const char *name;
6316 int regl;
6317 int regh;
6318 } sysregs[] = {
6319 {"FPSCR", 0x1, 0x0},
6320 {"FPSCR_nzcvqc", 0x2, 0x0},
6321 {"VPR", 0x4, 0x1},
6322 {"P0", 0x5, 0x1},
6323 {"FPCXTNS", 0x6, 0x1},
6324 {"FPCXTS", 0x7, 0x1}
6325 };
6326 char *op_end = strchr (*str, ',');
6327 size_t op_strlen = op_end - *str;
6328
6329 for (i = 0; i < sizeof (sysregs) / sizeof (sysregs[0]); i++)
6330 {
6331 if (!strncmp (*str, sysregs[i].name, op_strlen))
6332 {
6333 val = sysregs[i].regl | (sysregs[i].regh << 3);
6334 *str = op_end;
6335 break;
6336 }
6337 }
6338
6339 return val;
6340}
6341
c19d1205
ZW
6342/* Parse the flags argument to CPSI[ED]. Returns FAIL on error, or a
6343 value suitable for splatting into the AIF field of the instruction. */
a737bd4d 6344
c19d1205
ZW
6345static int
6346parse_cps_flags (char **str)
a737bd4d 6347{
c19d1205
ZW
6348 int val = 0;
6349 int saw_a_flag = 0;
6350 char *s = *str;
a737bd4d 6351
c19d1205
ZW
6352 for (;;)
6353 switch (*s++)
6354 {
6355 case '\0': case ',':
6356 goto done;
a737bd4d 6357
c19d1205
ZW
6358 case 'a': case 'A': saw_a_flag = 1; val |= 0x4; break;
6359 case 'i': case 'I': saw_a_flag = 1; val |= 0x2; break;
6360 case 'f': case 'F': saw_a_flag = 1; val |= 0x1; break;
a737bd4d 6361
c19d1205
ZW
6362 default:
6363 inst.error = _("unrecognized CPS flag");
6364 return FAIL;
6365 }
a737bd4d 6366
c19d1205
ZW
6367 done:
6368 if (saw_a_flag == 0)
a737bd4d 6369 {
c19d1205
ZW
6370 inst.error = _("missing CPS flags");
6371 return FAIL;
a737bd4d 6372 }
a737bd4d 6373
c19d1205
ZW
6374 *str = s - 1;
6375 return val;
a737bd4d
NC
6376}
6377
c19d1205
ZW
6378/* Parse an endian specifier ("BE" or "LE", case insensitive);
6379 returns 0 for big-endian, 1 for little-endian, FAIL for an error. */
a737bd4d
NC
6380
6381static int
c19d1205 6382parse_endian_specifier (char **str)
a737bd4d 6383{
c19d1205
ZW
6384 int little_endian;
6385 char *s = *str;
a737bd4d 6386
c19d1205
ZW
6387 if (strncasecmp (s, "BE", 2))
6388 little_endian = 0;
6389 else if (strncasecmp (s, "LE", 2))
6390 little_endian = 1;
6391 else
a737bd4d 6392 {
c19d1205 6393 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6394 return FAIL;
6395 }
6396
c19d1205 6397 if (ISALNUM (s[2]) || s[2] == '_')
a737bd4d 6398 {
c19d1205 6399 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6400 return FAIL;
6401 }
6402
c19d1205
ZW
6403 *str = s + 2;
6404 return little_endian;
6405}
a737bd4d 6406
c19d1205
ZW
6407/* Parse a rotation specifier: ROR #0, #8, #16, #24. *val receives a
6408 value suitable for poking into the rotate field of an sxt or sxta
6409 instruction, or FAIL on error. */
6410
6411static int
6412parse_ror (char **str)
6413{
6414 int rot;
6415 char *s = *str;
6416
6417 if (strncasecmp (s, "ROR", 3) == 0)
6418 s += 3;
6419 else
a737bd4d 6420 {
c19d1205 6421 inst.error = _("missing rotation field after comma");
a737bd4d
NC
6422 return FAIL;
6423 }
c19d1205
ZW
6424
6425 if (parse_immediate (&s, &rot, 0, 24, FALSE) == FAIL)
6426 return FAIL;
6427
6428 switch (rot)
a737bd4d 6429 {
c19d1205
ZW
6430 case 0: *str = s; return 0x0;
6431 case 8: *str = s; return 0x1;
6432 case 16: *str = s; return 0x2;
6433 case 24: *str = s; return 0x3;
6434
6435 default:
6436 inst.error = _("rotation can only be 0, 8, 16, or 24");
a737bd4d
NC
6437 return FAIL;
6438 }
c19d1205 6439}
a737bd4d 6440
c19d1205
ZW
6441/* Parse a conditional code (from conds[] below). The value returned is in the
6442 range 0 .. 14, or FAIL. */
6443static int
6444parse_cond (char **str)
6445{
c462b453 6446 char *q;
c19d1205 6447 const struct asm_cond *c;
c462b453
PB
6448 int n;
6449 /* Condition codes are always 2 characters, so matching up to
6450 3 characters is sufficient. */
6451 char cond[3];
a737bd4d 6452
c462b453
PB
6453 q = *str;
6454 n = 0;
6455 while (ISALPHA (*q) && n < 3)
6456 {
e07e6e58 6457 cond[n] = TOLOWER (*q);
c462b453
PB
6458 q++;
6459 n++;
6460 }
a737bd4d 6461
21d799b5 6462 c = (const struct asm_cond *) hash_find_n (arm_cond_hsh, cond, n);
c19d1205 6463 if (!c)
a737bd4d 6464 {
c19d1205 6465 inst.error = _("condition required");
a737bd4d
NC
6466 return FAIL;
6467 }
6468
c19d1205
ZW
6469 *str = q;
6470 return c->value;
6471}
6472
62b3e311
PB
6473/* Parse an option for a barrier instruction. Returns the encoding for the
6474 option, or FAIL. */
6475static int
6476parse_barrier (char **str)
6477{
6478 char *p, *q;
6479 const struct asm_barrier_opt *o;
6480
6481 p = q = *str;
6482 while (ISALPHA (*q))
6483 q++;
6484
21d799b5 6485 o = (const struct asm_barrier_opt *) hash_find_n (arm_barrier_opt_hsh, p,
477330fc 6486 q - p);
62b3e311
PB
6487 if (!o)
6488 return FAIL;
6489
e797f7e0
MGD
6490 if (!mark_feature_used (&o->arch))
6491 return FAIL;
6492
62b3e311
PB
6493 *str = q;
6494 return o->value;
6495}
6496
92e90b6e
PB
6497/* Parse the operands of a table branch instruction. Similar to a memory
6498 operand. */
6499static int
6500parse_tb (char **str)
6501{
6502 char * p = *str;
6503 int reg;
6504
6505 if (skip_past_char (&p, '[') == FAIL)
ab1eb5fe
PB
6506 {
6507 inst.error = _("'[' expected");
6508 return FAIL;
6509 }
92e90b6e 6510
dcbf9037 6511 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6512 {
6513 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6514 return FAIL;
6515 }
6516 inst.operands[0].reg = reg;
6517
6518 if (skip_past_comma (&p) == FAIL)
ab1eb5fe
PB
6519 {
6520 inst.error = _("',' expected");
6521 return FAIL;
6522 }
5f4273c7 6523
dcbf9037 6524 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6525 {
6526 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6527 return FAIL;
6528 }
6529 inst.operands[0].imm = reg;
6530
6531 if (skip_past_comma (&p) == SUCCESS)
6532 {
6533 if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
6534 return FAIL;
e2b0ab59 6535 if (inst.relocs[0].exp.X_add_number != 1)
92e90b6e
PB
6536 {
6537 inst.error = _("invalid shift");
6538 return FAIL;
6539 }
6540 inst.operands[0].shifted = 1;
6541 }
6542
6543 if (skip_past_char (&p, ']') == FAIL)
6544 {
6545 inst.error = _("']' expected");
6546 return FAIL;
6547 }
6548 *str = p;
6549 return SUCCESS;
6550}
6551
5287ad62
JB
6552/* Parse the operands of a Neon VMOV instruction. See do_neon_mov for more
6553 information on the types the operands can take and how they are encoded.
037e8744
JB
6554 Up to four operands may be read; this function handles setting the
6555 ".present" field for each read operand itself.
5287ad62
JB
6556 Updates STR and WHICH_OPERAND if parsing is successful and returns SUCCESS,
6557 else returns FAIL. */
6558
6559static int
6560parse_neon_mov (char **str, int *which_operand)
6561{
6562 int i = *which_operand, val;
6563 enum arm_reg_type rtype;
6564 char *ptr = *str;
dcbf9037 6565 struct neon_type_el optype;
5f4273c7 6566
57785aa2
AV
6567 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6568 {
6569 /* Cases 17 or 19. */
6570 inst.operands[i].reg = val;
6571 inst.operands[i].isvec = 1;
6572 inst.operands[i].isscalar = 2;
6573 inst.operands[i].vectype = optype;
6574 inst.operands[i++].present = 1;
6575
6576 if (skip_past_comma (&ptr) == FAIL)
6577 goto wanted_comma;
6578
6579 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
6580 {
6581 /* Case 17: VMOV<c>.<dt> <Qd[idx]>, <Rt> */
6582 inst.operands[i].reg = val;
6583 inst.operands[i].isreg = 1;
6584 inst.operands[i].present = 1;
6585 }
6586 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6587 {
6588 /* Case 19: VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2> */
6589 inst.operands[i].reg = val;
6590 inst.operands[i].isvec = 1;
6591 inst.operands[i].isscalar = 2;
6592 inst.operands[i].vectype = optype;
6593 inst.operands[i++].present = 1;
6594
6595 if (skip_past_comma (&ptr) == FAIL)
6596 goto wanted_comma;
6597
6598 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6599 goto wanted_arm;
6600
6601 inst.operands[i].reg = val;
6602 inst.operands[i].isreg = 1;
6603 inst.operands[i++].present = 1;
6604
6605 if (skip_past_comma (&ptr) == FAIL)
6606 goto wanted_comma;
6607
6608 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6609 goto wanted_arm;
6610
6611 inst.operands[i].reg = val;
6612 inst.operands[i].isreg = 1;
6613 inst.operands[i].present = 1;
6614 }
6615 else
6616 {
6617 first_error (_("expected ARM or MVE vector register"));
6618 return FAIL;
6619 }
6620 }
6621 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
5287ad62
JB
6622 {
6623 /* Case 4: VMOV<c><q>.<size> <Dn[x]>, <Rd>. */
6624 inst.operands[i].reg = val;
6625 inst.operands[i].isscalar = 1;
dcbf9037 6626 inst.operands[i].vectype = optype;
5287ad62
JB
6627 inst.operands[i++].present = 1;
6628
6629 if (skip_past_comma (&ptr) == FAIL)
477330fc 6630 goto wanted_comma;
5f4273c7 6631
dcbf9037 6632 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
477330fc 6633 goto wanted_arm;
5f4273c7 6634
5287ad62
JB
6635 inst.operands[i].reg = val;
6636 inst.operands[i].isreg = 1;
6637 inst.operands[i].present = 1;
6638 }
57785aa2
AV
6639 else if (((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype, &optype))
6640 != FAIL)
6641 || ((val = arm_typed_reg_parse (&ptr, REG_TYPE_MQ, &rtype, &optype))
6642 != FAIL))
5287ad62
JB
6643 {
6644 /* Cases 0, 1, 2, 3, 5 (D only). */
6645 if (skip_past_comma (&ptr) == FAIL)
477330fc 6646 goto wanted_comma;
5f4273c7 6647
5287ad62
JB
6648 inst.operands[i].reg = val;
6649 inst.operands[i].isreg = 1;
6650 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
037e8744
JB
6651 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6652 inst.operands[i].isvec = 1;
dcbf9037 6653 inst.operands[i].vectype = optype;
5287ad62
JB
6654 inst.operands[i++].present = 1;
6655
dcbf9037 6656 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc
RM
6657 {
6658 /* Case 5: VMOV<c><q> <Dm>, <Rd>, <Rn>.
6659 Case 13: VMOV <Sd>, <Rm> */
6660 inst.operands[i].reg = val;
6661 inst.operands[i].isreg = 1;
6662 inst.operands[i].present = 1;
6663
6664 if (rtype == REG_TYPE_NQ)
6665 {
6666 first_error (_("can't use Neon quad register here"));
6667 return FAIL;
6668 }
6669 else if (rtype != REG_TYPE_VFS)
6670 {
6671 i++;
6672 if (skip_past_comma (&ptr) == FAIL)
6673 goto wanted_comma;
6674 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6675 goto wanted_arm;
6676 inst.operands[i].reg = val;
6677 inst.operands[i].isreg = 1;
6678 inst.operands[i].present = 1;
6679 }
6680 }
037e8744 6681 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype,
477330fc
RM
6682 &optype)) != FAIL)
6683 {
6684 /* Case 0: VMOV<c><q> <Qd>, <Qm>
6685 Case 1: VMOV<c><q> <Dd>, <Dm>
6686 Case 8: VMOV.F32 <Sd>, <Sm>
6687 Case 15: VMOV <Sd>, <Se>, <Rn>, <Rm> */
6688
6689 inst.operands[i].reg = val;
6690 inst.operands[i].isreg = 1;
6691 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
6692 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6693 inst.operands[i].isvec = 1;
6694 inst.operands[i].vectype = optype;
6695 inst.operands[i].present = 1;
6696
6697 if (skip_past_comma (&ptr) == SUCCESS)
6698 {
6699 /* Case 15. */
6700 i++;
6701
6702 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6703 goto wanted_arm;
6704
6705 inst.operands[i].reg = val;
6706 inst.operands[i].isreg = 1;
6707 inst.operands[i++].present = 1;
6708
6709 if (skip_past_comma (&ptr) == FAIL)
6710 goto wanted_comma;
6711
6712 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6713 goto wanted_arm;
6714
6715 inst.operands[i].reg = val;
6716 inst.operands[i].isreg = 1;
6717 inst.operands[i].present = 1;
6718 }
6719 }
4641781c 6720 else if (parse_qfloat_immediate (&ptr, &inst.operands[i].imm) == SUCCESS)
477330fc
RM
6721 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<float-imm>
6722 Case 3: VMOV<c><q>.<dt> <Dd>, #<float-imm>
6723 Case 10: VMOV.F32 <Sd>, #<imm>
6724 Case 11: VMOV.F64 <Dd>, #<imm> */
6725 inst.operands[i].immisfloat = 1;
8335d6aa
JW
6726 else if (parse_big_immediate (&ptr, i, NULL, /*allow_symbol_p=*/FALSE)
6727 == SUCCESS)
477330fc
RM
6728 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<imm>
6729 Case 3: VMOV<c><q>.<dt> <Dd>, #<imm> */
6730 ;
5287ad62 6731 else
477330fc
RM
6732 {
6733 first_error (_("expected <Rm> or <Dm> or <Qm> operand"));
6734 return FAIL;
6735 }
5287ad62 6736 }
dcbf9037 6737 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
5287ad62 6738 {
57785aa2 6739 /* Cases 6, 7, 16, 18. */
5287ad62
JB
6740 inst.operands[i].reg = val;
6741 inst.operands[i].isreg = 1;
6742 inst.operands[i++].present = 1;
5f4273c7 6743
5287ad62 6744 if (skip_past_comma (&ptr) == FAIL)
477330fc 6745 goto wanted_comma;
5f4273c7 6746
57785aa2
AV
6747 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ)) != FAIL)
6748 {
6749 /* Case 18: VMOV<c>.<dt> <Rt>, <Qn[idx]> */
6750 inst.operands[i].reg = val;
6751 inst.operands[i].isscalar = 2;
6752 inst.operands[i].present = 1;
6753 inst.operands[i].vectype = optype;
6754 }
6755 else if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_VFD)) != FAIL)
477330fc
RM
6756 {
6757 /* Case 6: VMOV<c><q>.<dt> <Rd>, <Dn[x]> */
6758 inst.operands[i].reg = val;
6759 inst.operands[i].isscalar = 1;
6760 inst.operands[i].present = 1;
6761 inst.operands[i].vectype = optype;
6762 }
dcbf9037 6763 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc 6764 {
477330fc
RM
6765 inst.operands[i].reg = val;
6766 inst.operands[i].isreg = 1;
6767 inst.operands[i++].present = 1;
6768
6769 if (skip_past_comma (&ptr) == FAIL)
6770 goto wanted_comma;
6771
6772 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFSD, &rtype, &optype))
57785aa2 6773 != FAIL)
477330fc 6774 {
57785aa2 6775 /* Case 7: VMOV<c><q> <Rd>, <Rn>, <Dm> */
477330fc 6776
477330fc
RM
6777 inst.operands[i].reg = val;
6778 inst.operands[i].isreg = 1;
6779 inst.operands[i].isvec = 1;
57785aa2 6780 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
477330fc
RM
6781 inst.operands[i].vectype = optype;
6782 inst.operands[i].present = 1;
57785aa2
AV
6783
6784 if (rtype == REG_TYPE_VFS)
6785 {
6786 /* Case 14. */
6787 i++;
6788 if (skip_past_comma (&ptr) == FAIL)
6789 goto wanted_comma;
6790 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL,
6791 &optype)) == FAIL)
6792 {
6793 first_error (_(reg_expected_msgs[REG_TYPE_VFS]));
6794 return FAIL;
6795 }
6796 inst.operands[i].reg = val;
6797 inst.operands[i].isreg = 1;
6798 inst.operands[i].isvec = 1;
6799 inst.operands[i].issingle = 1;
6800 inst.operands[i].vectype = optype;
6801 inst.operands[i].present = 1;
6802 }
6803 }
6804 else
6805 {
6806 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
6807 != FAIL)
6808 {
6809 /* Case 16: VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]> */
6810 inst.operands[i].reg = val;
6811 inst.operands[i].isvec = 1;
6812 inst.operands[i].isscalar = 2;
6813 inst.operands[i].vectype = optype;
6814 inst.operands[i++].present = 1;
6815
6816 if (skip_past_comma (&ptr) == FAIL)
6817 goto wanted_comma;
6818
6819 if ((val = parse_scalar (&ptr, 8, &optype, REG_TYPE_MQ))
6820 == FAIL)
6821 {
6822 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
6823 return FAIL;
6824 }
6825 inst.operands[i].reg = val;
6826 inst.operands[i].isvec = 1;
6827 inst.operands[i].isscalar = 2;
6828 inst.operands[i].vectype = optype;
6829 inst.operands[i].present = 1;
6830 }
6831 else
6832 {
6833 first_error (_("VFP single, double or MVE vector register"
6834 " expected"));
6835 return FAIL;
6836 }
477330fc
RM
6837 }
6838 }
037e8744 6839 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL, &optype))
477330fc
RM
6840 != FAIL)
6841 {
6842 /* Case 13. */
6843 inst.operands[i].reg = val;
6844 inst.operands[i].isreg = 1;
6845 inst.operands[i].isvec = 1;
6846 inst.operands[i].issingle = 1;
6847 inst.operands[i].vectype = optype;
6848 inst.operands[i].present = 1;
6849 }
5287ad62
JB
6850 }
6851 else
6852 {
dcbf9037 6853 first_error (_("parse error"));
5287ad62
JB
6854 return FAIL;
6855 }
6856
6857 /* Successfully parsed the operands. Update args. */
6858 *which_operand = i;
6859 *str = ptr;
6860 return SUCCESS;
6861
5f4273c7 6862 wanted_comma:
dcbf9037 6863 first_error (_("expected comma"));
5287ad62 6864 return FAIL;
5f4273c7
NC
6865
6866 wanted_arm:
dcbf9037 6867 first_error (_(reg_expected_msgs[REG_TYPE_RN]));
5287ad62 6868 return FAIL;
5287ad62
JB
6869}
6870
5be8be5d
DG
6871/* Use this macro when the operand constraints are different
6872 for ARM and THUMB (e.g. ldrd). */
6873#define MIX_ARM_THUMB_OPERANDS(arm_operand, thumb_operand) \
6874 ((arm_operand) | ((thumb_operand) << 16))
6875
c19d1205
ZW
6876/* Matcher codes for parse_operands. */
6877enum operand_parse_code
6878{
6879 OP_stop, /* end of line */
6880
6881 OP_RR, /* ARM register */
6882 OP_RRnpc, /* ARM register, not r15 */
5be8be5d 6883 OP_RRnpcsp, /* ARM register, neither r15 nor r13 (a.k.a. 'BadReg') */
c19d1205 6884 OP_RRnpcb, /* ARM register, not r15, in square brackets */
fa94de6b 6885 OP_RRnpctw, /* ARM register, not r15 in Thumb-state or with writeback,
55881a11 6886 optional trailing ! */
c19d1205
ZW
6887 OP_RRw, /* ARM register, not r15, optional trailing ! */
6888 OP_RCP, /* Coprocessor number */
6889 OP_RCN, /* Coprocessor register */
6890 OP_RF, /* FPA register */
6891 OP_RVS, /* VFP single precision register */
5287ad62
JB
6892 OP_RVD, /* VFP double precision register (0..15) */
6893 OP_RND, /* Neon double precision register (0..31) */
5ee91343
AV
6894 OP_RNDMQ, /* Neon double precision (0..31) or MVE vector register. */
6895 OP_RNDMQR, /* Neon double precision (0..31), MVE vector or ARM register.
6896 */
5287ad62 6897 OP_RNQ, /* Neon quad precision register */
5ee91343 6898 OP_RNQMQ, /* Neon quad or MVE vector register. */
037e8744 6899 OP_RVSD, /* VFP single or double precision register */
1b883319 6900 OP_RVSD_COND, /* VFP single, double precision register or condition code. */
dd9634d9 6901 OP_RVSDMQ, /* VFP single, double precision or MVE vector register. */
dec41383 6902 OP_RNSD, /* Neon single or double precision register */
5287ad62 6903 OP_RNDQ, /* Neon double or quad precision register */
5ee91343 6904 OP_RNDQMQ, /* Neon double, quad or MVE vector register. */
7df54120 6905 OP_RNDQMQR, /* Neon double, quad, MVE vector or ARM register. */
037e8744 6906 OP_RNSDQ, /* Neon single, double or quad precision register */
5287ad62 6907 OP_RNSC, /* Neon scalar D[X] */
c19d1205
ZW
6908 OP_RVC, /* VFP control register */
6909 OP_RMF, /* Maverick F register */
6910 OP_RMD, /* Maverick D register */
6911 OP_RMFX, /* Maverick FX register */
6912 OP_RMDX, /* Maverick DX register */
6913 OP_RMAX, /* Maverick AX register */
6914 OP_RMDS, /* Maverick DSPSC register */
6915 OP_RIWR, /* iWMMXt wR register */
6916 OP_RIWC, /* iWMMXt wC register */
6917 OP_RIWG, /* iWMMXt wCG register */
6918 OP_RXA, /* XScale accumulator register */
6919
5ee91343
AV
6920 OP_RNSDQMQ, /* Neon single, double or quad register or MVE vector register
6921 */
6922 OP_RNSDQMQR, /* Neon single, double or quad register, MVE vector register or
6923 GPR (no SP/SP) */
a302e574 6924 OP_RMQ, /* MVE vector register. */
1b883319 6925 OP_RMQRZ, /* MVE vector or ARM register including ZR. */
a302e574 6926
60f993ce
AV
6927 /* New operands for Armv8.1-M Mainline. */
6928 OP_LR, /* ARM LR register */
a302e574
AV
6929 OP_RRe, /* ARM register, only even numbered. */
6930 OP_RRo, /* ARM register, only odd numbered, not r13 or r15. */
60f993ce
AV
6931 OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
6932
c19d1205 6933 OP_REGLST, /* ARM register list */
4b5a202f 6934 OP_CLRMLST, /* CLRM register list */
c19d1205
ZW
6935 OP_VRSLST, /* VFP single-precision register list */
6936 OP_VRDLST, /* VFP double-precision register list */
037e8744 6937 OP_VRSDLST, /* VFP single or double-precision register list (& quad) */
5287ad62
JB
6938 OP_NRDLST, /* Neon double-precision register list (d0-d31, qN aliases) */
6939 OP_NSTRLST, /* Neon element/structure list */
efd6b359 6940 OP_VRSDVLST, /* VFP single or double-precision register list and VPR */
35c228db
AV
6941 OP_MSTRLST2, /* MVE vector list with two elements. */
6942 OP_MSTRLST4, /* MVE vector list with four elements. */
5287ad62 6943
5287ad62 6944 OP_RNDQ_I0, /* Neon D or Q reg, or immediate zero. */
037e8744 6945 OP_RVSD_I0, /* VFP S or D reg, or immediate zero. */
aacf0b33 6946 OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero. */
1b883319
AV
6947 OP_RSVDMQ_FI0, /* VFP S, D, MVE vector register or floating point immediate
6948 zero. */
5287ad62 6949 OP_RR_RNSC, /* ARM reg or Neon scalar. */
dec41383 6950 OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar. */
037e8744 6951 OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar. */
886e1c73
AV
6952 OP_RNSDQ_RNSC_MQ, /* Vector S, D or Q reg, Neon scalar or MVE vector register.
6953 */
5287ad62 6954 OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar. */
5d281bf0 6955 OP_RNDQMQ_RNSC, /* Neon D, Q or MVE vector reg, or Neon scalar. */
5287ad62
JB
6956 OP_RND_RNSC, /* Neon D reg, or Neon scalar. */
6957 OP_VMOV, /* Neon VMOV operands. */
4316f0d2 6958 OP_RNDQ_Ibig, /* Neon D or Q reg, or big immediate for logic and VMVN. */
f601a00c
AV
6959 /* Neon D, Q or MVE vector register, or big immediate for logic and VMVN. */
6960 OP_RNDQMQ_Ibig,
5287ad62 6961 OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift. */
2d447fca 6962 OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2. */
32c36c3c 6963 OP_VLDR, /* VLDR operand. */
5287ad62
JB
6964
6965 OP_I0, /* immediate zero */
c19d1205
ZW
6966 OP_I7, /* immediate value 0 .. 7 */
6967 OP_I15, /* 0 .. 15 */
6968 OP_I16, /* 1 .. 16 */
5287ad62 6969 OP_I16z, /* 0 .. 16 */
c19d1205
ZW
6970 OP_I31, /* 0 .. 31 */
6971 OP_I31w, /* 0 .. 31, optional trailing ! */
6972 OP_I32, /* 1 .. 32 */
5287ad62
JB
6973 OP_I32z, /* 0 .. 32 */
6974 OP_I63, /* 0 .. 63 */
c19d1205 6975 OP_I63s, /* -64 .. 63 */
5287ad62
JB
6976 OP_I64, /* 1 .. 64 */
6977 OP_I64z, /* 0 .. 64 */
c19d1205 6978 OP_I255, /* 0 .. 255 */
c19d1205
ZW
6979
6980 OP_I4b, /* immediate, prefix optional, 1 .. 4 */
6981 OP_I7b, /* 0 .. 7 */
6982 OP_I15b, /* 0 .. 15 */
6983 OP_I31b, /* 0 .. 31 */
6984
6985 OP_SH, /* shifter operand */
4962c51a 6986 OP_SHG, /* shifter operand with possible group relocation */
c19d1205 6987 OP_ADDR, /* Memory address expression (any mode) */
35c228db 6988 OP_ADDRMVE, /* Memory address expression for MVE's VSTR/VLDR. */
4962c51a
MS
6989 OP_ADDRGLDR, /* Mem addr expr (any mode) with possible LDR group reloc */
6990 OP_ADDRGLDRS, /* Mem addr expr (any mode) with possible LDRS group reloc */
6991 OP_ADDRGLDC, /* Mem addr expr (any mode) with possible LDC group reloc */
c19d1205
ZW
6992 OP_EXP, /* arbitrary expression */
6993 OP_EXPi, /* same, with optional immediate prefix */
6994 OP_EXPr, /* same, with optional relocation suffix */
e2b0ab59 6995 OP_EXPs, /* same, with optional non-first operand relocation suffix */
b6895b4f 6996 OP_HALF, /* 0 .. 65535 or low/high reloc. */
c28eeff2
SN
6997 OP_IROT1, /* VCADD rotate immediate: 90, 270. */
6998 OP_IROT2, /* VCMLA rotate immediate: 0, 90, 180, 270. */
c19d1205
ZW
6999
7000 OP_CPSF, /* CPS flags */
7001 OP_ENDI, /* Endianness specifier */
d2cd1205
JB
7002 OP_wPSR, /* CPSR/SPSR/APSR mask for msr (writing). */
7003 OP_rPSR, /* CPSR/SPSR/APSR mask for msr (reading). */
c19d1205 7004 OP_COND, /* conditional code */
92e90b6e 7005 OP_TB, /* Table branch. */
c19d1205 7006
037e8744
JB
7007 OP_APSR_RR, /* ARM register or "APSR_nzcv". */
7008
c19d1205 7009 OP_RRnpc_I0, /* ARM register or literal 0 */
33eaf5de 7010 OP_RR_EXr, /* ARM register or expression with opt. reloc stuff. */
c19d1205
ZW
7011 OP_RR_EXi, /* ARM register or expression with imm prefix */
7012 OP_RF_IF, /* FPA register or immediate */
7013 OP_RIWR_RIWC, /* iWMMXt R or C reg */
41adaa5c 7014 OP_RIWC_RIWG, /* iWMMXt wC or wCG reg */
c19d1205
ZW
7015
7016 /* Optional operands. */
7017 OP_oI7b, /* immediate, prefix optional, 0 .. 7 */
7018 OP_oI31b, /* 0 .. 31 */
5287ad62 7019 OP_oI32b, /* 1 .. 32 */
5f1af56b 7020 OP_oI32z, /* 0 .. 32 */
c19d1205
ZW
7021 OP_oIffffb, /* 0 .. 65535 */
7022 OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
7023
7024 OP_oRR, /* ARM register */
60f993ce 7025 OP_oLR, /* ARM LR register */
c19d1205 7026 OP_oRRnpc, /* ARM register, not the PC */
5be8be5d 7027 OP_oRRnpcsp, /* ARM register, neither the PC nor the SP (a.k.a. BadReg) */
b6702015 7028 OP_oRRw, /* ARM register, not r15, optional trailing ! */
5287ad62
JB
7029 OP_oRND, /* Optional Neon double precision register */
7030 OP_oRNQ, /* Optional Neon quad precision register */
5ee91343 7031 OP_oRNDQMQ, /* Optional Neon double, quad or MVE vector register. */
5287ad62 7032 OP_oRNDQ, /* Optional Neon double or quad precision register */
037e8744 7033 OP_oRNSDQ, /* Optional single, double or quad precision vector register */
5ee91343
AV
7034 OP_oRNSDQMQ, /* Optional single, double or quad register or MVE vector
7035 register. */
c19d1205
ZW
7036 OP_oSHll, /* LSL immediate */
7037 OP_oSHar, /* ASR immediate */
7038 OP_oSHllar, /* LSL or ASR immediate */
7039 OP_oROR, /* ROR 0/8/16/24 */
52e7f43d 7040 OP_oBARRIER_I15, /* Option argument for a barrier instruction. */
c19d1205 7041
1b883319
AV
7042 OP_oRMQRZ, /* optional MVE vector or ARM register including ZR. */
7043
5be8be5d
DG
7044 /* Some pre-defined mixed (ARM/THUMB) operands. */
7045 OP_RR_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
7046 OP_RRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
7047 OP_oRRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_oRRnpc, OP_oRRnpcsp),
7048
c19d1205
ZW
7049 OP_FIRST_OPTIONAL = OP_oI7b
7050};
a737bd4d 7051
c19d1205
ZW
7052/* Generic instruction operand parser. This does no encoding and no
7053 semantic validation; it merely squirrels values away in the inst
7054 structure. Returns SUCCESS or FAIL depending on whether the
7055 specified grammar matched. */
7056static int
5be8be5d 7057parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
c19d1205 7058{
5be8be5d 7059 unsigned const int *upat = pattern;
c19d1205
ZW
7060 char *backtrack_pos = 0;
7061 const char *backtrack_error = 0;
99aad254 7062 int i, val = 0, backtrack_index = 0;
5287ad62 7063 enum arm_reg_type rtype;
4962c51a 7064 parse_operand_result result;
5be8be5d 7065 unsigned int op_parse_code;
efd6b359 7066 bfd_boolean partial_match;
c19d1205 7067
e07e6e58
NC
7068#define po_char_or_fail(chr) \
7069 do \
7070 { \
7071 if (skip_past_char (&str, chr) == FAIL) \
477330fc 7072 goto bad_args; \
e07e6e58
NC
7073 } \
7074 while (0)
c19d1205 7075
e07e6e58
NC
7076#define po_reg_or_fail(regtype) \
7077 do \
dcbf9037 7078 { \
e07e6e58 7079 val = arm_typed_reg_parse (& str, regtype, & rtype, \
477330fc 7080 & inst.operands[i].vectype); \
e07e6e58 7081 if (val == FAIL) \
477330fc
RM
7082 { \
7083 first_error (_(reg_expected_msgs[regtype])); \
7084 goto failure; \
7085 } \
e07e6e58
NC
7086 inst.operands[i].reg = val; \
7087 inst.operands[i].isreg = 1; \
7088 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7089 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7090 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc
RM
7091 || rtype == REG_TYPE_VFD \
7092 || rtype == REG_TYPE_NQ); \
1b883319 7093 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
dcbf9037 7094 } \
e07e6e58
NC
7095 while (0)
7096
7097#define po_reg_or_goto(regtype, label) \
7098 do \
7099 { \
7100 val = arm_typed_reg_parse (& str, regtype, & rtype, \
7101 & inst.operands[i].vectype); \
7102 if (val == FAIL) \
7103 goto label; \
dcbf9037 7104 \
e07e6e58
NC
7105 inst.operands[i].reg = val; \
7106 inst.operands[i].isreg = 1; \
7107 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
7108 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
7109 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc 7110 || rtype == REG_TYPE_VFD \
e07e6e58 7111 || rtype == REG_TYPE_NQ); \
1b883319 7112 inst.operands[i].iszr = (rtype == REG_TYPE_ZR); \
e07e6e58
NC
7113 } \
7114 while (0)
7115
7116#define po_imm_or_fail(min, max, popt) \
7117 do \
7118 { \
7119 if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
7120 goto failure; \
7121 inst.operands[i].imm = val; \
7122 } \
7123 while (0)
7124
57785aa2 7125#define po_scalar_or_goto(elsz, label, reg_type) \
e07e6e58
NC
7126 do \
7127 { \
57785aa2
AV
7128 val = parse_scalar (& str, elsz, & inst.operands[i].vectype, \
7129 reg_type); \
e07e6e58
NC
7130 if (val == FAIL) \
7131 goto label; \
7132 inst.operands[i].reg = val; \
7133 inst.operands[i].isscalar = 1; \
7134 } \
7135 while (0)
7136
7137#define po_misc_or_fail(expr) \
7138 do \
7139 { \
7140 if (expr) \
7141 goto failure; \
7142 } \
7143 while (0)
7144
7145#define po_misc_or_fail_no_backtrack(expr) \
7146 do \
7147 { \
7148 result = expr; \
7149 if (result == PARSE_OPERAND_FAIL_NO_BACKTRACK) \
7150 backtrack_pos = 0; \
7151 if (result != PARSE_OPERAND_SUCCESS) \
7152 goto failure; \
7153 } \
7154 while (0)
4962c51a 7155
52e7f43d
RE
7156#define po_barrier_or_imm(str) \
7157 do \
7158 { \
7159 val = parse_barrier (&str); \
ccb84d65
JB
7160 if (val == FAIL && ! ISALPHA (*str)) \
7161 goto immediate; \
7162 if (val == FAIL \
7163 /* ISB can only take SY as an option. */ \
7164 || ((inst.instruction & 0xf0) == 0x60 \
7165 && val != 0xf)) \
52e7f43d 7166 { \
ccb84d65
JB
7167 inst.error = _("invalid barrier type"); \
7168 backtrack_pos = 0; \
7169 goto failure; \
52e7f43d
RE
7170 } \
7171 } \
7172 while (0)
7173
c19d1205
ZW
7174 skip_whitespace (str);
7175
7176 for (i = 0; upat[i] != OP_stop; i++)
7177 {
5be8be5d
DG
7178 op_parse_code = upat[i];
7179 if (op_parse_code >= 1<<16)
7180 op_parse_code = thumb ? (op_parse_code >> 16)
7181 : (op_parse_code & ((1<<16)-1));
7182
7183 if (op_parse_code >= OP_FIRST_OPTIONAL)
c19d1205
ZW
7184 {
7185 /* Remember where we are in case we need to backtrack. */
c19d1205
ZW
7186 backtrack_pos = str;
7187 backtrack_error = inst.error;
7188 backtrack_index = i;
7189 }
7190
b6702015 7191 if (i > 0 && (i > 1 || inst.operands[0].present))
c19d1205
ZW
7192 po_char_or_fail (',');
7193
5be8be5d 7194 switch (op_parse_code)
c19d1205
ZW
7195 {
7196 /* Registers */
7197 case OP_oRRnpc:
5be8be5d 7198 case OP_oRRnpcsp:
c19d1205 7199 case OP_RRnpc:
5be8be5d 7200 case OP_RRnpcsp:
c19d1205 7201 case OP_oRR:
a302e574
AV
7202 case OP_RRe:
7203 case OP_RRo:
60f993ce
AV
7204 case OP_LR:
7205 case OP_oLR:
c19d1205
ZW
7206 case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
7207 case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
7208 case OP_RCN: po_reg_or_fail (REG_TYPE_CN); break;
7209 case OP_RF: po_reg_or_fail (REG_TYPE_FN); break;
7210 case OP_RVS: po_reg_or_fail (REG_TYPE_VFS); break;
7211 case OP_RVD: po_reg_or_fail (REG_TYPE_VFD); break;
477330fc 7212 case OP_oRND:
5ee91343
AV
7213 case OP_RNDMQR:
7214 po_reg_or_goto (REG_TYPE_RN, try_rndmq);
7215 break;
7216 try_rndmq:
7217 case OP_RNDMQ:
7218 po_reg_or_goto (REG_TYPE_MQ, try_rnd);
7219 break;
7220 try_rnd:
5287ad62 7221 case OP_RND: po_reg_or_fail (REG_TYPE_VFD); break;
cd2cf30b
PB
7222 case OP_RVC:
7223 po_reg_or_goto (REG_TYPE_VFC, coproc_reg);
7224 break;
7225 /* Also accept generic coprocessor regs for unknown registers. */
7226 coproc_reg:
7227 po_reg_or_fail (REG_TYPE_CN);
7228 break;
c19d1205
ZW
7229 case OP_RMF: po_reg_or_fail (REG_TYPE_MVF); break;
7230 case OP_RMD: po_reg_or_fail (REG_TYPE_MVD); break;
7231 case OP_RMFX: po_reg_or_fail (REG_TYPE_MVFX); break;
7232 case OP_RMDX: po_reg_or_fail (REG_TYPE_MVDX); break;
7233 case OP_RMAX: po_reg_or_fail (REG_TYPE_MVAX); break;
7234 case OP_RMDS: po_reg_or_fail (REG_TYPE_DSPSC); break;
7235 case OP_RIWR: po_reg_or_fail (REG_TYPE_MMXWR); break;
7236 case OP_RIWC: po_reg_or_fail (REG_TYPE_MMXWC); break;
7237 case OP_RIWG: po_reg_or_fail (REG_TYPE_MMXWCG); break;
7238 case OP_RXA: po_reg_or_fail (REG_TYPE_XSCALE); break;
477330fc 7239 case OP_oRNQ:
5ee91343
AV
7240 case OP_RNQMQ:
7241 po_reg_or_goto (REG_TYPE_MQ, try_nq);
7242 break;
7243 try_nq:
5287ad62 7244 case OP_RNQ: po_reg_or_fail (REG_TYPE_NQ); break;
dec41383 7245 case OP_RNSD: po_reg_or_fail (REG_TYPE_NSD); break;
7df54120
AV
7246 case OP_RNDQMQR:
7247 po_reg_or_goto (REG_TYPE_RN, try_rndqmq);
7248 break;
7249 try_rndqmq:
5ee91343
AV
7250 case OP_oRNDQMQ:
7251 case OP_RNDQMQ:
7252 po_reg_or_goto (REG_TYPE_MQ, try_rndq);
7253 break;
7254 try_rndq:
477330fc 7255 case OP_oRNDQ:
5287ad62 7256 case OP_RNDQ: po_reg_or_fail (REG_TYPE_NDQ); break;
dd9634d9
AV
7257 case OP_RVSDMQ:
7258 po_reg_or_goto (REG_TYPE_MQ, try_rvsd);
7259 break;
7260 try_rvsd:
477330fc 7261 case OP_RVSD: po_reg_or_fail (REG_TYPE_VFSD); break;
1b883319
AV
7262 case OP_RVSD_COND:
7263 po_reg_or_goto (REG_TYPE_VFSD, try_cond);
7264 break;
477330fc
RM
7265 case OP_oRNSDQ:
7266 case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ); break;
5ee91343
AV
7267 case OP_RNSDQMQR:
7268 po_reg_or_goto (REG_TYPE_RN, try_mq);
7269 break;
7270 try_mq:
7271 case OP_oRNSDQMQ:
7272 case OP_RNSDQMQ:
7273 po_reg_or_goto (REG_TYPE_MQ, try_nsdq2);
7274 break;
7275 try_nsdq2:
7276 po_reg_or_fail (REG_TYPE_NSDQ);
7277 inst.error = 0;
7278 break;
a302e574
AV
7279 case OP_RMQ:
7280 po_reg_or_fail (REG_TYPE_MQ);
7281 break;
477330fc
RM
7282 /* Neon scalar. Using an element size of 8 means that some invalid
7283 scalars are accepted here, so deal with those in later code. */
57785aa2 7284 case OP_RNSC: po_scalar_or_goto (8, failure, REG_TYPE_VFD); break;
477330fc
RM
7285
7286 case OP_RNDQ_I0:
7287 {
7288 po_reg_or_goto (REG_TYPE_NDQ, try_imm0);
7289 break;
7290 try_imm0:
7291 po_imm_or_fail (0, 0, TRUE);
7292 }
7293 break;
7294
7295 case OP_RVSD_I0:
7296 po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
7297 break;
7298
1b883319
AV
7299 case OP_RSVDMQ_FI0:
7300 po_reg_or_goto (REG_TYPE_MQ, try_rsvd_fi0);
7301 break;
7302 try_rsvd_fi0:
aacf0b33
KT
7303 case OP_RSVD_FI0:
7304 {
7305 po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
7306 break;
7307 try_ifimm0:
7308 if (parse_ifimm_zero (&str))
7309 inst.operands[i].imm = 0;
7310 else
7311 {
7312 inst.error
7313 = _("only floating point zero is allowed as immediate value");
7314 goto failure;
7315 }
7316 }
7317 break;
7318
477330fc
RM
7319 case OP_RR_RNSC:
7320 {
57785aa2 7321 po_scalar_or_goto (8, try_rr, REG_TYPE_VFD);
477330fc
RM
7322 break;
7323 try_rr:
7324 po_reg_or_fail (REG_TYPE_RN);
7325 }
7326 break;
7327
886e1c73
AV
7328 case OP_RNSDQ_RNSC_MQ:
7329 po_reg_or_goto (REG_TYPE_MQ, try_rnsdq_rnsc);
7330 break;
7331 try_rnsdq_rnsc:
477330fc
RM
7332 case OP_RNSDQ_RNSC:
7333 {
57785aa2
AV
7334 po_scalar_or_goto (8, try_nsdq, REG_TYPE_VFD);
7335 inst.error = 0;
477330fc
RM
7336 break;
7337 try_nsdq:
7338 po_reg_or_fail (REG_TYPE_NSDQ);
57785aa2 7339 inst.error = 0;
477330fc
RM
7340 }
7341 break;
7342
dec41383
JW
7343 case OP_RNSD_RNSC:
7344 {
57785aa2 7345 po_scalar_or_goto (8, try_s_scalar, REG_TYPE_VFD);
dec41383
JW
7346 break;
7347 try_s_scalar:
57785aa2 7348 po_scalar_or_goto (4, try_nsd, REG_TYPE_VFS);
dec41383
JW
7349 break;
7350 try_nsd:
7351 po_reg_or_fail (REG_TYPE_NSD);
7352 }
7353 break;
7354
5d281bf0
AV
7355 case OP_RNDQMQ_RNSC:
7356 po_reg_or_goto (REG_TYPE_MQ, try_rndq_rnsc);
7357 break;
7358 try_rndq_rnsc:
477330fc
RM
7359 case OP_RNDQ_RNSC:
7360 {
57785aa2 7361 po_scalar_or_goto (8, try_ndq, REG_TYPE_VFD);
477330fc
RM
7362 break;
7363 try_ndq:
7364 po_reg_or_fail (REG_TYPE_NDQ);
7365 }
7366 break;
7367
7368 case OP_RND_RNSC:
7369 {
57785aa2 7370 po_scalar_or_goto (8, try_vfd, REG_TYPE_VFD);
477330fc
RM
7371 break;
7372 try_vfd:
7373 po_reg_or_fail (REG_TYPE_VFD);
7374 }
7375 break;
7376
7377 case OP_VMOV:
7378 /* WARNING: parse_neon_mov can move the operand counter, i. If we're
7379 not careful then bad things might happen. */
7380 po_misc_or_fail (parse_neon_mov (&str, &i) == FAIL);
7381 break;
7382
f601a00c
AV
7383 case OP_RNDQMQ_Ibig:
7384 po_reg_or_goto (REG_TYPE_MQ, try_rndq_ibig);
7385 break;
7386 try_rndq_ibig:
477330fc
RM
7387 case OP_RNDQ_Ibig:
7388 {
7389 po_reg_or_goto (REG_TYPE_NDQ, try_immbig);
7390 break;
7391 try_immbig:
7392 /* There's a possibility of getting a 64-bit immediate here, so
7393 we need special handling. */
8335d6aa
JW
7394 if (parse_big_immediate (&str, i, NULL, /*allow_symbol_p=*/FALSE)
7395 == FAIL)
477330fc
RM
7396 {
7397 inst.error = _("immediate value is out of range");
7398 goto failure;
7399 }
7400 }
7401 break;
7402
7403 case OP_RNDQ_I63b:
7404 {
7405 po_reg_or_goto (REG_TYPE_NDQ, try_shimm);
7406 break;
7407 try_shimm:
7408 po_imm_or_fail (0, 63, TRUE);
7409 }
7410 break;
c19d1205
ZW
7411
7412 case OP_RRnpcb:
7413 po_char_or_fail ('[');
7414 po_reg_or_fail (REG_TYPE_RN);
7415 po_char_or_fail (']');
7416 break;
a737bd4d 7417
55881a11 7418 case OP_RRnpctw:
c19d1205 7419 case OP_RRw:
b6702015 7420 case OP_oRRw:
c19d1205
ZW
7421 po_reg_or_fail (REG_TYPE_RN);
7422 if (skip_past_char (&str, '!') == SUCCESS)
7423 inst.operands[i].writeback = 1;
7424 break;
7425
7426 /* Immediates */
7427 case OP_I7: po_imm_or_fail ( 0, 7, FALSE); break;
7428 case OP_I15: po_imm_or_fail ( 0, 15, FALSE); break;
7429 case OP_I16: po_imm_or_fail ( 1, 16, FALSE); break;
477330fc 7430 case OP_I16z: po_imm_or_fail ( 0, 16, FALSE); break;
c19d1205
ZW
7431 case OP_I31: po_imm_or_fail ( 0, 31, FALSE); break;
7432 case OP_I32: po_imm_or_fail ( 1, 32, FALSE); break;
477330fc 7433 case OP_I32z: po_imm_or_fail ( 0, 32, FALSE); break;
c19d1205 7434 case OP_I63s: po_imm_or_fail (-64, 63, FALSE); break;
477330fc
RM
7435 case OP_I63: po_imm_or_fail ( 0, 63, FALSE); break;
7436 case OP_I64: po_imm_or_fail ( 1, 64, FALSE); break;
7437 case OP_I64z: po_imm_or_fail ( 0, 64, FALSE); break;
c19d1205 7438 case OP_I255: po_imm_or_fail ( 0, 255, FALSE); break;
c19d1205
ZW
7439
7440 case OP_I4b: po_imm_or_fail ( 1, 4, TRUE); break;
7441 case OP_oI7b:
7442 case OP_I7b: po_imm_or_fail ( 0, 7, TRUE); break;
7443 case OP_I15b: po_imm_or_fail ( 0, 15, TRUE); break;
7444 case OP_oI31b:
7445 case OP_I31b: po_imm_or_fail ( 0, 31, TRUE); break;
477330fc
RM
7446 case OP_oI32b: po_imm_or_fail ( 1, 32, TRUE); break;
7447 case OP_oI32z: po_imm_or_fail ( 0, 32, TRUE); break;
c19d1205
ZW
7448 case OP_oIffffb: po_imm_or_fail ( 0, 0xffff, TRUE); break;
7449
7450 /* Immediate variants */
7451 case OP_oI255c:
7452 po_char_or_fail ('{');
7453 po_imm_or_fail (0, 255, TRUE);
7454 po_char_or_fail ('}');
7455 break;
7456
7457 case OP_I31w:
7458 /* The expression parser chokes on a trailing !, so we have
7459 to find it first and zap it. */
7460 {
7461 char *s = str;
7462 while (*s && *s != ',')
7463 s++;
7464 if (s[-1] == '!')
7465 {
7466 s[-1] = '\0';
7467 inst.operands[i].writeback = 1;
7468 }
7469 po_imm_or_fail (0, 31, TRUE);
7470 if (str == s - 1)
7471 str = s;
7472 }
7473 break;
7474
7475 /* Expressions */
7476 case OP_EXPi: EXPi:
e2b0ab59 7477 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7478 GE_OPT_PREFIX));
7479 break;
7480
7481 case OP_EXP:
e2b0ab59 7482 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7483 GE_NO_PREFIX));
7484 break;
7485
7486 case OP_EXPr: EXPr:
e2b0ab59 7487 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205 7488 GE_NO_PREFIX));
e2b0ab59 7489 if (inst.relocs[0].exp.X_op == O_symbol)
a737bd4d 7490 {
c19d1205
ZW
7491 val = parse_reloc (&str);
7492 if (val == -1)
7493 {
7494 inst.error = _("unrecognized relocation suffix");
7495 goto failure;
7496 }
7497 else if (val != BFD_RELOC_UNUSED)
7498 {
7499 inst.operands[i].imm = val;
7500 inst.operands[i].hasreloc = 1;
7501 }
a737bd4d 7502 }
c19d1205 7503 break;
a737bd4d 7504
e2b0ab59
AV
7505 case OP_EXPs:
7506 po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
7507 GE_NO_PREFIX));
7508 if (inst.relocs[i].exp.X_op == O_symbol)
7509 {
7510 inst.operands[i].hasreloc = 1;
7511 }
7512 else if (inst.relocs[i].exp.X_op == O_constant)
7513 {
7514 inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
7515 inst.operands[i].hasreloc = 0;
7516 }
7517 break;
7518
b6895b4f
PB
7519 /* Operand for MOVW or MOVT. */
7520 case OP_HALF:
7521 po_misc_or_fail (parse_half (&str));
7522 break;
7523
e07e6e58 7524 /* Register or expression. */
c19d1205
ZW
7525 case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
7526 case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
a737bd4d 7527
e07e6e58 7528 /* Register or immediate. */
c19d1205
ZW
7529 case OP_RRnpc_I0: po_reg_or_goto (REG_TYPE_RN, I0); break;
7530 I0: po_imm_or_fail (0, 0, FALSE); break;
a737bd4d 7531
c19d1205
ZW
7532 case OP_RF_IF: po_reg_or_goto (REG_TYPE_FN, IF); break;
7533 IF:
7534 if (!is_immediate_prefix (*str))
7535 goto bad_args;
7536 str++;
7537 val = parse_fpa_immediate (&str);
7538 if (val == FAIL)
7539 goto failure;
7540 /* FPA immediates are encoded as registers 8-15.
7541 parse_fpa_immediate has already applied the offset. */
7542 inst.operands[i].reg = val;
7543 inst.operands[i].isreg = 1;
7544 break;
09d92015 7545
2d447fca
JM
7546 case OP_RIWR_I32z: po_reg_or_goto (REG_TYPE_MMXWR, I32z); break;
7547 I32z: po_imm_or_fail (0, 32, FALSE); break;
7548
e07e6e58 7549 /* Two kinds of register. */
c19d1205
ZW
7550 case OP_RIWR_RIWC:
7551 {
7552 struct reg_entry *rege = arm_reg_parse_multi (&str);
97f87066
JM
7553 if (!rege
7554 || (rege->type != REG_TYPE_MMXWR
7555 && rege->type != REG_TYPE_MMXWC
7556 && rege->type != REG_TYPE_MMXWCG))
c19d1205
ZW
7557 {
7558 inst.error = _("iWMMXt data or control register expected");
7559 goto failure;
7560 }
7561 inst.operands[i].reg = rege->number;
7562 inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
7563 }
7564 break;
09d92015 7565
41adaa5c
JM
7566 case OP_RIWC_RIWG:
7567 {
7568 struct reg_entry *rege = arm_reg_parse_multi (&str);
7569 if (!rege
7570 || (rege->type != REG_TYPE_MMXWC
7571 && rege->type != REG_TYPE_MMXWCG))
7572 {
7573 inst.error = _("iWMMXt control register expected");
7574 goto failure;
7575 }
7576 inst.operands[i].reg = rege->number;
7577 inst.operands[i].isreg = 1;
7578 }
7579 break;
7580
c19d1205
ZW
7581 /* Misc */
7582 case OP_CPSF: val = parse_cps_flags (&str); break;
7583 case OP_ENDI: val = parse_endian_specifier (&str); break;
7584 case OP_oROR: val = parse_ror (&str); break;
1b883319 7585 try_cond:
c19d1205 7586 case OP_COND: val = parse_cond (&str); break;
52e7f43d
RE
7587 case OP_oBARRIER_I15:
7588 po_barrier_or_imm (str); break;
7589 immediate:
7590 if (parse_immediate (&str, &val, 0, 15, TRUE) == FAIL)
477330fc 7591 goto failure;
52e7f43d 7592 break;
c19d1205 7593
fa94de6b 7594 case OP_wPSR:
d2cd1205 7595 case OP_rPSR:
90ec0d68
MGD
7596 po_reg_or_goto (REG_TYPE_RNB, try_psr);
7597 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_virt))
7598 {
7599 inst.error = _("Banked registers are not available with this "
7600 "architecture.");
7601 goto failure;
7602 }
7603 break;
d2cd1205
JB
7604 try_psr:
7605 val = parse_psr (&str, op_parse_code == OP_wPSR);
7606 break;
037e8744 7607
32c36c3c
AV
7608 case OP_VLDR:
7609 po_reg_or_goto (REG_TYPE_VFSD, try_sysreg);
7610 break;
7611 try_sysreg:
7612 val = parse_sys_vldr_vstr (&str);
7613 break;
7614
477330fc
RM
7615 case OP_APSR_RR:
7616 po_reg_or_goto (REG_TYPE_RN, try_apsr);
7617 break;
7618 try_apsr:
7619 /* Parse "APSR_nvzc" operand (for FMSTAT-equivalent MRS
7620 instruction). */
7621 if (strncasecmp (str, "APSR_", 5) == 0)
7622 {
7623 unsigned found = 0;
7624 str += 5;
7625 while (found < 15)
7626 switch (*str++)
7627 {
7628 case 'c': found = (found & 1) ? 16 : found | 1; break;
7629 case 'n': found = (found & 2) ? 16 : found | 2; break;
7630 case 'z': found = (found & 4) ? 16 : found | 4; break;
7631 case 'v': found = (found & 8) ? 16 : found | 8; break;
7632 default: found = 16;
7633 }
7634 if (found != 15)
7635 goto failure;
7636 inst.operands[i].isvec = 1;
f7c21dc7
NC
7637 /* APSR_nzcv is encoded in instructions as if it were the REG_PC. */
7638 inst.operands[i].reg = REG_PC;
477330fc
RM
7639 }
7640 else
7641 goto failure;
7642 break;
037e8744 7643
92e90b6e
PB
7644 case OP_TB:
7645 po_misc_or_fail (parse_tb (&str));
7646 break;
7647
e07e6e58 7648 /* Register lists. */
c19d1205 7649 case OP_REGLST:
4b5a202f 7650 val = parse_reg_list (&str, REGLIST_RN);
c19d1205
ZW
7651 if (*str == '^')
7652 {
5e0d7f77 7653 inst.operands[i].writeback = 1;
c19d1205
ZW
7654 str++;
7655 }
7656 break;
09d92015 7657
4b5a202f
AV
7658 case OP_CLRMLST:
7659 val = parse_reg_list (&str, REGLIST_CLRM);
7660 break;
7661
c19d1205 7662 case OP_VRSLST:
efd6b359
AV
7663 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_S,
7664 &partial_match);
c19d1205 7665 break;
09d92015 7666
c19d1205 7667 case OP_VRDLST:
efd6b359
AV
7668 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_D,
7669 &partial_match);
c19d1205 7670 break;
a737bd4d 7671
477330fc
RM
7672 case OP_VRSDLST:
7673 /* Allow Q registers too. */
7674 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7675 REGLIST_NEON_D, &partial_match);
477330fc
RM
7676 if (val == FAIL)
7677 {
7678 inst.error = NULL;
7679 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359
AV
7680 REGLIST_VFP_S, &partial_match);
7681 inst.operands[i].issingle = 1;
7682 }
7683 break;
7684
7685 case OP_VRSDVLST:
7686 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7687 REGLIST_VFP_D_VPR, &partial_match);
7688 if (val == FAIL && !partial_match)
7689 {
7690 inst.error = NULL;
7691 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7692 REGLIST_VFP_S_VPR, &partial_match);
477330fc
RM
7693 inst.operands[i].issingle = 1;
7694 }
7695 break;
7696
7697 case OP_NRDLST:
7698 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7699 REGLIST_NEON_D, &partial_match);
477330fc 7700 break;
5287ad62 7701
35c228db
AV
7702 case OP_MSTRLST4:
7703 case OP_MSTRLST2:
7704 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
7705 1, &inst.operands[i].vectype);
7706 if (val != (((op_parse_code == OP_MSTRLST2) ? 3 : 7) << 5 | 0xe))
7707 goto failure;
7708 break;
5287ad62 7709 case OP_NSTRLST:
477330fc 7710 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
35c228db 7711 0, &inst.operands[i].vectype);
477330fc 7712 break;
5287ad62 7713
c19d1205 7714 /* Addressing modes */
35c228db
AV
7715 case OP_ADDRMVE:
7716 po_misc_or_fail (parse_address_group_reloc (&str, i, GROUP_MVE));
7717 break;
7718
c19d1205
ZW
7719 case OP_ADDR:
7720 po_misc_or_fail (parse_address (&str, i));
7721 break;
09d92015 7722
4962c51a
MS
7723 case OP_ADDRGLDR:
7724 po_misc_or_fail_no_backtrack (
477330fc 7725 parse_address_group_reloc (&str, i, GROUP_LDR));
4962c51a
MS
7726 break;
7727
7728 case OP_ADDRGLDRS:
7729 po_misc_or_fail_no_backtrack (
477330fc 7730 parse_address_group_reloc (&str, i, GROUP_LDRS));
4962c51a
MS
7731 break;
7732
7733 case OP_ADDRGLDC:
7734 po_misc_or_fail_no_backtrack (
477330fc 7735 parse_address_group_reloc (&str, i, GROUP_LDC));
4962c51a
MS
7736 break;
7737
c19d1205
ZW
7738 case OP_SH:
7739 po_misc_or_fail (parse_shifter_operand (&str, i));
7740 break;
09d92015 7741
4962c51a
MS
7742 case OP_SHG:
7743 po_misc_or_fail_no_backtrack (
477330fc 7744 parse_shifter_operand_group_reloc (&str, i));
4962c51a
MS
7745 break;
7746
c19d1205
ZW
7747 case OP_oSHll:
7748 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_IMMEDIATE));
7749 break;
09d92015 7750
c19d1205
ZW
7751 case OP_oSHar:
7752 po_misc_or_fail (parse_shift (&str, i, SHIFT_ASR_IMMEDIATE));
7753 break;
09d92015 7754
c19d1205
ZW
7755 case OP_oSHllar:
7756 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
7757 break;
09d92015 7758
1b883319
AV
7759 case OP_RMQRZ:
7760 case OP_oRMQRZ:
7761 po_reg_or_goto (REG_TYPE_MQ, try_rr_zr);
7762 break;
7763 try_rr_zr:
7764 po_reg_or_goto (REG_TYPE_RN, ZR);
7765 break;
7766 ZR:
7767 po_reg_or_fail (REG_TYPE_ZR);
7768 break;
7769
c19d1205 7770 default:
5be8be5d 7771 as_fatal (_("unhandled operand code %d"), op_parse_code);
c19d1205 7772 }
09d92015 7773
c19d1205
ZW
7774 /* Various value-based sanity checks and shared operations. We
7775 do not signal immediate failures for the register constraints;
7776 this allows a syntax error to take precedence. */
5be8be5d 7777 switch (op_parse_code)
c19d1205
ZW
7778 {
7779 case OP_oRRnpc:
7780 case OP_RRnpc:
7781 case OP_RRnpcb:
7782 case OP_RRw:
b6702015 7783 case OP_oRRw:
c19d1205
ZW
7784 case OP_RRnpc_I0:
7785 if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
7786 inst.error = BAD_PC;
7787 break;
09d92015 7788
5be8be5d
DG
7789 case OP_oRRnpcsp:
7790 case OP_RRnpcsp:
7791 if (inst.operands[i].isreg)
7792 {
7793 if (inst.operands[i].reg == REG_PC)
7794 inst.error = BAD_PC;
5c8ed6a4
JW
7795 else if (inst.operands[i].reg == REG_SP
7796 /* The restriction on Rd/Rt/Rt2 on Thumb mode has been
7797 relaxed since ARMv8-A. */
7798 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
7799 {
7800 gas_assert (thumb);
7801 inst.error = BAD_SP;
7802 }
5be8be5d
DG
7803 }
7804 break;
7805
55881a11 7806 case OP_RRnpctw:
fa94de6b
RM
7807 if (inst.operands[i].isreg
7808 && inst.operands[i].reg == REG_PC
55881a11
MGD
7809 && (inst.operands[i].writeback || thumb))
7810 inst.error = BAD_PC;
7811 break;
7812
1b883319 7813 case OP_RVSD_COND:
32c36c3c
AV
7814 case OP_VLDR:
7815 if (inst.operands[i].isreg)
7816 break;
7817 /* fall through. */
1b883319 7818
c19d1205
ZW
7819 case OP_CPSF:
7820 case OP_ENDI:
7821 case OP_oROR:
d2cd1205
JB
7822 case OP_wPSR:
7823 case OP_rPSR:
c19d1205 7824 case OP_COND:
52e7f43d 7825 case OP_oBARRIER_I15:
c19d1205 7826 case OP_REGLST:
4b5a202f 7827 case OP_CLRMLST:
c19d1205
ZW
7828 case OP_VRSLST:
7829 case OP_VRDLST:
477330fc 7830 case OP_VRSDLST:
efd6b359 7831 case OP_VRSDVLST:
477330fc
RM
7832 case OP_NRDLST:
7833 case OP_NSTRLST:
35c228db
AV
7834 case OP_MSTRLST2:
7835 case OP_MSTRLST4:
c19d1205
ZW
7836 if (val == FAIL)
7837 goto failure;
7838 inst.operands[i].imm = val;
7839 break;
a737bd4d 7840
60f993ce
AV
7841 case OP_LR:
7842 case OP_oLR:
7843 if (inst.operands[i].reg != REG_LR)
7844 inst.error = _("operand must be LR register");
7845 break;
7846
1b883319
AV
7847 case OP_RMQRZ:
7848 case OP_oRMQRZ:
7849 if (!inst.operands[i].iszr && inst.operands[i].reg == REG_PC)
7850 inst.error = BAD_PC;
7851 break;
7852
a302e574
AV
7853 case OP_RRe:
7854 if (inst.operands[i].isreg
7855 && (inst.operands[i].reg & 0x00000001) != 0)
7856 inst.error = BAD_ODD;
7857 break;
7858
7859 case OP_RRo:
7860 if (inst.operands[i].isreg)
7861 {
7862 if ((inst.operands[i].reg & 0x00000001) != 1)
7863 inst.error = BAD_EVEN;
7864 else if (inst.operands[i].reg == REG_SP)
7865 as_tsktsk (MVE_BAD_SP);
7866 else if (inst.operands[i].reg == REG_PC)
7867 inst.error = BAD_PC;
7868 }
7869 break;
7870
c19d1205
ZW
7871 default:
7872 break;
7873 }
09d92015 7874
c19d1205
ZW
7875 /* If we get here, this operand was successfully parsed. */
7876 inst.operands[i].present = 1;
7877 continue;
09d92015 7878
c19d1205 7879 bad_args:
09d92015 7880 inst.error = BAD_ARGS;
c19d1205
ZW
7881
7882 failure:
7883 if (!backtrack_pos)
d252fdde
PB
7884 {
7885 /* The parse routine should already have set inst.error, but set a
5f4273c7 7886 default here just in case. */
d252fdde 7887 if (!inst.error)
5ee91343 7888 inst.error = BAD_SYNTAX;
d252fdde
PB
7889 return FAIL;
7890 }
c19d1205
ZW
7891
7892 /* Do not backtrack over a trailing optional argument that
7893 absorbed some text. We will only fail again, with the
7894 'garbage following instruction' error message, which is
7895 probably less helpful than the current one. */
7896 if (backtrack_index == i && backtrack_pos != str
7897 && upat[i+1] == OP_stop)
d252fdde
PB
7898 {
7899 if (!inst.error)
5ee91343 7900 inst.error = BAD_SYNTAX;
d252fdde
PB
7901 return FAIL;
7902 }
c19d1205
ZW
7903
7904 /* Try again, skipping the optional argument at backtrack_pos. */
7905 str = backtrack_pos;
7906 inst.error = backtrack_error;
7907 inst.operands[backtrack_index].present = 0;
7908 i = backtrack_index;
7909 backtrack_pos = 0;
09d92015 7910 }
09d92015 7911
c19d1205
ZW
7912 /* Check that we have parsed all the arguments. */
7913 if (*str != '\0' && !inst.error)
7914 inst.error = _("garbage following instruction");
09d92015 7915
c19d1205 7916 return inst.error ? FAIL : SUCCESS;
09d92015
MM
7917}
7918
c19d1205
ZW
7919#undef po_char_or_fail
7920#undef po_reg_or_fail
7921#undef po_reg_or_goto
7922#undef po_imm_or_fail
5287ad62 7923#undef po_scalar_or_fail
52e7f43d 7924#undef po_barrier_or_imm
e07e6e58 7925
c19d1205 7926/* Shorthand macro for instruction encoding functions issuing errors. */
e07e6e58
NC
7927#define constraint(expr, err) \
7928 do \
c19d1205 7929 { \
e07e6e58
NC
7930 if (expr) \
7931 { \
7932 inst.error = err; \
7933 return; \
7934 } \
c19d1205 7935 } \
e07e6e58 7936 while (0)
c19d1205 7937
fdfde340
JM
7938/* Reject "bad registers" for Thumb-2 instructions. Many Thumb-2
7939 instructions are unpredictable if these registers are used. This
5c8ed6a4
JW
7940 is the BadReg predicate in ARM's Thumb-2 documentation.
7941
7942 Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few
7943 places, while the restriction on REG_SP was relaxed since ARMv8-A. */
7944#define reject_bad_reg(reg) \
7945 do \
7946 if (reg == REG_PC) \
7947 { \
7948 inst.error = BAD_PC; \
7949 return; \
7950 } \
7951 else if (reg == REG_SP \
7952 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) \
7953 { \
7954 inst.error = BAD_SP; \
7955 return; \
7956 } \
fdfde340
JM
7957 while (0)
7958
94206790
MM
7959/* If REG is R13 (the stack pointer), warn that its use is
7960 deprecated. */
7961#define warn_deprecated_sp(reg) \
7962 do \
7963 if (warn_on_deprecated && reg == REG_SP) \
5c3696f8 7964 as_tsktsk (_("use of r13 is deprecated")); \
94206790
MM
7965 while (0)
7966
c19d1205
ZW
7967/* Functions for operand encoding. ARM, then Thumb. */
7968
d840c081 7969#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31))
c19d1205 7970
9db2f6b4
RL
7971/* If the current inst is scalar ARMv8.2 fp16 instruction, do special encoding.
7972
7973 The only binary encoding difference is the Coprocessor number. Coprocessor
7974 9 is used for half-precision calculations or conversions. The format of the
2b0f3761 7975 instruction is the same as the equivalent Coprocessor 10 instruction that
9db2f6b4
RL
7976 exists for Single-Precision operation. */
7977
7978static void
7979do_scalar_fp16_v82_encode (void)
7980{
5ee91343 7981 if (inst.cond < COND_ALWAYS)
9db2f6b4
RL
7982 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
7983 " the behaviour is UNPREDICTABLE"));
7984 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
7985 _(BAD_FP16));
7986
7987 inst.instruction = (inst.instruction & 0xfffff0ff) | 0x900;
7988 mark_feature_used (&arm_ext_fp16);
7989}
7990
c19d1205
ZW
7991/* If VAL can be encoded in the immediate field of an ARM instruction,
7992 return the encoded form. Otherwise, return FAIL. */
7993
7994static unsigned int
7995encode_arm_immediate (unsigned int val)
09d92015 7996{
c19d1205
ZW
7997 unsigned int a, i;
7998
4f1d6205
L
7999 if (val <= 0xff)
8000 return val;
8001
8002 for (i = 2; i < 32; i += 2)
c19d1205
ZW
8003 if ((a = rotate_left (val, i)) <= 0xff)
8004 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
8005
8006 return FAIL;
09d92015
MM
8007}
8008
c19d1205
ZW
8009/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
8010 return the encoded form. Otherwise, return FAIL. */
8011static unsigned int
8012encode_thumb32_immediate (unsigned int val)
09d92015 8013{
c19d1205 8014 unsigned int a, i;
09d92015 8015
9c3c69f2 8016 if (val <= 0xff)
c19d1205 8017 return val;
a737bd4d 8018
9c3c69f2 8019 for (i = 1; i <= 24; i++)
09d92015 8020 {
9c3c69f2
PB
8021 a = val >> i;
8022 if ((val & ~(0xff << i)) == 0)
8023 return ((val >> i) & 0x7f) | ((32 - i) << 7);
09d92015 8024 }
a737bd4d 8025
c19d1205
ZW
8026 a = val & 0xff;
8027 if (val == ((a << 16) | a))
8028 return 0x100 | a;
8029 if (val == ((a << 24) | (a << 16) | (a << 8) | a))
8030 return 0x300 | a;
09d92015 8031
c19d1205
ZW
8032 a = val & 0xff00;
8033 if (val == ((a << 16) | a))
8034 return 0x200 | (a >> 8);
a737bd4d 8035
c19d1205 8036 return FAIL;
09d92015 8037}
5287ad62 8038/* Encode a VFP SP or DP register number into inst.instruction. */
09d92015
MM
8039
8040static void
5287ad62
JB
8041encode_arm_vfp_reg (int reg, enum vfp_reg_pos pos)
8042{
8043 if ((pos == VFP_REG_Dd || pos == VFP_REG_Dn || pos == VFP_REG_Dm)
8044 && reg > 15)
8045 {
b1cc4aeb 8046 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
8047 {
8048 if (thumb_mode)
8049 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
8050 fpu_vfp_ext_d32);
8051 else
8052 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
8053 fpu_vfp_ext_d32);
8054 }
5287ad62 8055 else
477330fc
RM
8056 {
8057 first_error (_("D register out of range for selected VFP version"));
8058 return;
8059 }
5287ad62
JB
8060 }
8061
c19d1205 8062 switch (pos)
09d92015 8063 {
c19d1205
ZW
8064 case VFP_REG_Sd:
8065 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8066 break;
8067
8068 case VFP_REG_Sn:
8069 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8070 break;
8071
8072 case VFP_REG_Sm:
8073 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8074 break;
8075
5287ad62
JB
8076 case VFP_REG_Dd:
8077 inst.instruction |= ((reg & 15) << 12) | ((reg >> 4) << 22);
8078 break;
5f4273c7 8079
5287ad62
JB
8080 case VFP_REG_Dn:
8081 inst.instruction |= ((reg & 15) << 16) | ((reg >> 4) << 7);
8082 break;
5f4273c7 8083
5287ad62
JB
8084 case VFP_REG_Dm:
8085 inst.instruction |= (reg & 15) | ((reg >> 4) << 5);
8086 break;
8087
c19d1205
ZW
8088 default:
8089 abort ();
09d92015 8090 }
09d92015
MM
8091}
8092
c19d1205 8093/* Encode a <shift> in an ARM-format instruction. The immediate,
55cf6793 8094 if any, is handled by md_apply_fix. */
09d92015 8095static void
c19d1205 8096encode_arm_shift (int i)
09d92015 8097{
008a97ef
RL
8098 /* register-shifted register. */
8099 if (inst.operands[i].immisreg)
8100 {
bf355b69
MR
8101 int op_index;
8102 for (op_index = 0; op_index <= i; ++op_index)
008a97ef 8103 {
5689c942
RL
8104 /* Check the operand only when it's presented. In pre-UAL syntax,
8105 if the destination register is the same as the first operand, two
8106 register form of the instruction can be used. */
bf355b69
MR
8107 if (inst.operands[op_index].present && inst.operands[op_index].isreg
8108 && inst.operands[op_index].reg == REG_PC)
008a97ef
RL
8109 as_warn (UNPRED_REG ("r15"));
8110 }
8111
8112 if (inst.operands[i].imm == REG_PC)
8113 as_warn (UNPRED_REG ("r15"));
8114 }
8115
c19d1205
ZW
8116 if (inst.operands[i].shift_kind == SHIFT_RRX)
8117 inst.instruction |= SHIFT_ROR << 5;
8118 else
09d92015 8119 {
c19d1205
ZW
8120 inst.instruction |= inst.operands[i].shift_kind << 5;
8121 if (inst.operands[i].immisreg)
8122 {
8123 inst.instruction |= SHIFT_BY_REG;
8124 inst.instruction |= inst.operands[i].imm << 8;
8125 }
8126 else
e2b0ab59 8127 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
09d92015 8128 }
c19d1205 8129}
09d92015 8130
c19d1205
ZW
8131static void
8132encode_arm_shifter_operand (int i)
8133{
8134 if (inst.operands[i].isreg)
09d92015 8135 {
c19d1205
ZW
8136 inst.instruction |= inst.operands[i].reg;
8137 encode_arm_shift (i);
09d92015 8138 }
c19d1205 8139 else
a415b1cd
JB
8140 {
8141 inst.instruction |= INST_IMMEDIATE;
e2b0ab59 8142 if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
a415b1cd
JB
8143 inst.instruction |= inst.operands[i].imm;
8144 }
09d92015
MM
8145}
8146
c19d1205 8147/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
09d92015 8148static void
c19d1205 8149encode_arm_addr_mode_common (int i, bfd_boolean is_t)
09d92015 8150{
2b2f5df9
NC
8151 /* PR 14260:
8152 Generate an error if the operand is not a register. */
8153 constraint (!inst.operands[i].isreg,
8154 _("Instruction does not support =N addresses"));
8155
c19d1205 8156 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 8157
c19d1205 8158 if (inst.operands[i].preind)
09d92015 8159 {
c19d1205
ZW
8160 if (is_t)
8161 {
8162 inst.error = _("instruction does not accept preindexed addressing");
8163 return;
8164 }
8165 inst.instruction |= PRE_INDEX;
8166 if (inst.operands[i].writeback)
8167 inst.instruction |= WRITE_BACK;
09d92015 8168
c19d1205
ZW
8169 }
8170 else if (inst.operands[i].postind)
8171 {
9c2799c2 8172 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
8173 if (is_t)
8174 inst.instruction |= WRITE_BACK;
8175 }
8176 else /* unindexed - only for coprocessor */
09d92015 8177 {
c19d1205 8178 inst.error = _("instruction does not accept unindexed addressing");
09d92015
MM
8179 return;
8180 }
8181
c19d1205
ZW
8182 if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
8183 && (((inst.instruction & 0x000f0000) >> 16)
8184 == ((inst.instruction & 0x0000f000) >> 12)))
8185 as_warn ((inst.instruction & LOAD_BIT)
8186 ? _("destination register same as write-back base")
8187 : _("source register same as write-back base"));
09d92015
MM
8188}
8189
c19d1205
ZW
8190/* inst.operands[i] was set up by parse_address. Encode it into an
8191 ARM-format mode 2 load or store instruction. If is_t is true,
8192 reject forms that cannot be used with a T instruction (i.e. not
8193 post-indexed). */
a737bd4d 8194static void
c19d1205 8195encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
09d92015 8196{
5be8be5d
DG
8197 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
8198
c19d1205 8199 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8200
c19d1205 8201 if (inst.operands[i].immisreg)
09d92015 8202 {
5be8be5d
DG
8203 constraint ((inst.operands[i].imm == REG_PC
8204 || (is_pc && inst.operands[i].writeback)),
8205 BAD_PC_ADDRESSING);
c19d1205
ZW
8206 inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
8207 inst.instruction |= inst.operands[i].imm;
8208 if (!inst.operands[i].negative)
8209 inst.instruction |= INDEX_UP;
8210 if (inst.operands[i].shifted)
8211 {
8212 if (inst.operands[i].shift_kind == SHIFT_RRX)
8213 inst.instruction |= SHIFT_ROR << 5;
8214 else
8215 {
8216 inst.instruction |= inst.operands[i].shift_kind << 5;
e2b0ab59 8217 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
c19d1205
ZW
8218 }
8219 }
09d92015 8220 }
e2b0ab59 8221 else /* immediate offset in inst.relocs[0] */
09d92015 8222 {
e2b0ab59 8223 if (is_pc && !inst.relocs[0].pc_rel)
5be8be5d
DG
8224 {
8225 const bfd_boolean is_load = ((inst.instruction & LOAD_BIT) != 0);
23a10334
JZ
8226
8227 /* If is_t is TRUE, it's called from do_ldstt. ldrt/strt
8228 cannot use PC in addressing.
8229 PC cannot be used in writeback addressing, either. */
8230 constraint ((is_t || inst.operands[i].writeback),
5be8be5d 8231 BAD_PC_ADDRESSING);
23a10334 8232
dc5ec521 8233 /* Use of PC in str is deprecated for ARMv7. */
23a10334
JZ
8234 if (warn_on_deprecated
8235 && !is_load
8236 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
5c3696f8 8237 as_tsktsk (_("use of PC in this instruction is deprecated"));
5be8be5d
DG
8238 }
8239
e2b0ab59 8240 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8241 {
8242 /* Prefer + for zero encoded value. */
8243 if (!inst.operands[i].negative)
8244 inst.instruction |= INDEX_UP;
e2b0ab59 8245 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
26d97720 8246 }
09d92015 8247 }
09d92015
MM
8248}
8249
c19d1205
ZW
8250/* inst.operands[i] was set up by parse_address. Encode it into an
8251 ARM-format mode 3 load or store instruction. Reject forms that
8252 cannot be used with such instructions. If is_t is true, reject
8253 forms that cannot be used with a T instruction (i.e. not
8254 post-indexed). */
8255static void
8256encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
09d92015 8257{
c19d1205 8258 if (inst.operands[i].immisreg && inst.operands[i].shifted)
09d92015 8259 {
c19d1205
ZW
8260 inst.error = _("instruction does not accept scaled register index");
8261 return;
09d92015 8262 }
a737bd4d 8263
c19d1205 8264 encode_arm_addr_mode_common (i, is_t);
a737bd4d 8265
c19d1205
ZW
8266 if (inst.operands[i].immisreg)
8267 {
5be8be5d 8268 constraint ((inst.operands[i].imm == REG_PC
eb9f3f00 8269 || (is_t && inst.operands[i].reg == REG_PC)),
5be8be5d 8270 BAD_PC_ADDRESSING);
eb9f3f00
JB
8271 constraint (inst.operands[i].reg == REG_PC && inst.operands[i].writeback,
8272 BAD_PC_WRITEBACK);
c19d1205
ZW
8273 inst.instruction |= inst.operands[i].imm;
8274 if (!inst.operands[i].negative)
8275 inst.instruction |= INDEX_UP;
8276 }
e2b0ab59 8277 else /* immediate offset in inst.relocs[0] */
c19d1205 8278 {
e2b0ab59 8279 constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
5be8be5d
DG
8280 && inst.operands[i].writeback),
8281 BAD_PC_WRITEBACK);
c19d1205 8282 inst.instruction |= HWOFFSET_IMM;
e2b0ab59 8283 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
8284 {
8285 /* Prefer + for zero encoded value. */
8286 if (!inst.operands[i].negative)
8287 inst.instruction |= INDEX_UP;
8288
e2b0ab59 8289 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
26d97720 8290 }
c19d1205 8291 }
a737bd4d
NC
8292}
8293
8335d6aa
JW
8294/* Write immediate bits [7:0] to the following locations:
8295
8296 |28/24|23 19|18 16|15 4|3 0|
8297 | 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|
8298
8299 This function is used by VMOV/VMVN/VORR/VBIC. */
8300
8301static void
8302neon_write_immbits (unsigned immbits)
8303{
8304 inst.instruction |= immbits & 0xf;
8305 inst.instruction |= ((immbits >> 4) & 0x7) << 16;
8306 inst.instruction |= ((immbits >> 7) & 0x1) << (thumb_mode ? 28 : 24);
8307}
8308
8309/* Invert low-order SIZE bits of XHI:XLO. */
8310
8311static void
8312neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
8313{
8314 unsigned immlo = xlo ? *xlo : 0;
8315 unsigned immhi = xhi ? *xhi : 0;
8316
8317 switch (size)
8318 {
8319 case 8:
8320 immlo = (~immlo) & 0xff;
8321 break;
8322
8323 case 16:
8324 immlo = (~immlo) & 0xffff;
8325 break;
8326
8327 case 64:
8328 immhi = (~immhi) & 0xffffffff;
8329 /* fall through. */
8330
8331 case 32:
8332 immlo = (~immlo) & 0xffffffff;
8333 break;
8334
8335 default:
8336 abort ();
8337 }
8338
8339 if (xlo)
8340 *xlo = immlo;
8341
8342 if (xhi)
8343 *xhi = immhi;
8344}
8345
8346/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
8347 A, B, C, D. */
09d92015 8348
c19d1205 8349static int
8335d6aa 8350neon_bits_same_in_bytes (unsigned imm)
09d92015 8351{
8335d6aa
JW
8352 return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
8353 && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
8354 && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
8355 && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
8356}
a737bd4d 8357
8335d6aa 8358/* For immediate of above form, return 0bABCD. */
09d92015 8359
8335d6aa
JW
8360static unsigned
8361neon_squash_bits (unsigned imm)
8362{
8363 return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
8364 | ((imm & 0x01000000) >> 21);
8365}
8366
8367/* Compress quarter-float representation to 0b...000 abcdefgh. */
8368
8369static unsigned
8370neon_qfloat_bits (unsigned imm)
8371{
8372 return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
8373}
8374
8375/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
8376 the instruction. *OP is passed as the initial value of the op field, and
8377 may be set to a different value depending on the constant (i.e.
8378 "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
8379 MVN). If the immediate looks like a repeated pattern then also
8380 try smaller element sizes. */
8381
8382static int
8383neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
8384 unsigned *immbits, int *op, int size,
8385 enum neon_el_type type)
8386{
8387 /* Only permit float immediates (including 0.0/-0.0) if the operand type is
8388 float. */
8389 if (type == NT_float && !float_p)
8390 return FAIL;
8391
8392 if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
09d92015 8393 {
8335d6aa
JW
8394 if (size != 32 || *op == 1)
8395 return FAIL;
8396 *immbits = neon_qfloat_bits (immlo);
8397 return 0xf;
8398 }
8399
8400 if (size == 64)
8401 {
8402 if (neon_bits_same_in_bytes (immhi)
8403 && neon_bits_same_in_bytes (immlo))
c19d1205 8404 {
8335d6aa
JW
8405 if (*op == 1)
8406 return FAIL;
8407 *immbits = (neon_squash_bits (immhi) << 4)
8408 | neon_squash_bits (immlo);
8409 *op = 1;
8410 return 0xe;
c19d1205 8411 }
a737bd4d 8412
8335d6aa
JW
8413 if (immhi != immlo)
8414 return FAIL;
8415 }
a737bd4d 8416
8335d6aa 8417 if (size >= 32)
09d92015 8418 {
8335d6aa 8419 if (immlo == (immlo & 0x000000ff))
c19d1205 8420 {
8335d6aa
JW
8421 *immbits = immlo;
8422 return 0x0;
c19d1205 8423 }
8335d6aa 8424 else if (immlo == (immlo & 0x0000ff00))
c19d1205 8425 {
8335d6aa
JW
8426 *immbits = immlo >> 8;
8427 return 0x2;
c19d1205 8428 }
8335d6aa
JW
8429 else if (immlo == (immlo & 0x00ff0000))
8430 {
8431 *immbits = immlo >> 16;
8432 return 0x4;
8433 }
8434 else if (immlo == (immlo & 0xff000000))
8435 {
8436 *immbits = immlo >> 24;
8437 return 0x6;
8438 }
8439 else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
8440 {
8441 *immbits = (immlo >> 8) & 0xff;
8442 return 0xc;
8443 }
8444 else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
8445 {
8446 *immbits = (immlo >> 16) & 0xff;
8447 return 0xd;
8448 }
8449
8450 if ((immlo & 0xffff) != (immlo >> 16))
8451 return FAIL;
8452 immlo &= 0xffff;
09d92015 8453 }
a737bd4d 8454
8335d6aa 8455 if (size >= 16)
4962c51a 8456 {
8335d6aa
JW
8457 if (immlo == (immlo & 0x000000ff))
8458 {
8459 *immbits = immlo;
8460 return 0x8;
8461 }
8462 else if (immlo == (immlo & 0x0000ff00))
8463 {
8464 *immbits = immlo >> 8;
8465 return 0xa;
8466 }
8467
8468 if ((immlo & 0xff) != (immlo >> 8))
8469 return FAIL;
8470 immlo &= 0xff;
4962c51a
MS
8471 }
8472
8335d6aa
JW
8473 if (immlo == (immlo & 0x000000ff))
8474 {
8475 /* Don't allow MVN with 8-bit immediate. */
8476 if (*op == 1)
8477 return FAIL;
8478 *immbits = immlo;
8479 return 0xe;
8480 }
26d97720 8481
8335d6aa 8482 return FAIL;
c19d1205 8483}
a737bd4d 8484
5fc177c8 8485#if defined BFD_HOST_64_BIT
ba592044
AM
8486/* Returns TRUE if double precision value V may be cast
8487 to single precision without loss of accuracy. */
8488
8489static bfd_boolean
5fc177c8 8490is_double_a_single (bfd_int64_t v)
ba592044 8491{
5fc177c8 8492 int exp = (int)((v >> 52) & 0x7FF);
8fe3f3d6 8493 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8494
8495 return (exp == 0 || exp == 0x7FF
8496 || (exp >= 1023 - 126 && exp <= 1023 + 127))
8497 && (mantissa & 0x1FFFFFFFl) == 0;
8498}
8499
3739860c 8500/* Returns a double precision value casted to single precision
ba592044
AM
8501 (ignoring the least significant bits in exponent and mantissa). */
8502
8503static int
5fc177c8 8504double_to_single (bfd_int64_t v)
ba592044
AM
8505{
8506 int sign = (int) ((v >> 63) & 1l);
5fc177c8 8507 int exp = (int) ((v >> 52) & 0x7FF);
8fe3f3d6 8508 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8509
8510 if (exp == 0x7FF)
8511 exp = 0xFF;
8512 else
8513 {
8514 exp = exp - 1023 + 127;
8515 if (exp >= 0xFF)
8516 {
8517 /* Infinity. */
8518 exp = 0x7F;
8519 mantissa = 0;
8520 }
8521 else if (exp < 0)
8522 {
8523 /* No denormalized numbers. */
8524 exp = 0;
8525 mantissa = 0;
8526 }
8527 }
8528 mantissa >>= 29;
8529 return (sign << 31) | (exp << 23) | mantissa;
8530}
5fc177c8 8531#endif /* BFD_HOST_64_BIT */
ba592044 8532
8335d6aa
JW
8533enum lit_type
8534{
8535 CONST_THUMB,
8536 CONST_ARM,
8537 CONST_VEC
8538};
8539
ba592044
AM
8540static void do_vfp_nsyn_opcode (const char *);
8541
e2b0ab59 8542/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
c19d1205
ZW
8543 Determine whether it can be performed with a move instruction; if
8544 it can, convert inst.instruction to that move instruction and
c921be7d
NC
8545 return TRUE; if it can't, convert inst.instruction to a literal-pool
8546 load and return FALSE. If this is not a valid thing to do in the
8547 current context, set inst.error and return TRUE.
a737bd4d 8548
c19d1205
ZW
8549 inst.operands[i] describes the destination register. */
8550
c921be7d 8551static bfd_boolean
8335d6aa 8552move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
c19d1205 8553{
53365c0d 8554 unsigned long tbit;
8335d6aa
JW
8555 bfd_boolean thumb_p = (t == CONST_THUMB);
8556 bfd_boolean arm_p = (t == CONST_ARM);
53365c0d
PB
8557
8558 if (thumb_p)
8559 tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
8560 else
8561 tbit = LOAD_BIT;
8562
8563 if ((inst.instruction & tbit) == 0)
09d92015 8564 {
c19d1205 8565 inst.error = _("invalid pseudo operation");
c921be7d 8566 return TRUE;
09d92015 8567 }
ba592044 8568
e2b0ab59
AV
8569 if (inst.relocs[0].exp.X_op != O_constant
8570 && inst.relocs[0].exp.X_op != O_symbol
8571 && inst.relocs[0].exp.X_op != O_big)
09d92015
MM
8572 {
8573 inst.error = _("constant expression expected");
c921be7d 8574 return TRUE;
09d92015 8575 }
ba592044 8576
e2b0ab59
AV
8577 if (inst.relocs[0].exp.X_op == O_constant
8578 || inst.relocs[0].exp.X_op == O_big)
8335d6aa 8579 {
5fc177c8
NC
8580#if defined BFD_HOST_64_BIT
8581 bfd_int64_t v;
8582#else
ba592044 8583 offsetT v;
5fc177c8 8584#endif
e2b0ab59 8585 if (inst.relocs[0].exp.X_op == O_big)
8335d6aa 8586 {
ba592044
AM
8587 LITTLENUM_TYPE w[X_PRECISION];
8588 LITTLENUM_TYPE * l;
8589
e2b0ab59 8590 if (inst.relocs[0].exp.X_add_number == -1)
8335d6aa 8591 {
ba592044
AM
8592 gen_to_words (w, X_PRECISION, E_PRECISION);
8593 l = w;
8594 /* FIXME: Should we check words w[2..5] ? */
8335d6aa 8595 }
ba592044
AM
8596 else
8597 l = generic_bignum;
3739860c 8598
5fc177c8
NC
8599#if defined BFD_HOST_64_BIT
8600 v =
8601 ((((((((bfd_int64_t) l[3] & LITTLENUM_MASK)
8602 << LITTLENUM_NUMBER_OF_BITS)
8603 | ((bfd_int64_t) l[2] & LITTLENUM_MASK))
8604 << LITTLENUM_NUMBER_OF_BITS)
8605 | ((bfd_int64_t) l[1] & LITTLENUM_MASK))
8606 << LITTLENUM_NUMBER_OF_BITS)
8607 | ((bfd_int64_t) l[0] & LITTLENUM_MASK));
8608#else
ba592044
AM
8609 v = ((l[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
8610 | (l[0] & LITTLENUM_MASK);
5fc177c8 8611#endif
8335d6aa 8612 }
ba592044 8613 else
e2b0ab59 8614 v = inst.relocs[0].exp.X_add_number;
ba592044
AM
8615
8616 if (!inst.operands[i].issingle)
8335d6aa 8617 {
12569877 8618 if (thumb_p)
8335d6aa 8619 {
53445554
TP
8620 /* LDR should not use lead in a flag-setting instruction being
8621 chosen so we do not check whether movs can be used. */
12569877 8622
53445554 8623 if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
ff8646ee 8624 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
53445554
TP
8625 && inst.operands[i].reg != 13
8626 && inst.operands[i].reg != 15)
12569877 8627 {
fc289b0a
TP
8628 /* Check if on thumb2 it can be done with a mov.w, mvn or
8629 movw instruction. */
12569877
AM
8630 unsigned int newimm;
8631 bfd_boolean isNegated;
8632
8633 newimm = encode_thumb32_immediate (v);
8634 if (newimm != (unsigned int) FAIL)
8635 isNegated = FALSE;
8636 else
8637 {
582cfe03 8638 newimm = encode_thumb32_immediate (~v);
12569877
AM
8639 if (newimm != (unsigned int) FAIL)
8640 isNegated = TRUE;
8641 }
8642
fc289b0a
TP
8643 /* The number can be loaded with a mov.w or mvn
8644 instruction. */
ff8646ee
TP
8645 if (newimm != (unsigned int) FAIL
8646 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
12569877 8647 {
fc289b0a 8648 inst.instruction = (0xf04f0000 /* MOV.W. */
582cfe03 8649 | (inst.operands[i].reg << 8));
fc289b0a 8650 /* Change to MOVN. */
582cfe03 8651 inst.instruction |= (isNegated ? 0x200000 : 0);
12569877
AM
8652 inst.instruction |= (newimm & 0x800) << 15;
8653 inst.instruction |= (newimm & 0x700) << 4;
8654 inst.instruction |= (newimm & 0x0ff);
8655 return TRUE;
8656 }
fc289b0a 8657 /* The number can be loaded with a movw instruction. */
ff8646ee
TP
8658 else if ((v & ~0xFFFF) == 0
8659 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
3739860c 8660 {
582cfe03 8661 int imm = v & 0xFFFF;
12569877 8662
582cfe03 8663 inst.instruction = 0xf2400000; /* MOVW. */
12569877
AM
8664 inst.instruction |= (inst.operands[i].reg << 8);
8665 inst.instruction |= (imm & 0xf000) << 4;
8666 inst.instruction |= (imm & 0x0800) << 15;
8667 inst.instruction |= (imm & 0x0700) << 4;
8668 inst.instruction |= (imm & 0x00ff);
8669 return TRUE;
8670 }
8671 }
8335d6aa 8672 }
12569877 8673 else if (arm_p)
ba592044
AM
8674 {
8675 int value = encode_arm_immediate (v);
12569877 8676
ba592044
AM
8677 if (value != FAIL)
8678 {
8679 /* This can be done with a mov instruction. */
8680 inst.instruction &= LITERAL_MASK;
8681 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
8682 inst.instruction |= value & 0xfff;
8683 return TRUE;
8684 }
8335d6aa 8685
ba592044
AM
8686 value = encode_arm_immediate (~ v);
8687 if (value != FAIL)
8688 {
8689 /* This can be done with a mvn instruction. */
8690 inst.instruction &= LITERAL_MASK;
8691 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
8692 inst.instruction |= value & 0xfff;
8693 return TRUE;
8694 }
8695 }
934c2632 8696 else if (t == CONST_VEC && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
8335d6aa 8697 {
ba592044
AM
8698 int op = 0;
8699 unsigned immbits = 0;
8700 unsigned immlo = inst.operands[1].imm;
8701 unsigned immhi = inst.operands[1].regisimm
8702 ? inst.operands[1].reg
e2b0ab59 8703 : inst.relocs[0].exp.X_unsigned
ba592044
AM
8704 ? 0
8705 : ((bfd_int64_t)((int) immlo)) >> 32;
8706 int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8707 &op, 64, NT_invtype);
8708
8709 if (cmode == FAIL)
8710 {
8711 neon_invert_size (&immlo, &immhi, 64);
8712 op = !op;
8713 cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8714 &op, 64, NT_invtype);
8715 }
8716
8717 if (cmode != FAIL)
8718 {
8719 inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
8720 | (1 << 23)
8721 | (cmode << 8)
8722 | (op << 5)
8723 | (1 << 4);
8724
8725 /* Fill other bits in vmov encoding for both thumb and arm. */
8726 if (thumb_mode)
eff0bc54 8727 inst.instruction |= (0x7U << 29) | (0xF << 24);
ba592044 8728 else
eff0bc54 8729 inst.instruction |= (0xFU << 28) | (0x1 << 25);
ba592044
AM
8730 neon_write_immbits (immbits);
8731 return TRUE;
8732 }
8335d6aa
JW
8733 }
8734 }
8335d6aa 8735
ba592044
AM
8736 if (t == CONST_VEC)
8737 {
8738 /* Check if vldr Rx, =constant could be optimized to vmov Rx, #constant. */
8739 if (inst.operands[i].issingle
8740 && is_quarter_float (inst.operands[1].imm)
8741 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3xd))
8335d6aa 8742 {
ba592044
AM
8743 inst.operands[1].imm =
8744 neon_qfloat_bits (v);
8745 do_vfp_nsyn_opcode ("fconsts");
8746 return TRUE;
8335d6aa 8747 }
5fc177c8
NC
8748
8749 /* If our host does not support a 64-bit type then we cannot perform
8750 the following optimization. This mean that there will be a
8751 discrepancy between the output produced by an assembler built for
8752 a 32-bit-only host and the output produced from a 64-bit host, but
8753 this cannot be helped. */
8754#if defined BFD_HOST_64_BIT
ba592044
AM
8755 else if (!inst.operands[1].issingle
8756 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
8335d6aa 8757 {
ba592044
AM
8758 if (is_double_a_single (v)
8759 && is_quarter_float (double_to_single (v)))
8760 {
8761 inst.operands[1].imm =
8762 neon_qfloat_bits (double_to_single (v));
8763 do_vfp_nsyn_opcode ("fconstd");
8764 return TRUE;
8765 }
8335d6aa 8766 }
5fc177c8 8767#endif
8335d6aa
JW
8768 }
8769 }
8770
8771 if (add_to_lit_pool ((!inst.operands[i].isvec
8772 || inst.operands[i].issingle) ? 4 : 8) == FAIL)
8773 return TRUE;
8774
8775 inst.operands[1].reg = REG_PC;
8776 inst.operands[1].isreg = 1;
8777 inst.operands[1].preind = 1;
e2b0ab59
AV
8778 inst.relocs[0].pc_rel = 1;
8779 inst.relocs[0].type = (thumb_p
8335d6aa
JW
8780 ? BFD_RELOC_ARM_THUMB_OFFSET
8781 : (mode_3
8782 ? BFD_RELOC_ARM_HWLITERAL
8783 : BFD_RELOC_ARM_LITERAL));
8784 return FALSE;
8785}
8786
8787/* inst.operands[i] was set up by parse_address. Encode it into an
8788 ARM-format instruction. Reject all forms which cannot be encoded
8789 into a coprocessor load/store instruction. If wb_ok is false,
8790 reject use of writeback; if unind_ok is false, reject use of
8791 unindexed addressing. If reloc_override is not 0, use it instead
8792 of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
8793 (in which case it is preserved). */
8794
8795static int
8796encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
8797{
8798 if (!inst.operands[i].isreg)
8799 {
99b2a2dd
NC
8800 /* PR 18256 */
8801 if (! inst.operands[0].isvec)
8802 {
8803 inst.error = _("invalid co-processor operand");
8804 return FAIL;
8805 }
8335d6aa
JW
8806 if (move_or_literal_pool (0, CONST_VEC, /*mode_3=*/FALSE))
8807 return SUCCESS;
8808 }
8809
8810 inst.instruction |= inst.operands[i].reg << 16;
8811
8812 gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
8813
8814 if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
8815 {
8816 gas_assert (!inst.operands[i].writeback);
8817 if (!unind_ok)
8818 {
8819 inst.error = _("instruction does not support unindexed addressing");
8820 return FAIL;
8821 }
8822 inst.instruction |= inst.operands[i].imm;
8823 inst.instruction |= INDEX_UP;
8824 return SUCCESS;
8825 }
8826
8827 if (inst.operands[i].preind)
8828 inst.instruction |= PRE_INDEX;
8829
8830 if (inst.operands[i].writeback)
09d92015 8831 {
8335d6aa 8832 if (inst.operands[i].reg == REG_PC)
c19d1205 8833 {
8335d6aa
JW
8834 inst.error = _("pc may not be used with write-back");
8835 return FAIL;
c19d1205 8836 }
8335d6aa 8837 if (!wb_ok)
c19d1205 8838 {
8335d6aa
JW
8839 inst.error = _("instruction does not support writeback");
8840 return FAIL;
c19d1205 8841 }
8335d6aa 8842 inst.instruction |= WRITE_BACK;
09d92015
MM
8843 }
8844
8335d6aa 8845 if (reloc_override)
e2b0ab59
AV
8846 inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
8847 else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
8848 || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
8849 && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
c19d1205 8850 {
8335d6aa 8851 if (thumb_mode)
e2b0ab59 8852 inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
8335d6aa 8853 else
e2b0ab59 8854 inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
c19d1205 8855 }
8335d6aa
JW
8856
8857 /* Prefer + for zero encoded value. */
8858 if (!inst.operands[i].negative)
8859 inst.instruction |= INDEX_UP;
8860
8861 return SUCCESS;
09d92015
MM
8862}
8863
5f4273c7 8864/* Functions for instruction encoding, sorted by sub-architecture.
c19d1205
ZW
8865 First some generics; their names are taken from the conventional
8866 bit positions for register arguments in ARM format instructions. */
09d92015 8867
a737bd4d 8868static void
c19d1205 8869do_noargs (void)
09d92015 8870{
c19d1205 8871}
a737bd4d 8872
c19d1205
ZW
8873static void
8874do_rd (void)
8875{
8876 inst.instruction |= inst.operands[0].reg << 12;
8877}
a737bd4d 8878
16a1fa25
TP
8879static void
8880do_rn (void)
8881{
8882 inst.instruction |= inst.operands[0].reg << 16;
8883}
8884
c19d1205
ZW
8885static void
8886do_rd_rm (void)
8887{
8888 inst.instruction |= inst.operands[0].reg << 12;
8889 inst.instruction |= inst.operands[1].reg;
8890}
09d92015 8891
9eb6c0f1
MGD
8892static void
8893do_rm_rn (void)
8894{
8895 inst.instruction |= inst.operands[0].reg;
8896 inst.instruction |= inst.operands[1].reg << 16;
8897}
8898
c19d1205
ZW
8899static void
8900do_rd_rn (void)
8901{
8902 inst.instruction |= inst.operands[0].reg << 12;
8903 inst.instruction |= inst.operands[1].reg << 16;
8904}
a737bd4d 8905
c19d1205
ZW
8906static void
8907do_rn_rd (void)
8908{
8909 inst.instruction |= inst.operands[0].reg << 16;
8910 inst.instruction |= inst.operands[1].reg << 12;
8911}
09d92015 8912
4ed7ed8d
TP
8913static void
8914do_tt (void)
8915{
8916 inst.instruction |= inst.operands[0].reg << 8;
8917 inst.instruction |= inst.operands[1].reg << 16;
8918}
8919
59d09be6
MGD
8920static bfd_boolean
8921check_obsolete (const arm_feature_set *feature, const char *msg)
8922{
8923 if (ARM_CPU_IS_ANY (cpu_variant))
8924 {
5c3696f8 8925 as_tsktsk ("%s", msg);
59d09be6
MGD
8926 return TRUE;
8927 }
8928 else if (ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
8929 {
8930 as_bad ("%s", msg);
8931 return TRUE;
8932 }
8933
8934 return FALSE;
8935}
8936
c19d1205
ZW
8937static void
8938do_rd_rm_rn (void)
8939{
9a64e435 8940 unsigned Rn = inst.operands[2].reg;
708587a4 8941 /* Enforce restrictions on SWP instruction. */
9a64e435 8942 if ((inst.instruction & 0x0fbfffff) == 0x01000090)
56adecf4
DG
8943 {
8944 constraint (Rn == inst.operands[0].reg || Rn == inst.operands[1].reg,
8945 _("Rn must not overlap other operands"));
8946
59d09be6
MGD
8947 /* SWP{b} is obsolete for ARMv8-A, and deprecated for ARMv6* and ARMv7.
8948 */
8949 if (!check_obsolete (&arm_ext_v8,
8950 _("swp{b} use is obsoleted for ARMv8 and later"))
8951 && warn_on_deprecated
8952 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6))
5c3696f8 8953 as_tsktsk (_("swp{b} use is deprecated for ARMv6 and ARMv7"));
56adecf4 8954 }
59d09be6 8955
c19d1205
ZW
8956 inst.instruction |= inst.operands[0].reg << 12;
8957 inst.instruction |= inst.operands[1].reg;
9a64e435 8958 inst.instruction |= Rn << 16;
c19d1205 8959}
09d92015 8960
c19d1205
ZW
8961static void
8962do_rd_rn_rm (void)
8963{
8964 inst.instruction |= inst.operands[0].reg << 12;
8965 inst.instruction |= inst.operands[1].reg << 16;
8966 inst.instruction |= inst.operands[2].reg;
8967}
a737bd4d 8968
c19d1205
ZW
8969static void
8970do_rm_rd_rn (void)
8971{
5be8be5d 8972 constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
e2b0ab59
AV
8973 constraint (((inst.relocs[0].exp.X_op != O_constant
8974 && inst.relocs[0].exp.X_op != O_illegal)
8975 || inst.relocs[0].exp.X_add_number != 0),
5be8be5d 8976 BAD_ADDR_MODE);
c19d1205
ZW
8977 inst.instruction |= inst.operands[0].reg;
8978 inst.instruction |= inst.operands[1].reg << 12;
8979 inst.instruction |= inst.operands[2].reg << 16;
8980}
09d92015 8981
c19d1205
ZW
8982static void
8983do_imm0 (void)
8984{
8985 inst.instruction |= inst.operands[0].imm;
8986}
09d92015 8987
c19d1205
ZW
8988static void
8989do_rd_cpaddr (void)
8990{
8991 inst.instruction |= inst.operands[0].reg << 12;
8992 encode_arm_cp_address (1, TRUE, TRUE, 0);
09d92015 8993}
a737bd4d 8994
c19d1205
ZW
8995/* ARM instructions, in alphabetical order by function name (except
8996 that wrapper functions appear immediately after the function they
8997 wrap). */
09d92015 8998
c19d1205
ZW
8999/* This is a pseudo-op of the form "adr rd, label" to be converted
9000 into a relative address of the form "add rd, pc, #label-.-8". */
09d92015
MM
9001
9002static void
c19d1205 9003do_adr (void)
09d92015 9004{
c19d1205 9005 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9006
c19d1205
ZW
9007 /* Frag hacking will turn this into a sub instruction if the offset turns
9008 out to be negative. */
e2b0ab59
AV
9009 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9010 inst.relocs[0].pc_rel = 1;
9011 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9012
fc6141f0 9013 if (support_interwork
e2b0ab59
AV
9014 && inst.relocs[0].exp.X_op == O_symbol
9015 && inst.relocs[0].exp.X_add_symbol != NULL
9016 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9017 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9018 inst.relocs[0].exp.X_add_number |= 1;
c19d1205 9019}
b99bd4ef 9020
c19d1205
ZW
9021/* This is a pseudo-op of the form "adrl rd, label" to be converted
9022 into a relative address of the form:
9023 add rd, pc, #low(label-.-8)"
9024 add rd, rd, #high(label-.-8)" */
b99bd4ef 9025
c19d1205
ZW
9026static void
9027do_adrl (void)
9028{
9029 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 9030
c19d1205
ZW
9031 /* Frag hacking will turn this into a sub instruction if the offset turns
9032 out to be negative. */
e2b0ab59
AV
9033 inst.relocs[0].type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
9034 inst.relocs[0].pc_rel = 1;
c19d1205 9035 inst.size = INSN_SIZE * 2;
e2b0ab59 9036 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 9037
fc6141f0 9038 if (support_interwork
e2b0ab59
AV
9039 && inst.relocs[0].exp.X_op == O_symbol
9040 && inst.relocs[0].exp.X_add_symbol != NULL
9041 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
9042 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
9043 inst.relocs[0].exp.X_add_number |= 1;
b99bd4ef
NC
9044}
9045
b99bd4ef 9046static void
c19d1205 9047do_arit (void)
b99bd4ef 9048{
e2b0ab59
AV
9049 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9050 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9051 THUMB1_RELOC_ONLY);
c19d1205
ZW
9052 if (!inst.operands[1].present)
9053 inst.operands[1].reg = inst.operands[0].reg;
9054 inst.instruction |= inst.operands[0].reg << 12;
9055 inst.instruction |= inst.operands[1].reg << 16;
9056 encode_arm_shifter_operand (2);
9057}
b99bd4ef 9058
62b3e311
PB
9059static void
9060do_barrier (void)
9061{
9062 if (inst.operands[0].present)
ccb84d65 9063 inst.instruction |= inst.operands[0].imm;
62b3e311
PB
9064 else
9065 inst.instruction |= 0xf;
9066}
9067
c19d1205
ZW
9068static void
9069do_bfc (void)
9070{
9071 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
9072 constraint (msb > 32, _("bit-field extends past end of register"));
9073 /* The instruction encoding stores the LSB and MSB,
9074 not the LSB and width. */
9075 inst.instruction |= inst.operands[0].reg << 12;
9076 inst.instruction |= inst.operands[1].imm << 7;
9077 inst.instruction |= (msb - 1) << 16;
9078}
b99bd4ef 9079
c19d1205
ZW
9080static void
9081do_bfi (void)
9082{
9083 unsigned int msb;
b99bd4ef 9084
c19d1205
ZW
9085 /* #0 in second position is alternative syntax for bfc, which is
9086 the same instruction but with REG_PC in the Rm field. */
9087 if (!inst.operands[1].isreg)
9088 inst.operands[1].reg = REG_PC;
b99bd4ef 9089
c19d1205
ZW
9090 msb = inst.operands[2].imm + inst.operands[3].imm;
9091 constraint (msb > 32, _("bit-field extends past end of register"));
9092 /* The instruction encoding stores the LSB and MSB,
9093 not the LSB and width. */
9094 inst.instruction |= inst.operands[0].reg << 12;
9095 inst.instruction |= inst.operands[1].reg;
9096 inst.instruction |= inst.operands[2].imm << 7;
9097 inst.instruction |= (msb - 1) << 16;
b99bd4ef
NC
9098}
9099
b99bd4ef 9100static void
c19d1205 9101do_bfx (void)
b99bd4ef 9102{
c19d1205
ZW
9103 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
9104 _("bit-field extends past end of register"));
9105 inst.instruction |= inst.operands[0].reg << 12;
9106 inst.instruction |= inst.operands[1].reg;
9107 inst.instruction |= inst.operands[2].imm << 7;
9108 inst.instruction |= (inst.operands[3].imm - 1) << 16;
9109}
09d92015 9110
c19d1205
ZW
9111/* ARM V5 breakpoint instruction (argument parse)
9112 BKPT <16 bit unsigned immediate>
9113 Instruction is not conditional.
9114 The bit pattern given in insns[] has the COND_ALWAYS condition,
9115 and it is an error if the caller tried to override that. */
b99bd4ef 9116
c19d1205
ZW
9117static void
9118do_bkpt (void)
9119{
9120 /* Top 12 of 16 bits to bits 19:8. */
9121 inst.instruction |= (inst.operands[0].imm & 0xfff0) << 4;
09d92015 9122
c19d1205
ZW
9123 /* Bottom 4 of 16 bits to bits 3:0. */
9124 inst.instruction |= inst.operands[0].imm & 0xf;
9125}
09d92015 9126
c19d1205
ZW
9127static void
9128encode_branch (int default_reloc)
9129{
9130 if (inst.operands[0].hasreloc)
9131 {
0855e32b
NS
9132 constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
9133 && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
9134 _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
e2b0ab59 9135 inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
0855e32b
NS
9136 ? BFD_RELOC_ARM_PLT32
9137 : thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
c19d1205 9138 }
b99bd4ef 9139 else
e2b0ab59
AV
9140 inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
9141 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
9142}
9143
b99bd4ef 9144static void
c19d1205 9145do_branch (void)
b99bd4ef 9146{
39b41c9c
PB
9147#ifdef OBJ_ELF
9148 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9149 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9150 else
9151#endif
9152 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
9153}
9154
9155static void
9156do_bl (void)
9157{
9158#ifdef OBJ_ELF
9159 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
9160 {
9161 if (inst.cond == COND_ALWAYS)
9162 encode_branch (BFD_RELOC_ARM_PCREL_CALL);
9163 else
9164 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
9165 }
9166 else
9167#endif
9168 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
c19d1205 9169}
b99bd4ef 9170
c19d1205
ZW
9171/* ARM V5 branch-link-exchange instruction (argument parse)
9172 BLX <target_addr> ie BLX(1)
9173 BLX{<condition>} <Rm> ie BLX(2)
9174 Unfortunately, there are two different opcodes for this mnemonic.
9175 So, the insns[].value is not used, and the code here zaps values
9176 into inst.instruction.
9177 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
b99bd4ef 9178
c19d1205
ZW
9179static void
9180do_blx (void)
9181{
9182 if (inst.operands[0].isreg)
b99bd4ef 9183 {
c19d1205
ZW
9184 /* Arg is a register; the opcode provided by insns[] is correct.
9185 It is not illegal to do "blx pc", just useless. */
9186 if (inst.operands[0].reg == REG_PC)
9187 as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
b99bd4ef 9188
c19d1205
ZW
9189 inst.instruction |= inst.operands[0].reg;
9190 }
9191 else
b99bd4ef 9192 {
c19d1205 9193 /* Arg is an address; this instruction cannot be executed
267bf995
RR
9194 conditionally, and the opcode must be adjusted.
9195 We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
9196 where we generate out a BFD_RELOC_ARM_PCREL_CALL instead. */
c19d1205 9197 constraint (inst.cond != COND_ALWAYS, BAD_COND);
2fc8bdac 9198 inst.instruction = 0xfa000000;
267bf995 9199 encode_branch (BFD_RELOC_ARM_PCREL_BLX);
b99bd4ef 9200 }
c19d1205
ZW
9201}
9202
9203static void
9204do_bx (void)
9205{
845b51d6
PB
9206 bfd_boolean want_reloc;
9207
c19d1205
ZW
9208 if (inst.operands[0].reg == REG_PC)
9209 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
b99bd4ef 9210
c19d1205 9211 inst.instruction |= inst.operands[0].reg;
845b51d6
PB
9212 /* Output R_ARM_V4BX relocations if is an EABI object that looks like
9213 it is for ARMv4t or earlier. */
9214 want_reloc = !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5);
4d354d8b
TP
9215 if (!ARM_FEATURE_ZERO (selected_object_arch)
9216 && !ARM_CPU_HAS_FEATURE (selected_object_arch, arm_ext_v5))
845b51d6
PB
9217 want_reloc = TRUE;
9218
5ad34203 9219#ifdef OBJ_ELF
845b51d6 9220 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
5ad34203 9221#endif
584206db 9222 want_reloc = FALSE;
845b51d6
PB
9223
9224 if (want_reloc)
e2b0ab59 9225 inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
09d92015
MM
9226}
9227
c19d1205
ZW
9228
9229/* ARM v5TEJ. Jump to Jazelle code. */
a737bd4d
NC
9230
9231static void
c19d1205 9232do_bxj (void)
a737bd4d 9233{
c19d1205
ZW
9234 if (inst.operands[0].reg == REG_PC)
9235 as_tsktsk (_("use of r15 in bxj is not really useful"));
9236
9237 inst.instruction |= inst.operands[0].reg;
a737bd4d
NC
9238}
9239
c19d1205
ZW
9240/* Co-processor data operation:
9241 CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
9242 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>} */
9243static void
9244do_cdp (void)
9245{
9246 inst.instruction |= inst.operands[0].reg << 8;
9247 inst.instruction |= inst.operands[1].imm << 20;
9248 inst.instruction |= inst.operands[2].reg << 12;
9249 inst.instruction |= inst.operands[3].reg << 16;
9250 inst.instruction |= inst.operands[4].reg;
9251 inst.instruction |= inst.operands[5].imm << 5;
9252}
a737bd4d
NC
9253
9254static void
c19d1205 9255do_cmp (void)
a737bd4d 9256{
c19d1205
ZW
9257 inst.instruction |= inst.operands[0].reg << 16;
9258 encode_arm_shifter_operand (1);
a737bd4d
NC
9259}
9260
c19d1205
ZW
9261/* Transfer between coprocessor and ARM registers.
9262 MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
9263 MRC2
9264 MCR{cond}
9265 MCR2
9266
9267 No special properties. */
09d92015 9268
dcbd0d71
MGD
9269struct deprecated_coproc_regs_s
9270{
9271 unsigned cp;
9272 int opc1;
9273 unsigned crn;
9274 unsigned crm;
9275 int opc2;
9276 arm_feature_set deprecated;
9277 arm_feature_set obsoleted;
9278 const char *dep_msg;
9279 const char *obs_msg;
9280};
9281
9282#define DEPR_ACCESS_V8 \
9283 N_("This coprocessor register access is deprecated in ARMv8")
9284
9285/* Table of all deprecated coprocessor registers. */
9286static struct deprecated_coproc_regs_s deprecated_coproc_regs[] =
9287{
9288 {15, 0, 7, 10, 5, /* CP15DMB. */
823d2571 9289 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9290 DEPR_ACCESS_V8, NULL},
9291 {15, 0, 7, 10, 4, /* CP15DSB. */
823d2571 9292 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9293 DEPR_ACCESS_V8, NULL},
9294 {15, 0, 7, 5, 4, /* CP15ISB. */
823d2571 9295 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9296 DEPR_ACCESS_V8, NULL},
9297 {14, 6, 1, 0, 0, /* TEEHBR. */
823d2571 9298 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9299 DEPR_ACCESS_V8, NULL},
9300 {14, 6, 0, 0, 0, /* TEECR. */
823d2571 9301 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
9302 DEPR_ACCESS_V8, NULL},
9303};
9304
9305#undef DEPR_ACCESS_V8
9306
9307static const size_t deprecated_coproc_reg_count =
9308 sizeof (deprecated_coproc_regs) / sizeof (deprecated_coproc_regs[0]);
9309
09d92015 9310static void
c19d1205 9311do_co_reg (void)
09d92015 9312{
fdfde340 9313 unsigned Rd;
dcbd0d71 9314 size_t i;
fdfde340
JM
9315
9316 Rd = inst.operands[2].reg;
9317 if (thumb_mode)
9318 {
9319 if (inst.instruction == 0xee000010
9320 || inst.instruction == 0xfe000010)
9321 /* MCR, MCR2 */
9322 reject_bad_reg (Rd);
5c8ed6a4 9323 else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
fdfde340
JM
9324 /* MRC, MRC2 */
9325 constraint (Rd == REG_SP, BAD_SP);
9326 }
9327 else
9328 {
9329 /* MCR */
9330 if (inst.instruction == 0xe000010)
9331 constraint (Rd == REG_PC, BAD_PC);
9332 }
9333
dcbd0d71
MGD
9334 for (i = 0; i < deprecated_coproc_reg_count; ++i)
9335 {
9336 const struct deprecated_coproc_regs_s *r =
9337 deprecated_coproc_regs + i;
9338
9339 if (inst.operands[0].reg == r->cp
9340 && inst.operands[1].imm == r->opc1
9341 && inst.operands[3].reg == r->crn
9342 && inst.operands[4].reg == r->crm
9343 && inst.operands[5].imm == r->opc2)
9344 {
b10bf8c5 9345 if (! ARM_CPU_IS_ANY (cpu_variant)
477330fc 9346 && warn_on_deprecated
dcbd0d71 9347 && ARM_CPU_HAS_FEATURE (cpu_variant, r->deprecated))
5c3696f8 9348 as_tsktsk ("%s", r->dep_msg);
dcbd0d71
MGD
9349 }
9350 }
fdfde340 9351
c19d1205
ZW
9352 inst.instruction |= inst.operands[0].reg << 8;
9353 inst.instruction |= inst.operands[1].imm << 21;
fdfde340 9354 inst.instruction |= Rd << 12;
c19d1205
ZW
9355 inst.instruction |= inst.operands[3].reg << 16;
9356 inst.instruction |= inst.operands[4].reg;
9357 inst.instruction |= inst.operands[5].imm << 5;
9358}
09d92015 9359
c19d1205
ZW
9360/* Transfer between coprocessor register and pair of ARM registers.
9361 MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
9362 MCRR2
9363 MRRC{cond}
9364 MRRC2
b99bd4ef 9365
c19d1205 9366 Two XScale instructions are special cases of these:
09d92015 9367
c19d1205
ZW
9368 MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
9369 MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
b99bd4ef 9370
5f4273c7 9371 Result unpredictable if Rd or Rn is R15. */
a737bd4d 9372
c19d1205
ZW
9373static void
9374do_co_reg2c (void)
9375{
fdfde340
JM
9376 unsigned Rd, Rn;
9377
9378 Rd = inst.operands[2].reg;
9379 Rn = inst.operands[3].reg;
9380
9381 if (thumb_mode)
9382 {
9383 reject_bad_reg (Rd);
9384 reject_bad_reg (Rn);
9385 }
9386 else
9387 {
9388 constraint (Rd == REG_PC, BAD_PC);
9389 constraint (Rn == REG_PC, BAD_PC);
9390 }
9391
873f10f0
TC
9392 /* Only check the MRRC{2} variants. */
9393 if ((inst.instruction & 0x0FF00000) == 0x0C500000)
9394 {
9395 /* If Rd == Rn, error that the operation is
9396 unpredictable (example MRRC p3,#1,r1,r1,c4). */
9397 constraint (Rd == Rn, BAD_OVERLAP);
9398 }
9399
c19d1205
ZW
9400 inst.instruction |= inst.operands[0].reg << 8;
9401 inst.instruction |= inst.operands[1].imm << 4;
fdfde340
JM
9402 inst.instruction |= Rd << 12;
9403 inst.instruction |= Rn << 16;
c19d1205 9404 inst.instruction |= inst.operands[4].reg;
b99bd4ef
NC
9405}
9406
c19d1205
ZW
9407static void
9408do_cpsi (void)
9409{
9410 inst.instruction |= inst.operands[0].imm << 6;
a028a6f5
PB
9411 if (inst.operands[1].present)
9412 {
9413 inst.instruction |= CPSI_MMOD;
9414 inst.instruction |= inst.operands[1].imm;
9415 }
c19d1205 9416}
b99bd4ef 9417
62b3e311
PB
9418static void
9419do_dbg (void)
9420{
9421 inst.instruction |= inst.operands[0].imm;
9422}
9423
eea54501
MGD
9424static void
9425do_div (void)
9426{
9427 unsigned Rd, Rn, Rm;
9428
9429 Rd = inst.operands[0].reg;
9430 Rn = (inst.operands[1].present
9431 ? inst.operands[1].reg : Rd);
9432 Rm = inst.operands[2].reg;
9433
9434 constraint ((Rd == REG_PC), BAD_PC);
9435 constraint ((Rn == REG_PC), BAD_PC);
9436 constraint ((Rm == REG_PC), BAD_PC);
9437
9438 inst.instruction |= Rd << 16;
9439 inst.instruction |= Rn << 0;
9440 inst.instruction |= Rm << 8;
9441}
9442
b99bd4ef 9443static void
c19d1205 9444do_it (void)
b99bd4ef 9445{
c19d1205 9446 /* There is no IT instruction in ARM mode. We
e07e6e58
NC
9447 process it to do the validation as if in
9448 thumb mode, just in case the code gets
9449 assembled for thumb using the unified syntax. */
9450
c19d1205 9451 inst.size = 0;
e07e6e58
NC
9452 if (unified_syntax)
9453 {
5ee91343
AV
9454 set_pred_insn_type (IT_INSN);
9455 now_pred.mask = (inst.instruction & 0xf) | 0x10;
9456 now_pred.cc = inst.operands[0].imm;
e07e6e58 9457 }
09d92015 9458}
b99bd4ef 9459
6530b175
NC
9460/* If there is only one register in the register list,
9461 then return its register number. Otherwise return -1. */
9462static int
9463only_one_reg_in_list (int range)
9464{
9465 int i = ffs (range) - 1;
9466 return (i > 15 || range != (1 << i)) ? -1 : i;
9467}
9468
09d92015 9469static void
6530b175 9470encode_ldmstm(int from_push_pop_mnem)
ea6ef066 9471{
c19d1205
ZW
9472 int base_reg = inst.operands[0].reg;
9473 int range = inst.operands[1].imm;
6530b175 9474 int one_reg;
ea6ef066 9475
c19d1205
ZW
9476 inst.instruction |= base_reg << 16;
9477 inst.instruction |= range;
ea6ef066 9478
c19d1205
ZW
9479 if (inst.operands[1].writeback)
9480 inst.instruction |= LDM_TYPE_2_OR_3;
09d92015 9481
c19d1205 9482 if (inst.operands[0].writeback)
ea6ef066 9483 {
c19d1205
ZW
9484 inst.instruction |= WRITE_BACK;
9485 /* Check for unpredictable uses of writeback. */
9486 if (inst.instruction & LOAD_BIT)
09d92015 9487 {
c19d1205
ZW
9488 /* Not allowed in LDM type 2. */
9489 if ((inst.instruction & LDM_TYPE_2_OR_3)
9490 && ((range & (1 << REG_PC)) == 0))
9491 as_warn (_("writeback of base register is UNPREDICTABLE"));
9492 /* Only allowed if base reg not in list for other types. */
9493 else if (range & (1 << base_reg))
9494 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
9495 }
9496 else /* STM. */
9497 {
9498 /* Not allowed for type 2. */
9499 if (inst.instruction & LDM_TYPE_2_OR_3)
9500 as_warn (_("writeback of base register is UNPREDICTABLE"));
9501 /* Only allowed if base reg not in list, or first in list. */
9502 else if ((range & (1 << base_reg))
9503 && (range & ((1 << base_reg) - 1)))
9504 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
09d92015 9505 }
ea6ef066 9506 }
6530b175
NC
9507
9508 /* If PUSH/POP has only one register, then use the A2 encoding. */
9509 one_reg = only_one_reg_in_list (range);
9510 if (from_push_pop_mnem && one_reg >= 0)
9511 {
9512 int is_push = (inst.instruction & A_PUSH_POP_OP_MASK) == A1_OPCODE_PUSH;
9513
4f588891
NC
9514 if (is_push && one_reg == 13 /* SP */)
9515 /* PR 22483: The A2 encoding cannot be used when
9516 pushing the stack pointer as this is UNPREDICTABLE. */
9517 return;
9518
6530b175
NC
9519 inst.instruction &= A_COND_MASK;
9520 inst.instruction |= is_push ? A2_OPCODE_PUSH : A2_OPCODE_POP;
9521 inst.instruction |= one_reg << 12;
9522 }
9523}
9524
9525static void
9526do_ldmstm (void)
9527{
9528 encode_ldmstm (/*from_push_pop_mnem=*/FALSE);
a737bd4d
NC
9529}
9530
c19d1205
ZW
9531/* ARMv5TE load-consecutive (argument parse)
9532 Mode is like LDRH.
9533
9534 LDRccD R, mode
9535 STRccD R, mode. */
9536
a737bd4d 9537static void
c19d1205 9538do_ldrd (void)
a737bd4d 9539{
c19d1205 9540 constraint (inst.operands[0].reg % 2 != 0,
c56791bb 9541 _("first transfer register must be even"));
c19d1205
ZW
9542 constraint (inst.operands[1].present
9543 && inst.operands[1].reg != inst.operands[0].reg + 1,
c56791bb 9544 _("can only transfer two consecutive registers"));
c19d1205
ZW
9545 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
9546 constraint (!inst.operands[2].isreg, _("'[' expected"));
a737bd4d 9547
c19d1205
ZW
9548 if (!inst.operands[1].present)
9549 inst.operands[1].reg = inst.operands[0].reg + 1;
5f4273c7 9550
c56791bb
RE
9551 /* encode_arm_addr_mode_3 will diagnose overlap between the base
9552 register and the first register written; we have to diagnose
9553 overlap between the base and the second register written here. */
ea6ef066 9554
c56791bb
RE
9555 if (inst.operands[2].reg == inst.operands[1].reg
9556 && (inst.operands[2].writeback || inst.operands[2].postind))
9557 as_warn (_("base register written back, and overlaps "
9558 "second transfer register"));
b05fe5cf 9559
c56791bb
RE
9560 if (!(inst.instruction & V4_STR_BIT))
9561 {
c19d1205 9562 /* For an index-register load, the index register must not overlap the
c56791bb
RE
9563 destination (even if not write-back). */
9564 if (inst.operands[2].immisreg
9565 && ((unsigned) inst.operands[2].imm == inst.operands[0].reg
9566 || (unsigned) inst.operands[2].imm == inst.operands[1].reg))
9567 as_warn (_("index register overlaps transfer register"));
b05fe5cf 9568 }
c19d1205
ZW
9569 inst.instruction |= inst.operands[0].reg << 12;
9570 encode_arm_addr_mode_3 (2, /*is_t=*/FALSE);
b05fe5cf
ZW
9571}
9572
9573static void
c19d1205 9574do_ldrex (void)
b05fe5cf 9575{
c19d1205
ZW
9576 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
9577 || inst.operands[1].postind || inst.operands[1].writeback
9578 || inst.operands[1].immisreg || inst.operands[1].shifted
01cfc07f
NC
9579 || inst.operands[1].negative
9580 /* This can arise if the programmer has written
9581 strex rN, rM, foo
9582 or if they have mistakenly used a register name as the last
9583 operand, eg:
9584 strex rN, rM, rX
9585 It is very difficult to distinguish between these two cases
9586 because "rX" might actually be a label. ie the register
9587 name has been occluded by a symbol of the same name. So we
9588 just generate a general 'bad addressing mode' type error
9589 message and leave it up to the programmer to discover the
9590 true cause and fix their mistake. */
9591 || (inst.operands[1].reg == REG_PC),
9592 BAD_ADDR_MODE);
b05fe5cf 9593
e2b0ab59
AV
9594 constraint (inst.relocs[0].exp.X_op != O_constant
9595 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9596 _("offset must be zero in ARM encoding"));
b05fe5cf 9597
5be8be5d
DG
9598 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
9599
c19d1205
ZW
9600 inst.instruction |= inst.operands[0].reg << 12;
9601 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 9602 inst.relocs[0].type = BFD_RELOC_UNUSED;
b05fe5cf
ZW
9603}
9604
9605static void
c19d1205 9606do_ldrexd (void)
b05fe5cf 9607{
c19d1205
ZW
9608 constraint (inst.operands[0].reg % 2 != 0,
9609 _("even register required"));
9610 constraint (inst.operands[1].present
9611 && inst.operands[1].reg != inst.operands[0].reg + 1,
9612 _("can only load two consecutive registers"));
9613 /* If op 1 were present and equal to PC, this function wouldn't
9614 have been called in the first place. */
9615 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
b05fe5cf 9616
c19d1205
ZW
9617 inst.instruction |= inst.operands[0].reg << 12;
9618 inst.instruction |= inst.operands[2].reg << 16;
b05fe5cf
ZW
9619}
9620
1be5fd2e
NC
9621/* In both ARM and thumb state 'ldr pc, #imm' with an immediate
9622 which is not a multiple of four is UNPREDICTABLE. */
9623static void
9624check_ldr_r15_aligned (void)
9625{
9626 constraint (!(inst.operands[1].immisreg)
9627 && (inst.operands[0].reg == REG_PC
9628 && inst.operands[1].reg == REG_PC
e2b0ab59 9629 && (inst.relocs[0].exp.X_add_number & 0x3)),
de194d85 9630 _("ldr to register 15 must be 4-byte aligned"));
1be5fd2e
NC
9631}
9632
b05fe5cf 9633static void
c19d1205 9634do_ldst (void)
b05fe5cf 9635{
c19d1205
ZW
9636 inst.instruction |= inst.operands[0].reg << 12;
9637 if (!inst.operands[1].isreg)
8335d6aa 9638 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/FALSE))
b05fe5cf 9639 return;
c19d1205 9640 encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
1be5fd2e 9641 check_ldr_r15_aligned ();
b05fe5cf
ZW
9642}
9643
9644static void
c19d1205 9645do_ldstt (void)
b05fe5cf 9646{
c19d1205
ZW
9647 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9648 reject [Rn,...]. */
9649 if (inst.operands[1].preind)
b05fe5cf 9650 {
e2b0ab59
AV
9651 constraint (inst.relocs[0].exp.X_op != O_constant
9652 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9653 _("this instruction requires a post-indexed address"));
b05fe5cf 9654
c19d1205
ZW
9655 inst.operands[1].preind = 0;
9656 inst.operands[1].postind = 1;
9657 inst.operands[1].writeback = 1;
b05fe5cf 9658 }
c19d1205
ZW
9659 inst.instruction |= inst.operands[0].reg << 12;
9660 encode_arm_addr_mode_2 (1, /*is_t=*/TRUE);
9661}
b05fe5cf 9662
c19d1205 9663/* Halfword and signed-byte load/store operations. */
b05fe5cf 9664
c19d1205
ZW
9665static void
9666do_ldstv4 (void)
9667{
ff4a8d2b 9668 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205
ZW
9669 inst.instruction |= inst.operands[0].reg << 12;
9670 if (!inst.operands[1].isreg)
8335d6aa 9671 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/TRUE))
b05fe5cf 9672 return;
c19d1205 9673 encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
b05fe5cf
ZW
9674}
9675
9676static void
c19d1205 9677do_ldsttv4 (void)
b05fe5cf 9678{
c19d1205
ZW
9679 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9680 reject [Rn,...]. */
9681 if (inst.operands[1].preind)
b05fe5cf 9682 {
e2b0ab59
AV
9683 constraint (inst.relocs[0].exp.X_op != O_constant
9684 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9685 _("this instruction requires a post-indexed address"));
b05fe5cf 9686
c19d1205
ZW
9687 inst.operands[1].preind = 0;
9688 inst.operands[1].postind = 1;
9689 inst.operands[1].writeback = 1;
b05fe5cf 9690 }
c19d1205
ZW
9691 inst.instruction |= inst.operands[0].reg << 12;
9692 encode_arm_addr_mode_3 (1, /*is_t=*/TRUE);
9693}
b05fe5cf 9694
c19d1205
ZW
9695/* Co-processor register load/store.
9696 Format: <LDC|STC>{cond}[L] CP#,CRd,<address> */
9697static void
9698do_lstc (void)
9699{
9700 inst.instruction |= inst.operands[0].reg << 8;
9701 inst.instruction |= inst.operands[1].reg << 12;
9702 encode_arm_cp_address (2, TRUE, TRUE, 0);
b05fe5cf
ZW
9703}
9704
b05fe5cf 9705static void
c19d1205 9706do_mlas (void)
b05fe5cf 9707{
8fb9d7b9 9708 /* This restriction does not apply to mls (nor to mla in v6 or later). */
c19d1205 9709 if (inst.operands[0].reg == inst.operands[1].reg
8fb9d7b9 9710 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6)
c19d1205 9711 && !(inst.instruction & 0x00400000))
8fb9d7b9 9712 as_tsktsk (_("Rd and Rm should be different in mla"));
b05fe5cf 9713
c19d1205
ZW
9714 inst.instruction |= inst.operands[0].reg << 16;
9715 inst.instruction |= inst.operands[1].reg;
9716 inst.instruction |= inst.operands[2].reg << 8;
9717 inst.instruction |= inst.operands[3].reg << 12;
c19d1205 9718}
b05fe5cf 9719
c19d1205
ZW
9720static void
9721do_mov (void)
9722{
e2b0ab59
AV
9723 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9724 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9725 THUMB1_RELOC_ONLY);
c19d1205
ZW
9726 inst.instruction |= inst.operands[0].reg << 12;
9727 encode_arm_shifter_operand (1);
9728}
b05fe5cf 9729
c19d1205
ZW
9730/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
9731static void
9732do_mov16 (void)
9733{
b6895b4f
PB
9734 bfd_vma imm;
9735 bfd_boolean top;
9736
9737 top = (inst.instruction & 0x00400000) != 0;
e2b0ab59 9738 constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
33eaf5de 9739 _(":lower16: not allowed in this instruction"));
e2b0ab59 9740 constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
33eaf5de 9741 _(":upper16: not allowed in this instruction"));
c19d1205 9742 inst.instruction |= inst.operands[0].reg << 12;
e2b0ab59 9743 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 9744 {
e2b0ab59 9745 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
9746 /* The value is in two pieces: 0:11, 16:19. */
9747 inst.instruction |= (imm & 0x00000fff);
9748 inst.instruction |= (imm & 0x0000f000) << 4;
9749 }
b05fe5cf 9750}
b99bd4ef 9751
037e8744
JB
9752static int
9753do_vfp_nsyn_mrs (void)
9754{
9755 if (inst.operands[0].isvec)
9756 {
9757 if (inst.operands[1].reg != 1)
477330fc 9758 first_error (_("operand 1 must be FPSCR"));
037e8744
JB
9759 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
9760 memset (&inst.operands[1], '\0', sizeof (inst.operands[1]));
9761 do_vfp_nsyn_opcode ("fmstat");
9762 }
9763 else if (inst.operands[1].isvec)
9764 do_vfp_nsyn_opcode ("fmrx");
9765 else
9766 return FAIL;
5f4273c7 9767
037e8744
JB
9768 return SUCCESS;
9769}
9770
9771static int
9772do_vfp_nsyn_msr (void)
9773{
9774 if (inst.operands[0].isvec)
9775 do_vfp_nsyn_opcode ("fmxr");
9776 else
9777 return FAIL;
9778
9779 return SUCCESS;
9780}
9781
f7c21dc7
NC
9782static void
9783do_vmrs (void)
9784{
9785 unsigned Rt = inst.operands[0].reg;
fa94de6b 9786
16d02dc9 9787 if (thumb_mode && Rt == REG_SP)
f7c21dc7
NC
9788 {
9789 inst.error = BAD_SP;
9790 return;
9791 }
9792
40c7d507
RR
9793 /* MVFR2 is only valid at ARMv8-A. */
9794 if (inst.operands[1].reg == 5)
9795 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9796 _(BAD_FPU));
9797
f7c21dc7 9798 /* APSR_ sets isvec. All other refs to PC are illegal. */
16d02dc9 9799 if (!inst.operands[0].isvec && Rt == REG_PC)
f7c21dc7
NC
9800 {
9801 inst.error = BAD_PC;
9802 return;
9803 }
9804
16d02dc9
JB
9805 /* If we get through parsing the register name, we just insert the number
9806 generated into the instruction without further validation. */
9807 inst.instruction |= (inst.operands[1].reg << 16);
f7c21dc7
NC
9808 inst.instruction |= (Rt << 12);
9809}
9810
9811static void
9812do_vmsr (void)
9813{
9814 unsigned Rt = inst.operands[1].reg;
fa94de6b 9815
f7c21dc7
NC
9816 if (thumb_mode)
9817 reject_bad_reg (Rt);
9818 else if (Rt == REG_PC)
9819 {
9820 inst.error = BAD_PC;
9821 return;
9822 }
9823
40c7d507
RR
9824 /* MVFR2 is only valid for ARMv8-A. */
9825 if (inst.operands[0].reg == 5)
9826 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9827 _(BAD_FPU));
9828
16d02dc9
JB
9829 /* If we get through parsing the register name, we just insert the number
9830 generated into the instruction without further validation. */
9831 inst.instruction |= (inst.operands[0].reg << 16);
f7c21dc7
NC
9832 inst.instruction |= (Rt << 12);
9833}
9834
b99bd4ef 9835static void
c19d1205 9836do_mrs (void)
b99bd4ef 9837{
90ec0d68
MGD
9838 unsigned br;
9839
037e8744
JB
9840 if (do_vfp_nsyn_mrs () == SUCCESS)
9841 return;
9842
ff4a8d2b 9843 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205 9844 inst.instruction |= inst.operands[0].reg << 12;
90ec0d68
MGD
9845
9846 if (inst.operands[1].isreg)
9847 {
9848 br = inst.operands[1].reg;
806ab1c0 9849 if (((br & 0x200) == 0) && ((br & 0xf0000) != 0xf0000))
90ec0d68
MGD
9850 as_bad (_("bad register for mrs"));
9851 }
9852 else
9853 {
9854 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
9855 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
9856 != (PSR_c|PSR_f),
d2cd1205 9857 _("'APSR', 'CPSR' or 'SPSR' expected"));
90ec0d68
MGD
9858 br = (15<<16) | (inst.operands[1].imm & SPSR_BIT);
9859 }
9860
9861 inst.instruction |= br;
c19d1205 9862}
b99bd4ef 9863
c19d1205
ZW
9864/* Two possible forms:
9865 "{C|S}PSR_<field>, Rm",
9866 "{C|S}PSR_f, #expression". */
b99bd4ef 9867
c19d1205
ZW
9868static void
9869do_msr (void)
9870{
037e8744
JB
9871 if (do_vfp_nsyn_msr () == SUCCESS)
9872 return;
9873
c19d1205
ZW
9874 inst.instruction |= inst.operands[0].imm;
9875 if (inst.operands[1].isreg)
9876 inst.instruction |= inst.operands[1].reg;
9877 else
b99bd4ef 9878 {
c19d1205 9879 inst.instruction |= INST_IMMEDIATE;
e2b0ab59
AV
9880 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9881 inst.relocs[0].pc_rel = 0;
b99bd4ef 9882 }
b99bd4ef
NC
9883}
9884
c19d1205
ZW
9885static void
9886do_mul (void)
a737bd4d 9887{
ff4a8d2b
NC
9888 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
9889
c19d1205
ZW
9890 if (!inst.operands[2].present)
9891 inst.operands[2].reg = inst.operands[0].reg;
9892 inst.instruction |= inst.operands[0].reg << 16;
9893 inst.instruction |= inst.operands[1].reg;
9894 inst.instruction |= inst.operands[2].reg << 8;
a737bd4d 9895
8fb9d7b9
MS
9896 if (inst.operands[0].reg == inst.operands[1].reg
9897 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
9898 as_tsktsk (_("Rd and Rm should be different in mul"));
a737bd4d
NC
9899}
9900
c19d1205
ZW
9901/* Long Multiply Parser
9902 UMULL RdLo, RdHi, Rm, Rs
9903 SMULL RdLo, RdHi, Rm, Rs
9904 UMLAL RdLo, RdHi, Rm, Rs
9905 SMLAL RdLo, RdHi, Rm, Rs. */
b99bd4ef
NC
9906
9907static void
c19d1205 9908do_mull (void)
b99bd4ef 9909{
c19d1205
ZW
9910 inst.instruction |= inst.operands[0].reg << 12;
9911 inst.instruction |= inst.operands[1].reg << 16;
9912 inst.instruction |= inst.operands[2].reg;
9913 inst.instruction |= inst.operands[3].reg << 8;
b99bd4ef 9914
682b27ad
PB
9915 /* rdhi and rdlo must be different. */
9916 if (inst.operands[0].reg == inst.operands[1].reg)
9917 as_tsktsk (_("rdhi and rdlo must be different"));
9918
9919 /* rdhi, rdlo and rm must all be different before armv6. */
9920 if ((inst.operands[0].reg == inst.operands[2].reg
c19d1205 9921 || inst.operands[1].reg == inst.operands[2].reg)
682b27ad 9922 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
c19d1205
ZW
9923 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
9924}
b99bd4ef 9925
c19d1205
ZW
9926static void
9927do_nop (void)
9928{
e7495e45
NS
9929 if (inst.operands[0].present
9930 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k))
c19d1205
ZW
9931 {
9932 /* Architectural NOP hints are CPSR sets with no bits selected. */
9933 inst.instruction &= 0xf0000000;
e7495e45
NS
9934 inst.instruction |= 0x0320f000;
9935 if (inst.operands[0].present)
9936 inst.instruction |= inst.operands[0].imm;
c19d1205 9937 }
b99bd4ef
NC
9938}
9939
c19d1205
ZW
9940/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
9941 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
9942 Condition defaults to COND_ALWAYS.
9943 Error if Rd, Rn or Rm are R15. */
b99bd4ef
NC
9944
9945static void
c19d1205 9946do_pkhbt (void)
b99bd4ef 9947{
c19d1205
ZW
9948 inst.instruction |= inst.operands[0].reg << 12;
9949 inst.instruction |= inst.operands[1].reg << 16;
9950 inst.instruction |= inst.operands[2].reg;
9951 if (inst.operands[3].present)
9952 encode_arm_shift (3);
9953}
b99bd4ef 9954
c19d1205 9955/* ARM V6 PKHTB (Argument Parse). */
b99bd4ef 9956
c19d1205
ZW
9957static void
9958do_pkhtb (void)
9959{
9960 if (!inst.operands[3].present)
b99bd4ef 9961 {
c19d1205
ZW
9962 /* If the shift specifier is omitted, turn the instruction
9963 into pkhbt rd, rm, rn. */
9964 inst.instruction &= 0xfff00010;
9965 inst.instruction |= inst.operands[0].reg << 12;
9966 inst.instruction |= inst.operands[1].reg;
9967 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
9968 }
9969 else
9970 {
c19d1205
ZW
9971 inst.instruction |= inst.operands[0].reg << 12;
9972 inst.instruction |= inst.operands[1].reg << 16;
9973 inst.instruction |= inst.operands[2].reg;
9974 encode_arm_shift (3);
b99bd4ef
NC
9975 }
9976}
9977
c19d1205 9978/* ARMv5TE: Preload-Cache
60e5ef9f 9979 MP Extensions: Preload for write
c19d1205 9980
60e5ef9f 9981 PLD(W) <addr_mode>
c19d1205
ZW
9982
9983 Syntactically, like LDR with B=1, W=0, L=1. */
b99bd4ef
NC
9984
9985static void
c19d1205 9986do_pld (void)
b99bd4ef 9987{
c19d1205
ZW
9988 constraint (!inst.operands[0].isreg,
9989 _("'[' expected after PLD mnemonic"));
9990 constraint (inst.operands[0].postind,
9991 _("post-indexed expression used in preload instruction"));
9992 constraint (inst.operands[0].writeback,
9993 _("writeback used in preload instruction"));
9994 constraint (!inst.operands[0].preind,
9995 _("unindexed addressing used in preload instruction"));
c19d1205
ZW
9996 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
9997}
b99bd4ef 9998
62b3e311
PB
9999/* ARMv7: PLI <addr_mode> */
10000static void
10001do_pli (void)
10002{
10003 constraint (!inst.operands[0].isreg,
10004 _("'[' expected after PLI mnemonic"));
10005 constraint (inst.operands[0].postind,
10006 _("post-indexed expression used in preload instruction"));
10007 constraint (inst.operands[0].writeback,
10008 _("writeback used in preload instruction"));
10009 constraint (!inst.operands[0].preind,
10010 _("unindexed addressing used in preload instruction"));
10011 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
10012 inst.instruction &= ~PRE_INDEX;
10013}
10014
c19d1205
ZW
10015static void
10016do_push_pop (void)
10017{
5e0d7f77
MP
10018 constraint (inst.operands[0].writeback,
10019 _("push/pop do not support {reglist}^"));
c19d1205
ZW
10020 inst.operands[1] = inst.operands[0];
10021 memset (&inst.operands[0], 0, sizeof inst.operands[0]);
10022 inst.operands[0].isreg = 1;
10023 inst.operands[0].writeback = 1;
10024 inst.operands[0].reg = REG_SP;
6530b175 10025 encode_ldmstm (/*from_push_pop_mnem=*/TRUE);
c19d1205 10026}
b99bd4ef 10027
c19d1205
ZW
10028/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
10029 word at the specified address and the following word
10030 respectively.
10031 Unconditionally executed.
10032 Error if Rn is R15. */
b99bd4ef 10033
c19d1205
ZW
10034static void
10035do_rfe (void)
10036{
10037 inst.instruction |= inst.operands[0].reg << 16;
10038 if (inst.operands[0].writeback)
10039 inst.instruction |= WRITE_BACK;
10040}
b99bd4ef 10041
c19d1205 10042/* ARM V6 ssat (argument parse). */
b99bd4ef 10043
c19d1205
ZW
10044static void
10045do_ssat (void)
10046{
10047 inst.instruction |= inst.operands[0].reg << 12;
10048 inst.instruction |= (inst.operands[1].imm - 1) << 16;
10049 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10050
c19d1205
ZW
10051 if (inst.operands[3].present)
10052 encode_arm_shift (3);
b99bd4ef
NC
10053}
10054
c19d1205 10055/* ARM V6 usat (argument parse). */
b99bd4ef
NC
10056
10057static void
c19d1205 10058do_usat (void)
b99bd4ef 10059{
c19d1205
ZW
10060 inst.instruction |= inst.operands[0].reg << 12;
10061 inst.instruction |= inst.operands[1].imm << 16;
10062 inst.instruction |= inst.operands[2].reg;
b99bd4ef 10063
c19d1205
ZW
10064 if (inst.operands[3].present)
10065 encode_arm_shift (3);
b99bd4ef
NC
10066}
10067
c19d1205 10068/* ARM V6 ssat16 (argument parse). */
09d92015
MM
10069
10070static void
c19d1205 10071do_ssat16 (void)
09d92015 10072{
c19d1205
ZW
10073 inst.instruction |= inst.operands[0].reg << 12;
10074 inst.instruction |= ((inst.operands[1].imm - 1) << 16);
10075 inst.instruction |= inst.operands[2].reg;
09d92015
MM
10076}
10077
c19d1205
ZW
10078static void
10079do_usat16 (void)
a737bd4d 10080{
c19d1205
ZW
10081 inst.instruction |= inst.operands[0].reg << 12;
10082 inst.instruction |= inst.operands[1].imm << 16;
10083 inst.instruction |= inst.operands[2].reg;
10084}
a737bd4d 10085
c19d1205
ZW
10086/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
10087 preserving the other bits.
a737bd4d 10088
c19d1205
ZW
10089 setend <endian_specifier>, where <endian_specifier> is either
10090 BE or LE. */
a737bd4d 10091
c19d1205
ZW
10092static void
10093do_setend (void)
10094{
12e37cbc
MGD
10095 if (warn_on_deprecated
10096 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 10097 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 10098
c19d1205
ZW
10099 if (inst.operands[0].imm)
10100 inst.instruction |= 0x200;
a737bd4d
NC
10101}
10102
10103static void
c19d1205 10104do_shift (void)
a737bd4d 10105{
c19d1205
ZW
10106 unsigned int Rm = (inst.operands[1].present
10107 ? inst.operands[1].reg
10108 : inst.operands[0].reg);
a737bd4d 10109
c19d1205
ZW
10110 inst.instruction |= inst.operands[0].reg << 12;
10111 inst.instruction |= Rm;
10112 if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
a737bd4d 10113 {
c19d1205
ZW
10114 inst.instruction |= inst.operands[2].reg << 8;
10115 inst.instruction |= SHIFT_BY_REG;
94342ec3
NC
10116 /* PR 12854: Error on extraneous shifts. */
10117 constraint (inst.operands[2].shifted,
10118 _("extraneous shift as part of operand to shift insn"));
a737bd4d
NC
10119 }
10120 else
e2b0ab59 10121 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
a737bd4d
NC
10122}
10123
09d92015 10124static void
3eb17e6b 10125do_smc (void)
09d92015 10126{
e2b0ab59
AV
10127 inst.relocs[0].type = BFD_RELOC_ARM_SMC;
10128 inst.relocs[0].pc_rel = 0;
09d92015
MM
10129}
10130
90ec0d68
MGD
10131static void
10132do_hvc (void)
10133{
e2b0ab59
AV
10134 inst.relocs[0].type = BFD_RELOC_ARM_HVC;
10135 inst.relocs[0].pc_rel = 0;
90ec0d68
MGD
10136}
10137
09d92015 10138static void
c19d1205 10139do_swi (void)
09d92015 10140{
e2b0ab59
AV
10141 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
10142 inst.relocs[0].pc_rel = 0;
09d92015
MM
10143}
10144
ddfded2f
MW
10145static void
10146do_setpan (void)
10147{
10148 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10149 _("selected processor does not support SETPAN instruction"));
10150
10151 inst.instruction |= ((inst.operands[0].imm & 1) << 9);
10152}
10153
10154static void
10155do_t_setpan (void)
10156{
10157 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
10158 _("selected processor does not support SETPAN instruction"));
10159
10160 inst.instruction |= (inst.operands[0].imm << 3);
10161}
10162
c19d1205
ZW
10163/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
10164 SMLAxy{cond} Rd,Rm,Rs,Rn
10165 SMLAWy{cond} Rd,Rm,Rs,Rn
10166 Error if any register is R15. */
e16bb312 10167
c19d1205
ZW
10168static void
10169do_smla (void)
e16bb312 10170{
c19d1205
ZW
10171 inst.instruction |= inst.operands[0].reg << 16;
10172 inst.instruction |= inst.operands[1].reg;
10173 inst.instruction |= inst.operands[2].reg << 8;
10174 inst.instruction |= inst.operands[3].reg << 12;
10175}
a737bd4d 10176
c19d1205
ZW
10177/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
10178 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
10179 Error if any register is R15.
10180 Warning if Rdlo == Rdhi. */
a737bd4d 10181
c19d1205
ZW
10182static void
10183do_smlal (void)
10184{
10185 inst.instruction |= inst.operands[0].reg << 12;
10186 inst.instruction |= inst.operands[1].reg << 16;
10187 inst.instruction |= inst.operands[2].reg;
10188 inst.instruction |= inst.operands[3].reg << 8;
a737bd4d 10189
c19d1205
ZW
10190 if (inst.operands[0].reg == inst.operands[1].reg)
10191 as_tsktsk (_("rdhi and rdlo must be different"));
10192}
a737bd4d 10193
c19d1205
ZW
10194/* ARM V5E (El Segundo) signed-multiply (argument parse)
10195 SMULxy{cond} Rd,Rm,Rs
10196 Error if any register is R15. */
a737bd4d 10197
c19d1205
ZW
10198static void
10199do_smul (void)
10200{
10201 inst.instruction |= inst.operands[0].reg << 16;
10202 inst.instruction |= inst.operands[1].reg;
10203 inst.instruction |= inst.operands[2].reg << 8;
10204}
a737bd4d 10205
b6702015
PB
10206/* ARM V6 srs (argument parse). The variable fields in the encoding are
10207 the same for both ARM and Thumb-2. */
a737bd4d 10208
c19d1205
ZW
10209static void
10210do_srs (void)
10211{
b6702015
PB
10212 int reg;
10213
10214 if (inst.operands[0].present)
10215 {
10216 reg = inst.operands[0].reg;
fdfde340 10217 constraint (reg != REG_SP, _("SRS base register must be r13"));
b6702015
PB
10218 }
10219 else
fdfde340 10220 reg = REG_SP;
b6702015
PB
10221
10222 inst.instruction |= reg << 16;
10223 inst.instruction |= inst.operands[1].imm;
10224 if (inst.operands[0].writeback || inst.operands[1].writeback)
c19d1205
ZW
10225 inst.instruction |= WRITE_BACK;
10226}
a737bd4d 10227
c19d1205 10228/* ARM V6 strex (argument parse). */
a737bd4d 10229
c19d1205
ZW
10230static void
10231do_strex (void)
10232{
10233 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10234 || inst.operands[2].postind || inst.operands[2].writeback
10235 || inst.operands[2].immisreg || inst.operands[2].shifted
01cfc07f
NC
10236 || inst.operands[2].negative
10237 /* See comment in do_ldrex(). */
10238 || (inst.operands[2].reg == REG_PC),
10239 BAD_ADDR_MODE);
a737bd4d 10240
c19d1205
ZW
10241 constraint (inst.operands[0].reg == inst.operands[1].reg
10242 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
a737bd4d 10243
e2b0ab59
AV
10244 constraint (inst.relocs[0].exp.X_op != O_constant
10245 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10246 _("offset must be zero in ARM encoding"));
a737bd4d 10247
c19d1205
ZW
10248 inst.instruction |= inst.operands[0].reg << 12;
10249 inst.instruction |= inst.operands[1].reg;
10250 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 10251 inst.relocs[0].type = BFD_RELOC_UNUSED;
e16bb312
NC
10252}
10253
877807f8
NC
10254static void
10255do_t_strexbh (void)
10256{
10257 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
10258 || inst.operands[2].postind || inst.operands[2].writeback
10259 || inst.operands[2].immisreg || inst.operands[2].shifted
10260 || inst.operands[2].negative,
10261 BAD_ADDR_MODE);
10262
10263 constraint (inst.operands[0].reg == inst.operands[1].reg
10264 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10265
10266 do_rm_rd_rn ();
10267}
10268
e16bb312 10269static void
c19d1205 10270do_strexd (void)
e16bb312 10271{
c19d1205
ZW
10272 constraint (inst.operands[1].reg % 2 != 0,
10273 _("even register required"));
10274 constraint (inst.operands[2].present
10275 && inst.operands[2].reg != inst.operands[1].reg + 1,
10276 _("can only store two consecutive registers"));
10277 /* If op 2 were present and equal to PC, this function wouldn't
10278 have been called in the first place. */
10279 constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
e16bb312 10280
c19d1205
ZW
10281 constraint (inst.operands[0].reg == inst.operands[1].reg
10282 || inst.operands[0].reg == inst.operands[1].reg + 1
10283 || inst.operands[0].reg == inst.operands[3].reg,
10284 BAD_OVERLAP);
e16bb312 10285
c19d1205
ZW
10286 inst.instruction |= inst.operands[0].reg << 12;
10287 inst.instruction |= inst.operands[1].reg;
10288 inst.instruction |= inst.operands[3].reg << 16;
e16bb312
NC
10289}
10290
9eb6c0f1
MGD
10291/* ARM V8 STRL. */
10292static void
4b8c8c02 10293do_stlex (void)
9eb6c0f1
MGD
10294{
10295 constraint (inst.operands[0].reg == inst.operands[1].reg
10296 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10297
10298 do_rd_rm_rn ();
10299}
10300
10301static void
4b8c8c02 10302do_t_stlex (void)
9eb6c0f1
MGD
10303{
10304 constraint (inst.operands[0].reg == inst.operands[1].reg
10305 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
10306
10307 do_rm_rd_rn ();
10308}
10309
c19d1205
ZW
10310/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
10311 extends it to 32-bits, and adds the result to a value in another
10312 register. You can specify a rotation by 0, 8, 16, or 24 bits
10313 before extracting the 16-bit value.
10314 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
10315 Condition defaults to COND_ALWAYS.
10316 Error if any register uses R15. */
10317
e16bb312 10318static void
c19d1205 10319do_sxtah (void)
e16bb312 10320{
c19d1205
ZW
10321 inst.instruction |= inst.operands[0].reg << 12;
10322 inst.instruction |= inst.operands[1].reg << 16;
10323 inst.instruction |= inst.operands[2].reg;
10324 inst.instruction |= inst.operands[3].imm << 10;
10325}
e16bb312 10326
c19d1205 10327/* ARM V6 SXTH.
e16bb312 10328
c19d1205
ZW
10329 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
10330 Condition defaults to COND_ALWAYS.
10331 Error if any register uses R15. */
e16bb312
NC
10332
10333static void
c19d1205 10334do_sxth (void)
e16bb312 10335{
c19d1205
ZW
10336 inst.instruction |= inst.operands[0].reg << 12;
10337 inst.instruction |= inst.operands[1].reg;
10338 inst.instruction |= inst.operands[2].imm << 10;
e16bb312 10339}
c19d1205
ZW
10340\f
10341/* VFP instructions. In a logical order: SP variant first, monad
10342 before dyad, arithmetic then move then load/store. */
e16bb312
NC
10343
10344static void
c19d1205 10345do_vfp_sp_monadic (void)
e16bb312 10346{
57785aa2
AV
10347 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10348 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10349 _(BAD_FPU));
10350
5287ad62
JB
10351 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10352 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10353}
10354
10355static void
c19d1205 10356do_vfp_sp_dyadic (void)
e16bb312 10357{
5287ad62
JB
10358 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10359 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
10360 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10361}
10362
10363static void
c19d1205 10364do_vfp_sp_compare_z (void)
e16bb312 10365{
5287ad62 10366 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
e16bb312
NC
10367}
10368
10369static void
c19d1205 10370do_vfp_dp_sp_cvt (void)
e16bb312 10371{
5287ad62
JB
10372 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10373 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
10374}
10375
10376static void
c19d1205 10377do_vfp_sp_dp_cvt (void)
e16bb312 10378{
5287ad62
JB
10379 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10380 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
e16bb312
NC
10381}
10382
10383static void
c19d1205 10384do_vfp_reg_from_sp (void)
e16bb312 10385{
57785aa2
AV
10386 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10387 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10388 _(BAD_FPU));
10389
c19d1205 10390 inst.instruction |= inst.operands[0].reg << 12;
5287ad62 10391 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
e16bb312
NC
10392}
10393
10394static void
c19d1205 10395do_vfp_reg2_from_sp2 (void)
e16bb312 10396{
c19d1205
ZW
10397 constraint (inst.operands[2].imm != 2,
10398 _("only two consecutive VFP SP registers allowed here"));
10399 inst.instruction |= inst.operands[0].reg << 12;
10400 inst.instruction |= inst.operands[1].reg << 16;
5287ad62 10401 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
10402}
10403
10404static void
c19d1205 10405do_vfp_sp_from_reg (void)
e16bb312 10406{
57785aa2
AV
10407 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
10408 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10409 _(BAD_FPU));
10410
5287ad62 10411 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sn);
c19d1205 10412 inst.instruction |= inst.operands[1].reg << 12;
e16bb312
NC
10413}
10414
10415static void
c19d1205 10416do_vfp_sp2_from_reg2 (void)
e16bb312 10417{
c19d1205
ZW
10418 constraint (inst.operands[0].imm != 2,
10419 _("only two consecutive VFP SP registers allowed here"));
5287ad62 10420 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sm);
c19d1205
ZW
10421 inst.instruction |= inst.operands[1].reg << 12;
10422 inst.instruction |= inst.operands[2].reg << 16;
e16bb312
NC
10423}
10424
10425static void
c19d1205 10426do_vfp_sp_ldst (void)
e16bb312 10427{
5287ad62 10428 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
c19d1205 10429 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
10430}
10431
10432static void
c19d1205 10433do_vfp_dp_ldst (void)
e16bb312 10434{
5287ad62 10435 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
c19d1205 10436 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
10437}
10438
c19d1205 10439
e16bb312 10440static void
c19d1205 10441vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10442{
c19d1205
ZW
10443 if (inst.operands[0].writeback)
10444 inst.instruction |= WRITE_BACK;
10445 else
10446 constraint (ldstm_type != VFP_LDSTMIA,
10447 _("this addressing mode requires base-register writeback"));
10448 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10449 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sd);
c19d1205 10450 inst.instruction |= inst.operands[1].imm;
e16bb312
NC
10451}
10452
10453static void
c19d1205 10454vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10455{
c19d1205 10456 int count;
e16bb312 10457
c19d1205
ZW
10458 if (inst.operands[0].writeback)
10459 inst.instruction |= WRITE_BACK;
10460 else
10461 constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
10462 _("this addressing mode requires base-register writeback"));
e16bb312 10463
c19d1205 10464 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10465 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
e16bb312 10466
c19d1205
ZW
10467 count = inst.operands[1].imm << 1;
10468 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
10469 count += 1;
e16bb312 10470
c19d1205 10471 inst.instruction |= count;
e16bb312
NC
10472}
10473
10474static void
c19d1205 10475do_vfp_sp_ldstmia (void)
e16bb312 10476{
c19d1205 10477 vfp_sp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10478}
10479
10480static void
c19d1205 10481do_vfp_sp_ldstmdb (void)
e16bb312 10482{
c19d1205 10483 vfp_sp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10484}
10485
10486static void
c19d1205 10487do_vfp_dp_ldstmia (void)
e16bb312 10488{
c19d1205 10489 vfp_dp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10490}
10491
10492static void
c19d1205 10493do_vfp_dp_ldstmdb (void)
e16bb312 10494{
c19d1205 10495 vfp_dp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10496}
10497
10498static void
c19d1205 10499do_vfp_xp_ldstmia (void)
e16bb312 10500{
c19d1205
ZW
10501 vfp_dp_ldstm (VFP_LDSTMIAX);
10502}
e16bb312 10503
c19d1205
ZW
10504static void
10505do_vfp_xp_ldstmdb (void)
10506{
10507 vfp_dp_ldstm (VFP_LDSTMDBX);
e16bb312 10508}
5287ad62
JB
10509
10510static void
10511do_vfp_dp_rd_rm (void)
10512{
57785aa2
AV
10513 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
10514 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10515 _(BAD_FPU));
10516
5287ad62
JB
10517 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10518 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
10519}
10520
10521static void
10522do_vfp_dp_rn_rd (void)
10523{
10524 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dn);
10525 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10526}
10527
10528static void
10529do_vfp_dp_rd_rn (void)
10530{
10531 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10532 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10533}
10534
10535static void
10536do_vfp_dp_rd_rn_rm (void)
10537{
57785aa2
AV
10538 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10539 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10540 _(BAD_FPU));
10541
5287ad62
JB
10542 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10543 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10544 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dm);
10545}
10546
10547static void
10548do_vfp_dp_rd (void)
10549{
10550 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10551}
10552
10553static void
10554do_vfp_dp_rm_rd_rn (void)
10555{
57785aa2
AV
10556 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
10557 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
10558 _(BAD_FPU));
10559
5287ad62
JB
10560 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dm);
10561 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10562 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dn);
10563}
10564
10565/* VFPv3 instructions. */
10566static void
10567do_vfp_sp_const (void)
10568{
10569 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
00249aaa
PB
10570 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10571 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10572}
10573
10574static void
10575do_vfp_dp_const (void)
10576{
10577 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
00249aaa
PB
10578 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10579 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10580}
10581
10582static void
10583vfp_conv (int srcsize)
10584{
5f1af56b
MGD
10585 int immbits = srcsize - inst.operands[1].imm;
10586
fa94de6b
RM
10587 if (srcsize == 16 && !(immbits >= 0 && immbits <= srcsize))
10588 {
5f1af56b 10589 /* If srcsize is 16, inst.operands[1].imm must be in the range 0-16.
477330fc 10590 i.e. immbits must be in range 0 - 16. */
5f1af56b
MGD
10591 inst.error = _("immediate value out of range, expected range [0, 16]");
10592 return;
10593 }
fa94de6b 10594 else if (srcsize == 32 && !(immbits >= 0 && immbits < srcsize))
5f1af56b
MGD
10595 {
10596 /* If srcsize is 32, inst.operands[1].imm must be in the range 1-32.
477330fc 10597 i.e. immbits must be in range 0 - 31. */
5f1af56b
MGD
10598 inst.error = _("immediate value out of range, expected range [1, 32]");
10599 return;
10600 }
10601
5287ad62
JB
10602 inst.instruction |= (immbits & 1) << 5;
10603 inst.instruction |= (immbits >> 1);
10604}
10605
10606static void
10607do_vfp_sp_conv_16 (void)
10608{
10609 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10610 vfp_conv (16);
10611}
10612
10613static void
10614do_vfp_dp_conv_16 (void)
10615{
10616 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10617 vfp_conv (16);
10618}
10619
10620static void
10621do_vfp_sp_conv_32 (void)
10622{
10623 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10624 vfp_conv (32);
10625}
10626
10627static void
10628do_vfp_dp_conv_32 (void)
10629{
10630 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10631 vfp_conv (32);
10632}
c19d1205
ZW
10633\f
10634/* FPA instructions. Also in a logical order. */
e16bb312 10635
c19d1205
ZW
10636static void
10637do_fpa_cmp (void)
10638{
10639 inst.instruction |= inst.operands[0].reg << 16;
10640 inst.instruction |= inst.operands[1].reg;
10641}
b99bd4ef
NC
10642
10643static void
c19d1205 10644do_fpa_ldmstm (void)
b99bd4ef 10645{
c19d1205
ZW
10646 inst.instruction |= inst.operands[0].reg << 12;
10647 switch (inst.operands[1].imm)
10648 {
10649 case 1: inst.instruction |= CP_T_X; break;
10650 case 2: inst.instruction |= CP_T_Y; break;
10651 case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
10652 case 4: break;
10653 default: abort ();
10654 }
b99bd4ef 10655
c19d1205
ZW
10656 if (inst.instruction & (PRE_INDEX | INDEX_UP))
10657 {
10658 /* The instruction specified "ea" or "fd", so we can only accept
10659 [Rn]{!}. The instruction does not really support stacking or
10660 unstacking, so we have to emulate these by setting appropriate
10661 bits and offsets. */
e2b0ab59
AV
10662 constraint (inst.relocs[0].exp.X_op != O_constant
10663 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10664 _("this instruction does not support indexing"));
b99bd4ef 10665
c19d1205 10666 if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
e2b0ab59 10667 inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
b99bd4ef 10668
c19d1205 10669 if (!(inst.instruction & INDEX_UP))
e2b0ab59 10670 inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
b99bd4ef 10671
c19d1205
ZW
10672 if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
10673 {
10674 inst.operands[2].preind = 0;
10675 inst.operands[2].postind = 1;
10676 }
10677 }
b99bd4ef 10678
c19d1205 10679 encode_arm_cp_address (2, TRUE, TRUE, 0);
b99bd4ef 10680}
c19d1205
ZW
10681\f
10682/* iWMMXt instructions: strictly in alphabetical order. */
b99bd4ef 10683
c19d1205
ZW
10684static void
10685do_iwmmxt_tandorc (void)
10686{
10687 constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
10688}
b99bd4ef 10689
c19d1205
ZW
10690static void
10691do_iwmmxt_textrc (void)
10692{
10693 inst.instruction |= inst.operands[0].reg << 12;
10694 inst.instruction |= inst.operands[1].imm;
10695}
b99bd4ef
NC
10696
10697static void
c19d1205 10698do_iwmmxt_textrm (void)
b99bd4ef 10699{
c19d1205
ZW
10700 inst.instruction |= inst.operands[0].reg << 12;
10701 inst.instruction |= inst.operands[1].reg << 16;
10702 inst.instruction |= inst.operands[2].imm;
10703}
b99bd4ef 10704
c19d1205
ZW
10705static void
10706do_iwmmxt_tinsr (void)
10707{
10708 inst.instruction |= inst.operands[0].reg << 16;
10709 inst.instruction |= inst.operands[1].reg << 12;
10710 inst.instruction |= inst.operands[2].imm;
10711}
b99bd4ef 10712
c19d1205
ZW
10713static void
10714do_iwmmxt_tmia (void)
10715{
10716 inst.instruction |= inst.operands[0].reg << 5;
10717 inst.instruction |= inst.operands[1].reg;
10718 inst.instruction |= inst.operands[2].reg << 12;
10719}
b99bd4ef 10720
c19d1205
ZW
10721static void
10722do_iwmmxt_waligni (void)
10723{
10724 inst.instruction |= inst.operands[0].reg << 12;
10725 inst.instruction |= inst.operands[1].reg << 16;
10726 inst.instruction |= inst.operands[2].reg;
10727 inst.instruction |= inst.operands[3].imm << 20;
10728}
b99bd4ef 10729
2d447fca
JM
10730static void
10731do_iwmmxt_wmerge (void)
10732{
10733 inst.instruction |= inst.operands[0].reg << 12;
10734 inst.instruction |= inst.operands[1].reg << 16;
10735 inst.instruction |= inst.operands[2].reg;
10736 inst.instruction |= inst.operands[3].imm << 21;
10737}
10738
c19d1205
ZW
10739static void
10740do_iwmmxt_wmov (void)
10741{
10742 /* WMOV rD, rN is an alias for WOR rD, rN, rN. */
10743 inst.instruction |= inst.operands[0].reg << 12;
10744 inst.instruction |= inst.operands[1].reg << 16;
10745 inst.instruction |= inst.operands[1].reg;
10746}
b99bd4ef 10747
c19d1205
ZW
10748static void
10749do_iwmmxt_wldstbh (void)
10750{
8f06b2d8 10751 int reloc;
c19d1205 10752 inst.instruction |= inst.operands[0].reg << 12;
8f06b2d8
PB
10753 if (thumb_mode)
10754 reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
10755 else
10756 reloc = BFD_RELOC_ARM_CP_OFF_IMM_S2;
10757 encode_arm_cp_address (1, TRUE, FALSE, reloc);
b99bd4ef
NC
10758}
10759
c19d1205
ZW
10760static void
10761do_iwmmxt_wldstw (void)
10762{
10763 /* RIWR_RIWC clears .isreg for a control register. */
10764 if (!inst.operands[0].isreg)
10765 {
10766 constraint (inst.cond != COND_ALWAYS, BAD_COND);
10767 inst.instruction |= 0xf0000000;
10768 }
b99bd4ef 10769
c19d1205
ZW
10770 inst.instruction |= inst.operands[0].reg << 12;
10771 encode_arm_cp_address (1, TRUE, TRUE, 0);
10772}
b99bd4ef
NC
10773
10774static void
c19d1205 10775do_iwmmxt_wldstd (void)
b99bd4ef 10776{
c19d1205 10777 inst.instruction |= inst.operands[0].reg << 12;
2d447fca
JM
10778 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)
10779 && inst.operands[1].immisreg)
10780 {
10781 inst.instruction &= ~0x1a000ff;
eff0bc54 10782 inst.instruction |= (0xfU << 28);
2d447fca
JM
10783 if (inst.operands[1].preind)
10784 inst.instruction |= PRE_INDEX;
10785 if (!inst.operands[1].negative)
10786 inst.instruction |= INDEX_UP;
10787 if (inst.operands[1].writeback)
10788 inst.instruction |= WRITE_BACK;
10789 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 10790 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
2d447fca
JM
10791 inst.instruction |= inst.operands[1].imm;
10792 }
10793 else
10794 encode_arm_cp_address (1, TRUE, FALSE, 0);
c19d1205 10795}
b99bd4ef 10796
c19d1205
ZW
10797static void
10798do_iwmmxt_wshufh (void)
10799{
10800 inst.instruction |= inst.operands[0].reg << 12;
10801 inst.instruction |= inst.operands[1].reg << 16;
10802 inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
10803 inst.instruction |= (inst.operands[2].imm & 0x0f);
10804}
b99bd4ef 10805
c19d1205
ZW
10806static void
10807do_iwmmxt_wzero (void)
10808{
10809 /* WZERO reg is an alias for WANDN reg, reg, reg. */
10810 inst.instruction |= inst.operands[0].reg;
10811 inst.instruction |= inst.operands[0].reg << 12;
10812 inst.instruction |= inst.operands[0].reg << 16;
10813}
2d447fca
JM
10814
10815static void
10816do_iwmmxt_wrwrwr_or_imm5 (void)
10817{
10818 if (inst.operands[2].isreg)
10819 do_rd_rn_rm ();
10820 else {
10821 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2),
10822 _("immediate operand requires iWMMXt2"));
10823 do_rd_rn ();
10824 if (inst.operands[2].imm == 0)
10825 {
10826 switch ((inst.instruction >> 20) & 0xf)
10827 {
10828 case 4:
10829 case 5:
10830 case 6:
5f4273c7 10831 case 7:
2d447fca
JM
10832 /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16. */
10833 inst.operands[2].imm = 16;
10834 inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
10835 break;
10836 case 8:
10837 case 9:
10838 case 10:
10839 case 11:
10840 /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32. */
10841 inst.operands[2].imm = 32;
10842 inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
10843 break;
10844 case 12:
10845 case 13:
10846 case 14:
10847 case 15:
10848 {
10849 /* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn. */
10850 unsigned long wrn;
10851 wrn = (inst.instruction >> 16) & 0xf;
10852 inst.instruction &= 0xff0fff0f;
10853 inst.instruction |= wrn;
10854 /* Bail out here; the instruction is now assembled. */
10855 return;
10856 }
10857 }
10858 }
10859 /* Map 32 -> 0, etc. */
10860 inst.operands[2].imm &= 0x1f;
eff0bc54 10861 inst.instruction |= (0xfU << 28) | ((inst.operands[2].imm & 0x10) << 4) | (inst.operands[2].imm & 0xf);
2d447fca
JM
10862 }
10863}
c19d1205
ZW
10864\f
10865/* Cirrus Maverick instructions. Simple 2-, 3-, and 4-register
10866 operations first, then control, shift, and load/store. */
b99bd4ef 10867
c19d1205 10868/* Insns like "foo X,Y,Z". */
b99bd4ef 10869
c19d1205
ZW
10870static void
10871do_mav_triple (void)
10872{
10873 inst.instruction |= inst.operands[0].reg << 16;
10874 inst.instruction |= inst.operands[1].reg;
10875 inst.instruction |= inst.operands[2].reg << 12;
10876}
b99bd4ef 10877
c19d1205
ZW
10878/* Insns like "foo W,X,Y,Z".
10879 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
a737bd4d 10880
c19d1205
ZW
10881static void
10882do_mav_quad (void)
10883{
10884 inst.instruction |= inst.operands[0].reg << 5;
10885 inst.instruction |= inst.operands[1].reg << 12;
10886 inst.instruction |= inst.operands[2].reg << 16;
10887 inst.instruction |= inst.operands[3].reg;
a737bd4d
NC
10888}
10889
c19d1205
ZW
10890/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
10891static void
10892do_mav_dspsc (void)
a737bd4d 10893{
c19d1205
ZW
10894 inst.instruction |= inst.operands[1].reg << 12;
10895}
a737bd4d 10896
c19d1205
ZW
10897/* Maverick shift immediate instructions.
10898 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10899 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
a737bd4d 10900
c19d1205
ZW
10901static void
10902do_mav_shift (void)
10903{
10904 int imm = inst.operands[2].imm;
a737bd4d 10905
c19d1205
ZW
10906 inst.instruction |= inst.operands[0].reg << 12;
10907 inst.instruction |= inst.operands[1].reg << 16;
a737bd4d 10908
c19d1205
ZW
10909 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10910 Bits 5-7 of the insn should have bits 4-6 of the immediate.
10911 Bit 4 should be 0. */
10912 imm = (imm & 0xf) | ((imm & 0x70) << 1);
a737bd4d 10913
c19d1205
ZW
10914 inst.instruction |= imm;
10915}
10916\f
10917/* XScale instructions. Also sorted arithmetic before move. */
a737bd4d 10918
c19d1205
ZW
10919/* Xscale multiply-accumulate (argument parse)
10920 MIAcc acc0,Rm,Rs
10921 MIAPHcc acc0,Rm,Rs
10922 MIAxycc acc0,Rm,Rs. */
a737bd4d 10923
c19d1205
ZW
10924static void
10925do_xsc_mia (void)
10926{
10927 inst.instruction |= inst.operands[1].reg;
10928 inst.instruction |= inst.operands[2].reg << 12;
10929}
a737bd4d 10930
c19d1205 10931/* Xscale move-accumulator-register (argument parse)
a737bd4d 10932
c19d1205 10933 MARcc acc0,RdLo,RdHi. */
b99bd4ef 10934
c19d1205
ZW
10935static void
10936do_xsc_mar (void)
10937{
10938 inst.instruction |= inst.operands[1].reg << 12;
10939 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
10940}
10941
c19d1205 10942/* Xscale move-register-accumulator (argument parse)
b99bd4ef 10943
c19d1205 10944 MRAcc RdLo,RdHi,acc0. */
b99bd4ef
NC
10945
10946static void
c19d1205 10947do_xsc_mra (void)
b99bd4ef 10948{
c19d1205
ZW
10949 constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
10950 inst.instruction |= inst.operands[0].reg << 12;
10951 inst.instruction |= inst.operands[1].reg << 16;
10952}
10953\f
10954/* Encoding functions relevant only to Thumb. */
b99bd4ef 10955
c19d1205
ZW
10956/* inst.operands[i] is a shifted-register operand; encode
10957 it into inst.instruction in the format used by Thumb32. */
10958
10959static void
10960encode_thumb32_shifted_operand (int i)
10961{
e2b0ab59 10962 unsigned int value = inst.relocs[0].exp.X_add_number;
c19d1205 10963 unsigned int shift = inst.operands[i].shift_kind;
b99bd4ef 10964
9c3c69f2
PB
10965 constraint (inst.operands[i].immisreg,
10966 _("shift by register not allowed in thumb mode"));
c19d1205
ZW
10967 inst.instruction |= inst.operands[i].reg;
10968 if (shift == SHIFT_RRX)
10969 inst.instruction |= SHIFT_ROR << 4;
10970 else
b99bd4ef 10971 {
e2b0ab59 10972 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
10973 _("expression too complex"));
10974
10975 constraint (value > 32
10976 || (value == 32 && (shift == SHIFT_LSL
10977 || shift == SHIFT_ROR)),
10978 _("shift expression is too large"));
10979
10980 if (value == 0)
10981 shift = SHIFT_LSL;
10982 else if (value == 32)
10983 value = 0;
10984
10985 inst.instruction |= shift << 4;
10986 inst.instruction |= (value & 0x1c) << 10;
10987 inst.instruction |= (value & 0x03) << 6;
b99bd4ef 10988 }
c19d1205 10989}
b99bd4ef 10990
b99bd4ef 10991
c19d1205
ZW
10992/* inst.operands[i] was set up by parse_address. Encode it into a
10993 Thumb32 format load or store instruction. Reject forms that cannot
10994 be used with such instructions. If is_t is true, reject forms that
10995 cannot be used with a T instruction; if is_d is true, reject forms
5be8be5d
DG
10996 that cannot be used with a D instruction. If it is a store insn,
10997 reject PC in Rn. */
b99bd4ef 10998
c19d1205
ZW
10999static void
11000encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
11001{
5be8be5d 11002 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
c19d1205
ZW
11003
11004 constraint (!inst.operands[i].isreg,
53365c0d 11005 _("Instruction does not support =N addresses"));
b99bd4ef 11006
c19d1205
ZW
11007 inst.instruction |= inst.operands[i].reg << 16;
11008 if (inst.operands[i].immisreg)
b99bd4ef 11009 {
5be8be5d 11010 constraint (is_pc, BAD_PC_ADDRESSING);
c19d1205
ZW
11011 constraint (is_t || is_d, _("cannot use register index with this instruction"));
11012 constraint (inst.operands[i].negative,
11013 _("Thumb does not support negative register indexing"));
11014 constraint (inst.operands[i].postind,
11015 _("Thumb does not support register post-indexing"));
11016 constraint (inst.operands[i].writeback,
11017 _("Thumb does not support register indexing with writeback"));
11018 constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
11019 _("Thumb supports only LSL in shifted register indexing"));
b99bd4ef 11020
f40d1643 11021 inst.instruction |= inst.operands[i].imm;
c19d1205 11022 if (inst.operands[i].shifted)
b99bd4ef 11023 {
e2b0ab59 11024 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 11025 _("expression too complex"));
e2b0ab59
AV
11026 constraint (inst.relocs[0].exp.X_add_number < 0
11027 || inst.relocs[0].exp.X_add_number > 3,
c19d1205 11028 _("shift out of range"));
e2b0ab59 11029 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
c19d1205 11030 }
e2b0ab59 11031 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
11032 }
11033 else if (inst.operands[i].preind)
11034 {
5be8be5d 11035 constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
f40d1643 11036 constraint (is_t && inst.operands[i].writeback,
c19d1205 11037 _("cannot use writeback with this instruction"));
4755303e
WN
11038 constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0),
11039 BAD_PC_ADDRESSING);
c19d1205
ZW
11040
11041 if (is_d)
11042 {
11043 inst.instruction |= 0x01000000;
11044 if (inst.operands[i].writeback)
11045 inst.instruction |= 0x00200000;
b99bd4ef 11046 }
c19d1205 11047 else
b99bd4ef 11048 {
c19d1205
ZW
11049 inst.instruction |= 0x00000c00;
11050 if (inst.operands[i].writeback)
11051 inst.instruction |= 0x00000100;
b99bd4ef 11052 }
e2b0ab59 11053 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
b99bd4ef 11054 }
c19d1205 11055 else if (inst.operands[i].postind)
b99bd4ef 11056 {
9c2799c2 11057 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
11058 constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
11059 constraint (is_t, _("cannot use post-indexing with this instruction"));
11060
11061 if (is_d)
11062 inst.instruction |= 0x00200000;
11063 else
11064 inst.instruction |= 0x00000900;
e2b0ab59 11065 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
c19d1205
ZW
11066 }
11067 else /* unindexed - only for coprocessor */
11068 inst.error = _("instruction does not accept unindexed addressing");
11069}
11070
11071/* Table of Thumb instructions which exist in both 16- and 32-bit
11072 encodings (the latter only in post-V6T2 cores). The index is the
11073 value used in the insns table below. When there is more than one
11074 possible 16-bit encoding for the instruction, this table always
0110f2b8
PB
11075 holds variant (1).
11076 Also contains several pseudo-instructions used during relaxation. */
c19d1205 11077#define T16_32_TAB \
21d799b5
NC
11078 X(_adc, 4140, eb400000), \
11079 X(_adcs, 4140, eb500000), \
11080 X(_add, 1c00, eb000000), \
11081 X(_adds, 1c00, eb100000), \
11082 X(_addi, 0000, f1000000), \
11083 X(_addis, 0000, f1100000), \
11084 X(_add_pc,000f, f20f0000), \
11085 X(_add_sp,000d, f10d0000), \
11086 X(_adr, 000f, f20f0000), \
11087 X(_and, 4000, ea000000), \
11088 X(_ands, 4000, ea100000), \
11089 X(_asr, 1000, fa40f000), \
11090 X(_asrs, 1000, fa50f000), \
11091 X(_b, e000, f000b000), \
11092 X(_bcond, d000, f0008000), \
4389b29a 11093 X(_bf, 0000, f040e001), \
f6b2b12d 11094 X(_bfcsel,0000, f000e001), \
f1c7f421 11095 X(_bfx, 0000, f060e001), \
65d1bc05 11096 X(_bfl, 0000, f000c001), \
f1c7f421 11097 X(_bflx, 0000, f070e001), \
21d799b5
NC
11098 X(_bic, 4380, ea200000), \
11099 X(_bics, 4380, ea300000), \
11100 X(_cmn, 42c0, eb100f00), \
11101 X(_cmp, 2800, ebb00f00), \
11102 X(_cpsie, b660, f3af8400), \
11103 X(_cpsid, b670, f3af8600), \
11104 X(_cpy, 4600, ea4f0000), \
11105 X(_dec_sp,80dd, f1ad0d00), \
60f993ce 11106 X(_dls, 0000, f040e001), \
21d799b5
NC
11107 X(_eor, 4040, ea800000), \
11108 X(_eors, 4040, ea900000), \
11109 X(_inc_sp,00dd, f10d0d00), \
11110 X(_ldmia, c800, e8900000), \
11111 X(_ldr, 6800, f8500000), \
11112 X(_ldrb, 7800, f8100000), \
11113 X(_ldrh, 8800, f8300000), \
11114 X(_ldrsb, 5600, f9100000), \
11115 X(_ldrsh, 5e00, f9300000), \
11116 X(_ldr_pc,4800, f85f0000), \
11117 X(_ldr_pc2,4800, f85f0000), \
11118 X(_ldr_sp,9800, f85d0000), \
60f993ce 11119 X(_le, 0000, f00fc001), \
21d799b5
NC
11120 X(_lsl, 0000, fa00f000), \
11121 X(_lsls, 0000, fa10f000), \
11122 X(_lsr, 0800, fa20f000), \
11123 X(_lsrs, 0800, fa30f000), \
11124 X(_mov, 2000, ea4f0000), \
11125 X(_movs, 2000, ea5f0000), \
11126 X(_mul, 4340, fb00f000), \
11127 X(_muls, 4340, ffffffff), /* no 32b muls */ \
11128 X(_mvn, 43c0, ea6f0000), \
11129 X(_mvns, 43c0, ea7f0000), \
11130 X(_neg, 4240, f1c00000), /* rsb #0 */ \
11131 X(_negs, 4240, f1d00000), /* rsbs #0 */ \
11132 X(_orr, 4300, ea400000), \
11133 X(_orrs, 4300, ea500000), \
11134 X(_pop, bc00, e8bd0000), /* ldmia sp!,... */ \
11135 X(_push, b400, e92d0000), /* stmdb sp!,... */ \
11136 X(_rev, ba00, fa90f080), \
11137 X(_rev16, ba40, fa90f090), \
11138 X(_revsh, bac0, fa90f0b0), \
11139 X(_ror, 41c0, fa60f000), \
11140 X(_rors, 41c0, fa70f000), \
11141 X(_sbc, 4180, eb600000), \
11142 X(_sbcs, 4180, eb700000), \
11143 X(_stmia, c000, e8800000), \
11144 X(_str, 6000, f8400000), \
11145 X(_strb, 7000, f8000000), \
11146 X(_strh, 8000, f8200000), \
11147 X(_str_sp,9000, f84d0000), \
11148 X(_sub, 1e00, eba00000), \
11149 X(_subs, 1e00, ebb00000), \
11150 X(_subi, 8000, f1a00000), \
11151 X(_subis, 8000, f1b00000), \
11152 X(_sxtb, b240, fa4ff080), \
11153 X(_sxth, b200, fa0ff080), \
11154 X(_tst, 4200, ea100f00), \
11155 X(_uxtb, b2c0, fa5ff080), \
11156 X(_uxth, b280, fa1ff080), \
11157 X(_nop, bf00, f3af8000), \
11158 X(_yield, bf10, f3af8001), \
11159 X(_wfe, bf20, f3af8002), \
11160 X(_wfi, bf30, f3af8003), \
60f993ce 11161 X(_wls, 0000, f040c001), \
53c4b28b 11162 X(_sev, bf40, f3af8004), \
74db7efb
NC
11163 X(_sevl, bf50, f3af8005), \
11164 X(_udf, de00, f7f0a000)
c19d1205
ZW
11165
11166/* To catch errors in encoding functions, the codes are all offset by
11167 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
11168 as 16-bit instructions. */
21d799b5 11169#define X(a,b,c) T_MNEM##a
c19d1205
ZW
11170enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
11171#undef X
11172
11173#define X(a,b,c) 0x##b
11174static const unsigned short thumb_op16[] = { T16_32_TAB };
11175#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
11176#undef X
11177
11178#define X(a,b,c) 0x##c
11179static const unsigned int thumb_op32[] = { T16_32_TAB };
c921be7d
NC
11180#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
11181#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
c19d1205
ZW
11182#undef X
11183#undef T16_32_TAB
11184
11185/* Thumb instruction encoders, in alphabetical order. */
11186
92e90b6e 11187/* ADDW or SUBW. */
c921be7d 11188
92e90b6e
PB
11189static void
11190do_t_add_sub_w (void)
11191{
11192 int Rd, Rn;
11193
11194 Rd = inst.operands[0].reg;
11195 Rn = inst.operands[1].reg;
11196
539d4391
NC
11197 /* If Rn is REG_PC, this is ADR; if Rn is REG_SP, then this
11198 is the SP-{plus,minus}-immediate form of the instruction. */
11199 if (Rn == REG_SP)
11200 constraint (Rd == REG_PC, BAD_PC);
11201 else
11202 reject_bad_reg (Rd);
fdfde340 11203
92e90b6e 11204 inst.instruction |= (Rn << 16) | (Rd << 8);
e2b0ab59 11205 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
92e90b6e
PB
11206}
11207
c19d1205 11208/* Parse an add or subtract instruction. We get here with inst.instruction
33eaf5de 11209 equaling any of THUMB_OPCODE_add, adds, sub, or subs. */
c19d1205
ZW
11210
11211static void
11212do_t_add_sub (void)
11213{
11214 int Rd, Rs, Rn;
11215
11216 Rd = inst.operands[0].reg;
11217 Rs = (inst.operands[1].present
11218 ? inst.operands[1].reg /* Rd, Rs, foo */
11219 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11220
e07e6e58 11221 if (Rd == REG_PC)
5ee91343 11222 set_pred_insn_type_last ();
e07e6e58 11223
c19d1205
ZW
11224 if (unified_syntax)
11225 {
0110f2b8
PB
11226 bfd_boolean flags;
11227 bfd_boolean narrow;
11228 int opcode;
11229
11230 flags = (inst.instruction == T_MNEM_adds
11231 || inst.instruction == T_MNEM_subs);
11232 if (flags)
5ee91343 11233 narrow = !in_pred_block ();
0110f2b8 11234 else
5ee91343 11235 narrow = in_pred_block ();
c19d1205 11236 if (!inst.operands[2].isreg)
b99bd4ef 11237 {
16805f35
PB
11238 int add;
11239
5c8ed6a4
JW
11240 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11241 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340 11242
16805f35
PB
11243 add = (inst.instruction == T_MNEM_add
11244 || inst.instruction == T_MNEM_adds);
0110f2b8
PB
11245 opcode = 0;
11246 if (inst.size_req != 4)
11247 {
0110f2b8 11248 /* Attempt to use a narrow opcode, with relaxation if
477330fc 11249 appropriate. */
0110f2b8
PB
11250 if (Rd == REG_SP && Rs == REG_SP && !flags)
11251 opcode = add ? T_MNEM_inc_sp : T_MNEM_dec_sp;
11252 else if (Rd <= 7 && Rs == REG_SP && add && !flags)
11253 opcode = T_MNEM_add_sp;
11254 else if (Rd <= 7 && Rs == REG_PC && add && !flags)
11255 opcode = T_MNEM_add_pc;
11256 else if (Rd <= 7 && Rs <= 7 && narrow)
11257 {
11258 if (flags)
11259 opcode = add ? T_MNEM_addis : T_MNEM_subis;
11260 else
11261 opcode = add ? T_MNEM_addi : T_MNEM_subi;
11262 }
11263 if (opcode)
11264 {
11265 inst.instruction = THUMB_OP16(opcode);
11266 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59
AV
11267 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
11268 || (inst.relocs[0].type
11269 > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
a9f02af8
MG
11270 {
11271 if (inst.size_req == 2)
e2b0ab59 11272 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
a9f02af8
MG
11273 else
11274 inst.relax = opcode;
11275 }
0110f2b8
PB
11276 }
11277 else
11278 constraint (inst.size_req == 2, BAD_HIREG);
11279 }
11280 if (inst.size_req == 4
11281 || (inst.size_req != 2 && !opcode))
11282 {
e2b0ab59
AV
11283 constraint ((inst.relocs[0].type
11284 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
11285 && (inst.relocs[0].type
11286 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8 11287 THUMB1_RELOC_ONLY);
efd81785
PB
11288 if (Rd == REG_PC)
11289 {
fdfde340 11290 constraint (add, BAD_PC);
efd81785
PB
11291 constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
11292 _("only SUBS PC, LR, #const allowed"));
e2b0ab59 11293 constraint (inst.relocs[0].exp.X_op != O_constant,
efd81785 11294 _("expression too complex"));
e2b0ab59
AV
11295 constraint (inst.relocs[0].exp.X_add_number < 0
11296 || inst.relocs[0].exp.X_add_number > 0xff,
efd81785
PB
11297 _("immediate value out of range"));
11298 inst.instruction = T2_SUBS_PC_LR
e2b0ab59
AV
11299 | inst.relocs[0].exp.X_add_number;
11300 inst.relocs[0].type = BFD_RELOC_UNUSED;
efd81785
PB
11301 return;
11302 }
11303 else if (Rs == REG_PC)
16805f35
PB
11304 {
11305 /* Always use addw/subw. */
11306 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
e2b0ab59 11307 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
16805f35
PB
11308 }
11309 else
11310 {
11311 inst.instruction = THUMB_OP32 (inst.instruction);
11312 inst.instruction = (inst.instruction & 0xe1ffffff)
11313 | 0x10000000;
11314 if (flags)
e2b0ab59 11315 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
16805f35 11316 else
e2b0ab59 11317 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
16805f35 11318 }
dc4503c6
PB
11319 inst.instruction |= Rd << 8;
11320 inst.instruction |= Rs << 16;
0110f2b8 11321 }
b99bd4ef 11322 }
c19d1205
ZW
11323 else
11324 {
e2b0ab59 11325 unsigned int value = inst.relocs[0].exp.X_add_number;
5f4cb198
NC
11326 unsigned int shift = inst.operands[2].shift_kind;
11327
c19d1205
ZW
11328 Rn = inst.operands[2].reg;
11329 /* See if we can do this with a 16-bit instruction. */
11330 if (!inst.operands[2].shifted && inst.size_req != 4)
11331 {
e27ec89e
PB
11332 if (Rd > 7 || Rs > 7 || Rn > 7)
11333 narrow = FALSE;
11334
11335 if (narrow)
c19d1205 11336 {
e27ec89e
PB
11337 inst.instruction = ((inst.instruction == T_MNEM_adds
11338 || inst.instruction == T_MNEM_add)
c19d1205
ZW
11339 ? T_OPCODE_ADD_R3
11340 : T_OPCODE_SUB_R3);
11341 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
11342 return;
11343 }
b99bd4ef 11344
7e806470 11345 if (inst.instruction == T_MNEM_add && (Rd == Rs || Rd == Rn))
c19d1205 11346 {
7e806470
PB
11347 /* Thumb-1 cores (except v6-M) require at least one high
11348 register in a narrow non flag setting add. */
11349 if (Rd > 7 || Rn > 7
11350 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2)
11351 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_msr))
c19d1205 11352 {
7e806470
PB
11353 if (Rd == Rn)
11354 {
11355 Rn = Rs;
11356 Rs = Rd;
11357 }
c19d1205
ZW
11358 inst.instruction = T_OPCODE_ADD_HI;
11359 inst.instruction |= (Rd & 8) << 4;
11360 inst.instruction |= (Rd & 7);
11361 inst.instruction |= Rn << 3;
11362 return;
11363 }
c19d1205
ZW
11364 }
11365 }
c921be7d 11366
fdfde340 11367 constraint (Rd == REG_PC, BAD_PC);
5c8ed6a4
JW
11368 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
11369 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340
JM
11370 constraint (Rs == REG_PC, BAD_PC);
11371 reject_bad_reg (Rn);
11372
c19d1205
ZW
11373 /* If we get here, it can't be done in 16 bits. */
11374 constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
11375 _("shift must be constant"));
11376 inst.instruction = THUMB_OP32 (inst.instruction);
11377 inst.instruction |= Rd << 8;
11378 inst.instruction |= Rs << 16;
5f4cb198
NC
11379 constraint (Rd == REG_SP && Rs == REG_SP && value > 3,
11380 _("shift value over 3 not allowed in thumb mode"));
11381 constraint (Rd == REG_SP && Rs == REG_SP && shift != SHIFT_LSL,
11382 _("only LSL shift allowed in thumb mode"));
c19d1205
ZW
11383 encode_thumb32_shifted_operand (2);
11384 }
11385 }
11386 else
11387 {
11388 constraint (inst.instruction == T_MNEM_adds
11389 || inst.instruction == T_MNEM_subs,
11390 BAD_THUMB32);
b99bd4ef 11391
c19d1205 11392 if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
b99bd4ef 11393 {
c19d1205
ZW
11394 constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
11395 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
11396 BAD_HIREG);
11397
11398 inst.instruction = (inst.instruction == T_MNEM_add
11399 ? 0x0000 : 0x8000);
11400 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59 11401 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
b99bd4ef
NC
11402 return;
11403 }
11404
c19d1205
ZW
11405 Rn = inst.operands[2].reg;
11406 constraint (inst.operands[2].shifted, _("unshifted register required"));
b99bd4ef 11407
c19d1205
ZW
11408 /* We now have Rd, Rs, and Rn set to registers. */
11409 if (Rd > 7 || Rs > 7 || Rn > 7)
b99bd4ef 11410 {
c19d1205
ZW
11411 /* Can't do this for SUB. */
11412 constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
11413 inst.instruction = T_OPCODE_ADD_HI;
11414 inst.instruction |= (Rd & 8) << 4;
11415 inst.instruction |= (Rd & 7);
11416 if (Rs == Rd)
11417 inst.instruction |= Rn << 3;
11418 else if (Rn == Rd)
11419 inst.instruction |= Rs << 3;
11420 else
11421 constraint (1, _("dest must overlap one source register"));
11422 }
11423 else
11424 {
11425 inst.instruction = (inst.instruction == T_MNEM_add
11426 ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
11427 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
b99bd4ef 11428 }
b99bd4ef 11429 }
b99bd4ef
NC
11430}
11431
c19d1205
ZW
11432static void
11433do_t_adr (void)
11434{
fdfde340
JM
11435 unsigned Rd;
11436
11437 Rd = inst.operands[0].reg;
11438 reject_bad_reg (Rd);
11439
11440 if (unified_syntax && inst.size_req == 0 && Rd <= 7)
0110f2b8
PB
11441 {
11442 /* Defer to section relaxation. */
11443 inst.relax = inst.instruction;
11444 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 11445 inst.instruction |= Rd << 4;
0110f2b8
PB
11446 }
11447 else if (unified_syntax && inst.size_req != 2)
e9f89963 11448 {
0110f2b8 11449 /* Generate a 32-bit opcode. */
e9f89963 11450 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 11451 inst.instruction |= Rd << 8;
e2b0ab59
AV
11452 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
11453 inst.relocs[0].pc_rel = 1;
e9f89963
PB
11454 }
11455 else
11456 {
0110f2b8 11457 /* Generate a 16-bit opcode. */
e9f89963 11458 inst.instruction = THUMB_OP16 (inst.instruction);
e2b0ab59
AV
11459 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
11460 inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust. */
11461 inst.relocs[0].pc_rel = 1;
fdfde340 11462 inst.instruction |= Rd << 4;
e9f89963 11463 }
52a86f84 11464
e2b0ab59
AV
11465 if (inst.relocs[0].exp.X_op == O_symbol
11466 && inst.relocs[0].exp.X_add_symbol != NULL
11467 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11468 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11469 inst.relocs[0].exp.X_add_number += 1;
c19d1205 11470}
b99bd4ef 11471
c19d1205
ZW
11472/* Arithmetic instructions for which there is just one 16-bit
11473 instruction encoding, and it allows only two low registers.
11474 For maximal compatibility with ARM syntax, we allow three register
11475 operands even when Thumb-32 instructions are not available, as long
11476 as the first two are identical. For instance, both "sbc r0,r1" and
11477 "sbc r0,r0,r1" are allowed. */
b99bd4ef 11478static void
c19d1205 11479do_t_arit3 (void)
b99bd4ef 11480{
c19d1205 11481 int Rd, Rs, Rn;
b99bd4ef 11482
c19d1205
ZW
11483 Rd = inst.operands[0].reg;
11484 Rs = (inst.operands[1].present
11485 ? inst.operands[1].reg /* Rd, Rs, foo */
11486 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11487 Rn = inst.operands[2].reg;
b99bd4ef 11488
fdfde340
JM
11489 reject_bad_reg (Rd);
11490 reject_bad_reg (Rs);
11491 if (inst.operands[2].isreg)
11492 reject_bad_reg (Rn);
11493
c19d1205 11494 if (unified_syntax)
b99bd4ef 11495 {
c19d1205
ZW
11496 if (!inst.operands[2].isreg)
11497 {
11498 /* For an immediate, we always generate a 32-bit opcode;
11499 section relaxation will shrink it later if possible. */
11500 inst.instruction = THUMB_OP32 (inst.instruction);
11501 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11502 inst.instruction |= Rd << 8;
11503 inst.instruction |= Rs << 16;
e2b0ab59 11504 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
c19d1205
ZW
11505 }
11506 else
11507 {
e27ec89e
PB
11508 bfd_boolean narrow;
11509
c19d1205 11510 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11511 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 11512 narrow = !in_pred_block ();
e27ec89e 11513 else
5ee91343 11514 narrow = in_pred_block ();
e27ec89e
PB
11515
11516 if (Rd > 7 || Rn > 7 || Rs > 7)
11517 narrow = FALSE;
11518 if (inst.operands[2].shifted)
11519 narrow = FALSE;
11520 if (inst.size_req == 4)
11521 narrow = FALSE;
11522
11523 if (narrow
c19d1205
ZW
11524 && Rd == Rs)
11525 {
11526 inst.instruction = THUMB_OP16 (inst.instruction);
11527 inst.instruction |= Rd;
11528 inst.instruction |= Rn << 3;
11529 return;
11530 }
b99bd4ef 11531
c19d1205
ZW
11532 /* If we get here, it can't be done in 16 bits. */
11533 constraint (inst.operands[2].shifted
11534 && inst.operands[2].immisreg,
11535 _("shift must be constant"));
11536 inst.instruction = THUMB_OP32 (inst.instruction);
11537 inst.instruction |= Rd << 8;
11538 inst.instruction |= Rs << 16;
11539 encode_thumb32_shifted_operand (2);
11540 }
a737bd4d 11541 }
c19d1205 11542 else
b99bd4ef 11543 {
c19d1205
ZW
11544 /* On its face this is a lie - the instruction does set the
11545 flags. However, the only supported mnemonic in this mode
11546 says it doesn't. */
11547 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11548
c19d1205
ZW
11549 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11550 _("unshifted register required"));
11551 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11552 constraint (Rd != Rs,
11553 _("dest and source1 must be the same register"));
a737bd4d 11554
c19d1205
ZW
11555 inst.instruction = THUMB_OP16 (inst.instruction);
11556 inst.instruction |= Rd;
11557 inst.instruction |= Rn << 3;
b99bd4ef 11558 }
a737bd4d 11559}
b99bd4ef 11560
c19d1205
ZW
11561/* Similarly, but for instructions where the arithmetic operation is
11562 commutative, so we can allow either of them to be different from
11563 the destination operand in a 16-bit instruction. For instance, all
11564 three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
11565 accepted. */
11566static void
11567do_t_arit3c (void)
a737bd4d 11568{
c19d1205 11569 int Rd, Rs, Rn;
b99bd4ef 11570
c19d1205
ZW
11571 Rd = inst.operands[0].reg;
11572 Rs = (inst.operands[1].present
11573 ? inst.operands[1].reg /* Rd, Rs, foo */
11574 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11575 Rn = inst.operands[2].reg;
c921be7d 11576
fdfde340
JM
11577 reject_bad_reg (Rd);
11578 reject_bad_reg (Rs);
11579 if (inst.operands[2].isreg)
11580 reject_bad_reg (Rn);
a737bd4d 11581
c19d1205 11582 if (unified_syntax)
a737bd4d 11583 {
c19d1205 11584 if (!inst.operands[2].isreg)
b99bd4ef 11585 {
c19d1205
ZW
11586 /* For an immediate, we always generate a 32-bit opcode;
11587 section relaxation will shrink it later if possible. */
11588 inst.instruction = THUMB_OP32 (inst.instruction);
11589 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11590 inst.instruction |= Rd << 8;
11591 inst.instruction |= Rs << 16;
e2b0ab59 11592 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 11593 }
c19d1205 11594 else
a737bd4d 11595 {
e27ec89e
PB
11596 bfd_boolean narrow;
11597
c19d1205 11598 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11599 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 11600 narrow = !in_pred_block ();
e27ec89e 11601 else
5ee91343 11602 narrow = in_pred_block ();
e27ec89e
PB
11603
11604 if (Rd > 7 || Rn > 7 || Rs > 7)
11605 narrow = FALSE;
11606 if (inst.operands[2].shifted)
11607 narrow = FALSE;
11608 if (inst.size_req == 4)
11609 narrow = FALSE;
11610
11611 if (narrow)
a737bd4d 11612 {
c19d1205 11613 if (Rd == Rs)
a737bd4d 11614 {
c19d1205
ZW
11615 inst.instruction = THUMB_OP16 (inst.instruction);
11616 inst.instruction |= Rd;
11617 inst.instruction |= Rn << 3;
11618 return;
a737bd4d 11619 }
c19d1205 11620 if (Rd == Rn)
a737bd4d 11621 {
c19d1205
ZW
11622 inst.instruction = THUMB_OP16 (inst.instruction);
11623 inst.instruction |= Rd;
11624 inst.instruction |= Rs << 3;
11625 return;
a737bd4d
NC
11626 }
11627 }
c19d1205
ZW
11628
11629 /* If we get here, it can't be done in 16 bits. */
11630 constraint (inst.operands[2].shifted
11631 && inst.operands[2].immisreg,
11632 _("shift must be constant"));
11633 inst.instruction = THUMB_OP32 (inst.instruction);
11634 inst.instruction |= Rd << 8;
11635 inst.instruction |= Rs << 16;
11636 encode_thumb32_shifted_operand (2);
a737bd4d 11637 }
b99bd4ef 11638 }
c19d1205
ZW
11639 else
11640 {
11641 /* On its face this is a lie - the instruction does set the
11642 flags. However, the only supported mnemonic in this mode
11643 says it doesn't. */
11644 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11645
c19d1205
ZW
11646 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11647 _("unshifted register required"));
11648 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11649
11650 inst.instruction = THUMB_OP16 (inst.instruction);
11651 inst.instruction |= Rd;
11652
11653 if (Rd == Rs)
11654 inst.instruction |= Rn << 3;
11655 else if (Rd == Rn)
11656 inst.instruction |= Rs << 3;
11657 else
11658 constraint (1, _("dest must overlap one source register"));
11659 }
a737bd4d
NC
11660}
11661
c19d1205
ZW
11662static void
11663do_t_bfc (void)
a737bd4d 11664{
fdfde340 11665 unsigned Rd;
c19d1205
ZW
11666 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
11667 constraint (msb > 32, _("bit-field extends past end of register"));
11668 /* The instruction encoding stores the LSB and MSB,
11669 not the LSB and width. */
fdfde340
JM
11670 Rd = inst.operands[0].reg;
11671 reject_bad_reg (Rd);
11672 inst.instruction |= Rd << 8;
c19d1205
ZW
11673 inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
11674 inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
11675 inst.instruction |= msb - 1;
b99bd4ef
NC
11676}
11677
c19d1205
ZW
11678static void
11679do_t_bfi (void)
b99bd4ef 11680{
fdfde340 11681 int Rd, Rn;
c19d1205 11682 unsigned int msb;
b99bd4ef 11683
fdfde340
JM
11684 Rd = inst.operands[0].reg;
11685 reject_bad_reg (Rd);
11686
c19d1205
ZW
11687 /* #0 in second position is alternative syntax for bfc, which is
11688 the same instruction but with REG_PC in the Rm field. */
11689 if (!inst.operands[1].isreg)
fdfde340
JM
11690 Rn = REG_PC;
11691 else
11692 {
11693 Rn = inst.operands[1].reg;
11694 reject_bad_reg (Rn);
11695 }
b99bd4ef 11696
c19d1205
ZW
11697 msb = inst.operands[2].imm + inst.operands[3].imm;
11698 constraint (msb > 32, _("bit-field extends past end of register"));
11699 /* The instruction encoding stores the LSB and MSB,
11700 not the LSB and width. */
fdfde340
JM
11701 inst.instruction |= Rd << 8;
11702 inst.instruction |= Rn << 16;
c19d1205
ZW
11703 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11704 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11705 inst.instruction |= msb - 1;
b99bd4ef
NC
11706}
11707
c19d1205
ZW
11708static void
11709do_t_bfx (void)
b99bd4ef 11710{
fdfde340
JM
11711 unsigned Rd, Rn;
11712
11713 Rd = inst.operands[0].reg;
11714 Rn = inst.operands[1].reg;
11715
11716 reject_bad_reg (Rd);
11717 reject_bad_reg (Rn);
11718
c19d1205
ZW
11719 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
11720 _("bit-field extends past end of register"));
fdfde340
JM
11721 inst.instruction |= Rd << 8;
11722 inst.instruction |= Rn << 16;
c19d1205
ZW
11723 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11724 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11725 inst.instruction |= inst.operands[3].imm - 1;
11726}
b99bd4ef 11727
c19d1205
ZW
11728/* ARM V5 Thumb BLX (argument parse)
11729 BLX <target_addr> which is BLX(1)
11730 BLX <Rm> which is BLX(2)
11731 Unfortunately, there are two different opcodes for this mnemonic.
11732 So, the insns[].value is not used, and the code here zaps values
11733 into inst.instruction.
b99bd4ef 11734
c19d1205
ZW
11735 ??? How to take advantage of the additional two bits of displacement
11736 available in Thumb32 mode? Need new relocation? */
b99bd4ef 11737
c19d1205
ZW
11738static void
11739do_t_blx (void)
11740{
5ee91343 11741 set_pred_insn_type_last ();
e07e6e58 11742
c19d1205 11743 if (inst.operands[0].isreg)
fdfde340
JM
11744 {
11745 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
11746 /* We have a register, so this is BLX(2). */
11747 inst.instruction |= inst.operands[0].reg << 3;
11748 }
b99bd4ef
NC
11749 else
11750 {
c19d1205 11751 /* No register. This must be BLX(1). */
2fc8bdac 11752 inst.instruction = 0xf000e800;
0855e32b 11753 encode_branch (BFD_RELOC_THUMB_PCREL_BLX);
b99bd4ef
NC
11754 }
11755}
11756
c19d1205
ZW
11757static void
11758do_t_branch (void)
b99bd4ef 11759{
0110f2b8 11760 int opcode;
dfa9f0d5 11761 int cond;
2fe88214 11762 bfd_reloc_code_real_type reloc;
dfa9f0d5 11763
e07e6e58 11764 cond = inst.cond;
5ee91343 11765 set_pred_insn_type (IF_INSIDE_IT_LAST_INSN);
e07e6e58 11766
5ee91343 11767 if (in_pred_block ())
dfa9f0d5
PB
11768 {
11769 /* Conditional branches inside IT blocks are encoded as unconditional
477330fc 11770 branches. */
dfa9f0d5 11771 cond = COND_ALWAYS;
dfa9f0d5
PB
11772 }
11773 else
11774 cond = inst.cond;
11775
11776 if (cond != COND_ALWAYS)
0110f2b8
PB
11777 opcode = T_MNEM_bcond;
11778 else
11779 opcode = inst.instruction;
11780
12d6b0b7
RS
11781 if (unified_syntax
11782 && (inst.size_req == 4
10960bfb
PB
11783 || (inst.size_req != 2
11784 && (inst.operands[0].hasreloc
e2b0ab59 11785 || inst.relocs[0].exp.X_op == O_constant))))
c19d1205 11786 {
0110f2b8 11787 inst.instruction = THUMB_OP32(opcode);
dfa9f0d5 11788 if (cond == COND_ALWAYS)
9ae92b05 11789 reloc = BFD_RELOC_THUMB_PCREL_BRANCH25;
c19d1205
ZW
11790 else
11791 {
ff8646ee
TP
11792 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2),
11793 _("selected architecture does not support "
11794 "wide conditional branch instruction"));
11795
9c2799c2 11796 gas_assert (cond != 0xF);
dfa9f0d5 11797 inst.instruction |= cond << 22;
9ae92b05 11798 reloc = BFD_RELOC_THUMB_PCREL_BRANCH20;
c19d1205
ZW
11799 }
11800 }
b99bd4ef
NC
11801 else
11802 {
0110f2b8 11803 inst.instruction = THUMB_OP16(opcode);
dfa9f0d5 11804 if (cond == COND_ALWAYS)
9ae92b05 11805 reloc = BFD_RELOC_THUMB_PCREL_BRANCH12;
c19d1205 11806 else
b99bd4ef 11807 {
dfa9f0d5 11808 inst.instruction |= cond << 8;
9ae92b05 11809 reloc = BFD_RELOC_THUMB_PCREL_BRANCH9;
b99bd4ef 11810 }
0110f2b8
PB
11811 /* Allow section relaxation. */
11812 if (unified_syntax && inst.size_req != 2)
11813 inst.relax = opcode;
b99bd4ef 11814 }
e2b0ab59
AV
11815 inst.relocs[0].type = reloc;
11816 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
11817}
11818
8884b720 11819/* Actually do the work for Thumb state bkpt and hlt. The only difference
bacebabc 11820 between the two is the maximum immediate allowed - which is passed in
8884b720 11821 RANGE. */
b99bd4ef 11822static void
8884b720 11823do_t_bkpt_hlt1 (int range)
b99bd4ef 11824{
dfa9f0d5
PB
11825 constraint (inst.cond != COND_ALWAYS,
11826 _("instruction is always unconditional"));
c19d1205 11827 if (inst.operands[0].present)
b99bd4ef 11828 {
8884b720 11829 constraint (inst.operands[0].imm > range,
c19d1205
ZW
11830 _("immediate value out of range"));
11831 inst.instruction |= inst.operands[0].imm;
b99bd4ef 11832 }
8884b720 11833
5ee91343 11834 set_pred_insn_type (NEUTRAL_IT_INSN);
8884b720
MGD
11835}
11836
11837static void
11838do_t_hlt (void)
11839{
11840 do_t_bkpt_hlt1 (63);
11841}
11842
11843static void
11844do_t_bkpt (void)
11845{
11846 do_t_bkpt_hlt1 (255);
b99bd4ef
NC
11847}
11848
11849static void
c19d1205 11850do_t_branch23 (void)
b99bd4ef 11851{
5ee91343 11852 set_pred_insn_type_last ();
0855e32b 11853 encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
fa94de6b 11854
0855e32b
NS
11855 /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
11856 this file. We used to simply ignore the PLT reloc type here --
11857 the branch encoding is now needed to deal with TLSCALL relocs.
11858 So if we see a PLT reloc now, put it back to how it used to be to
11859 keep the preexisting behaviour. */
e2b0ab59
AV
11860 if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
11861 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
90e4755a 11862
4343666d 11863#if defined(OBJ_COFF)
c19d1205
ZW
11864 /* If the destination of the branch is a defined symbol which does not have
11865 the THUMB_FUNC attribute, then we must be calling a function which has
11866 the (interfacearm) attribute. We look for the Thumb entry point to that
11867 function and change the branch to refer to that function instead. */
e2b0ab59
AV
11868 if ( inst.relocs[0].exp.X_op == O_symbol
11869 && inst.relocs[0].exp.X_add_symbol != NULL
11870 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11871 && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11872 inst.relocs[0].exp.X_add_symbol
11873 = find_real_start (inst.relocs[0].exp.X_add_symbol);
4343666d 11874#endif
90e4755a
RE
11875}
11876
11877static void
c19d1205 11878do_t_bx (void)
90e4755a 11879{
5ee91343 11880 set_pred_insn_type_last ();
c19d1205
ZW
11881 inst.instruction |= inst.operands[0].reg << 3;
11882 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
11883 should cause the alignment to be checked once it is known. This is
11884 because BX PC only works if the instruction is word aligned. */
11885}
90e4755a 11886
c19d1205
ZW
11887static void
11888do_t_bxj (void)
11889{
fdfde340 11890 int Rm;
90e4755a 11891
5ee91343 11892 set_pred_insn_type_last ();
fdfde340
JM
11893 Rm = inst.operands[0].reg;
11894 reject_bad_reg (Rm);
11895 inst.instruction |= Rm << 16;
90e4755a
RE
11896}
11897
11898static void
c19d1205 11899do_t_clz (void)
90e4755a 11900{
fdfde340
JM
11901 unsigned Rd;
11902 unsigned Rm;
11903
11904 Rd = inst.operands[0].reg;
11905 Rm = inst.operands[1].reg;
11906
11907 reject_bad_reg (Rd);
11908 reject_bad_reg (Rm);
11909
11910 inst.instruction |= Rd << 8;
11911 inst.instruction |= Rm << 16;
11912 inst.instruction |= Rm;
c19d1205 11913}
90e4755a 11914
91d8b670
JG
11915static void
11916do_t_csdb (void)
11917{
5ee91343 11918 set_pred_insn_type (OUTSIDE_PRED_INSN);
91d8b670
JG
11919}
11920
dfa9f0d5
PB
11921static void
11922do_t_cps (void)
11923{
5ee91343 11924 set_pred_insn_type (OUTSIDE_PRED_INSN);
dfa9f0d5
PB
11925 inst.instruction |= inst.operands[0].imm;
11926}
11927
c19d1205
ZW
11928static void
11929do_t_cpsi (void)
11930{
5ee91343 11931 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205 11932 if (unified_syntax
62b3e311
PB
11933 && (inst.operands[1].present || inst.size_req == 4)
11934 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
90e4755a 11935 {
c19d1205
ZW
11936 unsigned int imod = (inst.instruction & 0x0030) >> 4;
11937 inst.instruction = 0xf3af8000;
11938 inst.instruction |= imod << 9;
11939 inst.instruction |= inst.operands[0].imm << 5;
11940 if (inst.operands[1].present)
11941 inst.instruction |= 0x100 | inst.operands[1].imm;
90e4755a 11942 }
c19d1205 11943 else
90e4755a 11944 {
62b3e311
PB
11945 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)
11946 && (inst.operands[0].imm & 4),
11947 _("selected processor does not support 'A' form "
11948 "of this instruction"));
11949 constraint (inst.operands[1].present || inst.size_req == 4,
c19d1205
ZW
11950 _("Thumb does not support the 2-argument "
11951 "form of this instruction"));
11952 inst.instruction |= inst.operands[0].imm;
90e4755a 11953 }
90e4755a
RE
11954}
11955
c19d1205
ZW
11956/* THUMB CPY instruction (argument parse). */
11957
90e4755a 11958static void
c19d1205 11959do_t_cpy (void)
90e4755a 11960{
c19d1205 11961 if (inst.size_req == 4)
90e4755a 11962 {
c19d1205
ZW
11963 inst.instruction = THUMB_OP32 (T_MNEM_mov);
11964 inst.instruction |= inst.operands[0].reg << 8;
11965 inst.instruction |= inst.operands[1].reg;
90e4755a 11966 }
c19d1205 11967 else
90e4755a 11968 {
c19d1205
ZW
11969 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
11970 inst.instruction |= (inst.operands[0].reg & 0x7);
11971 inst.instruction |= inst.operands[1].reg << 3;
90e4755a 11972 }
90e4755a
RE
11973}
11974
90e4755a 11975static void
25fe350b 11976do_t_cbz (void)
90e4755a 11977{
5ee91343 11978 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
11979 constraint (inst.operands[0].reg > 7, BAD_HIREG);
11980 inst.instruction |= inst.operands[0].reg;
e2b0ab59
AV
11981 inst.relocs[0].pc_rel = 1;
11982 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
c19d1205 11983}
90e4755a 11984
62b3e311
PB
11985static void
11986do_t_dbg (void)
11987{
11988 inst.instruction |= inst.operands[0].imm;
11989}
11990
11991static void
11992do_t_div (void)
11993{
fdfde340
JM
11994 unsigned Rd, Rn, Rm;
11995
11996 Rd = inst.operands[0].reg;
11997 Rn = (inst.operands[1].present
11998 ? inst.operands[1].reg : Rd);
11999 Rm = inst.operands[2].reg;
12000
12001 reject_bad_reg (Rd);
12002 reject_bad_reg (Rn);
12003 reject_bad_reg (Rm);
12004
12005 inst.instruction |= Rd << 8;
12006 inst.instruction |= Rn << 16;
12007 inst.instruction |= Rm;
62b3e311
PB
12008}
12009
c19d1205
ZW
12010static void
12011do_t_hint (void)
12012{
12013 if (unified_syntax && inst.size_req == 4)
12014 inst.instruction = THUMB_OP32 (inst.instruction);
12015 else
12016 inst.instruction = THUMB_OP16 (inst.instruction);
12017}
90e4755a 12018
c19d1205
ZW
12019static void
12020do_t_it (void)
12021{
12022 unsigned int cond = inst.operands[0].imm;
e27ec89e 12023
5ee91343
AV
12024 set_pred_insn_type (IT_INSN);
12025 now_pred.mask = (inst.instruction & 0xf) | 0x10;
12026 now_pred.cc = cond;
12027 now_pred.warn_deprecated = FALSE;
12028 now_pred.type = SCALAR_PRED;
e27ec89e
PB
12029
12030 /* If the condition is a negative condition, invert the mask. */
c19d1205 12031 if ((cond & 0x1) == 0x0)
90e4755a 12032 {
c19d1205 12033 unsigned int mask = inst.instruction & 0x000f;
90e4755a 12034
c19d1205 12035 if ((mask & 0x7) == 0)
5a01bb1d
MGD
12036 {
12037 /* No conversion needed. */
5ee91343 12038 now_pred.block_length = 1;
5a01bb1d 12039 }
c19d1205 12040 else if ((mask & 0x3) == 0)
5a01bb1d
MGD
12041 {
12042 mask ^= 0x8;
5ee91343 12043 now_pred.block_length = 2;
5a01bb1d 12044 }
e27ec89e 12045 else if ((mask & 0x1) == 0)
5a01bb1d
MGD
12046 {
12047 mask ^= 0xC;
5ee91343 12048 now_pred.block_length = 3;
5a01bb1d 12049 }
c19d1205 12050 else
5a01bb1d
MGD
12051 {
12052 mask ^= 0xE;
5ee91343 12053 now_pred.block_length = 4;
5a01bb1d 12054 }
90e4755a 12055
e27ec89e
PB
12056 inst.instruction &= 0xfff0;
12057 inst.instruction |= mask;
c19d1205 12058 }
90e4755a 12059
c19d1205
ZW
12060 inst.instruction |= cond << 4;
12061}
90e4755a 12062
3c707909
PB
12063/* Helper function used for both push/pop and ldm/stm. */
12064static void
4b5a202f
AV
12065encode_thumb2_multi (bfd_boolean do_io, int base, unsigned mask,
12066 bfd_boolean writeback)
3c707909 12067{
4b5a202f 12068 bfd_boolean load, store;
3c707909 12069
4b5a202f
AV
12070 gas_assert (base != -1 || !do_io);
12071 load = do_io && ((inst.instruction & (1 << 20)) != 0);
12072 store = do_io && !load;
3c707909
PB
12073
12074 if (mask & (1 << 13))
12075 inst.error = _("SP not allowed in register list");
1e5b0379 12076
4b5a202f 12077 if (do_io && (mask & (1 << base)) != 0
1e5b0379
NC
12078 && writeback)
12079 inst.error = _("having the base register in the register list when "
12080 "using write back is UNPREDICTABLE");
12081
3c707909
PB
12082 if (load)
12083 {
e07e6e58 12084 if (mask & (1 << 15))
477330fc
RM
12085 {
12086 if (mask & (1 << 14))
12087 inst.error = _("LR and PC should not both be in register list");
12088 else
5ee91343 12089 set_pred_insn_type_last ();
477330fc 12090 }
3c707909 12091 }
4b5a202f 12092 else if (store)
3c707909
PB
12093 {
12094 if (mask & (1 << 15))
12095 inst.error = _("PC not allowed in register list");
3c707909
PB
12096 }
12097
4b5a202f 12098 if (do_io && ((mask & (mask - 1)) == 0))
3c707909
PB
12099 {
12100 /* Single register transfers implemented as str/ldr. */
12101 if (writeback)
12102 {
12103 if (inst.instruction & (1 << 23))
12104 inst.instruction = 0x00000b04; /* ia! -> [base], #4 */
12105 else
12106 inst.instruction = 0x00000d04; /* db! -> [base, #-4]! */
12107 }
12108 else
12109 {
12110 if (inst.instruction & (1 << 23))
12111 inst.instruction = 0x00800000; /* ia -> [base] */
12112 else
12113 inst.instruction = 0x00000c04; /* db -> [base, #-4] */
12114 }
12115
12116 inst.instruction |= 0xf8400000;
12117 if (load)
12118 inst.instruction |= 0x00100000;
12119
5f4273c7 12120 mask = ffs (mask) - 1;
3c707909
PB
12121 mask <<= 12;
12122 }
12123 else if (writeback)
12124 inst.instruction |= WRITE_BACK;
12125
12126 inst.instruction |= mask;
4b5a202f
AV
12127 if (do_io)
12128 inst.instruction |= base << 16;
3c707909
PB
12129}
12130
c19d1205
ZW
12131static void
12132do_t_ldmstm (void)
12133{
12134 /* This really doesn't seem worth it. */
e2b0ab59 12135 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205
ZW
12136 _("expression too complex"));
12137 constraint (inst.operands[1].writeback,
12138 _("Thumb load/store multiple does not support {reglist}^"));
90e4755a 12139
c19d1205
ZW
12140 if (unified_syntax)
12141 {
3c707909
PB
12142 bfd_boolean narrow;
12143 unsigned mask;
12144
12145 narrow = FALSE;
c19d1205
ZW
12146 /* See if we can use a 16-bit instruction. */
12147 if (inst.instruction < 0xffff /* not ldmdb/stmdb */
12148 && inst.size_req != 4
3c707909 12149 && !(inst.operands[1].imm & ~0xff))
90e4755a 12150 {
3c707909 12151 mask = 1 << inst.operands[0].reg;
90e4755a 12152
eab4f823 12153 if (inst.operands[0].reg <= 7)
90e4755a 12154 {
3c707909 12155 if (inst.instruction == T_MNEM_stmia
eab4f823
MGD
12156 ? inst.operands[0].writeback
12157 : (inst.operands[0].writeback
12158 == !(inst.operands[1].imm & mask)))
477330fc 12159 {
eab4f823
MGD
12160 if (inst.instruction == T_MNEM_stmia
12161 && (inst.operands[1].imm & mask)
12162 && (inst.operands[1].imm & (mask - 1)))
12163 as_warn (_("value stored for r%d is UNKNOWN"),
12164 inst.operands[0].reg);
3c707909 12165
eab4f823
MGD
12166 inst.instruction = THUMB_OP16 (inst.instruction);
12167 inst.instruction |= inst.operands[0].reg << 8;
12168 inst.instruction |= inst.operands[1].imm;
12169 narrow = TRUE;
12170 }
12171 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12172 {
12173 /* This means 1 register in reg list one of 3 situations:
12174 1. Instruction is stmia, but without writeback.
12175 2. lmdia without writeback, but with Rn not in
477330fc 12176 reglist.
eab4f823
MGD
12177 3. ldmia with writeback, but with Rn in reglist.
12178 Case 3 is UNPREDICTABLE behaviour, so we handle
12179 case 1 and 2 which can be converted into a 16-bit
12180 str or ldr. The SP cases are handled below. */
12181 unsigned long opcode;
12182 /* First, record an error for Case 3. */
12183 if (inst.operands[1].imm & mask
12184 && inst.operands[0].writeback)
fa94de6b 12185 inst.error =
eab4f823
MGD
12186 _("having the base register in the register list when "
12187 "using write back is UNPREDICTABLE");
fa94de6b
RM
12188
12189 opcode = (inst.instruction == T_MNEM_stmia ? T_MNEM_str
eab4f823
MGD
12190 : T_MNEM_ldr);
12191 inst.instruction = THUMB_OP16 (opcode);
12192 inst.instruction |= inst.operands[0].reg << 3;
12193 inst.instruction |= (ffs (inst.operands[1].imm)-1);
12194 narrow = TRUE;
12195 }
90e4755a 12196 }
eab4f823 12197 else if (inst.operands[0] .reg == REG_SP)
90e4755a 12198 {
eab4f823
MGD
12199 if (inst.operands[0].writeback)
12200 {
fa94de6b 12201 inst.instruction =
eab4f823 12202 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12203 ? T_MNEM_push : T_MNEM_pop);
eab4f823 12204 inst.instruction |= inst.operands[1].imm;
477330fc 12205 narrow = TRUE;
eab4f823
MGD
12206 }
12207 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
12208 {
fa94de6b 12209 inst.instruction =
eab4f823 12210 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 12211 ? T_MNEM_str_sp : T_MNEM_ldr_sp);
eab4f823 12212 inst.instruction |= ((ffs (inst.operands[1].imm)-1) << 8);
477330fc 12213 narrow = TRUE;
eab4f823 12214 }
90e4755a 12215 }
3c707909
PB
12216 }
12217
12218 if (!narrow)
12219 {
c19d1205
ZW
12220 if (inst.instruction < 0xffff)
12221 inst.instruction = THUMB_OP32 (inst.instruction);
3c707909 12222
4b5a202f
AV
12223 encode_thumb2_multi (TRUE /* do_io */, inst.operands[0].reg,
12224 inst.operands[1].imm,
12225 inst.operands[0].writeback);
90e4755a
RE
12226 }
12227 }
c19d1205 12228 else
90e4755a 12229 {
c19d1205
ZW
12230 constraint (inst.operands[0].reg > 7
12231 || (inst.operands[1].imm & ~0xff), BAD_HIREG);
1198ca51
PB
12232 constraint (inst.instruction != T_MNEM_ldmia
12233 && inst.instruction != T_MNEM_stmia,
12234 _("Thumb-2 instruction only valid in unified syntax"));
c19d1205 12235 if (inst.instruction == T_MNEM_stmia)
f03698e6 12236 {
c19d1205
ZW
12237 if (!inst.operands[0].writeback)
12238 as_warn (_("this instruction will write back the base register"));
12239 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
12240 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
1e5b0379 12241 as_warn (_("value stored for r%d is UNKNOWN"),
c19d1205 12242 inst.operands[0].reg);
f03698e6 12243 }
c19d1205 12244 else
90e4755a 12245 {
c19d1205
ZW
12246 if (!inst.operands[0].writeback
12247 && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
12248 as_warn (_("this instruction will write back the base register"));
12249 else if (inst.operands[0].writeback
12250 && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
12251 as_warn (_("this instruction will not write back the base register"));
90e4755a
RE
12252 }
12253
c19d1205
ZW
12254 inst.instruction = THUMB_OP16 (inst.instruction);
12255 inst.instruction |= inst.operands[0].reg << 8;
12256 inst.instruction |= inst.operands[1].imm;
12257 }
12258}
e28cd48c 12259
c19d1205
ZW
12260static void
12261do_t_ldrex (void)
12262{
12263 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
12264 || inst.operands[1].postind || inst.operands[1].writeback
12265 || inst.operands[1].immisreg || inst.operands[1].shifted
12266 || inst.operands[1].negative,
01cfc07f 12267 BAD_ADDR_MODE);
e28cd48c 12268
5be8be5d
DG
12269 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
12270
c19d1205
ZW
12271 inst.instruction |= inst.operands[0].reg << 12;
12272 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 12273 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
c19d1205 12274}
e28cd48c 12275
c19d1205
ZW
12276static void
12277do_t_ldrexd (void)
12278{
12279 if (!inst.operands[1].present)
1cac9012 12280 {
c19d1205
ZW
12281 constraint (inst.operands[0].reg == REG_LR,
12282 _("r14 not allowed as first register "
12283 "when second register is omitted"));
12284 inst.operands[1].reg = inst.operands[0].reg + 1;
b99bd4ef 12285 }
c19d1205
ZW
12286 constraint (inst.operands[0].reg == inst.operands[1].reg,
12287 BAD_OVERLAP);
b99bd4ef 12288
c19d1205
ZW
12289 inst.instruction |= inst.operands[0].reg << 12;
12290 inst.instruction |= inst.operands[1].reg << 8;
12291 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
12292}
12293
12294static void
c19d1205 12295do_t_ldst (void)
b99bd4ef 12296{
0110f2b8
PB
12297 unsigned long opcode;
12298 int Rn;
12299
e07e6e58
NC
12300 if (inst.operands[0].isreg
12301 && !inst.operands[0].preind
12302 && inst.operands[0].reg == REG_PC)
5ee91343 12303 set_pred_insn_type_last ();
e07e6e58 12304
0110f2b8 12305 opcode = inst.instruction;
c19d1205 12306 if (unified_syntax)
b99bd4ef 12307 {
53365c0d
PB
12308 if (!inst.operands[1].isreg)
12309 {
12310 if (opcode <= 0xffff)
12311 inst.instruction = THUMB_OP32 (opcode);
8335d6aa 12312 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
53365c0d
PB
12313 return;
12314 }
0110f2b8
PB
12315 if (inst.operands[1].isreg
12316 && !inst.operands[1].writeback
c19d1205
ZW
12317 && !inst.operands[1].shifted && !inst.operands[1].postind
12318 && !inst.operands[1].negative && inst.operands[0].reg <= 7
0110f2b8
PB
12319 && opcode <= 0xffff
12320 && inst.size_req != 4)
c19d1205 12321 {
0110f2b8
PB
12322 /* Insn may have a 16-bit form. */
12323 Rn = inst.operands[1].reg;
12324 if (inst.operands[1].immisreg)
12325 {
12326 inst.instruction = THUMB_OP16 (opcode);
5f4273c7 12327 /* [Rn, Rik] */
0110f2b8
PB
12328 if (Rn <= 7 && inst.operands[1].imm <= 7)
12329 goto op16;
5be8be5d
DG
12330 else if (opcode != T_MNEM_ldr && opcode != T_MNEM_str)
12331 reject_bad_reg (inst.operands[1].imm);
0110f2b8
PB
12332 }
12333 else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
12334 && opcode != T_MNEM_ldrsb)
12335 || ((Rn == REG_PC || Rn == REG_SP) && opcode == T_MNEM_ldr)
12336 || (Rn == REG_SP && opcode == T_MNEM_str))
12337 {
12338 /* [Rn, #const] */
12339 if (Rn > 7)
12340 {
12341 if (Rn == REG_PC)
12342 {
e2b0ab59 12343 if (inst.relocs[0].pc_rel)
0110f2b8
PB
12344 opcode = T_MNEM_ldr_pc2;
12345 else
12346 opcode = T_MNEM_ldr_pc;
12347 }
12348 else
12349 {
12350 if (opcode == T_MNEM_ldr)
12351 opcode = T_MNEM_ldr_sp;
12352 else
12353 opcode = T_MNEM_str_sp;
12354 }
12355 inst.instruction = inst.operands[0].reg << 8;
12356 }
12357 else
12358 {
12359 inst.instruction = inst.operands[0].reg;
12360 inst.instruction |= inst.operands[1].reg << 3;
12361 }
12362 inst.instruction |= THUMB_OP16 (opcode);
12363 if (inst.size_req == 2)
e2b0ab59 12364 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
0110f2b8
PB
12365 else
12366 inst.relax = opcode;
12367 return;
12368 }
c19d1205 12369 }
0110f2b8 12370 /* Definitely a 32-bit variant. */
5be8be5d 12371
8d67f500
NC
12372 /* Warning for Erratum 752419. */
12373 if (opcode == T_MNEM_ldr
12374 && inst.operands[0].reg == REG_SP
12375 && inst.operands[1].writeback == 1
12376 && !inst.operands[1].immisreg)
12377 {
12378 if (no_cpu_selected ()
12379 || (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7)
477330fc
RM
12380 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a)
12381 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7r)))
8d67f500
NC
12382 as_warn (_("This instruction may be unpredictable "
12383 "if executed on M-profile cores "
12384 "with interrupts enabled."));
12385 }
12386
5be8be5d 12387 /* Do some validations regarding addressing modes. */
1be5fd2e 12388 if (inst.operands[1].immisreg)
5be8be5d
DG
12389 reject_bad_reg (inst.operands[1].imm);
12390
1be5fd2e
NC
12391 constraint (inst.operands[1].writeback == 1
12392 && inst.operands[0].reg == inst.operands[1].reg,
12393 BAD_OVERLAP);
12394
0110f2b8 12395 inst.instruction = THUMB_OP32 (opcode);
c19d1205
ZW
12396 inst.instruction |= inst.operands[0].reg << 12;
12397 encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
1be5fd2e 12398 check_ldr_r15_aligned ();
b99bd4ef
NC
12399 return;
12400 }
12401
c19d1205
ZW
12402 constraint (inst.operands[0].reg > 7, BAD_HIREG);
12403
12404 if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
b99bd4ef 12405 {
c19d1205
ZW
12406 /* Only [Rn,Rm] is acceptable. */
12407 constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
12408 constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
12409 || inst.operands[1].postind || inst.operands[1].shifted
12410 || inst.operands[1].negative,
12411 _("Thumb does not support this addressing mode"));
12412 inst.instruction = THUMB_OP16 (inst.instruction);
12413 goto op16;
b99bd4ef 12414 }
5f4273c7 12415
c19d1205
ZW
12416 inst.instruction = THUMB_OP16 (inst.instruction);
12417 if (!inst.operands[1].isreg)
8335d6aa 12418 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
c19d1205 12419 return;
b99bd4ef 12420
c19d1205
ZW
12421 constraint (!inst.operands[1].preind
12422 || inst.operands[1].shifted
12423 || inst.operands[1].writeback,
12424 _("Thumb does not support this addressing mode"));
12425 if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
90e4755a 12426 {
c19d1205
ZW
12427 constraint (inst.instruction & 0x0600,
12428 _("byte or halfword not valid for base register"));
12429 constraint (inst.operands[1].reg == REG_PC
12430 && !(inst.instruction & THUMB_LOAD_BIT),
12431 _("r15 based store not allowed"));
12432 constraint (inst.operands[1].immisreg,
12433 _("invalid base register for register offset"));
b99bd4ef 12434
c19d1205
ZW
12435 if (inst.operands[1].reg == REG_PC)
12436 inst.instruction = T_OPCODE_LDR_PC;
12437 else if (inst.instruction & THUMB_LOAD_BIT)
12438 inst.instruction = T_OPCODE_LDR_SP;
12439 else
12440 inst.instruction = T_OPCODE_STR_SP;
b99bd4ef 12441
c19d1205 12442 inst.instruction |= inst.operands[0].reg << 8;
e2b0ab59 12443 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12444 return;
12445 }
90e4755a 12446
c19d1205
ZW
12447 constraint (inst.operands[1].reg > 7, BAD_HIREG);
12448 if (!inst.operands[1].immisreg)
12449 {
12450 /* Immediate offset. */
12451 inst.instruction |= inst.operands[0].reg;
12452 inst.instruction |= inst.operands[1].reg << 3;
e2b0ab59 12453 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12454 return;
12455 }
90e4755a 12456
c19d1205
ZW
12457 /* Register offset. */
12458 constraint (inst.operands[1].imm > 7, BAD_HIREG);
12459 constraint (inst.operands[1].negative,
12460 _("Thumb does not support this addressing mode"));
90e4755a 12461
c19d1205
ZW
12462 op16:
12463 switch (inst.instruction)
12464 {
12465 case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
12466 case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
12467 case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
12468 case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
12469 case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
12470 case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
12471 case 0x5600 /* ldrsb */:
12472 case 0x5e00 /* ldrsh */: break;
12473 default: abort ();
12474 }
90e4755a 12475
c19d1205
ZW
12476 inst.instruction |= inst.operands[0].reg;
12477 inst.instruction |= inst.operands[1].reg << 3;
12478 inst.instruction |= inst.operands[1].imm << 6;
12479}
90e4755a 12480
c19d1205
ZW
12481static void
12482do_t_ldstd (void)
12483{
12484 if (!inst.operands[1].present)
b99bd4ef 12485 {
c19d1205
ZW
12486 inst.operands[1].reg = inst.operands[0].reg + 1;
12487 constraint (inst.operands[0].reg == REG_LR,
12488 _("r14 not allowed here"));
bd340a04 12489 constraint (inst.operands[0].reg == REG_R12,
477330fc 12490 _("r12 not allowed here"));
b99bd4ef 12491 }
bd340a04
MGD
12492
12493 if (inst.operands[2].writeback
12494 && (inst.operands[0].reg == inst.operands[2].reg
12495 || inst.operands[1].reg == inst.operands[2].reg))
12496 as_warn (_("base register written back, and overlaps "
477330fc 12497 "one of transfer registers"));
bd340a04 12498
c19d1205
ZW
12499 inst.instruction |= inst.operands[0].reg << 12;
12500 inst.instruction |= inst.operands[1].reg << 8;
12501 encode_thumb32_addr_mode (2, /*is_t=*/FALSE, /*is_d=*/TRUE);
b99bd4ef
NC
12502}
12503
c19d1205
ZW
12504static void
12505do_t_ldstt (void)
12506{
12507 inst.instruction |= inst.operands[0].reg << 12;
12508 encode_thumb32_addr_mode (1, /*is_t=*/TRUE, /*is_d=*/FALSE);
12509}
a737bd4d 12510
b99bd4ef 12511static void
c19d1205 12512do_t_mla (void)
b99bd4ef 12513{
fdfde340 12514 unsigned Rd, Rn, Rm, Ra;
c921be7d 12515
fdfde340
JM
12516 Rd = inst.operands[0].reg;
12517 Rn = inst.operands[1].reg;
12518 Rm = inst.operands[2].reg;
12519 Ra = inst.operands[3].reg;
12520
12521 reject_bad_reg (Rd);
12522 reject_bad_reg (Rn);
12523 reject_bad_reg (Rm);
12524 reject_bad_reg (Ra);
12525
12526 inst.instruction |= Rd << 8;
12527 inst.instruction |= Rn << 16;
12528 inst.instruction |= Rm;
12529 inst.instruction |= Ra << 12;
c19d1205 12530}
b99bd4ef 12531
c19d1205
ZW
12532static void
12533do_t_mlal (void)
12534{
fdfde340
JM
12535 unsigned RdLo, RdHi, Rn, Rm;
12536
12537 RdLo = inst.operands[0].reg;
12538 RdHi = inst.operands[1].reg;
12539 Rn = inst.operands[2].reg;
12540 Rm = inst.operands[3].reg;
12541
12542 reject_bad_reg (RdLo);
12543 reject_bad_reg (RdHi);
12544 reject_bad_reg (Rn);
12545 reject_bad_reg (Rm);
12546
12547 inst.instruction |= RdLo << 12;
12548 inst.instruction |= RdHi << 8;
12549 inst.instruction |= Rn << 16;
12550 inst.instruction |= Rm;
c19d1205 12551}
b99bd4ef 12552
c19d1205
ZW
12553static void
12554do_t_mov_cmp (void)
12555{
fdfde340
JM
12556 unsigned Rn, Rm;
12557
12558 Rn = inst.operands[0].reg;
12559 Rm = inst.operands[1].reg;
12560
e07e6e58 12561 if (Rn == REG_PC)
5ee91343 12562 set_pred_insn_type_last ();
e07e6e58 12563
c19d1205 12564 if (unified_syntax)
b99bd4ef 12565 {
c19d1205
ZW
12566 int r0off = (inst.instruction == T_MNEM_mov
12567 || inst.instruction == T_MNEM_movs) ? 8 : 16;
0110f2b8 12568 unsigned long opcode;
3d388997
PB
12569 bfd_boolean narrow;
12570 bfd_boolean low_regs;
12571
fdfde340 12572 low_regs = (Rn <= 7 && Rm <= 7);
0110f2b8 12573 opcode = inst.instruction;
5ee91343 12574 if (in_pred_block ())
0110f2b8 12575 narrow = opcode != T_MNEM_movs;
3d388997 12576 else
0110f2b8 12577 narrow = opcode != T_MNEM_movs || low_regs;
3d388997
PB
12578 if (inst.size_req == 4
12579 || inst.operands[1].shifted)
12580 narrow = FALSE;
12581
efd81785
PB
12582 /* MOVS PC, LR is encoded as SUBS PC, LR, #0. */
12583 if (opcode == T_MNEM_movs && inst.operands[1].isreg
12584 && !inst.operands[1].shifted
fdfde340
JM
12585 && Rn == REG_PC
12586 && Rm == REG_LR)
efd81785
PB
12587 {
12588 inst.instruction = T2_SUBS_PC_LR;
12589 return;
12590 }
12591
fdfde340
JM
12592 if (opcode == T_MNEM_cmp)
12593 {
12594 constraint (Rn == REG_PC, BAD_PC);
94206790
MM
12595 if (narrow)
12596 {
12597 /* In the Thumb-2 ISA, use of R13 as Rm is deprecated,
12598 but valid. */
12599 warn_deprecated_sp (Rm);
12600 /* R15 was documented as a valid choice for Rm in ARMv6,
12601 but as UNPREDICTABLE in ARMv7. ARM's proprietary
12602 tools reject R15, so we do too. */
12603 constraint (Rm == REG_PC, BAD_PC);
12604 }
12605 else
12606 reject_bad_reg (Rm);
fdfde340
JM
12607 }
12608 else if (opcode == T_MNEM_mov
12609 || opcode == T_MNEM_movs)
12610 {
12611 if (inst.operands[1].isreg)
12612 {
12613 if (opcode == T_MNEM_movs)
12614 {
12615 reject_bad_reg (Rn);
12616 reject_bad_reg (Rm);
12617 }
76fa04a4
MGD
12618 else if (narrow)
12619 {
12620 /* This is mov.n. */
12621 if ((Rn == REG_SP || Rn == REG_PC)
12622 && (Rm == REG_SP || Rm == REG_PC))
12623 {
5c3696f8 12624 as_tsktsk (_("Use of r%u as a source register is "
76fa04a4
MGD
12625 "deprecated when r%u is the destination "
12626 "register."), Rm, Rn);
12627 }
12628 }
12629 else
12630 {
12631 /* This is mov.w. */
12632 constraint (Rn == REG_PC, BAD_PC);
12633 constraint (Rm == REG_PC, BAD_PC);
5c8ed6a4
JW
12634 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
12635 constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
76fa04a4 12636 }
fdfde340
JM
12637 }
12638 else
12639 reject_bad_reg (Rn);
12640 }
12641
c19d1205
ZW
12642 if (!inst.operands[1].isreg)
12643 {
0110f2b8 12644 /* Immediate operand. */
5ee91343 12645 if (!in_pred_block () && opcode == T_MNEM_mov)
0110f2b8
PB
12646 narrow = 0;
12647 if (low_regs && narrow)
12648 {
12649 inst.instruction = THUMB_OP16 (opcode);
fdfde340 12650 inst.instruction |= Rn << 8;
e2b0ab59
AV
12651 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
12652 || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
72d98d16 12653 {
a9f02af8 12654 if (inst.size_req == 2)
e2b0ab59 12655 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
a9f02af8
MG
12656 else
12657 inst.relax = opcode;
72d98d16 12658 }
0110f2b8
PB
12659 }
12660 else
12661 {
e2b0ab59
AV
12662 constraint ((inst.relocs[0].type
12663 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
12664 && (inst.relocs[0].type
12665 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8
MG
12666 THUMB1_RELOC_ONLY);
12667
0110f2b8
PB
12668 inst.instruction = THUMB_OP32 (inst.instruction);
12669 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12670 inst.instruction |= Rn << r0off;
e2b0ab59 12671 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8 12672 }
c19d1205 12673 }
728ca7c9
PB
12674 else if (inst.operands[1].shifted && inst.operands[1].immisreg
12675 && (inst.instruction == T_MNEM_mov
12676 || inst.instruction == T_MNEM_movs))
12677 {
12678 /* Register shifts are encoded as separate shift instructions. */
12679 bfd_boolean flags = (inst.instruction == T_MNEM_movs);
12680
5ee91343 12681 if (in_pred_block ())
728ca7c9
PB
12682 narrow = !flags;
12683 else
12684 narrow = flags;
12685
12686 if (inst.size_req == 4)
12687 narrow = FALSE;
12688
12689 if (!low_regs || inst.operands[1].imm > 7)
12690 narrow = FALSE;
12691
fdfde340 12692 if (Rn != Rm)
728ca7c9
PB
12693 narrow = FALSE;
12694
12695 switch (inst.operands[1].shift_kind)
12696 {
12697 case SHIFT_LSL:
12698 opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl);
12699 break;
12700 case SHIFT_ASR:
12701 opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr);
12702 break;
12703 case SHIFT_LSR:
12704 opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr);
12705 break;
12706 case SHIFT_ROR:
12707 opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror);
12708 break;
12709 default:
5f4273c7 12710 abort ();
728ca7c9
PB
12711 }
12712
12713 inst.instruction = opcode;
12714 if (narrow)
12715 {
fdfde340 12716 inst.instruction |= Rn;
728ca7c9
PB
12717 inst.instruction |= inst.operands[1].imm << 3;
12718 }
12719 else
12720 {
12721 if (flags)
12722 inst.instruction |= CONDS_BIT;
12723
fdfde340
JM
12724 inst.instruction |= Rn << 8;
12725 inst.instruction |= Rm << 16;
728ca7c9
PB
12726 inst.instruction |= inst.operands[1].imm;
12727 }
12728 }
3d388997 12729 else if (!narrow)
c19d1205 12730 {
728ca7c9
PB
12731 /* Some mov with immediate shift have narrow variants.
12732 Register shifts are handled above. */
12733 if (low_regs && inst.operands[1].shifted
12734 && (inst.instruction == T_MNEM_mov
12735 || inst.instruction == T_MNEM_movs))
12736 {
5ee91343 12737 if (in_pred_block ())
728ca7c9
PB
12738 narrow = (inst.instruction == T_MNEM_mov);
12739 else
12740 narrow = (inst.instruction == T_MNEM_movs);
12741 }
12742
12743 if (narrow)
12744 {
12745 switch (inst.operands[1].shift_kind)
12746 {
12747 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
12748 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
12749 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
12750 default: narrow = FALSE; break;
12751 }
12752 }
12753
12754 if (narrow)
12755 {
fdfde340
JM
12756 inst.instruction |= Rn;
12757 inst.instruction |= Rm << 3;
e2b0ab59 12758 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
728ca7c9
PB
12759 }
12760 else
12761 {
12762 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12763 inst.instruction |= Rn << r0off;
728ca7c9
PB
12764 encode_thumb32_shifted_operand (1);
12765 }
c19d1205
ZW
12766 }
12767 else
12768 switch (inst.instruction)
12769 {
12770 case T_MNEM_mov:
837b3435 12771 /* In v4t or v5t a move of two lowregs produces unpredictable
c6400f8a
MGD
12772 results. Don't allow this. */
12773 if (low_regs)
12774 {
12775 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
12776 "MOV Rd, Rs with two low registers is not "
12777 "permitted on this architecture");
fa94de6b 12778 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
c6400f8a
MGD
12779 arm_ext_v6);
12780 }
12781
c19d1205 12782 inst.instruction = T_OPCODE_MOV_HR;
fdfde340
JM
12783 inst.instruction |= (Rn & 0x8) << 4;
12784 inst.instruction |= (Rn & 0x7);
12785 inst.instruction |= Rm << 3;
c19d1205 12786 break;
b99bd4ef 12787
c19d1205
ZW
12788 case T_MNEM_movs:
12789 /* We know we have low registers at this point.
941a8a52
MGD
12790 Generate LSLS Rd, Rs, #0. */
12791 inst.instruction = T_OPCODE_LSL_I;
fdfde340
JM
12792 inst.instruction |= Rn;
12793 inst.instruction |= Rm << 3;
c19d1205
ZW
12794 break;
12795
12796 case T_MNEM_cmp:
3d388997 12797 if (low_regs)
c19d1205
ZW
12798 {
12799 inst.instruction = T_OPCODE_CMP_LR;
fdfde340
JM
12800 inst.instruction |= Rn;
12801 inst.instruction |= Rm << 3;
c19d1205
ZW
12802 }
12803 else
12804 {
12805 inst.instruction = T_OPCODE_CMP_HR;
fdfde340
JM
12806 inst.instruction |= (Rn & 0x8) << 4;
12807 inst.instruction |= (Rn & 0x7);
12808 inst.instruction |= Rm << 3;
c19d1205
ZW
12809 }
12810 break;
12811 }
b99bd4ef
NC
12812 return;
12813 }
12814
c19d1205 12815 inst.instruction = THUMB_OP16 (inst.instruction);
539d4391
NC
12816
12817 /* PR 10443: Do not silently ignore shifted operands. */
12818 constraint (inst.operands[1].shifted,
12819 _("shifts in CMP/MOV instructions are only supported in unified syntax"));
12820
c19d1205 12821 if (inst.operands[1].isreg)
b99bd4ef 12822 {
fdfde340 12823 if (Rn < 8 && Rm < 8)
b99bd4ef 12824 {
c19d1205
ZW
12825 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
12826 since a MOV instruction produces unpredictable results. */
12827 if (inst.instruction == T_OPCODE_MOV_I8)
12828 inst.instruction = T_OPCODE_ADD_I3;
b99bd4ef 12829 else
c19d1205 12830 inst.instruction = T_OPCODE_CMP_LR;
b99bd4ef 12831
fdfde340
JM
12832 inst.instruction |= Rn;
12833 inst.instruction |= Rm << 3;
b99bd4ef
NC
12834 }
12835 else
12836 {
c19d1205
ZW
12837 if (inst.instruction == T_OPCODE_MOV_I8)
12838 inst.instruction = T_OPCODE_MOV_HR;
12839 else
12840 inst.instruction = T_OPCODE_CMP_HR;
12841 do_t_cpy ();
b99bd4ef
NC
12842 }
12843 }
c19d1205 12844 else
b99bd4ef 12845 {
fdfde340 12846 constraint (Rn > 7,
c19d1205 12847 _("only lo regs allowed with immediate"));
fdfde340 12848 inst.instruction |= Rn << 8;
e2b0ab59 12849 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
c19d1205
ZW
12850 }
12851}
b99bd4ef 12852
c19d1205
ZW
12853static void
12854do_t_mov16 (void)
12855{
fdfde340 12856 unsigned Rd;
b6895b4f
PB
12857 bfd_vma imm;
12858 bfd_boolean top;
12859
12860 top = (inst.instruction & 0x00800000) != 0;
e2b0ab59 12861 if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
b6895b4f 12862 {
33eaf5de 12863 constraint (top, _(":lower16: not allowed in this instruction"));
e2b0ab59 12864 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
b6895b4f 12865 }
e2b0ab59 12866 else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
b6895b4f 12867 {
33eaf5de 12868 constraint (!top, _(":upper16: not allowed in this instruction"));
e2b0ab59 12869 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
b6895b4f
PB
12870 }
12871
fdfde340
JM
12872 Rd = inst.operands[0].reg;
12873 reject_bad_reg (Rd);
12874
12875 inst.instruction |= Rd << 8;
e2b0ab59 12876 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 12877 {
e2b0ab59 12878 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
12879 inst.instruction |= (imm & 0xf000) << 4;
12880 inst.instruction |= (imm & 0x0800) << 15;
12881 inst.instruction |= (imm & 0x0700) << 4;
12882 inst.instruction |= (imm & 0x00ff);
12883 }
c19d1205 12884}
b99bd4ef 12885
c19d1205
ZW
12886static void
12887do_t_mvn_tst (void)
12888{
fdfde340 12889 unsigned Rn, Rm;
c921be7d 12890
fdfde340
JM
12891 Rn = inst.operands[0].reg;
12892 Rm = inst.operands[1].reg;
12893
12894 if (inst.instruction == T_MNEM_cmp
12895 || inst.instruction == T_MNEM_cmn)
12896 constraint (Rn == REG_PC, BAD_PC);
12897 else
12898 reject_bad_reg (Rn);
12899 reject_bad_reg (Rm);
12900
c19d1205
ZW
12901 if (unified_syntax)
12902 {
12903 int r0off = (inst.instruction == T_MNEM_mvn
12904 || inst.instruction == T_MNEM_mvns) ? 8 : 16;
3d388997
PB
12905 bfd_boolean narrow;
12906
12907 if (inst.size_req == 4
12908 || inst.instruction > 0xffff
12909 || inst.operands[1].shifted
fdfde340 12910 || Rn > 7 || Rm > 7)
3d388997 12911 narrow = FALSE;
fe8b4cc3
KT
12912 else if (inst.instruction == T_MNEM_cmn
12913 || inst.instruction == T_MNEM_tst)
3d388997
PB
12914 narrow = TRUE;
12915 else if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 12916 narrow = !in_pred_block ();
3d388997 12917 else
5ee91343 12918 narrow = in_pred_block ();
3d388997 12919
c19d1205 12920 if (!inst.operands[1].isreg)
b99bd4ef 12921 {
c19d1205
ZW
12922 /* For an immediate, we always generate a 32-bit opcode;
12923 section relaxation will shrink it later if possible. */
12924 if (inst.instruction < 0xffff)
12925 inst.instruction = THUMB_OP32 (inst.instruction);
12926 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12927 inst.instruction |= Rn << r0off;
e2b0ab59 12928 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 12929 }
c19d1205 12930 else
b99bd4ef 12931 {
c19d1205 12932 /* See if we can do this with a 16-bit instruction. */
3d388997 12933 if (narrow)
b99bd4ef 12934 {
c19d1205 12935 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12936 inst.instruction |= Rn;
12937 inst.instruction |= Rm << 3;
b99bd4ef 12938 }
c19d1205 12939 else
b99bd4ef 12940 {
c19d1205
ZW
12941 constraint (inst.operands[1].shifted
12942 && inst.operands[1].immisreg,
12943 _("shift must be constant"));
12944 if (inst.instruction < 0xffff)
12945 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12946 inst.instruction |= Rn << r0off;
c19d1205 12947 encode_thumb32_shifted_operand (1);
b99bd4ef 12948 }
b99bd4ef
NC
12949 }
12950 }
12951 else
12952 {
c19d1205
ZW
12953 constraint (inst.instruction > 0xffff
12954 || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
12955 constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
12956 _("unshifted register required"));
fdfde340 12957 constraint (Rn > 7 || Rm > 7,
c19d1205 12958 BAD_HIREG);
b99bd4ef 12959
c19d1205 12960 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12961 inst.instruction |= Rn;
12962 inst.instruction |= Rm << 3;
b99bd4ef 12963 }
b99bd4ef
NC
12964}
12965
b05fe5cf 12966static void
c19d1205 12967do_t_mrs (void)
b05fe5cf 12968{
fdfde340 12969 unsigned Rd;
037e8744
JB
12970
12971 if (do_vfp_nsyn_mrs () == SUCCESS)
12972 return;
12973
90ec0d68
MGD
12974 Rd = inst.operands[0].reg;
12975 reject_bad_reg (Rd);
12976 inst.instruction |= Rd << 8;
12977
12978 if (inst.operands[1].isreg)
62b3e311 12979 {
90ec0d68
MGD
12980 unsigned br = inst.operands[1].reg;
12981 if (((br & 0x200) == 0) && ((br & 0xf000) != 0xf000))
12982 as_bad (_("bad register for mrs"));
12983
12984 inst.instruction |= br & (0xf << 16);
12985 inst.instruction |= (br & 0x300) >> 4;
12986 inst.instruction |= (br & SPSR_BIT) >> 2;
62b3e311
PB
12987 }
12988 else
12989 {
90ec0d68 12990 int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
5f4273c7 12991
d2cd1205 12992 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
1a43faaf
NC
12993 {
12994 /* PR gas/12698: The constraint is only applied for m_profile.
12995 If the user has specified -march=all, we want to ignore it as
12996 we are building for any CPU type, including non-m variants. */
823d2571
TG
12997 bfd_boolean m_profile =
12998 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf
NC
12999 constraint ((flags != 0) && m_profile, _("selected processor does "
13000 "not support requested special purpose register"));
13001 }
90ec0d68 13002 else
d2cd1205
JB
13003 /* mrs only accepts APSR/CPSR/SPSR/CPSR_all/SPSR_all (for non-M profile
13004 devices). */
13005 constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
13006 _("'APSR', 'CPSR' or 'SPSR' expected"));
fdfde340 13007
90ec0d68
MGD
13008 inst.instruction |= (flags & SPSR_BIT) >> 2;
13009 inst.instruction |= inst.operands[1].imm & 0xff;
13010 inst.instruction |= 0xf0000;
13011 }
c19d1205 13012}
b05fe5cf 13013
c19d1205
ZW
13014static void
13015do_t_msr (void)
13016{
62b3e311 13017 int flags;
fdfde340 13018 unsigned Rn;
62b3e311 13019
037e8744
JB
13020 if (do_vfp_nsyn_msr () == SUCCESS)
13021 return;
13022
c19d1205
ZW
13023 constraint (!inst.operands[1].isreg,
13024 _("Thumb encoding does not support an immediate here"));
90ec0d68
MGD
13025
13026 if (inst.operands[0].isreg)
13027 flags = (int)(inst.operands[0].reg);
13028 else
13029 flags = inst.operands[0].imm;
13030
d2cd1205 13031 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
62b3e311 13032 {
d2cd1205
JB
13033 int bits = inst.operands[0].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
13034
1a43faaf 13035 /* PR gas/12698: The constraint is only applied for m_profile.
477330fc
RM
13036 If the user has specified -march=all, we want to ignore it as
13037 we are building for any CPU type, including non-m variants. */
823d2571
TG
13038 bfd_boolean m_profile =
13039 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf 13040 constraint (((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
477330fc
RM
13041 && (bits & ~(PSR_s | PSR_f)) != 0)
13042 || (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
13043 && bits != PSR_f)) && m_profile,
13044 _("selected processor does not support requested special "
13045 "purpose register"));
62b3e311
PB
13046 }
13047 else
d2cd1205
JB
13048 constraint ((flags & 0xff) != 0, _("selected processor does not support "
13049 "requested special purpose register"));
c921be7d 13050
fdfde340
JM
13051 Rn = inst.operands[1].reg;
13052 reject_bad_reg (Rn);
13053
62b3e311 13054 inst.instruction |= (flags & SPSR_BIT) >> 2;
90ec0d68
MGD
13055 inst.instruction |= (flags & 0xf0000) >> 8;
13056 inst.instruction |= (flags & 0x300) >> 4;
62b3e311 13057 inst.instruction |= (flags & 0xff);
fdfde340 13058 inst.instruction |= Rn << 16;
c19d1205 13059}
b05fe5cf 13060
c19d1205
ZW
13061static void
13062do_t_mul (void)
13063{
17828f45 13064 bfd_boolean narrow;
fdfde340 13065 unsigned Rd, Rn, Rm;
17828f45 13066
c19d1205
ZW
13067 if (!inst.operands[2].present)
13068 inst.operands[2].reg = inst.operands[0].reg;
b05fe5cf 13069
fdfde340
JM
13070 Rd = inst.operands[0].reg;
13071 Rn = inst.operands[1].reg;
13072 Rm = inst.operands[2].reg;
13073
17828f45 13074 if (unified_syntax)
b05fe5cf 13075 {
17828f45 13076 if (inst.size_req == 4
fdfde340
JM
13077 || (Rd != Rn
13078 && Rd != Rm)
13079 || Rn > 7
13080 || Rm > 7)
17828f45
JM
13081 narrow = FALSE;
13082 else if (inst.instruction == T_MNEM_muls)
5ee91343 13083 narrow = !in_pred_block ();
17828f45 13084 else
5ee91343 13085 narrow = in_pred_block ();
b05fe5cf 13086 }
c19d1205 13087 else
b05fe5cf 13088 {
17828f45 13089 constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32);
fdfde340 13090 constraint (Rn > 7 || Rm > 7,
c19d1205 13091 BAD_HIREG);
17828f45
JM
13092 narrow = TRUE;
13093 }
b05fe5cf 13094
17828f45
JM
13095 if (narrow)
13096 {
13097 /* 16-bit MULS/Conditional MUL. */
c19d1205 13098 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 13099 inst.instruction |= Rd;
b05fe5cf 13100
fdfde340
JM
13101 if (Rd == Rn)
13102 inst.instruction |= Rm << 3;
13103 else if (Rd == Rm)
13104 inst.instruction |= Rn << 3;
c19d1205
ZW
13105 else
13106 constraint (1, _("dest must overlap one source register"));
13107 }
17828f45
JM
13108 else
13109 {
e07e6e58
NC
13110 constraint (inst.instruction != T_MNEM_mul,
13111 _("Thumb-2 MUL must not set flags"));
17828f45
JM
13112 /* 32-bit MUL. */
13113 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13114 inst.instruction |= Rd << 8;
13115 inst.instruction |= Rn << 16;
13116 inst.instruction |= Rm << 0;
13117
13118 reject_bad_reg (Rd);
13119 reject_bad_reg (Rn);
13120 reject_bad_reg (Rm);
17828f45 13121 }
c19d1205 13122}
b05fe5cf 13123
c19d1205
ZW
13124static void
13125do_t_mull (void)
13126{
fdfde340 13127 unsigned RdLo, RdHi, Rn, Rm;
b05fe5cf 13128
fdfde340
JM
13129 RdLo = inst.operands[0].reg;
13130 RdHi = inst.operands[1].reg;
13131 Rn = inst.operands[2].reg;
13132 Rm = inst.operands[3].reg;
13133
13134 reject_bad_reg (RdLo);
13135 reject_bad_reg (RdHi);
13136 reject_bad_reg (Rn);
13137 reject_bad_reg (Rm);
13138
13139 inst.instruction |= RdLo << 12;
13140 inst.instruction |= RdHi << 8;
13141 inst.instruction |= Rn << 16;
13142 inst.instruction |= Rm;
13143
13144 if (RdLo == RdHi)
c19d1205
ZW
13145 as_tsktsk (_("rdhi and rdlo must be different"));
13146}
b05fe5cf 13147
c19d1205
ZW
13148static void
13149do_t_nop (void)
13150{
5ee91343 13151 set_pred_insn_type (NEUTRAL_IT_INSN);
e07e6e58 13152
c19d1205
ZW
13153 if (unified_syntax)
13154 {
13155 if (inst.size_req == 4 || inst.operands[0].imm > 15)
b05fe5cf 13156 {
c19d1205
ZW
13157 inst.instruction = THUMB_OP32 (inst.instruction);
13158 inst.instruction |= inst.operands[0].imm;
13159 }
13160 else
13161 {
bc2d1808
NC
13162 /* PR9722: Check for Thumb2 availability before
13163 generating a thumb2 nop instruction. */
afa62d5e 13164 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
bc2d1808
NC
13165 {
13166 inst.instruction = THUMB_OP16 (inst.instruction);
13167 inst.instruction |= inst.operands[0].imm << 4;
13168 }
13169 else
13170 inst.instruction = 0x46c0;
c19d1205
ZW
13171 }
13172 }
13173 else
13174 {
13175 constraint (inst.operands[0].present,
13176 _("Thumb does not support NOP with hints"));
13177 inst.instruction = 0x46c0;
13178 }
13179}
b05fe5cf 13180
c19d1205
ZW
13181static void
13182do_t_neg (void)
13183{
13184 if (unified_syntax)
13185 {
3d388997
PB
13186 bfd_boolean narrow;
13187
13188 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13189 narrow = !in_pred_block ();
3d388997 13190 else
5ee91343 13191 narrow = in_pred_block ();
3d388997
PB
13192 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
13193 narrow = FALSE;
13194 if (inst.size_req == 4)
13195 narrow = FALSE;
13196
13197 if (!narrow)
c19d1205
ZW
13198 {
13199 inst.instruction = THUMB_OP32 (inst.instruction);
13200 inst.instruction |= inst.operands[0].reg << 8;
13201 inst.instruction |= inst.operands[1].reg << 16;
b05fe5cf
ZW
13202 }
13203 else
13204 {
c19d1205
ZW
13205 inst.instruction = THUMB_OP16 (inst.instruction);
13206 inst.instruction |= inst.operands[0].reg;
13207 inst.instruction |= inst.operands[1].reg << 3;
b05fe5cf
ZW
13208 }
13209 }
13210 else
13211 {
c19d1205
ZW
13212 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
13213 BAD_HIREG);
13214 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
13215
13216 inst.instruction = THUMB_OP16 (inst.instruction);
13217 inst.instruction |= inst.operands[0].reg;
13218 inst.instruction |= inst.operands[1].reg << 3;
13219 }
13220}
13221
1c444d06
JM
13222static void
13223do_t_orn (void)
13224{
13225 unsigned Rd, Rn;
13226
13227 Rd = inst.operands[0].reg;
13228 Rn = inst.operands[1].present ? inst.operands[1].reg : Rd;
13229
fdfde340
JM
13230 reject_bad_reg (Rd);
13231 /* Rn == REG_SP is unpredictable; Rn == REG_PC is MVN. */
13232 reject_bad_reg (Rn);
13233
1c444d06
JM
13234 inst.instruction |= Rd << 8;
13235 inst.instruction |= Rn << 16;
13236
13237 if (!inst.operands[2].isreg)
13238 {
13239 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13240 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
1c444d06
JM
13241 }
13242 else
13243 {
13244 unsigned Rm;
13245
13246 Rm = inst.operands[2].reg;
fdfde340 13247 reject_bad_reg (Rm);
1c444d06
JM
13248
13249 constraint (inst.operands[2].shifted
13250 && inst.operands[2].immisreg,
13251 _("shift must be constant"));
13252 encode_thumb32_shifted_operand (2);
13253 }
13254}
13255
c19d1205
ZW
13256static void
13257do_t_pkhbt (void)
13258{
fdfde340
JM
13259 unsigned Rd, Rn, Rm;
13260
13261 Rd = inst.operands[0].reg;
13262 Rn = inst.operands[1].reg;
13263 Rm = inst.operands[2].reg;
13264
13265 reject_bad_reg (Rd);
13266 reject_bad_reg (Rn);
13267 reject_bad_reg (Rm);
13268
13269 inst.instruction |= Rd << 8;
13270 inst.instruction |= Rn << 16;
13271 inst.instruction |= Rm;
c19d1205
ZW
13272 if (inst.operands[3].present)
13273 {
e2b0ab59
AV
13274 unsigned int val = inst.relocs[0].exp.X_add_number;
13275 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
13276 _("expression too complex"));
13277 inst.instruction |= (val & 0x1c) << 10;
13278 inst.instruction |= (val & 0x03) << 6;
b05fe5cf 13279 }
c19d1205 13280}
b05fe5cf 13281
c19d1205
ZW
13282static void
13283do_t_pkhtb (void)
13284{
13285 if (!inst.operands[3].present)
1ef52f49
NC
13286 {
13287 unsigned Rtmp;
13288
13289 inst.instruction &= ~0x00000020;
13290
13291 /* PR 10168. Swap the Rm and Rn registers. */
13292 Rtmp = inst.operands[1].reg;
13293 inst.operands[1].reg = inst.operands[2].reg;
13294 inst.operands[2].reg = Rtmp;
13295 }
c19d1205 13296 do_t_pkhbt ();
b05fe5cf
ZW
13297}
13298
c19d1205
ZW
13299static void
13300do_t_pld (void)
13301{
fdfde340
JM
13302 if (inst.operands[0].immisreg)
13303 reject_bad_reg (inst.operands[0].imm);
13304
c19d1205
ZW
13305 encode_thumb32_addr_mode (0, /*is_t=*/FALSE, /*is_d=*/FALSE);
13306}
b05fe5cf 13307
c19d1205
ZW
13308static void
13309do_t_push_pop (void)
b99bd4ef 13310{
e9f89963 13311 unsigned mask;
5f4273c7 13312
c19d1205
ZW
13313 constraint (inst.operands[0].writeback,
13314 _("push/pop do not support {reglist}^"));
e2b0ab59 13315 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205 13316 _("expression too complex"));
b99bd4ef 13317
e9f89963 13318 mask = inst.operands[0].imm;
d3bfe16e 13319 if (inst.size_req != 4 && (mask & ~0xff) == 0)
3c707909 13320 inst.instruction = THUMB_OP16 (inst.instruction) | mask;
d3bfe16e 13321 else if (inst.size_req != 4
c6025a80 13322 && (mask & ~0xff) == (1U << (inst.instruction == T_MNEM_push
d3bfe16e 13323 ? REG_LR : REG_PC)))
b99bd4ef 13324 {
c19d1205
ZW
13325 inst.instruction = THUMB_OP16 (inst.instruction);
13326 inst.instruction |= THUMB_PP_PC_LR;
3c707909 13327 inst.instruction |= mask & 0xff;
c19d1205
ZW
13328 }
13329 else if (unified_syntax)
13330 {
3c707909 13331 inst.instruction = THUMB_OP32 (inst.instruction);
4b5a202f
AV
13332 encode_thumb2_multi (TRUE /* do_io */, 13, mask, TRUE);
13333 }
13334 else
13335 {
13336 inst.error = _("invalid register list to push/pop instruction");
13337 return;
c19d1205 13338 }
4b5a202f
AV
13339}
13340
13341static void
13342do_t_clrm (void)
13343{
13344 if (unified_syntax)
13345 encode_thumb2_multi (FALSE /* do_io */, -1, inst.operands[0].imm, FALSE);
c19d1205
ZW
13346 else
13347 {
13348 inst.error = _("invalid register list to push/pop instruction");
13349 return;
13350 }
c19d1205 13351}
b99bd4ef 13352
efd6b359
AV
13353static void
13354do_t_vscclrm (void)
13355{
13356 if (inst.operands[0].issingle)
13357 {
13358 inst.instruction |= (inst.operands[0].reg & 0x1) << 22;
13359 inst.instruction |= (inst.operands[0].reg & 0x1e) << 11;
13360 inst.instruction |= inst.operands[0].imm;
13361 }
13362 else
13363 {
13364 inst.instruction |= (inst.operands[0].reg & 0x10) << 18;
13365 inst.instruction |= (inst.operands[0].reg & 0xf) << 12;
13366 inst.instruction |= 1 << 8;
13367 inst.instruction |= inst.operands[0].imm << 1;
13368 }
13369}
13370
c19d1205
ZW
13371static void
13372do_t_rbit (void)
13373{
fdfde340
JM
13374 unsigned Rd, Rm;
13375
13376 Rd = inst.operands[0].reg;
13377 Rm = inst.operands[1].reg;
13378
13379 reject_bad_reg (Rd);
13380 reject_bad_reg (Rm);
13381
13382 inst.instruction |= Rd << 8;
13383 inst.instruction |= Rm << 16;
13384 inst.instruction |= Rm;
c19d1205 13385}
b99bd4ef 13386
c19d1205
ZW
13387static void
13388do_t_rev (void)
13389{
fdfde340
JM
13390 unsigned Rd, Rm;
13391
13392 Rd = inst.operands[0].reg;
13393 Rm = inst.operands[1].reg;
13394
13395 reject_bad_reg (Rd);
13396 reject_bad_reg (Rm);
13397
13398 if (Rd <= 7 && Rm <= 7
c19d1205
ZW
13399 && inst.size_req != 4)
13400 {
13401 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13402 inst.instruction |= Rd;
13403 inst.instruction |= Rm << 3;
c19d1205
ZW
13404 }
13405 else if (unified_syntax)
13406 {
13407 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13408 inst.instruction |= Rd << 8;
13409 inst.instruction |= Rm << 16;
13410 inst.instruction |= Rm;
c19d1205
ZW
13411 }
13412 else
13413 inst.error = BAD_HIREG;
13414}
b99bd4ef 13415
1c444d06
JM
13416static void
13417do_t_rrx (void)
13418{
13419 unsigned Rd, Rm;
13420
13421 Rd = inst.operands[0].reg;
13422 Rm = inst.operands[1].reg;
13423
fdfde340
JM
13424 reject_bad_reg (Rd);
13425 reject_bad_reg (Rm);
c921be7d 13426
1c444d06
JM
13427 inst.instruction |= Rd << 8;
13428 inst.instruction |= Rm;
13429}
13430
c19d1205
ZW
13431static void
13432do_t_rsb (void)
13433{
fdfde340 13434 unsigned Rd, Rs;
b99bd4ef 13435
c19d1205
ZW
13436 Rd = inst.operands[0].reg;
13437 Rs = (inst.operands[1].present
13438 ? inst.operands[1].reg /* Rd, Rs, foo */
13439 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
b99bd4ef 13440
fdfde340
JM
13441 reject_bad_reg (Rd);
13442 reject_bad_reg (Rs);
13443 if (inst.operands[2].isreg)
13444 reject_bad_reg (inst.operands[2].reg);
13445
c19d1205
ZW
13446 inst.instruction |= Rd << 8;
13447 inst.instruction |= Rs << 16;
13448 if (!inst.operands[2].isreg)
13449 {
026d3abb
PB
13450 bfd_boolean narrow;
13451
13452 if ((inst.instruction & 0x00100000) != 0)
5ee91343 13453 narrow = !in_pred_block ();
026d3abb 13454 else
5ee91343 13455 narrow = in_pred_block ();
026d3abb
PB
13456
13457 if (Rd > 7 || Rs > 7)
13458 narrow = FALSE;
13459
13460 if (inst.size_req == 4 || !unified_syntax)
13461 narrow = FALSE;
13462
e2b0ab59
AV
13463 if (inst.relocs[0].exp.X_op != O_constant
13464 || inst.relocs[0].exp.X_add_number != 0)
026d3abb
PB
13465 narrow = FALSE;
13466
13467 /* Turn rsb #0 into 16-bit neg. We should probably do this via
477330fc 13468 relaxation, but it doesn't seem worth the hassle. */
026d3abb
PB
13469 if (narrow)
13470 {
e2b0ab59 13471 inst.relocs[0].type = BFD_RELOC_UNUSED;
026d3abb
PB
13472 inst.instruction = THUMB_OP16 (T_MNEM_negs);
13473 inst.instruction |= Rs << 3;
13474 inst.instruction |= Rd;
13475 }
13476 else
13477 {
13478 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13479 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
026d3abb 13480 }
c19d1205
ZW
13481 }
13482 else
13483 encode_thumb32_shifted_operand (2);
13484}
b99bd4ef 13485
c19d1205
ZW
13486static void
13487do_t_setend (void)
13488{
12e37cbc
MGD
13489 if (warn_on_deprecated
13490 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 13491 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 13492
5ee91343 13493 set_pred_insn_type (OUTSIDE_PRED_INSN);
c19d1205
ZW
13494 if (inst.operands[0].imm)
13495 inst.instruction |= 0x8;
13496}
b99bd4ef 13497
c19d1205
ZW
13498static void
13499do_t_shift (void)
13500{
13501 if (!inst.operands[1].present)
13502 inst.operands[1].reg = inst.operands[0].reg;
13503
13504 if (unified_syntax)
13505 {
3d388997
PB
13506 bfd_boolean narrow;
13507 int shift_kind;
13508
13509 switch (inst.instruction)
13510 {
13511 case T_MNEM_asr:
13512 case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
13513 case T_MNEM_lsl:
13514 case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
13515 case T_MNEM_lsr:
13516 case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
13517 case T_MNEM_ror:
13518 case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
13519 default: abort ();
13520 }
13521
13522 if (THUMB_SETS_FLAGS (inst.instruction))
5ee91343 13523 narrow = !in_pred_block ();
3d388997 13524 else
5ee91343 13525 narrow = in_pred_block ();
3d388997
PB
13526 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
13527 narrow = FALSE;
13528 if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
13529 narrow = FALSE;
13530 if (inst.operands[2].isreg
13531 && (inst.operands[1].reg != inst.operands[0].reg
13532 || inst.operands[2].reg > 7))
13533 narrow = FALSE;
13534 if (inst.size_req == 4)
13535 narrow = FALSE;
13536
fdfde340
JM
13537 reject_bad_reg (inst.operands[0].reg);
13538 reject_bad_reg (inst.operands[1].reg);
c921be7d 13539
3d388997 13540 if (!narrow)
c19d1205
ZW
13541 {
13542 if (inst.operands[2].isreg)
b99bd4ef 13543 {
fdfde340 13544 reject_bad_reg (inst.operands[2].reg);
c19d1205
ZW
13545 inst.instruction = THUMB_OP32 (inst.instruction);
13546 inst.instruction |= inst.operands[0].reg << 8;
13547 inst.instruction |= inst.operands[1].reg << 16;
13548 inst.instruction |= inst.operands[2].reg;
94342ec3
NC
13549
13550 /* PR 12854: Error on extraneous shifts. */
13551 constraint (inst.operands[2].shifted,
13552 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13553 }
13554 else
13555 {
13556 inst.operands[1].shifted = 1;
3d388997 13557 inst.operands[1].shift_kind = shift_kind;
c19d1205
ZW
13558 inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
13559 ? T_MNEM_movs : T_MNEM_mov);
13560 inst.instruction |= inst.operands[0].reg << 8;
13561 encode_thumb32_shifted_operand (1);
13562 /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
e2b0ab59 13563 inst.relocs[0].type = BFD_RELOC_UNUSED;
b99bd4ef
NC
13564 }
13565 }
13566 else
13567 {
c19d1205 13568 if (inst.operands[2].isreg)
b99bd4ef 13569 {
3d388997 13570 switch (shift_kind)
b99bd4ef 13571 {
3d388997
PB
13572 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
13573 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
13574 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
13575 case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
c19d1205 13576 default: abort ();
b99bd4ef 13577 }
5f4273c7 13578
c19d1205
ZW
13579 inst.instruction |= inst.operands[0].reg;
13580 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13581
13582 /* PR 12854: Error on extraneous shifts. */
13583 constraint (inst.operands[2].shifted,
13584 _("extraneous shift as part of operand to shift insn"));
b99bd4ef
NC
13585 }
13586 else
13587 {
3d388997 13588 switch (shift_kind)
b99bd4ef 13589 {
3d388997
PB
13590 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
13591 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
13592 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
c19d1205 13593 default: abort ();
b99bd4ef 13594 }
e2b0ab59 13595 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13596 inst.instruction |= inst.operands[0].reg;
13597 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13598 }
13599 }
c19d1205
ZW
13600 }
13601 else
13602 {
13603 constraint (inst.operands[0].reg > 7
13604 || inst.operands[1].reg > 7, BAD_HIREG);
13605 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
b99bd4ef 13606
c19d1205
ZW
13607 if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
13608 {
13609 constraint (inst.operands[2].reg > 7, BAD_HIREG);
13610 constraint (inst.operands[0].reg != inst.operands[1].reg,
13611 _("source1 and dest must be same register"));
b99bd4ef 13612
c19d1205
ZW
13613 switch (inst.instruction)
13614 {
13615 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
13616 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
13617 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
13618 case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
13619 default: abort ();
13620 }
5f4273c7 13621
c19d1205
ZW
13622 inst.instruction |= inst.operands[0].reg;
13623 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13624
13625 /* PR 12854: Error on extraneous shifts. */
13626 constraint (inst.operands[2].shifted,
13627 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13628 }
13629 else
b99bd4ef 13630 {
c19d1205
ZW
13631 switch (inst.instruction)
13632 {
13633 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
13634 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
13635 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
13636 case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
13637 default: abort ();
13638 }
e2b0ab59 13639 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13640 inst.instruction |= inst.operands[0].reg;
13641 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13642 }
13643 }
b99bd4ef
NC
13644}
13645
13646static void
c19d1205 13647do_t_simd (void)
b99bd4ef 13648{
fdfde340
JM
13649 unsigned Rd, Rn, Rm;
13650
13651 Rd = inst.operands[0].reg;
13652 Rn = inst.operands[1].reg;
13653 Rm = inst.operands[2].reg;
13654
13655 reject_bad_reg (Rd);
13656 reject_bad_reg (Rn);
13657 reject_bad_reg (Rm);
13658
13659 inst.instruction |= Rd << 8;
13660 inst.instruction |= Rn << 16;
13661 inst.instruction |= Rm;
c19d1205 13662}
b99bd4ef 13663
03ee1b7f
NC
13664static void
13665do_t_simd2 (void)
13666{
13667 unsigned Rd, Rn, Rm;
13668
13669 Rd = inst.operands[0].reg;
13670 Rm = inst.operands[1].reg;
13671 Rn = inst.operands[2].reg;
13672
13673 reject_bad_reg (Rd);
13674 reject_bad_reg (Rn);
13675 reject_bad_reg (Rm);
13676
13677 inst.instruction |= Rd << 8;
13678 inst.instruction |= Rn << 16;
13679 inst.instruction |= Rm;
13680}
13681
c19d1205 13682static void
3eb17e6b 13683do_t_smc (void)
c19d1205 13684{
e2b0ab59 13685 unsigned int value = inst.relocs[0].exp.X_add_number;
f4c65163
MGD
13686 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
13687 _("SMC is not permitted on this architecture"));
e2b0ab59 13688 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13689 _("expression too complex"));
e2b0ab59 13690 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
13691 inst.instruction |= (value & 0xf000) >> 12;
13692 inst.instruction |= (value & 0x0ff0);
13693 inst.instruction |= (value & 0x000f) << 16;
24382199 13694 /* PR gas/15623: SMC instructions must be last in an IT block. */
5ee91343 13695 set_pred_insn_type_last ();
c19d1205 13696}
b99bd4ef 13697
90ec0d68
MGD
13698static void
13699do_t_hvc (void)
13700{
e2b0ab59 13701 unsigned int value = inst.relocs[0].exp.X_add_number;
90ec0d68 13702
e2b0ab59 13703 inst.relocs[0].type = BFD_RELOC_UNUSED;
90ec0d68
MGD
13704 inst.instruction |= (value & 0x0fff);
13705 inst.instruction |= (value & 0xf000) << 4;
13706}
13707
c19d1205 13708static void
3a21c15a 13709do_t_ssat_usat (int bias)
c19d1205 13710{
fdfde340
JM
13711 unsigned Rd, Rn;
13712
13713 Rd = inst.operands[0].reg;
13714 Rn = inst.operands[2].reg;
13715
13716 reject_bad_reg (Rd);
13717 reject_bad_reg (Rn);
13718
13719 inst.instruction |= Rd << 8;
3a21c15a 13720 inst.instruction |= inst.operands[1].imm - bias;
fdfde340 13721 inst.instruction |= Rn << 16;
b99bd4ef 13722
c19d1205 13723 if (inst.operands[3].present)
b99bd4ef 13724 {
e2b0ab59 13725 offsetT shift_amount = inst.relocs[0].exp.X_add_number;
3a21c15a 13726
e2b0ab59 13727 inst.relocs[0].type = BFD_RELOC_UNUSED;
3a21c15a 13728
e2b0ab59 13729 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13730 _("expression too complex"));
b99bd4ef 13731
3a21c15a 13732 if (shift_amount != 0)
6189168b 13733 {
3a21c15a
NC
13734 constraint (shift_amount > 31,
13735 _("shift expression is too large"));
13736
c19d1205 13737 if (inst.operands[3].shift_kind == SHIFT_ASR)
3a21c15a
NC
13738 inst.instruction |= 0x00200000; /* sh bit. */
13739
13740 inst.instruction |= (shift_amount & 0x1c) << 10;
13741 inst.instruction |= (shift_amount & 0x03) << 6;
6189168b
NC
13742 }
13743 }
b99bd4ef 13744}
c921be7d 13745
3a21c15a
NC
13746static void
13747do_t_ssat (void)
13748{
13749 do_t_ssat_usat (1);
13750}
b99bd4ef 13751
0dd132b6 13752static void
c19d1205 13753do_t_ssat16 (void)
0dd132b6 13754{
fdfde340
JM
13755 unsigned Rd, Rn;
13756
13757 Rd = inst.operands[0].reg;
13758 Rn = inst.operands[2].reg;
13759
13760 reject_bad_reg (Rd);
13761 reject_bad_reg (Rn);
13762
13763 inst.instruction |= Rd << 8;
c19d1205 13764 inst.instruction |= inst.operands[1].imm - 1;
fdfde340 13765 inst.instruction |= Rn << 16;
c19d1205 13766}
0dd132b6 13767
c19d1205
ZW
13768static void
13769do_t_strex (void)
13770{
13771 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
13772 || inst.operands[2].postind || inst.operands[2].writeback
13773 || inst.operands[2].immisreg || inst.operands[2].shifted
13774 || inst.operands[2].negative,
01cfc07f 13775 BAD_ADDR_MODE);
0dd132b6 13776
5be8be5d
DG
13777 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
13778
c19d1205
ZW
13779 inst.instruction |= inst.operands[0].reg << 8;
13780 inst.instruction |= inst.operands[1].reg << 12;
13781 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 13782 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
0dd132b6
NC
13783}
13784
b99bd4ef 13785static void
c19d1205 13786do_t_strexd (void)
b99bd4ef 13787{
c19d1205
ZW
13788 if (!inst.operands[2].present)
13789 inst.operands[2].reg = inst.operands[1].reg + 1;
b99bd4ef 13790
c19d1205
ZW
13791 constraint (inst.operands[0].reg == inst.operands[1].reg
13792 || inst.operands[0].reg == inst.operands[2].reg
f8a8e9d6 13793 || inst.operands[0].reg == inst.operands[3].reg,
c19d1205 13794 BAD_OVERLAP);
b99bd4ef 13795
c19d1205
ZW
13796 inst.instruction |= inst.operands[0].reg;
13797 inst.instruction |= inst.operands[1].reg << 12;
13798 inst.instruction |= inst.operands[2].reg << 8;
13799 inst.instruction |= inst.operands[3].reg << 16;
b99bd4ef
NC
13800}
13801
13802static void
c19d1205 13803do_t_sxtah (void)
b99bd4ef 13804{
fdfde340
JM
13805 unsigned Rd, Rn, Rm;
13806
13807 Rd = inst.operands[0].reg;
13808 Rn = inst.operands[1].reg;
13809 Rm = inst.operands[2].reg;
13810
13811 reject_bad_reg (Rd);
13812 reject_bad_reg (Rn);
13813 reject_bad_reg (Rm);
13814
13815 inst.instruction |= Rd << 8;
13816 inst.instruction |= Rn << 16;
13817 inst.instruction |= Rm;
c19d1205
ZW
13818 inst.instruction |= inst.operands[3].imm << 4;
13819}
b99bd4ef 13820
c19d1205
ZW
13821static void
13822do_t_sxth (void)
13823{
fdfde340
JM
13824 unsigned Rd, Rm;
13825
13826 Rd = inst.operands[0].reg;
13827 Rm = inst.operands[1].reg;
13828
13829 reject_bad_reg (Rd);
13830 reject_bad_reg (Rm);
c921be7d
NC
13831
13832 if (inst.instruction <= 0xffff
13833 && inst.size_req != 4
fdfde340 13834 && Rd <= 7 && Rm <= 7
c19d1205 13835 && (!inst.operands[2].present || inst.operands[2].imm == 0))
b99bd4ef 13836 {
c19d1205 13837 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13838 inst.instruction |= Rd;
13839 inst.instruction |= Rm << 3;
b99bd4ef 13840 }
c19d1205 13841 else if (unified_syntax)
b99bd4ef 13842 {
c19d1205
ZW
13843 if (inst.instruction <= 0xffff)
13844 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13845 inst.instruction |= Rd << 8;
13846 inst.instruction |= Rm;
c19d1205 13847 inst.instruction |= inst.operands[2].imm << 4;
b99bd4ef 13848 }
c19d1205 13849 else
b99bd4ef 13850 {
c19d1205
ZW
13851 constraint (inst.operands[2].present && inst.operands[2].imm != 0,
13852 _("Thumb encoding does not support rotation"));
13853 constraint (1, BAD_HIREG);
b99bd4ef 13854 }
c19d1205 13855}
b99bd4ef 13856
c19d1205
ZW
13857static void
13858do_t_swi (void)
13859{
e2b0ab59 13860 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
c19d1205 13861}
b99bd4ef 13862
92e90b6e
PB
13863static void
13864do_t_tb (void)
13865{
fdfde340 13866 unsigned Rn, Rm;
92e90b6e
PB
13867 int half;
13868
13869 half = (inst.instruction & 0x10) != 0;
5ee91343 13870 set_pred_insn_type_last ();
dfa9f0d5
PB
13871 constraint (inst.operands[0].immisreg,
13872 _("instruction requires register index"));
fdfde340
JM
13873
13874 Rn = inst.operands[0].reg;
13875 Rm = inst.operands[0].imm;
c921be7d 13876
5c8ed6a4
JW
13877 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
13878 constraint (Rn == REG_SP, BAD_SP);
fdfde340
JM
13879 reject_bad_reg (Rm);
13880
92e90b6e
PB
13881 constraint (!half && inst.operands[0].shifted,
13882 _("instruction does not allow shifted index"));
fdfde340 13883 inst.instruction |= (Rn << 16) | Rm;
92e90b6e
PB
13884}
13885
74db7efb
NC
13886static void
13887do_t_udf (void)
13888{
13889 if (!inst.operands[0].present)
13890 inst.operands[0].imm = 0;
13891
13892 if ((unsigned int) inst.operands[0].imm > 255 || inst.size_req == 4)
13893 {
13894 constraint (inst.size_req == 2,
13895 _("immediate value out of range"));
13896 inst.instruction = THUMB_OP32 (inst.instruction);
13897 inst.instruction |= (inst.operands[0].imm & 0xf000u) << 4;
13898 inst.instruction |= (inst.operands[0].imm & 0x0fffu) << 0;
13899 }
13900 else
13901 {
13902 inst.instruction = THUMB_OP16 (inst.instruction);
13903 inst.instruction |= inst.operands[0].imm;
13904 }
13905
5ee91343 13906 set_pred_insn_type (NEUTRAL_IT_INSN);
74db7efb
NC
13907}
13908
13909
c19d1205
ZW
13910static void
13911do_t_usat (void)
13912{
3a21c15a 13913 do_t_ssat_usat (0);
b99bd4ef
NC
13914}
13915
13916static void
c19d1205 13917do_t_usat16 (void)
b99bd4ef 13918{
fdfde340
JM
13919 unsigned Rd, Rn;
13920
13921 Rd = inst.operands[0].reg;
13922 Rn = inst.operands[2].reg;
13923
13924 reject_bad_reg (Rd);
13925 reject_bad_reg (Rn);
13926
13927 inst.instruction |= Rd << 8;
c19d1205 13928 inst.instruction |= inst.operands[1].imm;
fdfde340 13929 inst.instruction |= Rn << 16;
b99bd4ef 13930}
c19d1205 13931
e12437dc
AV
13932/* Checking the range of the branch offset (VAL) with NBITS bits
13933 and IS_SIGNED signedness. Also checks the LSB to be 0. */
13934static int
13935v8_1_branch_value_check (int val, int nbits, int is_signed)
13936{
13937 gas_assert (nbits > 0 && nbits <= 32);
13938 if (is_signed)
13939 {
13940 int cmp = (1 << (nbits - 1));
13941 if ((val < -cmp) || (val >= cmp) || (val & 0x01))
13942 return FAIL;
13943 }
13944 else
13945 {
13946 if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
13947 return FAIL;
13948 }
13949 return SUCCESS;
13950}
13951
4389b29a
AV
13952/* For branches in Armv8.1-M Mainline. */
13953static void
13954do_t_branch_future (void)
13955{
13956 unsigned long insn = inst.instruction;
13957
13958 inst.instruction = THUMB_OP32 (inst.instruction);
13959 if (inst.operands[0].hasreloc == 0)
13960 {
13961 if (v8_1_branch_value_check (inst.operands[0].imm, 5, FALSE) == FAIL)
13962 as_bad (BAD_BRANCH_OFF);
13963
13964 inst.instruction |= ((inst.operands[0].imm & 0x1f) >> 1) << 23;
13965 }
13966 else
13967 {
13968 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH5;
13969 inst.relocs[0].pc_rel = 1;
13970 }
13971
13972 switch (insn)
13973 {
13974 case T_MNEM_bf:
13975 if (inst.operands[1].hasreloc == 0)
13976 {
13977 int val = inst.operands[1].imm;
13978 if (v8_1_branch_value_check (inst.operands[1].imm, 17, TRUE) == FAIL)
13979 as_bad (BAD_BRANCH_OFF);
13980
13981 int immA = (val & 0x0001f000) >> 12;
13982 int immB = (val & 0x00000ffc) >> 2;
13983 int immC = (val & 0x00000002) >> 1;
13984 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
13985 }
13986 else
13987 {
13988 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF17;
13989 inst.relocs[1].pc_rel = 1;
13990 }
13991 break;
13992
65d1bc05
AV
13993 case T_MNEM_bfl:
13994 if (inst.operands[1].hasreloc == 0)
13995 {
13996 int val = inst.operands[1].imm;
13997 if (v8_1_branch_value_check (inst.operands[1].imm, 19, TRUE) == FAIL)
13998 as_bad (BAD_BRANCH_OFF);
13999
14000 int immA = (val & 0x0007f000) >> 12;
14001 int immB = (val & 0x00000ffc) >> 2;
14002 int immC = (val & 0x00000002) >> 1;
14003 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14004 }
14005 else
14006 {
14007 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
14008 inst.relocs[1].pc_rel = 1;
14009 }
14010 break;
14011
f6b2b12d
AV
14012 case T_MNEM_bfcsel:
14013 /* Operand 1. */
14014 if (inst.operands[1].hasreloc == 0)
14015 {
14016 int val = inst.operands[1].imm;
14017 int immA = (val & 0x00001000) >> 12;
14018 int immB = (val & 0x00000ffc) >> 2;
14019 int immC = (val & 0x00000002) >> 1;
14020 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
14021 }
14022 else
14023 {
14024 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF13;
14025 inst.relocs[1].pc_rel = 1;
14026 }
14027
14028 /* Operand 2. */
14029 if (inst.operands[2].hasreloc == 0)
14030 {
14031 constraint ((inst.operands[0].hasreloc != 0), BAD_ARGS);
14032 int val2 = inst.operands[2].imm;
14033 int val0 = inst.operands[0].imm & 0x1f;
14034 int diff = val2 - val0;
14035 if (diff == 4)
14036 inst.instruction |= 1 << 17; /* T bit. */
14037 else if (diff != 2)
14038 as_bad (_("out of range label-relative fixup value"));
14039 }
14040 else
14041 {
14042 constraint ((inst.operands[0].hasreloc == 0), BAD_ARGS);
14043 inst.relocs[2].type = BFD_RELOC_THUMB_PCREL_BFCSEL;
14044 inst.relocs[2].pc_rel = 1;
14045 }
14046
14047 /* Operand 3. */
14048 constraint (inst.cond != COND_ALWAYS, BAD_COND);
14049 inst.instruction |= (inst.operands[3].imm & 0xf) << 18;
14050 break;
14051
f1c7f421
AV
14052 case T_MNEM_bfx:
14053 case T_MNEM_bflx:
14054 inst.instruction |= inst.operands[1].reg << 16;
14055 break;
14056
4389b29a
AV
14057 default: abort ();
14058 }
14059}
14060
60f993ce
AV
14061/* Helper function for do_t_loloop to handle relocations. */
14062static void
14063v8_1_loop_reloc (int is_le)
14064{
14065 if (inst.relocs[0].exp.X_op == O_constant)
14066 {
14067 int value = inst.relocs[0].exp.X_add_number;
14068 value = (is_le) ? -value : value;
14069
14070 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
14071 as_bad (BAD_BRANCH_OFF);
14072
14073 int imml, immh;
14074
14075 immh = (value & 0x00000ffc) >> 2;
14076 imml = (value & 0x00000002) >> 1;
14077
14078 inst.instruction |= (imml << 11) | (immh << 1);
14079 }
14080 else
14081 {
14082 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_LOOP12;
14083 inst.relocs[0].pc_rel = 1;
14084 }
14085}
14086
14087/* To handle the Scalar Low Overhead Loop instructions
14088 in Armv8.1-M Mainline. */
14089static void
14090do_t_loloop (void)
14091{
14092 unsigned long insn = inst.instruction;
14093
5ee91343 14094 set_pred_insn_type (OUTSIDE_PRED_INSN);
60f993ce
AV
14095 inst.instruction = THUMB_OP32 (inst.instruction);
14096
14097 switch (insn)
14098 {
14099 case T_MNEM_le:
14100 /* le <label>. */
14101 if (!inst.operands[0].present)
14102 inst.instruction |= 1 << 21;
14103
14104 v8_1_loop_reloc (TRUE);
14105 break;
14106
14107 case T_MNEM_wls:
14108 v8_1_loop_reloc (FALSE);
14109 /* Fall through. */
14110 case T_MNEM_dls:
14111 constraint (inst.operands[1].isreg != 1, BAD_ARGS);
14112 inst.instruction |= (inst.operands[1].reg << 16);
14113 break;
14114
14115 default: abort();
14116 }
14117}
14118
a302e574
AV
14119/* MVE instruction encoder helpers. */
14120#define M_MNEM_vabav 0xee800f01
14121#define M_MNEM_vmladav 0xeef00e00
14122#define M_MNEM_vmladava 0xeef00e20
14123#define M_MNEM_vmladavx 0xeef01e00
14124#define M_MNEM_vmladavax 0xeef01e20
14125#define M_MNEM_vmlsdav 0xeef00e01
14126#define M_MNEM_vmlsdava 0xeef00e21
14127#define M_MNEM_vmlsdavx 0xeef01e01
14128#define M_MNEM_vmlsdavax 0xeef01e21
886e1c73
AV
14129#define M_MNEM_vmullt 0xee011e00
14130#define M_MNEM_vmullb 0xee010e00
35c228db
AV
14131#define M_MNEM_vst20 0xfc801e00
14132#define M_MNEM_vst21 0xfc801e20
14133#define M_MNEM_vst40 0xfc801e01
14134#define M_MNEM_vst41 0xfc801e21
14135#define M_MNEM_vst42 0xfc801e41
14136#define M_MNEM_vst43 0xfc801e61
14137#define M_MNEM_vld20 0xfc901e00
14138#define M_MNEM_vld21 0xfc901e20
14139#define M_MNEM_vld40 0xfc901e01
14140#define M_MNEM_vld41 0xfc901e21
14141#define M_MNEM_vld42 0xfc901e41
14142#define M_MNEM_vld43 0xfc901e61
f5f10c66
AV
14143#define M_MNEM_vstrb 0xec000e00
14144#define M_MNEM_vstrh 0xec000e10
14145#define M_MNEM_vstrw 0xec000e40
14146#define M_MNEM_vstrd 0xec000e50
14147#define M_MNEM_vldrb 0xec100e00
14148#define M_MNEM_vldrh 0xec100e10
14149#define M_MNEM_vldrw 0xec100e40
14150#define M_MNEM_vldrd 0xec100e50
57785aa2
AV
14151#define M_MNEM_vmovlt 0xeea01f40
14152#define M_MNEM_vmovlb 0xeea00f40
14153#define M_MNEM_vmovnt 0xfe311e81
14154#define M_MNEM_vmovnb 0xfe310e81
c2dafc2a
AV
14155#define M_MNEM_vadc 0xee300f00
14156#define M_MNEM_vadci 0xee301f00
14157#define M_MNEM_vbrsr 0xfe011e60
26c1e780
AV
14158#define M_MNEM_vaddlv 0xee890f00
14159#define M_MNEM_vaddlva 0xee890f20
14160#define M_MNEM_vaddv 0xeef10f00
14161#define M_MNEM_vaddva 0xeef10f20
b409bdb6
AV
14162#define M_MNEM_vddup 0xee011f6e
14163#define M_MNEM_vdwdup 0xee011f60
14164#define M_MNEM_vidup 0xee010f6e
14165#define M_MNEM_viwdup 0xee010f60
13ccd4c0
AV
14166#define M_MNEM_vmaxv 0xeee20f00
14167#define M_MNEM_vmaxav 0xeee00f00
14168#define M_MNEM_vminv 0xeee20f80
14169#define M_MNEM_vminav 0xeee00f80
93925576
AV
14170#define M_MNEM_vmlaldav 0xee800e00
14171#define M_MNEM_vmlaldava 0xee800e20
14172#define M_MNEM_vmlaldavx 0xee801e00
14173#define M_MNEM_vmlaldavax 0xee801e20
14174#define M_MNEM_vmlsldav 0xee800e01
14175#define M_MNEM_vmlsldava 0xee800e21
14176#define M_MNEM_vmlsldavx 0xee801e01
14177#define M_MNEM_vmlsldavax 0xee801e21
14178#define M_MNEM_vrmlaldavhx 0xee801f00
14179#define M_MNEM_vrmlaldavhax 0xee801f20
14180#define M_MNEM_vrmlsldavh 0xfe800e01
14181#define M_MNEM_vrmlsldavha 0xfe800e21
14182#define M_MNEM_vrmlsldavhx 0xfe801e01
14183#define M_MNEM_vrmlsldavhax 0xfe801e21
a302e574 14184
5287ad62 14185/* Neon instruction encoder helpers. */
5f4273c7 14186
5287ad62 14187/* Encodings for the different types for various Neon opcodes. */
b99bd4ef 14188
5287ad62
JB
14189/* An "invalid" code for the following tables. */
14190#define N_INV -1u
14191
14192struct neon_tab_entry
b99bd4ef 14193{
5287ad62
JB
14194 unsigned integer;
14195 unsigned float_or_poly;
14196 unsigned scalar_or_imm;
14197};
5f4273c7 14198
5287ad62
JB
14199/* Map overloaded Neon opcodes to their respective encodings. */
14200#define NEON_ENC_TAB \
14201 X(vabd, 0x0000700, 0x1200d00, N_INV), \
5ee91343 14202 X(vabdl, 0x0800700, N_INV, N_INV), \
5287ad62
JB
14203 X(vmax, 0x0000600, 0x0000f00, N_INV), \
14204 X(vmin, 0x0000610, 0x0200f00, N_INV), \
14205 X(vpadd, 0x0000b10, 0x1000d00, N_INV), \
14206 X(vpmax, 0x0000a00, 0x1000f00, N_INV), \
14207 X(vpmin, 0x0000a10, 0x1200f00, N_INV), \
14208 X(vadd, 0x0000800, 0x0000d00, N_INV), \
5ee91343 14209 X(vaddl, 0x0800000, N_INV, N_INV), \
5287ad62 14210 X(vsub, 0x1000800, 0x0200d00, N_INV), \
5ee91343 14211 X(vsubl, 0x0800200, N_INV, N_INV), \
5287ad62
JB
14212 X(vceq, 0x1000810, 0x0000e00, 0x1b10100), \
14213 X(vcge, 0x0000310, 0x1000e00, 0x1b10080), \
14214 X(vcgt, 0x0000300, 0x1200e00, 0x1b10000), \
14215 /* Register variants of the following two instructions are encoded as
e07e6e58 14216 vcge / vcgt with the operands reversed. */ \
92559b5b
PB
14217 X(vclt, 0x0000300, 0x1200e00, 0x1b10200), \
14218 X(vcle, 0x0000310, 0x1000e00, 0x1b10180), \
62f3b8c8
PB
14219 X(vfma, N_INV, 0x0000c10, N_INV), \
14220 X(vfms, N_INV, 0x0200c10, N_INV), \
5287ad62
JB
14221 X(vmla, 0x0000900, 0x0000d10, 0x0800040), \
14222 X(vmls, 0x1000900, 0x0200d10, 0x0800440), \
14223 X(vmul, 0x0000910, 0x1000d10, 0x0800840), \
14224 X(vmull, 0x0800c00, 0x0800e00, 0x0800a40), /* polynomial not float. */ \
14225 X(vmlal, 0x0800800, N_INV, 0x0800240), \
14226 X(vmlsl, 0x0800a00, N_INV, 0x0800640), \
14227 X(vqdmlal, 0x0800900, N_INV, 0x0800340), \
14228 X(vqdmlsl, 0x0800b00, N_INV, 0x0800740), \
14229 X(vqdmull, 0x0800d00, N_INV, 0x0800b40), \
14230 X(vqdmulh, 0x0000b00, N_INV, 0x0800c40), \
14231 X(vqrdmulh, 0x1000b00, N_INV, 0x0800d40), \
d6b4b13e
MW
14232 X(vqrdmlah, 0x3000b10, N_INV, 0x0800e40), \
14233 X(vqrdmlsh, 0x3000c10, N_INV, 0x0800f40), \
5287ad62
JB
14234 X(vshl, 0x0000400, N_INV, 0x0800510), \
14235 X(vqshl, 0x0000410, N_INV, 0x0800710), \
14236 X(vand, 0x0000110, N_INV, 0x0800030), \
14237 X(vbic, 0x0100110, N_INV, 0x0800030), \
14238 X(veor, 0x1000110, N_INV, N_INV), \
14239 X(vorn, 0x0300110, N_INV, 0x0800010), \
14240 X(vorr, 0x0200110, N_INV, 0x0800010), \
14241 X(vmvn, 0x1b00580, N_INV, 0x0800030), \
14242 X(vshll, 0x1b20300, N_INV, 0x0800a10), /* max shift, immediate. */ \
14243 X(vcvt, 0x1b30600, N_INV, 0x0800e10), /* integer, fixed-point. */ \
14244 X(vdup, 0xe800b10, N_INV, 0x1b00c00), /* arm, scalar. */ \
14245 X(vld1, 0x0200000, 0x0a00000, 0x0a00c00), /* interlv, lane, dup. */ \
14246 X(vst1, 0x0000000, 0x0800000, N_INV), \
14247 X(vld2, 0x0200100, 0x0a00100, 0x0a00d00), \
14248 X(vst2, 0x0000100, 0x0800100, N_INV), \
14249 X(vld3, 0x0200200, 0x0a00200, 0x0a00e00), \
14250 X(vst3, 0x0000200, 0x0800200, N_INV), \
14251 X(vld4, 0x0200300, 0x0a00300, 0x0a00f00), \
14252 X(vst4, 0x0000300, 0x0800300, N_INV), \
14253 X(vmovn, 0x1b20200, N_INV, N_INV), \
14254 X(vtrn, 0x1b20080, N_INV, N_INV), \
14255 X(vqmovn, 0x1b20200, N_INV, N_INV), \
037e8744
JB
14256 X(vqmovun, 0x1b20240, N_INV, N_INV), \
14257 X(vnmul, 0xe200a40, 0xe200b40, N_INV), \
e6655fda
PB
14258 X(vnmla, 0xe100a40, 0xe100b40, N_INV), \
14259 X(vnmls, 0xe100a00, 0xe100b00, N_INV), \
62f3b8c8
PB
14260 X(vfnma, 0xe900a40, 0xe900b40, N_INV), \
14261 X(vfnms, 0xe900a00, 0xe900b00, N_INV), \
037e8744
JB
14262 X(vcmp, 0xeb40a40, 0xeb40b40, N_INV), \
14263 X(vcmpz, 0xeb50a40, 0xeb50b40, N_INV), \
14264 X(vcmpe, 0xeb40ac0, 0xeb40bc0, N_INV), \
33399f07
MGD
14265 X(vcmpez, 0xeb50ac0, 0xeb50bc0, N_INV), \
14266 X(vseleq, 0xe000a00, N_INV, N_INV), \
14267 X(vselvs, 0xe100a00, N_INV, N_INV), \
14268 X(vselge, 0xe200a00, N_INV, N_INV), \
73924fbc
MGD
14269 X(vselgt, 0xe300a00, N_INV, N_INV), \
14270 X(vmaxnm, 0xe800a00, 0x3000f10, N_INV), \
7e8e6784 14271 X(vminnm, 0xe800a40, 0x3200f10, N_INV), \
30bdf752
MGD
14272 X(vcvta, 0xebc0a40, 0x3bb0000, N_INV), \
14273 X(vrintr, 0xeb60a40, 0x3ba0400, N_INV), \
91ff7894 14274 X(vrinta, 0xeb80a40, 0x3ba0400, N_INV), \
48adcd8e 14275 X(aes, 0x3b00300, N_INV, N_INV), \
3c9017d2
MGD
14276 X(sha3op, 0x2000c00, N_INV, N_INV), \
14277 X(sha1h, 0x3b902c0, N_INV, N_INV), \
14278 X(sha2op, 0x3ba0380, N_INV, N_INV)
5287ad62
JB
14279
14280enum neon_opc
14281{
14282#define X(OPC,I,F,S) N_MNEM_##OPC
14283NEON_ENC_TAB
14284#undef X
14285};
b99bd4ef 14286
5287ad62
JB
14287static const struct neon_tab_entry neon_enc_tab[] =
14288{
14289#define X(OPC,I,F,S) { (I), (F), (S) }
14290NEON_ENC_TAB
14291#undef X
14292};
b99bd4ef 14293
88714cb8
DG
14294/* Do not use these macros; instead, use NEON_ENCODE defined below. */
14295#define NEON_ENC_INTEGER_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14296#define NEON_ENC_ARMREG_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14297#define NEON_ENC_POLY_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14298#define NEON_ENC_FLOAT_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14299#define NEON_ENC_SCALAR_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14300#define NEON_ENC_IMMED_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14301#define NEON_ENC_INTERLV_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
14302#define NEON_ENC_LANE_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
14303#define NEON_ENC_DUP_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
14304#define NEON_ENC_SINGLE_(X) \
037e8744 14305 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf0000000))
88714cb8 14306#define NEON_ENC_DOUBLE_(X) \
037e8744 14307 ((neon_enc_tab[(X) & 0x0fffffff].float_or_poly) | ((X) & 0xf0000000))
33399f07
MGD
14308#define NEON_ENC_FPV8_(X) \
14309 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf000000))
5287ad62 14310
88714cb8
DG
14311#define NEON_ENCODE(type, inst) \
14312 do \
14313 { \
14314 inst.instruction = NEON_ENC_##type##_ (inst.instruction); \
14315 inst.is_neon = 1; \
14316 } \
14317 while (0)
14318
14319#define check_neon_suffixes \
14320 do \
14321 { \
14322 if (!inst.error && inst.vectype.elems > 0 && !inst.is_neon) \
14323 { \
14324 as_bad (_("invalid neon suffix for non neon instruction")); \
14325 return; \
14326 } \
14327 } \
14328 while (0)
14329
037e8744
JB
14330/* Define shapes for instruction operands. The following mnemonic characters
14331 are used in this table:
5287ad62 14332
037e8744 14333 F - VFP S<n> register
5287ad62
JB
14334 D - Neon D<n> register
14335 Q - Neon Q<n> register
14336 I - Immediate
14337 S - Scalar
14338 R - ARM register
14339 L - D<n> register list
5f4273c7 14340
037e8744
JB
14341 This table is used to generate various data:
14342 - enumerations of the form NS_DDR to be used as arguments to
14343 neon_select_shape.
14344 - a table classifying shapes into single, double, quad, mixed.
5f4273c7 14345 - a table used to drive neon_select_shape. */
b99bd4ef 14346
037e8744 14347#define NEON_SHAPE_DEF \
93925576 14348 X(4, (R, R, Q, Q), QUAD), \
b409bdb6 14349 X(4, (Q, R, R, I), QUAD), \
57785aa2
AV
14350 X(4, (R, R, S, S), QUAD), \
14351 X(4, (S, S, R, R), QUAD), \
b409bdb6 14352 X(3, (Q, R, I), QUAD), \
1b883319
AV
14353 X(3, (I, Q, Q), QUAD), \
14354 X(3, (I, Q, R), QUAD), \
a302e574 14355 X(3, (R, Q, Q), QUAD), \
037e8744
JB
14356 X(3, (D, D, D), DOUBLE), \
14357 X(3, (Q, Q, Q), QUAD), \
14358 X(3, (D, D, I), DOUBLE), \
14359 X(3, (Q, Q, I), QUAD), \
14360 X(3, (D, D, S), DOUBLE), \
14361 X(3, (Q, Q, S), QUAD), \
5ee91343 14362 X(3, (Q, Q, R), QUAD), \
26c1e780
AV
14363 X(3, (R, R, Q), QUAD), \
14364 X(2, (R, Q), QUAD), \
037e8744
JB
14365 X(2, (D, D), DOUBLE), \
14366 X(2, (Q, Q), QUAD), \
14367 X(2, (D, S), DOUBLE), \
14368 X(2, (Q, S), QUAD), \
14369 X(2, (D, R), DOUBLE), \
14370 X(2, (Q, R), QUAD), \
14371 X(2, (D, I), DOUBLE), \
14372 X(2, (Q, I), QUAD), \
14373 X(3, (D, L, D), DOUBLE), \
14374 X(2, (D, Q), MIXED), \
14375 X(2, (Q, D), MIXED), \
14376 X(3, (D, Q, I), MIXED), \
14377 X(3, (Q, D, I), MIXED), \
14378 X(3, (Q, D, D), MIXED), \
14379 X(3, (D, Q, Q), MIXED), \
14380 X(3, (Q, Q, D), MIXED), \
14381 X(3, (Q, D, S), MIXED), \
14382 X(3, (D, Q, S), MIXED), \
14383 X(4, (D, D, D, I), DOUBLE), \
14384 X(4, (Q, Q, Q, I), QUAD), \
c28eeff2
SN
14385 X(4, (D, D, S, I), DOUBLE), \
14386 X(4, (Q, Q, S, I), QUAD), \
037e8744
JB
14387 X(2, (F, F), SINGLE), \
14388 X(3, (F, F, F), SINGLE), \
14389 X(2, (F, I), SINGLE), \
14390 X(2, (F, D), MIXED), \
14391 X(2, (D, F), MIXED), \
14392 X(3, (F, F, I), MIXED), \
14393 X(4, (R, R, F, F), SINGLE), \
14394 X(4, (F, F, R, R), SINGLE), \
14395 X(3, (D, R, R), DOUBLE), \
14396 X(3, (R, R, D), DOUBLE), \
14397 X(2, (S, R), SINGLE), \
14398 X(2, (R, S), SINGLE), \
14399 X(2, (F, R), SINGLE), \
d54af2d0
RL
14400 X(2, (R, F), SINGLE), \
14401/* Half float shape supported so far. */\
14402 X (2, (H, D), MIXED), \
14403 X (2, (D, H), MIXED), \
14404 X (2, (H, F), MIXED), \
14405 X (2, (F, H), MIXED), \
14406 X (2, (H, H), HALF), \
14407 X (2, (H, R), HALF), \
14408 X (2, (R, H), HALF), \
14409 X (2, (H, I), HALF), \
14410 X (3, (H, H, H), HALF), \
14411 X (3, (H, F, I), MIXED), \
dec41383
JW
14412 X (3, (F, H, I), MIXED), \
14413 X (3, (D, H, H), MIXED), \
14414 X (3, (D, H, S), MIXED)
037e8744
JB
14415
14416#define S2(A,B) NS_##A##B
14417#define S3(A,B,C) NS_##A##B##C
14418#define S4(A,B,C,D) NS_##A##B##C##D
14419
14420#define X(N, L, C) S##N L
14421
5287ad62
JB
14422enum neon_shape
14423{
037e8744
JB
14424 NEON_SHAPE_DEF,
14425 NS_NULL
5287ad62 14426};
b99bd4ef 14427
037e8744
JB
14428#undef X
14429#undef S2
14430#undef S3
14431#undef S4
14432
14433enum neon_shape_class
14434{
d54af2d0 14435 SC_HALF,
037e8744
JB
14436 SC_SINGLE,
14437 SC_DOUBLE,
14438 SC_QUAD,
14439 SC_MIXED
14440};
14441
14442#define X(N, L, C) SC_##C
14443
14444static enum neon_shape_class neon_shape_class[] =
14445{
14446 NEON_SHAPE_DEF
14447};
14448
14449#undef X
14450
14451enum neon_shape_el
14452{
d54af2d0 14453 SE_H,
037e8744
JB
14454 SE_F,
14455 SE_D,
14456 SE_Q,
14457 SE_I,
14458 SE_S,
14459 SE_R,
14460 SE_L
14461};
14462
14463/* Register widths of above. */
14464static unsigned neon_shape_el_size[] =
14465{
d54af2d0 14466 16,
037e8744
JB
14467 32,
14468 64,
14469 128,
14470 0,
14471 32,
14472 32,
14473 0
14474};
14475
14476struct neon_shape_info
14477{
14478 unsigned els;
14479 enum neon_shape_el el[NEON_MAX_TYPE_ELS];
14480};
14481
14482#define S2(A,B) { SE_##A, SE_##B }
14483#define S3(A,B,C) { SE_##A, SE_##B, SE_##C }
14484#define S4(A,B,C,D) { SE_##A, SE_##B, SE_##C, SE_##D }
14485
14486#define X(N, L, C) { N, S##N L }
14487
14488static struct neon_shape_info neon_shape_tab[] =
14489{
14490 NEON_SHAPE_DEF
14491};
14492
14493#undef X
14494#undef S2
14495#undef S3
14496#undef S4
14497
5287ad62
JB
14498/* Bit masks used in type checking given instructions.
14499 'N_EQK' means the type must be the same as (or based on in some way) the key
14500 type, which itself is marked with the 'N_KEY' bit. If the 'N_EQK' bit is
14501 set, various other bits can be set as well in order to modify the meaning of
14502 the type constraint. */
14503
14504enum neon_type_mask
14505{
8e79c3df
CM
14506 N_S8 = 0x0000001,
14507 N_S16 = 0x0000002,
14508 N_S32 = 0x0000004,
14509 N_S64 = 0x0000008,
14510 N_U8 = 0x0000010,
14511 N_U16 = 0x0000020,
14512 N_U32 = 0x0000040,
14513 N_U64 = 0x0000080,
14514 N_I8 = 0x0000100,
14515 N_I16 = 0x0000200,
14516 N_I32 = 0x0000400,
14517 N_I64 = 0x0000800,
14518 N_8 = 0x0001000,
14519 N_16 = 0x0002000,
14520 N_32 = 0x0004000,
14521 N_64 = 0x0008000,
14522 N_P8 = 0x0010000,
14523 N_P16 = 0x0020000,
14524 N_F16 = 0x0040000,
14525 N_F32 = 0x0080000,
14526 N_F64 = 0x0100000,
4f51b4bd 14527 N_P64 = 0x0200000,
c921be7d
NC
14528 N_KEY = 0x1000000, /* Key element (main type specifier). */
14529 N_EQK = 0x2000000, /* Given operand has the same type & size as the key. */
8e79c3df 14530 N_VFP = 0x4000000, /* VFP mode: operand size must match register width. */
91ff7894 14531 N_UNT = 0x8000000, /* Must be explicitly untyped. */
c921be7d
NC
14532 N_DBL = 0x0000001, /* If N_EQK, this operand is twice the size. */
14533 N_HLF = 0x0000002, /* If N_EQK, this operand is half the size. */
14534 N_SGN = 0x0000004, /* If N_EQK, this operand is forced to be signed. */
14535 N_UNS = 0x0000008, /* If N_EQK, this operand is forced to be unsigned. */
14536 N_INT = 0x0000010, /* If N_EQK, this operand is forced to be integer. */
14537 N_FLT = 0x0000020, /* If N_EQK, this operand is forced to be float. */
14538 N_SIZ = 0x0000040, /* If N_EQK, this operand is forced to be size-only. */
5287ad62 14539 N_UTYP = 0,
4f51b4bd 14540 N_MAX_NONSPECIAL = N_P64
5287ad62
JB
14541};
14542
dcbf9037
JB
14543#define N_ALLMODS (N_DBL | N_HLF | N_SGN | N_UNS | N_INT | N_FLT | N_SIZ)
14544
5287ad62
JB
14545#define N_SU_ALL (N_S8 | N_S16 | N_S32 | N_S64 | N_U8 | N_U16 | N_U32 | N_U64)
14546#define N_SU_32 (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
14547#define N_SU_16_64 (N_S16 | N_S32 | N_S64 | N_U16 | N_U32 | N_U64)
cc933301
JW
14548#define N_S_32 (N_S8 | N_S16 | N_S32)
14549#define N_F_16_32 (N_F16 | N_F32)
14550#define N_SUF_32 (N_SU_32 | N_F_16_32)
5287ad62 14551#define N_I_ALL (N_I8 | N_I16 | N_I32 | N_I64)
cc933301 14552#define N_IF_32 (N_I8 | N_I16 | N_I32 | N_F16 | N_F32)
d54af2d0 14553#define N_F_ALL (N_F16 | N_F32 | N_F64)
5ee91343
AV
14554#define N_I_MVE (N_I8 | N_I16 | N_I32)
14555#define N_F_MVE (N_F16 | N_F32)
14556#define N_SU_MVE (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
5287ad62
JB
14557
14558/* Pass this as the first type argument to neon_check_type to ignore types
14559 altogether. */
14560#define N_IGNORE_TYPE (N_KEY | N_EQK)
14561
037e8744
JB
14562/* Select a "shape" for the current instruction (describing register types or
14563 sizes) from a list of alternatives. Return NS_NULL if the current instruction
14564 doesn't fit. For non-polymorphic shapes, checking is usually done as a
14565 function of operand parsing, so this function doesn't need to be called.
14566 Shapes should be listed in order of decreasing length. */
5287ad62
JB
14567
14568static enum neon_shape
037e8744 14569neon_select_shape (enum neon_shape shape, ...)
5287ad62 14570{
037e8744
JB
14571 va_list ap;
14572 enum neon_shape first_shape = shape;
5287ad62
JB
14573
14574 /* Fix missing optional operands. FIXME: we don't know at this point how
14575 many arguments we should have, so this makes the assumption that we have
14576 > 1. This is true of all current Neon opcodes, I think, but may not be
14577 true in the future. */
14578 if (!inst.operands[1].present)
14579 inst.operands[1] = inst.operands[0];
14580
037e8744 14581 va_start (ap, shape);
5f4273c7 14582
21d799b5 14583 for (; shape != NS_NULL; shape = (enum neon_shape) va_arg (ap, int))
037e8744
JB
14584 {
14585 unsigned j;
14586 int matches = 1;
14587
14588 for (j = 0; j < neon_shape_tab[shape].els; j++)
477330fc
RM
14589 {
14590 if (!inst.operands[j].present)
14591 {
14592 matches = 0;
14593 break;
14594 }
14595
14596 switch (neon_shape_tab[shape].el[j])
14597 {
d54af2d0
RL
14598 /* If a .f16, .16, .u16, .s16 type specifier is given over
14599 a VFP single precision register operand, it's essentially
14600 means only half of the register is used.
14601
14602 If the type specifier is given after the mnemonics, the
14603 information is stored in inst.vectype. If the type specifier
14604 is given after register operand, the information is stored
14605 in inst.operands[].vectype.
14606
14607 When there is only one type specifier, and all the register
14608 operands are the same type of hardware register, the type
14609 specifier applies to all register operands.
14610
14611 If no type specifier is given, the shape is inferred from
14612 operand information.
14613
14614 for example:
14615 vadd.f16 s0, s1, s2: NS_HHH
14616 vabs.f16 s0, s1: NS_HH
14617 vmov.f16 s0, r1: NS_HR
14618 vmov.f16 r0, s1: NS_RH
14619 vcvt.f16 r0, s1: NS_RH
14620 vcvt.f16.s32 s2, s2, #29: NS_HFI
14621 vcvt.f16.s32 s2, s2: NS_HF
14622 */
14623 case SE_H:
14624 if (!(inst.operands[j].isreg
14625 && inst.operands[j].isvec
14626 && inst.operands[j].issingle
14627 && !inst.operands[j].isquad
14628 && ((inst.vectype.elems == 1
14629 && inst.vectype.el[0].size == 16)
14630 || (inst.vectype.elems > 1
14631 && inst.vectype.el[j].size == 16)
14632 || (inst.vectype.elems == 0
14633 && inst.operands[j].vectype.type != NT_invtype
14634 && inst.operands[j].vectype.size == 16))))
14635 matches = 0;
14636 break;
14637
477330fc
RM
14638 case SE_F:
14639 if (!(inst.operands[j].isreg
14640 && inst.operands[j].isvec
14641 && inst.operands[j].issingle
d54af2d0
RL
14642 && !inst.operands[j].isquad
14643 && ((inst.vectype.elems == 1 && inst.vectype.el[0].size == 32)
14644 || (inst.vectype.elems > 1 && inst.vectype.el[j].size == 32)
14645 || (inst.vectype.elems == 0
14646 && (inst.operands[j].vectype.size == 32
14647 || inst.operands[j].vectype.type == NT_invtype)))))
477330fc
RM
14648 matches = 0;
14649 break;
14650
14651 case SE_D:
14652 if (!(inst.operands[j].isreg
14653 && inst.operands[j].isvec
14654 && !inst.operands[j].isquad
14655 && !inst.operands[j].issingle))
14656 matches = 0;
14657 break;
14658
14659 case SE_R:
14660 if (!(inst.operands[j].isreg
14661 && !inst.operands[j].isvec))
14662 matches = 0;
14663 break;
14664
14665 case SE_Q:
14666 if (!(inst.operands[j].isreg
14667 && inst.operands[j].isvec
14668 && inst.operands[j].isquad
14669 && !inst.operands[j].issingle))
14670 matches = 0;
14671 break;
14672
14673 case SE_I:
14674 if (!(!inst.operands[j].isreg
14675 && !inst.operands[j].isscalar))
14676 matches = 0;
14677 break;
14678
14679 case SE_S:
14680 if (!(!inst.operands[j].isreg
14681 && inst.operands[j].isscalar))
14682 matches = 0;
14683 break;
14684
14685 case SE_L:
14686 break;
14687 }
3fde54a2
JZ
14688 if (!matches)
14689 break;
477330fc 14690 }
ad6cec43
MGD
14691 if (matches && (j >= ARM_IT_MAX_OPERANDS || !inst.operands[j].present))
14692 /* We've matched all the entries in the shape table, and we don't
14693 have any left over operands which have not been matched. */
477330fc 14694 break;
037e8744 14695 }
5f4273c7 14696
037e8744 14697 va_end (ap);
5287ad62 14698
037e8744
JB
14699 if (shape == NS_NULL && first_shape != NS_NULL)
14700 first_error (_("invalid instruction shape"));
5287ad62 14701
037e8744
JB
14702 return shape;
14703}
5287ad62 14704
037e8744
JB
14705/* True if SHAPE is predominantly a quadword operation (most of the time, this
14706 means the Q bit should be set). */
14707
14708static int
14709neon_quad (enum neon_shape shape)
14710{
14711 return neon_shape_class[shape] == SC_QUAD;
5287ad62 14712}
037e8744 14713
5287ad62
JB
14714static void
14715neon_modify_type_size (unsigned typebits, enum neon_el_type *g_type,
477330fc 14716 unsigned *g_size)
5287ad62
JB
14717{
14718 /* Allow modification to be made to types which are constrained to be
14719 based on the key element, based on bits set alongside N_EQK. */
14720 if ((typebits & N_EQK) != 0)
14721 {
14722 if ((typebits & N_HLF) != 0)
14723 *g_size /= 2;
14724 else if ((typebits & N_DBL) != 0)
14725 *g_size *= 2;
14726 if ((typebits & N_SGN) != 0)
14727 *g_type = NT_signed;
14728 else if ((typebits & N_UNS) != 0)
477330fc 14729 *g_type = NT_unsigned;
5287ad62 14730 else if ((typebits & N_INT) != 0)
477330fc 14731 *g_type = NT_integer;
5287ad62 14732 else if ((typebits & N_FLT) != 0)
477330fc 14733 *g_type = NT_float;
dcbf9037 14734 else if ((typebits & N_SIZ) != 0)
477330fc 14735 *g_type = NT_untyped;
5287ad62
JB
14736 }
14737}
5f4273c7 14738
5287ad62
JB
14739/* Return operand OPNO promoted by bits set in THISARG. KEY should be the "key"
14740 operand type, i.e. the single type specified in a Neon instruction when it
14741 is the only one given. */
14742
14743static struct neon_type_el
14744neon_type_promote (struct neon_type_el *key, unsigned thisarg)
14745{
14746 struct neon_type_el dest = *key;
5f4273c7 14747
9c2799c2 14748 gas_assert ((thisarg & N_EQK) != 0);
5f4273c7 14749
5287ad62
JB
14750 neon_modify_type_size (thisarg, &dest.type, &dest.size);
14751
14752 return dest;
14753}
14754
14755/* Convert Neon type and size into compact bitmask representation. */
14756
14757static enum neon_type_mask
14758type_chk_of_el_type (enum neon_el_type type, unsigned size)
14759{
14760 switch (type)
14761 {
14762 case NT_untyped:
14763 switch (size)
477330fc
RM
14764 {
14765 case 8: return N_8;
14766 case 16: return N_16;
14767 case 32: return N_32;
14768 case 64: return N_64;
14769 default: ;
14770 }
5287ad62
JB
14771 break;
14772
14773 case NT_integer:
14774 switch (size)
477330fc
RM
14775 {
14776 case 8: return N_I8;
14777 case 16: return N_I16;
14778 case 32: return N_I32;
14779 case 64: return N_I64;
14780 default: ;
14781 }
5287ad62
JB
14782 break;
14783
14784 case NT_float:
037e8744 14785 switch (size)
477330fc 14786 {
8e79c3df 14787 case 16: return N_F16;
477330fc
RM
14788 case 32: return N_F32;
14789 case 64: return N_F64;
14790 default: ;
14791 }
5287ad62
JB
14792 break;
14793
14794 case NT_poly:
14795 switch (size)
477330fc
RM
14796 {
14797 case 8: return N_P8;
14798 case 16: return N_P16;
4f51b4bd 14799 case 64: return N_P64;
477330fc
RM
14800 default: ;
14801 }
5287ad62
JB
14802 break;
14803
14804 case NT_signed:
14805 switch (size)
477330fc
RM
14806 {
14807 case 8: return N_S8;
14808 case 16: return N_S16;
14809 case 32: return N_S32;
14810 case 64: return N_S64;
14811 default: ;
14812 }
5287ad62
JB
14813 break;
14814
14815 case NT_unsigned:
14816 switch (size)
477330fc
RM
14817 {
14818 case 8: return N_U8;
14819 case 16: return N_U16;
14820 case 32: return N_U32;
14821 case 64: return N_U64;
14822 default: ;
14823 }
5287ad62
JB
14824 break;
14825
14826 default: ;
14827 }
5f4273c7 14828
5287ad62
JB
14829 return N_UTYP;
14830}
14831
14832/* Convert compact Neon bitmask type representation to a type and size. Only
14833 handles the case where a single bit is set in the mask. */
14834
dcbf9037 14835static int
5287ad62 14836el_type_of_type_chk (enum neon_el_type *type, unsigned *size,
477330fc 14837 enum neon_type_mask mask)
5287ad62 14838{
dcbf9037
JB
14839 if ((mask & N_EQK) != 0)
14840 return FAIL;
14841
5287ad62
JB
14842 if ((mask & (N_S8 | N_U8 | N_I8 | N_8 | N_P8)) != 0)
14843 *size = 8;
c70a8987 14844 else if ((mask & (N_S16 | N_U16 | N_I16 | N_16 | N_F16 | N_P16)) != 0)
5287ad62 14845 *size = 16;
dcbf9037 14846 else if ((mask & (N_S32 | N_U32 | N_I32 | N_32 | N_F32)) != 0)
5287ad62 14847 *size = 32;
4f51b4bd 14848 else if ((mask & (N_S64 | N_U64 | N_I64 | N_64 | N_F64 | N_P64)) != 0)
5287ad62 14849 *size = 64;
dcbf9037
JB
14850 else
14851 return FAIL;
14852
5287ad62
JB
14853 if ((mask & (N_S8 | N_S16 | N_S32 | N_S64)) != 0)
14854 *type = NT_signed;
dcbf9037 14855 else if ((mask & (N_U8 | N_U16 | N_U32 | N_U64)) != 0)
5287ad62 14856 *type = NT_unsigned;
dcbf9037 14857 else if ((mask & (N_I8 | N_I16 | N_I32 | N_I64)) != 0)
5287ad62 14858 *type = NT_integer;
dcbf9037 14859 else if ((mask & (N_8 | N_16 | N_32 | N_64)) != 0)
5287ad62 14860 *type = NT_untyped;
4f51b4bd 14861 else if ((mask & (N_P8 | N_P16 | N_P64)) != 0)
5287ad62 14862 *type = NT_poly;
d54af2d0 14863 else if ((mask & (N_F_ALL)) != 0)
5287ad62 14864 *type = NT_float;
dcbf9037
JB
14865 else
14866 return FAIL;
5f4273c7 14867
dcbf9037 14868 return SUCCESS;
5287ad62
JB
14869}
14870
14871/* Modify a bitmask of allowed types. This is only needed for type
14872 relaxation. */
14873
14874static unsigned
14875modify_types_allowed (unsigned allowed, unsigned mods)
14876{
14877 unsigned size;
14878 enum neon_el_type type;
14879 unsigned destmask;
14880 int i;
5f4273c7 14881
5287ad62 14882 destmask = 0;
5f4273c7 14883
5287ad62
JB
14884 for (i = 1; i <= N_MAX_NONSPECIAL; i <<= 1)
14885 {
21d799b5 14886 if (el_type_of_type_chk (&type, &size,
477330fc
RM
14887 (enum neon_type_mask) (allowed & i)) == SUCCESS)
14888 {
14889 neon_modify_type_size (mods, &type, &size);
14890 destmask |= type_chk_of_el_type (type, size);
14891 }
5287ad62 14892 }
5f4273c7 14893
5287ad62
JB
14894 return destmask;
14895}
14896
14897/* Check type and return type classification.
14898 The manual states (paraphrase): If one datatype is given, it indicates the
14899 type given in:
14900 - the second operand, if there is one
14901 - the operand, if there is no second operand
14902 - the result, if there are no operands.
14903 This isn't quite good enough though, so we use a concept of a "key" datatype
14904 which is set on a per-instruction basis, which is the one which matters when
14905 only one data type is written.
14906 Note: this function has side-effects (e.g. filling in missing operands). All
037e8744 14907 Neon instructions should call it before performing bit encoding. */
5287ad62
JB
14908
14909static struct neon_type_el
14910neon_check_type (unsigned els, enum neon_shape ns, ...)
14911{
14912 va_list ap;
14913 unsigned i, pass, key_el = 0;
14914 unsigned types[NEON_MAX_TYPE_ELS];
14915 enum neon_el_type k_type = NT_invtype;
14916 unsigned k_size = -1u;
14917 struct neon_type_el badtype = {NT_invtype, -1};
14918 unsigned key_allowed = 0;
14919
14920 /* Optional registers in Neon instructions are always (not) in operand 1.
14921 Fill in the missing operand here, if it was omitted. */
14922 if (els > 1 && !inst.operands[1].present)
14923 inst.operands[1] = inst.operands[0];
14924
14925 /* Suck up all the varargs. */
14926 va_start (ap, ns);
14927 for (i = 0; i < els; i++)
14928 {
14929 unsigned thisarg = va_arg (ap, unsigned);
14930 if (thisarg == N_IGNORE_TYPE)
477330fc
RM
14931 {
14932 va_end (ap);
14933 return badtype;
14934 }
5287ad62
JB
14935 types[i] = thisarg;
14936 if ((thisarg & N_KEY) != 0)
477330fc 14937 key_el = i;
5287ad62
JB
14938 }
14939 va_end (ap);
14940
dcbf9037
JB
14941 if (inst.vectype.elems > 0)
14942 for (i = 0; i < els; i++)
14943 if (inst.operands[i].vectype.type != NT_invtype)
477330fc
RM
14944 {
14945 first_error (_("types specified in both the mnemonic and operands"));
14946 return badtype;
14947 }
dcbf9037 14948
5287ad62
JB
14949 /* Duplicate inst.vectype elements here as necessary.
14950 FIXME: No idea if this is exactly the same as the ARM assembler,
14951 particularly when an insn takes one register and one non-register
14952 operand. */
14953 if (inst.vectype.elems == 1 && els > 1)
14954 {
14955 unsigned j;
14956 inst.vectype.elems = els;
14957 inst.vectype.el[key_el] = inst.vectype.el[0];
14958 for (j = 0; j < els; j++)
477330fc
RM
14959 if (j != key_el)
14960 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14961 types[j]);
dcbf9037
JB
14962 }
14963 else if (inst.vectype.elems == 0 && els > 0)
14964 {
14965 unsigned j;
14966 /* No types were given after the mnemonic, so look for types specified
477330fc
RM
14967 after each operand. We allow some flexibility here; as long as the
14968 "key" operand has a type, we can infer the others. */
dcbf9037 14969 for (j = 0; j < els; j++)
477330fc
RM
14970 if (inst.operands[j].vectype.type != NT_invtype)
14971 inst.vectype.el[j] = inst.operands[j].vectype;
dcbf9037
JB
14972
14973 if (inst.operands[key_el].vectype.type != NT_invtype)
477330fc
RM
14974 {
14975 for (j = 0; j < els; j++)
14976 if (inst.operands[j].vectype.type == NT_invtype)
14977 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14978 types[j]);
14979 }
dcbf9037 14980 else
477330fc
RM
14981 {
14982 first_error (_("operand types can't be inferred"));
14983 return badtype;
14984 }
5287ad62
JB
14985 }
14986 else if (inst.vectype.elems != els)
14987 {
dcbf9037 14988 first_error (_("type specifier has the wrong number of parts"));
5287ad62
JB
14989 return badtype;
14990 }
14991
14992 for (pass = 0; pass < 2; pass++)
14993 {
14994 for (i = 0; i < els; i++)
477330fc
RM
14995 {
14996 unsigned thisarg = types[i];
14997 unsigned types_allowed = ((thisarg & N_EQK) != 0 && pass != 0)
14998 ? modify_types_allowed (key_allowed, thisarg) : thisarg;
14999 enum neon_el_type g_type = inst.vectype.el[i].type;
15000 unsigned g_size = inst.vectype.el[i].size;
15001
15002 /* Decay more-specific signed & unsigned types to sign-insensitive
5287ad62 15003 integer types if sign-specific variants are unavailable. */
477330fc 15004 if ((g_type == NT_signed || g_type == NT_unsigned)
5287ad62
JB
15005 && (types_allowed & N_SU_ALL) == 0)
15006 g_type = NT_integer;
15007
477330fc 15008 /* If only untyped args are allowed, decay any more specific types to
5287ad62
JB
15009 them. Some instructions only care about signs for some element
15010 sizes, so handle that properly. */
477330fc 15011 if (((types_allowed & N_UNT) == 0)
91ff7894
MGD
15012 && ((g_size == 8 && (types_allowed & N_8) != 0)
15013 || (g_size == 16 && (types_allowed & N_16) != 0)
15014 || (g_size == 32 && (types_allowed & N_32) != 0)
15015 || (g_size == 64 && (types_allowed & N_64) != 0)))
5287ad62
JB
15016 g_type = NT_untyped;
15017
477330fc
RM
15018 if (pass == 0)
15019 {
15020 if ((thisarg & N_KEY) != 0)
15021 {
15022 k_type = g_type;
15023 k_size = g_size;
15024 key_allowed = thisarg & ~N_KEY;
cc933301
JW
15025
15026 /* Check architecture constraint on FP16 extension. */
15027 if (k_size == 16
15028 && k_type == NT_float
15029 && ! ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15030 {
15031 inst.error = _(BAD_FP16);
15032 return badtype;
15033 }
477330fc
RM
15034 }
15035 }
15036 else
15037 {
15038 if ((thisarg & N_VFP) != 0)
15039 {
15040 enum neon_shape_el regshape;
15041 unsigned regwidth, match;
99b253c5
NC
15042
15043 /* PR 11136: Catch the case where we are passed a shape of NS_NULL. */
15044 if (ns == NS_NULL)
15045 {
15046 first_error (_("invalid instruction shape"));
15047 return badtype;
15048 }
477330fc
RM
15049 regshape = neon_shape_tab[ns].el[i];
15050 regwidth = neon_shape_el_size[regshape];
15051
15052 /* In VFP mode, operands must match register widths. If we
15053 have a key operand, use its width, else use the width of
15054 the current operand. */
15055 if (k_size != -1u)
15056 match = k_size;
15057 else
15058 match = g_size;
15059
9db2f6b4
RL
15060 /* FP16 will use a single precision register. */
15061 if (regwidth == 32 && match == 16)
15062 {
15063 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
15064 match = regwidth;
15065 else
15066 {
15067 inst.error = _(BAD_FP16);
15068 return badtype;
15069 }
15070 }
15071
477330fc
RM
15072 if (regwidth != match)
15073 {
15074 first_error (_("operand size must match register width"));
15075 return badtype;
15076 }
15077 }
15078
15079 if ((thisarg & N_EQK) == 0)
15080 {
15081 unsigned given_type = type_chk_of_el_type (g_type, g_size);
15082
15083 if ((given_type & types_allowed) == 0)
15084 {
a302e574 15085 first_error (BAD_SIMD_TYPE);
477330fc
RM
15086 return badtype;
15087 }
15088 }
15089 else
15090 {
15091 enum neon_el_type mod_k_type = k_type;
15092 unsigned mod_k_size = k_size;
15093 neon_modify_type_size (thisarg, &mod_k_type, &mod_k_size);
15094 if (g_type != mod_k_type || g_size != mod_k_size)
15095 {
15096 first_error (_("inconsistent types in Neon instruction"));
15097 return badtype;
15098 }
15099 }
15100 }
15101 }
5287ad62
JB
15102 }
15103
15104 return inst.vectype.el[key_el];
15105}
15106
037e8744 15107/* Neon-style VFP instruction forwarding. */
5287ad62 15108
037e8744
JB
15109/* Thumb VFP instructions have 0xE in the condition field. */
15110
15111static void
15112do_vfp_cond_or_thumb (void)
5287ad62 15113{
88714cb8
DG
15114 inst.is_neon = 1;
15115
5287ad62 15116 if (thumb_mode)
037e8744 15117 inst.instruction |= 0xe0000000;
5287ad62 15118 else
037e8744 15119 inst.instruction |= inst.cond << 28;
5287ad62
JB
15120}
15121
037e8744
JB
15122/* Look up and encode a simple mnemonic, for use as a helper function for the
15123 Neon-style VFP syntax. This avoids duplication of bits of the insns table,
15124 etc. It is assumed that operand parsing has already been done, and that the
15125 operands are in the form expected by the given opcode (this isn't necessarily
15126 the same as the form in which they were parsed, hence some massaging must
15127 take place before this function is called).
15128 Checks current arch version against that in the looked-up opcode. */
5287ad62 15129
037e8744
JB
15130static void
15131do_vfp_nsyn_opcode (const char *opname)
5287ad62 15132{
037e8744 15133 const struct asm_opcode *opcode;
5f4273c7 15134
21d799b5 15135 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, opname);
5287ad62 15136
037e8744
JB
15137 if (!opcode)
15138 abort ();
5287ad62 15139
037e8744 15140 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant,
477330fc
RM
15141 thumb_mode ? *opcode->tvariant : *opcode->avariant),
15142 _(BAD_FPU));
5287ad62 15143
88714cb8
DG
15144 inst.is_neon = 1;
15145
037e8744
JB
15146 if (thumb_mode)
15147 {
15148 inst.instruction = opcode->tvalue;
15149 opcode->tencode ();
15150 }
15151 else
15152 {
15153 inst.instruction = (inst.cond << 28) | opcode->avalue;
15154 opcode->aencode ();
15155 }
15156}
5287ad62
JB
15157
15158static void
037e8744 15159do_vfp_nsyn_add_sub (enum neon_shape rs)
5287ad62 15160{
037e8744
JB
15161 int is_add = (inst.instruction & 0x0fffffff) == N_MNEM_vadd;
15162
9db2f6b4 15163 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15164 {
15165 if (is_add)
477330fc 15166 do_vfp_nsyn_opcode ("fadds");
037e8744 15167 else
477330fc 15168 do_vfp_nsyn_opcode ("fsubs");
9db2f6b4
RL
15169
15170 /* ARMv8.2 fp16 instruction. */
15171 if (rs == NS_HHH)
15172 do_scalar_fp16_v82_encode ();
037e8744
JB
15173 }
15174 else
15175 {
15176 if (is_add)
477330fc 15177 do_vfp_nsyn_opcode ("faddd");
037e8744 15178 else
477330fc 15179 do_vfp_nsyn_opcode ("fsubd");
037e8744
JB
15180 }
15181}
15182
15183/* Check operand types to see if this is a VFP instruction, and if so call
15184 PFN (). */
15185
15186static int
15187try_vfp_nsyn (int args, void (*pfn) (enum neon_shape))
15188{
15189 enum neon_shape rs;
15190 struct neon_type_el et;
15191
15192 switch (args)
15193 {
15194 case 2:
9db2f6b4
RL
15195 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15196 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
037e8744 15197 break;
5f4273c7 15198
037e8744 15199 case 3:
9db2f6b4
RL
15200 rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
15201 et = neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
15202 N_F_ALL | N_KEY | N_VFP);
037e8744
JB
15203 break;
15204
15205 default:
15206 abort ();
15207 }
15208
15209 if (et.type != NT_invtype)
15210 {
15211 pfn (rs);
15212 return SUCCESS;
15213 }
037e8744 15214
99b253c5 15215 inst.error = NULL;
037e8744
JB
15216 return FAIL;
15217}
15218
15219static void
15220do_vfp_nsyn_mla_mls (enum neon_shape rs)
15221{
15222 int is_mla = (inst.instruction & 0x0fffffff) == N_MNEM_vmla;
5f4273c7 15223
9db2f6b4 15224 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
15225 {
15226 if (is_mla)
477330fc 15227 do_vfp_nsyn_opcode ("fmacs");
037e8744 15228 else
477330fc 15229 do_vfp_nsyn_opcode ("fnmacs");
9db2f6b4
RL
15230
15231 /* ARMv8.2 fp16 instruction. */
15232 if (rs == NS_HHH)
15233 do_scalar_fp16_v82_encode ();
037e8744
JB
15234 }
15235 else
15236 {
15237 if (is_mla)
477330fc 15238 do_vfp_nsyn_opcode ("fmacd");
037e8744 15239 else
477330fc 15240 do_vfp_nsyn_opcode ("fnmacd");
037e8744
JB
15241 }
15242}
15243
62f3b8c8
PB
15244static void
15245do_vfp_nsyn_fma_fms (enum neon_shape rs)
15246{
15247 int is_fma = (inst.instruction & 0x0fffffff) == N_MNEM_vfma;
15248
9db2f6b4 15249 if (rs == NS_FFF || rs == NS_HHH)
62f3b8c8
PB
15250 {
15251 if (is_fma)
477330fc 15252 do_vfp_nsyn_opcode ("ffmas");
62f3b8c8 15253 else
477330fc 15254 do_vfp_nsyn_opcode ("ffnmas");
9db2f6b4
RL
15255
15256 /* ARMv8.2 fp16 instruction. */
15257 if (rs == NS_HHH)
15258 do_scalar_fp16_v82_encode ();
62f3b8c8
PB
15259 }
15260 else
15261 {
15262 if (is_fma)
477330fc 15263 do_vfp_nsyn_opcode ("ffmad");
62f3b8c8 15264 else
477330fc 15265 do_vfp_nsyn_opcode ("ffnmad");
62f3b8c8
PB
15266 }
15267}
15268
037e8744
JB
15269static void
15270do_vfp_nsyn_mul (enum neon_shape rs)
15271{
9db2f6b4
RL
15272 if (rs == NS_FFF || rs == NS_HHH)
15273 {
15274 do_vfp_nsyn_opcode ("fmuls");
15275
15276 /* ARMv8.2 fp16 instruction. */
15277 if (rs == NS_HHH)
15278 do_scalar_fp16_v82_encode ();
15279 }
037e8744
JB
15280 else
15281 do_vfp_nsyn_opcode ("fmuld");
15282}
15283
15284static void
15285do_vfp_nsyn_abs_neg (enum neon_shape rs)
15286{
15287 int is_neg = (inst.instruction & 0x80) != 0;
9db2f6b4 15288 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_VFP | N_KEY);
037e8744 15289
9db2f6b4 15290 if (rs == NS_FF || rs == NS_HH)
037e8744
JB
15291 {
15292 if (is_neg)
477330fc 15293 do_vfp_nsyn_opcode ("fnegs");
037e8744 15294 else
477330fc 15295 do_vfp_nsyn_opcode ("fabss");
9db2f6b4
RL
15296
15297 /* ARMv8.2 fp16 instruction. */
15298 if (rs == NS_HH)
15299 do_scalar_fp16_v82_encode ();
037e8744
JB
15300 }
15301 else
15302 {
15303 if (is_neg)
477330fc 15304 do_vfp_nsyn_opcode ("fnegd");
037e8744 15305 else
477330fc 15306 do_vfp_nsyn_opcode ("fabsd");
037e8744
JB
15307 }
15308}
15309
15310/* Encode single-precision (only!) VFP fldm/fstm instructions. Double precision
15311 insns belong to Neon, and are handled elsewhere. */
15312
15313static void
15314do_vfp_nsyn_ldm_stm (int is_dbmode)
15315{
15316 int is_ldm = (inst.instruction & (1 << 20)) != 0;
15317 if (is_ldm)
15318 {
15319 if (is_dbmode)
477330fc 15320 do_vfp_nsyn_opcode ("fldmdbs");
037e8744 15321 else
477330fc 15322 do_vfp_nsyn_opcode ("fldmias");
037e8744
JB
15323 }
15324 else
15325 {
15326 if (is_dbmode)
477330fc 15327 do_vfp_nsyn_opcode ("fstmdbs");
037e8744 15328 else
477330fc 15329 do_vfp_nsyn_opcode ("fstmias");
037e8744
JB
15330 }
15331}
15332
037e8744
JB
15333static void
15334do_vfp_nsyn_sqrt (void)
15335{
9db2f6b4
RL
15336 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15337 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 15338
9db2f6b4
RL
15339 if (rs == NS_FF || rs == NS_HH)
15340 {
15341 do_vfp_nsyn_opcode ("fsqrts");
15342
15343 /* ARMv8.2 fp16 instruction. */
15344 if (rs == NS_HH)
15345 do_scalar_fp16_v82_encode ();
15346 }
037e8744
JB
15347 else
15348 do_vfp_nsyn_opcode ("fsqrtd");
15349}
15350
15351static void
15352do_vfp_nsyn_div (void)
15353{
9db2f6b4 15354 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15355 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15356 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15357
9db2f6b4
RL
15358 if (rs == NS_FFF || rs == NS_HHH)
15359 {
15360 do_vfp_nsyn_opcode ("fdivs");
15361
15362 /* ARMv8.2 fp16 instruction. */
15363 if (rs == NS_HHH)
15364 do_scalar_fp16_v82_encode ();
15365 }
037e8744
JB
15366 else
15367 do_vfp_nsyn_opcode ("fdivd");
15368}
15369
15370static void
15371do_vfp_nsyn_nmul (void)
15372{
9db2f6b4 15373 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 15374 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 15375 N_F_ALL | N_KEY | N_VFP);
5f4273c7 15376
9db2f6b4 15377 if (rs == NS_FFF || rs == NS_HHH)
037e8744 15378 {
88714cb8 15379 NEON_ENCODE (SINGLE, inst);
037e8744 15380 do_vfp_sp_dyadic ();
9db2f6b4
RL
15381
15382 /* ARMv8.2 fp16 instruction. */
15383 if (rs == NS_HHH)
15384 do_scalar_fp16_v82_encode ();
037e8744
JB
15385 }
15386 else
15387 {
88714cb8 15388 NEON_ENCODE (DOUBLE, inst);
037e8744
JB
15389 do_vfp_dp_rd_rn_rm ();
15390 }
15391 do_vfp_cond_or_thumb ();
9db2f6b4 15392
037e8744
JB
15393}
15394
1b883319
AV
15395/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
15396 (0, 1, 2, 3). */
15397
15398static unsigned
15399neon_logbits (unsigned x)
15400{
15401 return ffs (x) - 4;
15402}
15403
15404#define LOW4(R) ((R) & 0xf)
15405#define HI1(R) (((R) >> 4) & 1)
15406
15407static unsigned
15408mve_get_vcmp_vpt_cond (struct neon_type_el et)
15409{
15410 switch (et.type)
15411 {
15412 default:
15413 first_error (BAD_EL_TYPE);
15414 return 0;
15415 case NT_float:
15416 switch (inst.operands[0].imm)
15417 {
15418 default:
15419 first_error (_("invalid condition"));
15420 return 0;
15421 case 0x0:
15422 /* eq. */
15423 return 0;
15424 case 0x1:
15425 /* ne. */
15426 return 1;
15427 case 0xa:
15428 /* ge/ */
15429 return 4;
15430 case 0xb:
15431 /* lt. */
15432 return 5;
15433 case 0xc:
15434 /* gt. */
15435 return 6;
15436 case 0xd:
15437 /* le. */
15438 return 7;
15439 }
15440 case NT_integer:
15441 /* only accept eq and ne. */
15442 if (inst.operands[0].imm > 1)
15443 {
15444 first_error (_("invalid condition"));
15445 return 0;
15446 }
15447 return inst.operands[0].imm;
15448 case NT_unsigned:
15449 if (inst.operands[0].imm == 0x2)
15450 return 2;
15451 else if (inst.operands[0].imm == 0x8)
15452 return 3;
15453 else
15454 {
15455 first_error (_("invalid condition"));
15456 return 0;
15457 }
15458 case NT_signed:
15459 switch (inst.operands[0].imm)
15460 {
15461 default:
15462 first_error (_("invalid condition"));
15463 return 0;
15464 case 0xa:
15465 /* ge. */
15466 return 4;
15467 case 0xb:
15468 /* lt. */
15469 return 5;
15470 case 0xc:
15471 /* gt. */
15472 return 6;
15473 case 0xd:
15474 /* le. */
15475 return 7;
15476 }
15477 }
15478 /* Should be unreachable. */
15479 abort ();
15480}
15481
15482static void
15483do_mve_vpt (void)
15484{
15485 /* We are dealing with a vector predicated block. */
15486 if (inst.operands[0].present)
15487 {
15488 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
15489 struct neon_type_el et
15490 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
15491 N_EQK);
15492
15493 unsigned fcond = mve_get_vcmp_vpt_cond (et);
15494
15495 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
15496
15497 if (et.type == NT_invtype)
15498 return;
15499
15500 if (et.type == NT_float)
15501 {
15502 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
15503 BAD_FPU);
15504 constraint (et.size != 16 && et.size != 32, BAD_EL_TYPE);
15505 inst.instruction |= (et.size == 16) << 28;
15506 inst.instruction |= 0x3 << 20;
15507 }
15508 else
15509 {
15510 constraint (et.size != 8 && et.size != 16 && et.size != 32,
15511 BAD_EL_TYPE);
15512 inst.instruction |= 1 << 28;
15513 inst.instruction |= neon_logbits (et.size) << 20;
15514 }
15515
15516 if (inst.operands[2].isquad)
15517 {
15518 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15519 inst.instruction |= LOW4 (inst.operands[2].reg);
15520 inst.instruction |= (fcond & 0x2) >> 1;
15521 }
15522 else
15523 {
15524 if (inst.operands[2].reg == REG_SP)
15525 as_tsktsk (MVE_BAD_SP);
15526 inst.instruction |= 1 << 6;
15527 inst.instruction |= (fcond & 0x2) << 4;
15528 inst.instruction |= inst.operands[2].reg;
15529 }
15530 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15531 inst.instruction |= (fcond & 0x4) << 10;
15532 inst.instruction |= (fcond & 0x1) << 7;
15533
15534 }
15535 set_pred_insn_type (VPT_INSN);
15536 now_pred.cc = 0;
15537 now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
15538 | ((inst.instruction & 0xe000) >> 13);
15539 now_pred.warn_deprecated = FALSE;
15540 now_pred.type = VECTOR_PRED;
15541 inst.is_neon = 1;
15542}
15543
15544static void
15545do_mve_vcmp (void)
15546{
15547 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
15548 if (!inst.operands[1].isreg || !inst.operands[1].isquad)
15549 first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
15550 if (!inst.operands[2].present)
15551 first_error (_("MVE vector or ARM register expected"));
15552 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
15553
15554 /* Deal with 'else' conditional MVE's vcmp, it will be parsed as vcmpe. */
15555 if ((inst.instruction & 0xffffffff) == N_MNEM_vcmpe
15556 && inst.operands[1].isquad)
15557 {
15558 inst.instruction = N_MNEM_vcmp;
15559 inst.cond = 0x10;
15560 }
15561
15562 if (inst.cond > COND_ALWAYS)
15563 inst.pred_insn_type = INSIDE_VPT_INSN;
15564 else
15565 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15566
15567 enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
15568 struct neon_type_el et
15569 = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
15570 N_EQK);
15571
15572 constraint (rs == NS_IQR && inst.operands[2].reg == REG_PC
15573 && !inst.operands[2].iszr, BAD_PC);
15574
15575 unsigned fcond = mve_get_vcmp_vpt_cond (et);
15576
15577 inst.instruction = 0xee010f00;
15578 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15579 inst.instruction |= (fcond & 0x4) << 10;
15580 inst.instruction |= (fcond & 0x1) << 7;
15581 if (et.type == NT_float)
15582 {
15583 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
15584 BAD_FPU);
15585 inst.instruction |= (et.size == 16) << 28;
15586 inst.instruction |= 0x3 << 20;
15587 }
15588 else
15589 {
15590 inst.instruction |= 1 << 28;
15591 inst.instruction |= neon_logbits (et.size) << 20;
15592 }
15593 if (inst.operands[2].isquad)
15594 {
15595 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15596 inst.instruction |= (fcond & 0x2) >> 1;
15597 inst.instruction |= LOW4 (inst.operands[2].reg);
15598 }
15599 else
15600 {
15601 if (inst.operands[2].reg == REG_SP)
15602 as_tsktsk (MVE_BAD_SP);
15603 inst.instruction |= 1 << 6;
15604 inst.instruction |= (fcond & 0x2) << 4;
15605 inst.instruction |= inst.operands[2].reg;
15606 }
15607
15608 inst.is_neon = 1;
15609 return;
15610}
15611
935295b5
AV
15612static void
15613do_mve_vmaxa_vmina (void)
15614{
15615 if (inst.cond > COND_ALWAYS)
15616 inst.pred_insn_type = INSIDE_VPT_INSN;
15617 else
15618 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15619
15620 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
15621 struct neon_type_el et
15622 = neon_check_type (2, rs, N_EQK, N_KEY | N_S8 | N_S16 | N_S32);
15623
15624 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15625 inst.instruction |= neon_logbits (et.size) << 18;
15626 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15627 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15628 inst.instruction |= LOW4 (inst.operands[1].reg);
15629 inst.is_neon = 1;
15630}
15631
f30ee27c
AV
15632static void
15633do_mve_vfmas (void)
15634{
15635 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
15636 struct neon_type_el et
15637 = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK, N_EQK);
15638
15639 if (inst.cond > COND_ALWAYS)
15640 inst.pred_insn_type = INSIDE_VPT_INSN;
15641 else
15642 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15643
15644 if (inst.operands[2].reg == REG_SP)
15645 as_tsktsk (MVE_BAD_SP);
15646 else if (inst.operands[2].reg == REG_PC)
15647 as_tsktsk (MVE_BAD_PC);
15648
15649 inst.instruction |= (et.size == 16) << 28;
15650 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15651 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15652 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15653 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15654 inst.instruction |= inst.operands[2].reg;
15655 inst.is_neon = 1;
15656}
15657
b409bdb6
AV
15658static void
15659do_mve_viddup (void)
15660{
15661 if (inst.cond > COND_ALWAYS)
15662 inst.pred_insn_type = INSIDE_VPT_INSN;
15663 else
15664 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15665
15666 unsigned imm = inst.relocs[0].exp.X_add_number;
15667 constraint (imm != 1 && imm != 2 && imm != 4 && imm != 8,
15668 _("immediate must be either 1, 2, 4 or 8"));
15669
15670 enum neon_shape rs;
15671 struct neon_type_el et;
15672 unsigned Rm;
15673 if (inst.instruction == M_MNEM_vddup || inst.instruction == M_MNEM_vidup)
15674 {
15675 rs = neon_select_shape (NS_QRI, NS_NULL);
15676 et = neon_check_type (2, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK);
15677 Rm = 7;
15678 }
15679 else
15680 {
15681 constraint ((inst.operands[2].reg % 2) != 1, BAD_EVEN);
15682 if (inst.operands[2].reg == REG_SP)
15683 as_tsktsk (MVE_BAD_SP);
15684 else if (inst.operands[2].reg == REG_PC)
15685 first_error (BAD_PC);
15686
15687 rs = neon_select_shape (NS_QRRI, NS_NULL);
15688 et = neon_check_type (3, rs, N_KEY | N_U8 | N_U16 | N_U32, N_EQK, N_EQK);
15689 Rm = inst.operands[2].reg >> 1;
15690 }
15691 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15692 inst.instruction |= neon_logbits (et.size) << 20;
15693 inst.instruction |= inst.operands[1].reg << 16;
15694 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15695 inst.instruction |= (imm > 2) << 7;
15696 inst.instruction |= Rm << 1;
15697 inst.instruction |= (imm == 2 || imm == 8);
15698 inst.is_neon = 1;
15699}
15700
935295b5
AV
15701static void
15702do_mve_vmaxnma_vminnma (void)
15703{
15704 enum neon_shape rs = neon_select_shape (NS_QQ, NS_NULL);
15705 struct neon_type_el et
15706 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
15707
15708 if (inst.cond > COND_ALWAYS)
15709 inst.pred_insn_type = INSIDE_VPT_INSN;
15710 else
15711 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15712
15713 inst.instruction |= (et.size == 16) << 28;
15714 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15715 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15716 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15717 inst.instruction |= LOW4 (inst.operands[1].reg);
15718 inst.is_neon = 1;
15719}
15720
5d281bf0
AV
15721static void
15722do_mve_vcmul (void)
15723{
15724 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
15725 struct neon_type_el et
15726 = neon_check_type (3, rs, N_EQK, N_EQK, N_F_MVE | N_KEY);
15727
15728 if (inst.cond > COND_ALWAYS)
15729 inst.pred_insn_type = INSIDE_VPT_INSN;
15730 else
15731 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
15732
15733 unsigned rot = inst.relocs[0].exp.X_add_number;
15734 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
15735 _("immediate out of range"));
15736
15737 if (et.size == 32 && (inst.operands[0].reg == inst.operands[1].reg
15738 || inst.operands[0].reg == inst.operands[2].reg))
15739 as_tsktsk (BAD_MVE_SRCDEST);
15740
15741 inst.instruction |= (et.size == 32) << 28;
15742 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15743 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15744 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15745 inst.instruction |= (rot > 90) << 12;
15746 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15747 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15748 inst.instruction |= LOW4 (inst.operands[2].reg);
15749 inst.instruction |= (rot == 90 || rot == 270);
15750 inst.is_neon = 1;
15751}
15752
037e8744
JB
15753static void
15754do_vfp_nsyn_cmp (void)
15755{
9db2f6b4 15756 enum neon_shape rs;
1b883319
AV
15757 if (!inst.operands[0].isreg)
15758 {
15759 do_mve_vcmp ();
15760 return;
15761 }
15762 else
15763 {
15764 constraint (inst.operands[2].present, BAD_SYNTAX);
15765 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd),
15766 BAD_FPU);
15767 }
15768
037e8744
JB
15769 if (inst.operands[1].isreg)
15770 {
9db2f6b4
RL
15771 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
15772 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 15773
9db2f6b4 15774 if (rs == NS_FF || rs == NS_HH)
477330fc
RM
15775 {
15776 NEON_ENCODE (SINGLE, inst);
15777 do_vfp_sp_monadic ();
15778 }
037e8744 15779 else
477330fc
RM
15780 {
15781 NEON_ENCODE (DOUBLE, inst);
15782 do_vfp_dp_rd_rm ();
15783 }
037e8744
JB
15784 }
15785 else
15786 {
9db2f6b4
RL
15787 rs = neon_select_shape (NS_HI, NS_FI, NS_DI, NS_NULL);
15788 neon_check_type (2, rs, N_F_ALL | N_KEY | N_VFP, N_EQK);
037e8744
JB
15789
15790 switch (inst.instruction & 0x0fffffff)
477330fc
RM
15791 {
15792 case N_MNEM_vcmp:
15793 inst.instruction += N_MNEM_vcmpz - N_MNEM_vcmp;
15794 break;
15795 case N_MNEM_vcmpe:
15796 inst.instruction += N_MNEM_vcmpez - N_MNEM_vcmpe;
15797 break;
15798 default:
15799 abort ();
15800 }
5f4273c7 15801
9db2f6b4 15802 if (rs == NS_FI || rs == NS_HI)
477330fc
RM
15803 {
15804 NEON_ENCODE (SINGLE, inst);
15805 do_vfp_sp_compare_z ();
15806 }
037e8744 15807 else
477330fc
RM
15808 {
15809 NEON_ENCODE (DOUBLE, inst);
15810 do_vfp_dp_rd ();
15811 }
037e8744
JB
15812 }
15813 do_vfp_cond_or_thumb ();
9db2f6b4
RL
15814
15815 /* ARMv8.2 fp16 instruction. */
15816 if (rs == NS_HI || rs == NS_HH)
15817 do_scalar_fp16_v82_encode ();
037e8744
JB
15818}
15819
15820static void
15821nsyn_insert_sp (void)
15822{
15823 inst.operands[1] = inst.operands[0];
15824 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
fdfde340 15825 inst.operands[0].reg = REG_SP;
037e8744
JB
15826 inst.operands[0].isreg = 1;
15827 inst.operands[0].writeback = 1;
15828 inst.operands[0].present = 1;
15829}
15830
15831static void
15832do_vfp_nsyn_push (void)
15833{
15834 nsyn_insert_sp ();
b126985e
NC
15835
15836 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
15837 _("register list must contain at least 1 and at most 16 "
15838 "registers"));
15839
037e8744
JB
15840 if (inst.operands[1].issingle)
15841 do_vfp_nsyn_opcode ("fstmdbs");
15842 else
15843 do_vfp_nsyn_opcode ("fstmdbd");
15844}
15845
15846static void
15847do_vfp_nsyn_pop (void)
15848{
15849 nsyn_insert_sp ();
b126985e
NC
15850
15851 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
15852 _("register list must contain at least 1 and at most 16 "
15853 "registers"));
15854
037e8744 15855 if (inst.operands[1].issingle)
22b5b651 15856 do_vfp_nsyn_opcode ("fldmias");
037e8744 15857 else
22b5b651 15858 do_vfp_nsyn_opcode ("fldmiad");
037e8744
JB
15859}
15860
15861/* Fix up Neon data-processing instructions, ORing in the correct bits for
15862 ARM mode or Thumb mode and moving the encoded bit 24 to bit 28. */
15863
88714cb8
DG
15864static void
15865neon_dp_fixup (struct arm_it* insn)
037e8744 15866{
88714cb8
DG
15867 unsigned int i = insn->instruction;
15868 insn->is_neon = 1;
15869
037e8744
JB
15870 if (thumb_mode)
15871 {
15872 /* The U bit is at bit 24 by default. Move to bit 28 in Thumb mode. */
15873 if (i & (1 << 24))
477330fc 15874 i |= 1 << 28;
5f4273c7 15875
037e8744 15876 i &= ~(1 << 24);
5f4273c7 15877
037e8744
JB
15878 i |= 0xef000000;
15879 }
15880 else
15881 i |= 0xf2000000;
5f4273c7 15882
88714cb8 15883 insn->instruction = i;
037e8744
JB
15884}
15885
5ee91343 15886static void
7df54120 15887mve_encode_qqr (int size, int U, int fp)
5ee91343
AV
15888{
15889 if (inst.operands[2].reg == REG_SP)
15890 as_tsktsk (MVE_BAD_SP);
15891 else if (inst.operands[2].reg == REG_PC)
15892 as_tsktsk (MVE_BAD_PC);
15893
15894 if (fp)
15895 {
15896 /* vadd. */
15897 if (((unsigned)inst.instruction) == 0xd00)
15898 inst.instruction = 0xee300f40;
15899 /* vsub. */
15900 else if (((unsigned)inst.instruction) == 0x200d00)
15901 inst.instruction = 0xee301f40;
15902
15903 /* Setting size which is 1 for F16 and 0 for F32. */
15904 inst.instruction |= (size == 16) << 28;
15905 }
15906 else
15907 {
15908 /* vadd. */
15909 if (((unsigned)inst.instruction) == 0x800)
15910 inst.instruction = 0xee010f40;
15911 /* vsub. */
15912 else if (((unsigned)inst.instruction) == 0x1000800)
15913 inst.instruction = 0xee011f40;
7df54120
AV
15914 /* vhadd. */
15915 else if (((unsigned)inst.instruction) == 0)
15916 inst.instruction = 0xee000f40;
15917 /* vhsub. */
15918 else if (((unsigned)inst.instruction) == 0x200)
15919 inst.instruction = 0xee001f40;
15920
15921 /* Set U-bit. */
15922 inst.instruction |= U << 28;
15923
5ee91343
AV
15924 /* Setting bits for size. */
15925 inst.instruction |= neon_logbits (size) << 20;
15926 }
15927 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15928 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15929 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15930 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15931 inst.instruction |= inst.operands[2].reg;
15932 inst.is_neon = 1;
15933}
15934
a302e574
AV
15935static void
15936mve_encode_rqq (unsigned bit28, unsigned size)
15937{
15938 inst.instruction |= bit28 << 28;
15939 inst.instruction |= neon_logbits (size) << 20;
15940 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15941 inst.instruction |= inst.operands[0].reg << 12;
15942 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15943 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15944 inst.instruction |= LOW4 (inst.operands[2].reg);
15945 inst.is_neon = 1;
15946}
15947
886e1c73
AV
15948static void
15949mve_encode_qqq (int ubit, int size)
15950{
15951
15952 inst.instruction |= (ubit != 0) << 28;
15953 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15954 inst.instruction |= neon_logbits (size) << 20;
15955 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15956 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15957 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15958 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15959 inst.instruction |= LOW4 (inst.operands[2].reg);
15960
15961 inst.is_neon = 1;
15962}
15963
26c1e780
AV
15964static void
15965mve_encode_rq (unsigned bit28, unsigned size)
15966{
15967 inst.instruction |= bit28 << 28;
15968 inst.instruction |= neon_logbits (size) << 18;
15969 inst.instruction |= inst.operands[0].reg << 12;
15970 inst.instruction |= LOW4 (inst.operands[1].reg);
15971 inst.is_neon = 1;
15972}
886e1c73 15973
93925576
AV
15974static void
15975mve_encode_rrqq (unsigned U, unsigned size)
15976{
15977 constraint (inst.operands[3].reg > 14, MVE_BAD_QREG);
15978
15979 inst.instruction |= U << 28;
15980 inst.instruction |= (inst.operands[1].reg >> 1) << 20;
15981 inst.instruction |= LOW4 (inst.operands[2].reg) << 16;
15982 inst.instruction |= (size == 32) << 16;
15983 inst.instruction |= inst.operands[0].reg << 12;
15984 inst.instruction |= HI1 (inst.operands[2].reg) << 7;
15985 inst.instruction |= inst.operands[3].reg;
15986 inst.is_neon = 1;
15987}
15988
037e8744
JB
15989/* Encode insns with bit pattern:
15990
15991 |28/24|23|22 |21 20|19 16|15 12|11 8|7|6|5|4|3 0|
15992 | U |x |D |size | Rn | Rd |x x x x|N|Q|M|x| Rm |
5f4273c7 15993
037e8744
JB
15994 SIZE is passed in bits. -1 means size field isn't changed, in case it has a
15995 different meaning for some instruction. */
15996
15997static void
15998neon_three_same (int isquad, int ubit, int size)
15999{
16000 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16001 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16002 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16003 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16004 inst.instruction |= LOW4 (inst.operands[2].reg);
16005 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16006 inst.instruction |= (isquad != 0) << 6;
16007 inst.instruction |= (ubit != 0) << 24;
16008 if (size != -1)
16009 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 16010
88714cb8 16011 neon_dp_fixup (&inst);
037e8744
JB
16012}
16013
16014/* Encode instructions of the form:
16015
16016 |28/24|23|22|21 20|19 18|17 16|15 12|11 7|6|5|4|3 0|
16017 | U |x |D |x x |size |x x | Rd |x x x x x|Q|M|x| Rm |
5287ad62
JB
16018
16019 Don't write size if SIZE == -1. */
16020
16021static void
16022neon_two_same (int qbit, int ubit, int size)
16023{
16024 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16025 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16026 inst.instruction |= LOW4 (inst.operands[1].reg);
16027 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16028 inst.instruction |= (qbit != 0) << 6;
16029 inst.instruction |= (ubit != 0) << 24;
16030
16031 if (size != -1)
16032 inst.instruction |= neon_logbits (size) << 18;
16033
88714cb8 16034 neon_dp_fixup (&inst);
5287ad62
JB
16035}
16036
7df54120
AV
16037enum vfp_or_neon_is_neon_bits
16038{
16039NEON_CHECK_CC = 1,
16040NEON_CHECK_ARCH = 2,
16041NEON_CHECK_ARCH8 = 4
16042};
16043
16044/* Call this function if an instruction which may have belonged to the VFP or
16045 Neon instruction sets, but turned out to be a Neon instruction (due to the
16046 operand types involved, etc.). We have to check and/or fix-up a couple of
16047 things:
16048
16049 - Make sure the user hasn't attempted to make a Neon instruction
16050 conditional.
16051 - Alter the value in the condition code field if necessary.
16052 - Make sure that the arch supports Neon instructions.
16053
16054 Which of these operations take place depends on bits from enum
16055 vfp_or_neon_is_neon_bits.
16056
16057 WARNING: This function has side effects! If NEON_CHECK_CC is used and the
16058 current instruction's condition is COND_ALWAYS, the condition field is
16059 changed to inst.uncond_value. This is necessary because instructions shared
16060 between VFP and Neon may be conditional for the VFP variants only, and the
16061 unconditional Neon version must have, e.g., 0xF in the condition field. */
16062
16063static int
16064vfp_or_neon_is_neon (unsigned check)
16065{
16066/* Conditions are always legal in Thumb mode (IT blocks). */
16067if (!thumb_mode && (check & NEON_CHECK_CC))
16068 {
16069 if (inst.cond != COND_ALWAYS)
16070 {
16071 first_error (_(BAD_COND));
16072 return FAIL;
16073 }
16074 if (inst.uncond_value != -1)
16075 inst.instruction |= inst.uncond_value << 28;
16076 }
16077
16078
16079 if (((check & NEON_CHECK_ARCH) && !mark_feature_used (&fpu_neon_ext_v1))
16080 || ((check & NEON_CHECK_ARCH8)
16081 && !mark_feature_used (&fpu_neon_ext_armv8)))
16082 {
16083 first_error (_(BAD_FPU));
16084 return FAIL;
16085 }
16086
16087return SUCCESS;
16088}
16089
16090static int
16091check_simd_pred_availability (int fp, unsigned check)
16092{
16093if (inst.cond > COND_ALWAYS)
16094 {
16095 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16096 {
16097 inst.error = BAD_FPU;
16098 return 1;
16099 }
16100 inst.pred_insn_type = INSIDE_VPT_INSN;
16101 }
16102else if (inst.cond < COND_ALWAYS)
16103 {
16104 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16105 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16106 else if (vfp_or_neon_is_neon (check) == FAIL)
16107 return 2;
16108 }
16109else
16110 {
16111 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fp ? mve_fp_ext : mve_ext)
16112 && vfp_or_neon_is_neon (check) == FAIL)
16113 return 3;
16114
16115 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16116 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16117 }
16118return 0;
16119}
16120
5287ad62
JB
16121/* Neon instruction encoders, in approximate order of appearance. */
16122
16123static void
16124do_neon_dyadic_i_su (void)
16125{
7df54120
AV
16126 if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
16127 return;
16128
16129 enum neon_shape rs;
16130 struct neon_type_el et;
16131 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16132 rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
16133 else
16134 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16135
16136 et = neon_check_type (3, rs, N_EQK, N_EQK, N_SU_32 | N_KEY);
16137
16138
16139 if (rs != NS_QQR)
16140 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
16141 else
16142 mve_encode_qqr (et.size, et.type == NT_unsigned, 0);
5287ad62
JB
16143}
16144
16145static void
16146do_neon_dyadic_i64_su (void)
16147{
037e8744 16148 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
16149 struct neon_type_el et = neon_check_type (3, rs,
16150 N_EQK, N_EQK, N_SU_ALL | N_KEY);
037e8744 16151 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
16152}
16153
16154static void
16155neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
477330fc 16156 unsigned immbits)
5287ad62
JB
16157{
16158 unsigned size = et.size >> 3;
16159 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16160 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16161 inst.instruction |= LOW4 (inst.operands[1].reg);
16162 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16163 inst.instruction |= (isquad != 0) << 6;
16164 inst.instruction |= immbits << 16;
16165 inst.instruction |= (size >> 3) << 7;
16166 inst.instruction |= (size & 0x7) << 19;
16167 if (write_ubit)
16168 inst.instruction |= (uval != 0) << 24;
16169
88714cb8 16170 neon_dp_fixup (&inst);
5287ad62
JB
16171}
16172
16173static void
16174do_neon_shl_imm (void)
16175{
16176 if (!inst.operands[2].isreg)
16177 {
037e8744 16178 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62 16179 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
cb3b1e65
JB
16180 int imm = inst.operands[2].imm;
16181
16182 constraint (imm < 0 || (unsigned)imm >= et.size,
16183 _("immediate out of range for shift"));
88714cb8 16184 NEON_ENCODE (IMMED, inst);
cb3b1e65 16185 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
16186 }
16187 else
16188 {
037e8744 16189 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 16190 struct neon_type_el et = neon_check_type (3, rs,
477330fc 16191 N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
627907b7
JB
16192 unsigned int tmp;
16193
16194 /* VSHL/VQSHL 3-register variants have syntax such as:
477330fc
RM
16195 vshl.xx Dd, Dm, Dn
16196 whereas other 3-register operations encoded by neon_three_same have
16197 syntax like:
16198 vadd.xx Dd, Dn, Dm
16199 (i.e. with Dn & Dm reversed). Swap operands[1].reg and operands[2].reg
16200 here. */
627907b7
JB
16201 tmp = inst.operands[2].reg;
16202 inst.operands[2].reg = inst.operands[1].reg;
16203 inst.operands[1].reg = tmp;
88714cb8 16204 NEON_ENCODE (INTEGER, inst);
037e8744 16205 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
16206 }
16207}
16208
16209static void
16210do_neon_qshl_imm (void)
16211{
16212 if (!inst.operands[2].isreg)
16213 {
037e8744 16214 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62 16215 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
cb3b1e65 16216 int imm = inst.operands[2].imm;
627907b7 16217
cb3b1e65
JB
16218 constraint (imm < 0 || (unsigned)imm >= et.size,
16219 _("immediate out of range for shift"));
88714cb8 16220 NEON_ENCODE (IMMED, inst);
cb3b1e65 16221 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et, imm);
5287ad62
JB
16222 }
16223 else
16224 {
037e8744 16225 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 16226 struct neon_type_el et = neon_check_type (3, rs,
477330fc 16227 N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
627907b7
JB
16228 unsigned int tmp;
16229
16230 /* See note in do_neon_shl_imm. */
16231 tmp = inst.operands[2].reg;
16232 inst.operands[2].reg = inst.operands[1].reg;
16233 inst.operands[1].reg = tmp;
88714cb8 16234 NEON_ENCODE (INTEGER, inst);
037e8744 16235 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
16236 }
16237}
16238
627907b7
JB
16239static void
16240do_neon_rshl (void)
16241{
16242 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
16243 struct neon_type_el et = neon_check_type (3, rs,
16244 N_EQK, N_EQK, N_SU_ALL | N_KEY);
16245 unsigned int tmp;
16246
16247 tmp = inst.operands[2].reg;
16248 inst.operands[2].reg = inst.operands[1].reg;
16249 inst.operands[1].reg = tmp;
16250 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
16251}
16252
5287ad62
JB
16253static int
16254neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
16255{
036dc3f7
PB
16256 /* Handle .I8 pseudo-instructions. */
16257 if (size == 8)
5287ad62 16258 {
5287ad62 16259 /* Unfortunately, this will make everything apart from zero out-of-range.
477330fc
RM
16260 FIXME is this the intended semantics? There doesn't seem much point in
16261 accepting .I8 if so. */
5287ad62
JB
16262 immediate |= immediate << 8;
16263 size = 16;
036dc3f7
PB
16264 }
16265
16266 if (size >= 32)
16267 {
16268 if (immediate == (immediate & 0x000000ff))
16269 {
16270 *immbits = immediate;
16271 return 0x1;
16272 }
16273 else if (immediate == (immediate & 0x0000ff00))
16274 {
16275 *immbits = immediate >> 8;
16276 return 0x3;
16277 }
16278 else if (immediate == (immediate & 0x00ff0000))
16279 {
16280 *immbits = immediate >> 16;
16281 return 0x5;
16282 }
16283 else if (immediate == (immediate & 0xff000000))
16284 {
16285 *immbits = immediate >> 24;
16286 return 0x7;
16287 }
16288 if ((immediate & 0xffff) != (immediate >> 16))
16289 goto bad_immediate;
16290 immediate &= 0xffff;
5287ad62
JB
16291 }
16292
16293 if (immediate == (immediate & 0x000000ff))
16294 {
16295 *immbits = immediate;
036dc3f7 16296 return 0x9;
5287ad62
JB
16297 }
16298 else if (immediate == (immediate & 0x0000ff00))
16299 {
16300 *immbits = immediate >> 8;
036dc3f7 16301 return 0xb;
5287ad62
JB
16302 }
16303
16304 bad_immediate:
dcbf9037 16305 first_error (_("immediate value out of range"));
5287ad62
JB
16306 return FAIL;
16307}
16308
5287ad62
JB
16309static void
16310do_neon_logic (void)
16311{
16312 if (inst.operands[2].present && inst.operands[2].isreg)
16313 {
037e8744 16314 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
f601a00c
AV
16315 if (rs == NS_QQQ
16316 && check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC)
16317 == FAIL)
16318 return;
16319 else if (rs != NS_QQQ
16320 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
16321 first_error (BAD_FPU);
16322
5287ad62
JB
16323 neon_check_type (3, rs, N_IGNORE_TYPE);
16324 /* U bit and size field were set as part of the bitmask. */
88714cb8 16325 NEON_ENCODE (INTEGER, inst);
037e8744 16326 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
16327 }
16328 else
16329 {
4316f0d2
DG
16330 const int three_ops_form = (inst.operands[2].present
16331 && !inst.operands[2].isreg);
16332 const int immoperand = (three_ops_form ? 2 : 1);
16333 enum neon_shape rs = (three_ops_form
16334 ? neon_select_shape (NS_DDI, NS_QQI, NS_NULL)
16335 : neon_select_shape (NS_DI, NS_QI, NS_NULL));
f601a00c
AV
16336 /* Because neon_select_shape makes the second operand a copy of the first
16337 if the second operand is not present. */
16338 if (rs == NS_QQI
16339 && check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC)
16340 == FAIL)
16341 return;
16342 else if (rs != NS_QQI
16343 && !ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
16344 first_error (BAD_FPU);
16345
16346 struct neon_type_el et;
16347 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16348 et = neon_check_type (2, rs, N_I32 | N_I16 | N_KEY, N_EQK);
16349 else
16350 et = neon_check_type (2, rs, N_I8 | N_I16 | N_I32 | N_I64 | N_F32
16351 | N_KEY, N_EQK);
16352
16353 if (et.type == NT_invtype)
16354 return;
21d799b5 16355 enum neon_opc opcode = (enum neon_opc) inst.instruction & 0x0fffffff;
5287ad62
JB
16356 unsigned immbits;
16357 int cmode;
5f4273c7 16358
5f4273c7 16359
4316f0d2
DG
16360 if (three_ops_form)
16361 constraint (inst.operands[0].reg != inst.operands[1].reg,
16362 _("first and second operands shall be the same register"));
16363
88714cb8 16364 NEON_ENCODE (IMMED, inst);
5287ad62 16365
4316f0d2 16366 immbits = inst.operands[immoperand].imm;
036dc3f7
PB
16367 if (et.size == 64)
16368 {
16369 /* .i64 is a pseudo-op, so the immediate must be a repeating
16370 pattern. */
4316f0d2
DG
16371 if (immbits != (inst.operands[immoperand].regisimm ?
16372 inst.operands[immoperand].reg : 0))
036dc3f7
PB
16373 {
16374 /* Set immbits to an invalid constant. */
16375 immbits = 0xdeadbeef;
16376 }
16377 }
16378
5287ad62 16379 switch (opcode)
477330fc
RM
16380 {
16381 case N_MNEM_vbic:
16382 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16383 break;
16384
16385 case N_MNEM_vorr:
16386 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16387 break;
16388
16389 case N_MNEM_vand:
16390 /* Pseudo-instruction for VBIC. */
16391 neon_invert_size (&immbits, 0, et.size);
16392 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16393 break;
16394
16395 case N_MNEM_vorn:
16396 /* Pseudo-instruction for VORR. */
16397 neon_invert_size (&immbits, 0, et.size);
16398 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
16399 break;
16400
16401 default:
16402 abort ();
16403 }
5287ad62
JB
16404
16405 if (cmode == FAIL)
477330fc 16406 return;
5287ad62 16407
037e8744 16408 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16409 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16410 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16411 inst.instruction |= cmode << 8;
16412 neon_write_immbits (immbits);
5f4273c7 16413
88714cb8 16414 neon_dp_fixup (&inst);
5287ad62
JB
16415 }
16416}
16417
16418static void
16419do_neon_bitfield (void)
16420{
037e8744 16421 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 16422 neon_check_type (3, rs, N_IGNORE_TYPE);
037e8744 16423 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
16424}
16425
16426static void
dcbf9037 16427neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types,
477330fc 16428 unsigned destbits)
5287ad62 16429{
5ee91343 16430 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
dcbf9037 16431 struct neon_type_el et = neon_check_type (3, rs, N_EQK | destbits, N_EQK,
477330fc 16432 types | N_KEY);
5287ad62
JB
16433 if (et.type == NT_float)
16434 {
88714cb8 16435 NEON_ENCODE (FLOAT, inst);
5ee91343 16436 if (rs == NS_QQR)
7df54120 16437 mve_encode_qqr (et.size, 0, 1);
5ee91343
AV
16438 else
16439 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
16440 }
16441 else
16442 {
88714cb8 16443 NEON_ENCODE (INTEGER, inst);
5ee91343 16444 if (rs == NS_QQR)
7df54120 16445 mve_encode_qqr (et.size, 0, 0);
5ee91343
AV
16446 else
16447 neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
5287ad62
JB
16448 }
16449}
16450
5287ad62
JB
16451
16452static void
16453do_neon_dyadic_if_su_d (void)
16454{
16455 /* This version only allow D registers, but that constraint is enforced during
16456 operand parsing so we don't need to do anything extra here. */
dcbf9037 16457 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
16458}
16459
5287ad62
JB
16460static void
16461do_neon_dyadic_if_i_d (void)
16462{
428e3f1f
PB
16463 /* The "untyped" case can't happen. Do this to stop the "U" bit being
16464 affected if we specify unsigned args. */
16465 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
5287ad62
JB
16466}
16467
f5f10c66
AV
16468static void
16469do_mve_vstr_vldr_QI (int size, int elsize, int load)
16470{
16471 constraint (size < 32, BAD_ADDR_MODE);
16472 constraint (size != elsize, BAD_EL_TYPE);
16473 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
16474 constraint (!inst.operands[1].preind, BAD_ADDR_MODE);
16475 constraint (load && inst.operands[0].reg == inst.operands[1].reg,
16476 _("destination register and offset register may not be the"
16477 " same"));
16478
16479 int imm = inst.relocs[0].exp.X_add_number;
16480 int add = 1;
16481 if (imm < 0)
16482 {
16483 add = 0;
16484 imm = -imm;
16485 }
16486 constraint ((imm % (size / 8) != 0)
16487 || imm > (0x7f << neon_logbits (size)),
16488 (size == 32) ? _("immediate must be a multiple of 4 in the"
16489 " range of +/-[0,508]")
16490 : _("immediate must be a multiple of 8 in the"
16491 " range of +/-[0,1016]"));
16492 inst.instruction |= 0x11 << 24;
16493 inst.instruction |= add << 23;
16494 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16495 inst.instruction |= inst.operands[1].writeback << 21;
16496 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16497 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16498 inst.instruction |= 1 << 12;
16499 inst.instruction |= (size == 64) << 8;
16500 inst.instruction &= 0xffffff00;
16501 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16502 inst.instruction |= imm >> neon_logbits (size);
16503}
16504
16505static void
16506do_mve_vstr_vldr_RQ (int size, int elsize, int load)
16507{
16508 unsigned os = inst.operands[1].imm >> 5;
16509 constraint (os != 0 && size == 8,
16510 _("can not shift offsets when accessing less than half-word"));
16511 constraint (os && os != neon_logbits (size),
16512 _("shift immediate must be 1, 2 or 3 for half-word, word"
16513 " or double-word accesses respectively"));
16514 if (inst.operands[1].reg == REG_PC)
16515 as_tsktsk (MVE_BAD_PC);
16516
16517 switch (size)
16518 {
16519 case 8:
16520 constraint (elsize >= 64, BAD_EL_TYPE);
16521 break;
16522 case 16:
16523 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
16524 break;
16525 case 32:
16526 case 64:
16527 constraint (elsize != size, BAD_EL_TYPE);
16528 break;
16529 default:
16530 break;
16531 }
16532 constraint (inst.operands[1].writeback || !inst.operands[1].preind,
16533 BAD_ADDR_MODE);
16534 if (load)
16535 {
16536 constraint (inst.operands[0].reg == (inst.operands[1].imm & 0x1f),
16537 _("destination register and offset register may not be"
16538 " the same"));
16539 constraint (size == elsize && inst.vectype.el[0].type != NT_unsigned,
16540 BAD_EL_TYPE);
16541 constraint (inst.vectype.el[0].type != NT_unsigned
16542 && inst.vectype.el[0].type != NT_signed, BAD_EL_TYPE);
16543 inst.instruction |= (inst.vectype.el[0].type == NT_unsigned) << 28;
16544 }
16545 else
16546 {
16547 constraint (inst.vectype.el[0].type != NT_untyped, BAD_EL_TYPE);
16548 }
16549
16550 inst.instruction |= 1 << 23;
16551 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16552 inst.instruction |= inst.operands[1].reg << 16;
16553 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16554 inst.instruction |= neon_logbits (elsize) << 7;
16555 inst.instruction |= HI1 (inst.operands[1].imm) << 5;
16556 inst.instruction |= LOW4 (inst.operands[1].imm);
16557 inst.instruction |= !!os;
16558}
16559
16560static void
16561do_mve_vstr_vldr_RI (int size, int elsize, int load)
16562{
16563 enum neon_el_type type = inst.vectype.el[0].type;
16564
16565 constraint (size >= 64, BAD_ADDR_MODE);
16566 switch (size)
16567 {
16568 case 16:
16569 constraint (elsize < 16 || elsize >= 64, BAD_EL_TYPE);
16570 break;
16571 case 32:
16572 constraint (elsize != size, BAD_EL_TYPE);
16573 break;
16574 default:
16575 break;
16576 }
16577 if (load)
16578 {
16579 constraint (elsize != size && type != NT_unsigned
16580 && type != NT_signed, BAD_EL_TYPE);
16581 }
16582 else
16583 {
16584 constraint (elsize != size && type != NT_untyped, BAD_EL_TYPE);
16585 }
16586
16587 int imm = inst.relocs[0].exp.X_add_number;
16588 int add = 1;
16589 if (imm < 0)
16590 {
16591 add = 0;
16592 imm = -imm;
16593 }
16594
16595 if ((imm % (size / 8) != 0) || imm > (0x7f << neon_logbits (size)))
16596 {
16597 switch (size)
16598 {
16599 case 8:
16600 constraint (1, _("immediate must be in the range of +/-[0,127]"));
16601 break;
16602 case 16:
16603 constraint (1, _("immediate must be a multiple of 2 in the"
16604 " range of +/-[0,254]"));
16605 break;
16606 case 32:
16607 constraint (1, _("immediate must be a multiple of 4 in the"
16608 " range of +/-[0,508]"));
16609 break;
16610 }
16611 }
16612
16613 if (size != elsize)
16614 {
16615 constraint (inst.operands[1].reg > 7, BAD_HIREG);
16616 constraint (inst.operands[0].reg > 14,
16617 _("MVE vector register in the range [Q0..Q7] expected"));
16618 inst.instruction |= (load && type == NT_unsigned) << 28;
16619 inst.instruction |= (size == 16) << 19;
16620 inst.instruction |= neon_logbits (elsize) << 7;
16621 }
16622 else
16623 {
16624 if (inst.operands[1].reg == REG_PC)
16625 as_tsktsk (MVE_BAD_PC);
16626 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
16627 as_tsktsk (MVE_BAD_SP);
16628 inst.instruction |= 1 << 12;
16629 inst.instruction |= neon_logbits (size) << 7;
16630 }
16631 inst.instruction |= inst.operands[1].preind << 24;
16632 inst.instruction |= add << 23;
16633 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16634 inst.instruction |= inst.operands[1].writeback << 21;
16635 inst.instruction |= inst.operands[1].reg << 16;
16636 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16637 inst.instruction &= 0xffffff80;
16638 inst.instruction |= imm >> neon_logbits (size);
16639
16640}
16641
16642static void
16643do_mve_vstr_vldr (void)
16644{
16645 unsigned size;
16646 int load = 0;
16647
16648 if (inst.cond > COND_ALWAYS)
16649 inst.pred_insn_type = INSIDE_VPT_INSN;
16650 else
16651 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16652
16653 switch (inst.instruction)
16654 {
16655 default:
16656 gas_assert (0);
16657 break;
16658 case M_MNEM_vldrb:
16659 load = 1;
16660 /* fall through. */
16661 case M_MNEM_vstrb:
16662 size = 8;
16663 break;
16664 case M_MNEM_vldrh:
16665 load = 1;
16666 /* fall through. */
16667 case M_MNEM_vstrh:
16668 size = 16;
16669 break;
16670 case M_MNEM_vldrw:
16671 load = 1;
16672 /* fall through. */
16673 case M_MNEM_vstrw:
16674 size = 32;
16675 break;
16676 case M_MNEM_vldrd:
16677 load = 1;
16678 /* fall through. */
16679 case M_MNEM_vstrd:
16680 size = 64;
16681 break;
16682 }
16683 unsigned elsize = inst.vectype.el[0].size;
16684
16685 if (inst.operands[1].isquad)
16686 {
16687 /* We are dealing with [Q, imm]{!} cases. */
16688 do_mve_vstr_vldr_QI (size, elsize, load);
16689 }
16690 else
16691 {
16692 if (inst.operands[1].immisreg == 2)
16693 {
16694 /* We are dealing with [R, Q, {UXTW #os}] cases. */
16695 do_mve_vstr_vldr_RQ (size, elsize, load);
16696 }
16697 else if (!inst.operands[1].immisreg)
16698 {
16699 /* We are dealing with [R, Imm]{!}/[R], Imm cases. */
16700 do_mve_vstr_vldr_RI (size, elsize, load);
16701 }
16702 else
16703 constraint (1, BAD_ADDR_MODE);
16704 }
16705
16706 inst.is_neon = 1;
16707}
16708
35c228db
AV
16709static void
16710do_mve_vst_vld (void)
16711{
16712 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
16713 return;
16714
16715 constraint (!inst.operands[1].preind || inst.relocs[0].exp.X_add_symbol != 0
16716 || inst.relocs[0].exp.X_add_number != 0
16717 || inst.operands[1].immisreg != 0,
16718 BAD_ADDR_MODE);
16719 constraint (inst.vectype.el[0].size > 32, BAD_EL_TYPE);
16720 if (inst.operands[1].reg == REG_PC)
16721 as_tsktsk (MVE_BAD_PC);
16722 else if (inst.operands[1].reg == REG_SP && inst.operands[1].writeback)
16723 as_tsktsk (MVE_BAD_SP);
16724
16725
16726 /* These instructions are one of the "exceptions" mentioned in
16727 handle_pred_state. They are MVE instructions that are not VPT compatible
16728 and do not accept a VPT code, thus appending such a code is a syntax
16729 error. */
16730 if (inst.cond > COND_ALWAYS)
16731 first_error (BAD_SYNTAX);
16732 /* If we append a scalar condition code we can set this to
16733 MVE_OUTSIDE_PRED_INSN as it will also lead to a syntax error. */
16734 else if (inst.cond < COND_ALWAYS)
16735 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16736 else
16737 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
16738
16739 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16740 inst.instruction |= inst.operands[1].writeback << 21;
16741 inst.instruction |= inst.operands[1].reg << 16;
16742 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16743 inst.instruction |= neon_logbits (inst.vectype.el[0].size) << 7;
16744 inst.is_neon = 1;
16745}
16746
26c1e780
AV
16747static void
16748do_mve_vaddlv (void)
16749{
16750 enum neon_shape rs = neon_select_shape (NS_RRQ, NS_NULL);
16751 struct neon_type_el et
16752 = neon_check_type (3, rs, N_EQK, N_EQK, N_S32 | N_U32 | N_KEY);
16753
16754 if (et.type == NT_invtype)
16755 first_error (BAD_EL_TYPE);
16756
16757 if (inst.cond > COND_ALWAYS)
16758 inst.pred_insn_type = INSIDE_VPT_INSN;
16759 else
16760 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
16761
16762 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
16763
16764 inst.instruction |= (et.type == NT_unsigned) << 28;
16765 inst.instruction |= inst.operands[1].reg << 19;
16766 inst.instruction |= inst.operands[0].reg << 12;
16767 inst.instruction |= inst.operands[2].reg;
16768 inst.is_neon = 1;
16769}
16770
5287ad62 16771static void
5ee91343 16772do_neon_dyadic_if_su (void)
5287ad62 16773{
5ee91343
AV
16774 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
16775 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
16776 N_SUF_32 | N_KEY);
16777
935295b5
AV
16778 constraint ((inst.instruction == ((unsigned) N_MNEM_vmax)
16779 || inst.instruction == ((unsigned) N_MNEM_vmin))
16780 && et.type == NT_float
16781 && !ARM_CPU_HAS_FEATURE (cpu_variant,fpu_neon_ext_v1), BAD_FPU);
16782
5ee91343
AV
16783 if (check_simd_pred_availability (et.type == NT_float,
16784 NEON_CHECK_ARCH | NEON_CHECK_CC))
037e8744
JB
16785 return;
16786
5ee91343
AV
16787 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
16788}
16789
16790static void
16791do_neon_addsub_if_i (void)
16792{
16793 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd)
16794 && try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
037e8744
JB
16795 return;
16796
5ee91343
AV
16797 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_QQR, NS_NULL);
16798 struct neon_type_el et = neon_check_type (3, rs, N_EQK,
16799 N_EQK, N_IF_32 | N_I64 | N_KEY);
16800
16801 constraint (rs == NS_QQR && et.size == 64, BAD_FPU);
16802 /* If we are parsing Q registers and the element types match MVE, which NEON
16803 also supports, then we must check whether this is an instruction that can
16804 be used by both MVE/NEON. This distinction can be made based on whether
16805 they are predicated or not. */
16806 if ((rs == NS_QQQ || rs == NS_QQR) && et.size != 64)
16807 {
16808 if (check_simd_pred_availability (et.type == NT_float,
16809 NEON_CHECK_ARCH | NEON_CHECK_CC))
16810 return;
16811 }
16812 else
16813 {
16814 /* If they are either in a D register or are using an unsupported. */
16815 if (rs != NS_QQR
16816 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16817 return;
16818 }
16819
5287ad62
JB
16820 /* The "untyped" case can't happen. Do this to stop the "U" bit being
16821 affected if we specify unsigned args. */
dcbf9037 16822 neon_dyadic_misc (NT_untyped, N_IF_32 | N_I64, 0);
5287ad62
JB
16823}
16824
16825/* Swaps operands 1 and 2. If operand 1 (optional arg) was omitted, we want the
16826 result to be:
16827 V<op> A,B (A is operand 0, B is operand 2)
16828 to mean:
16829 V<op> A,B,A
16830 not:
16831 V<op> A,B,B
16832 so handle that case specially. */
16833
16834static void
16835neon_exchange_operands (void)
16836{
5287ad62
JB
16837 if (inst.operands[1].present)
16838 {
e1fa0163
NC
16839 void *scratch = xmalloc (sizeof (inst.operands[0]));
16840
5287ad62
JB
16841 /* Swap operands[1] and operands[2]. */
16842 memcpy (scratch, &inst.operands[1], sizeof (inst.operands[0]));
16843 inst.operands[1] = inst.operands[2];
16844 memcpy (&inst.operands[2], scratch, sizeof (inst.operands[0]));
e1fa0163 16845 free (scratch);
5287ad62
JB
16846 }
16847 else
16848 {
16849 inst.operands[1] = inst.operands[2];
16850 inst.operands[2] = inst.operands[0];
16851 }
16852}
16853
16854static void
16855neon_compare (unsigned regtypes, unsigned immtypes, int invert)
16856{
16857 if (inst.operands[2].isreg)
16858 {
16859 if (invert)
477330fc 16860 neon_exchange_operands ();
dcbf9037 16861 neon_dyadic_misc (NT_unsigned, regtypes, N_SIZ);
5287ad62
JB
16862 }
16863 else
16864 {
037e8744 16865 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
dcbf9037 16866 struct neon_type_el et = neon_check_type (2, rs,
477330fc 16867 N_EQK | N_SIZ, immtypes | N_KEY);
5287ad62 16868
88714cb8 16869 NEON_ENCODE (IMMED, inst);
5287ad62
JB
16870 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16871 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16872 inst.instruction |= LOW4 (inst.operands[1].reg);
16873 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 16874 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16875 inst.instruction |= (et.type == NT_float) << 10;
16876 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 16877
88714cb8 16878 neon_dp_fixup (&inst);
5287ad62
JB
16879 }
16880}
16881
16882static void
16883do_neon_cmp (void)
16884{
cc933301 16885 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, FALSE);
5287ad62
JB
16886}
16887
16888static void
16889do_neon_cmp_inv (void)
16890{
cc933301 16891 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, TRUE);
5287ad62
JB
16892}
16893
16894static void
16895do_neon_ceq (void)
16896{
16897 neon_compare (N_IF_32, N_IF_32, FALSE);
16898}
16899
16900/* For multiply instructions, we have the possibility of 16-bit or 32-bit
16901 scalars, which are encoded in 5 bits, M : Rm.
16902 For 16-bit scalars, the register is encoded in Rm[2:0] and the index in
16903 M:Rm[3], and for 32-bit scalars, the register is encoded in Rm[3:0] and the
c604a79a
JW
16904 index in M.
16905
16906 Dot Product instructions are similar to multiply instructions except elsize
16907 should always be 32.
16908
16909 This function translates SCALAR, which is GAS's internal encoding of indexed
16910 scalar register, to raw encoding. There is also register and index range
16911 check based on ELSIZE. */
5287ad62
JB
16912
16913static unsigned
16914neon_scalar_for_mul (unsigned scalar, unsigned elsize)
16915{
dcbf9037
JB
16916 unsigned regno = NEON_SCALAR_REG (scalar);
16917 unsigned elno = NEON_SCALAR_INDEX (scalar);
5287ad62
JB
16918
16919 switch (elsize)
16920 {
16921 case 16:
16922 if (regno > 7 || elno > 3)
477330fc 16923 goto bad_scalar;
5287ad62 16924 return regno | (elno << 3);
5f4273c7 16925
5287ad62
JB
16926 case 32:
16927 if (regno > 15 || elno > 1)
477330fc 16928 goto bad_scalar;
5287ad62
JB
16929 return regno | (elno << 4);
16930
16931 default:
16932 bad_scalar:
dcbf9037 16933 first_error (_("scalar out of range for multiply instruction"));
5287ad62
JB
16934 }
16935
16936 return 0;
16937}
16938
16939/* Encode multiply / multiply-accumulate scalar instructions. */
16940
16941static void
16942neon_mul_mac (struct neon_type_el et, int ubit)
16943{
dcbf9037
JB
16944 unsigned scalar;
16945
16946 /* Give a more helpful error message if we have an invalid type. */
16947 if (et.type == NT_invtype)
16948 return;
5f4273c7 16949
dcbf9037 16950 scalar = neon_scalar_for_mul (inst.operands[2].reg, et.size);
5287ad62
JB
16951 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16952 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16953 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16954 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16955 inst.instruction |= LOW4 (scalar);
16956 inst.instruction |= HI1 (scalar) << 5;
16957 inst.instruction |= (et.type == NT_float) << 8;
16958 inst.instruction |= neon_logbits (et.size) << 20;
16959 inst.instruction |= (ubit != 0) << 24;
16960
88714cb8 16961 neon_dp_fixup (&inst);
5287ad62
JB
16962}
16963
16964static void
16965do_neon_mac_maybe_scalar (void)
16966{
037e8744
JB
16967 if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
16968 return;
16969
16970 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16971 return;
16972
5287ad62
JB
16973 if (inst.operands[2].isscalar)
16974 {
037e8744 16975 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 16976 struct neon_type_el et = neon_check_type (3, rs,
589a7d88 16977 N_EQK, N_EQK, N_I16 | N_I32 | N_F_16_32 | N_KEY);
88714cb8 16978 NEON_ENCODE (SCALAR, inst);
037e8744 16979 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
16980 }
16981 else
428e3f1f
PB
16982 {
16983 /* The "untyped" case can't happen. Do this to stop the "U" bit being
16984 affected if we specify unsigned args. */
16985 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
16986 }
5287ad62
JB
16987}
16988
62f3b8c8
PB
16989static void
16990do_neon_fmac (void)
16991{
d58196e0
AV
16992 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_fma)
16993 && try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS)
62f3b8c8
PB
16994 return;
16995
d58196e0 16996 if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH))
62f3b8c8
PB
16997 return;
16998
d58196e0
AV
16999 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
17000 {
17001 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_QQR, NS_NULL);
17002 struct neon_type_el et = neon_check_type (3, rs, N_F_MVE | N_KEY, N_EQK,
17003 N_EQK);
17004
17005 if (rs == NS_QQR)
17006 {
17007 if (inst.operands[2].reg == REG_SP)
17008 as_tsktsk (MVE_BAD_SP);
17009 else if (inst.operands[2].reg == REG_PC)
17010 as_tsktsk (MVE_BAD_PC);
17011
17012 inst.instruction = 0xee310e40;
17013 inst.instruction |= (et.size == 16) << 28;
17014 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17015 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17016 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17017 inst.instruction |= HI1 (inst.operands[1].reg) << 6;
17018 inst.instruction |= inst.operands[2].reg;
17019 inst.is_neon = 1;
17020 return;
17021 }
17022 }
17023 else
17024 {
17025 constraint (!inst.operands[2].isvec, BAD_FPU);
17026 }
17027
62f3b8c8
PB
17028 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
17029}
17030
5287ad62
JB
17031static void
17032do_neon_tst (void)
17033{
037e8744 17034 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
17035 struct neon_type_el et = neon_check_type (3, rs,
17036 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
037e8744 17037 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
17038}
17039
17040/* VMUL with 3 registers allows the P8 type. The scalar version supports the
17041 same types as the MAC equivalents. The polynomial type for this instruction
17042 is encoded the same as the integer type. */
17043
17044static void
17045do_neon_mul (void)
17046{
037e8744
JB
17047 if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
17048 return;
17049
17050 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
17051 return;
17052
5287ad62
JB
17053 if (inst.operands[2].isscalar)
17054 do_neon_mac_maybe_scalar ();
17055 else
cc933301 17056 neon_dyadic_misc (NT_poly, N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
5287ad62
JB
17057}
17058
17059static void
17060do_neon_qdmulh (void)
17061{
17062 if (inst.operands[2].isscalar)
17063 {
037e8744 17064 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 17065 struct neon_type_el et = neon_check_type (3, rs,
477330fc 17066 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 17067 NEON_ENCODE (SCALAR, inst);
037e8744 17068 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
17069 }
17070 else
17071 {
037e8744 17072 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 17073 struct neon_type_el et = neon_check_type (3, rs,
477330fc 17074 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 17075 NEON_ENCODE (INTEGER, inst);
5287ad62 17076 /* The U bit (rounding) comes from bit mask. */
037e8744 17077 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
17078 }
17079}
17080
26c1e780
AV
17081static void
17082do_mve_vaddv (void)
17083{
17084 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
17085 struct neon_type_el et
17086 = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
17087
17088 if (et.type == NT_invtype)
17089 first_error (BAD_EL_TYPE);
17090
17091 if (inst.cond > COND_ALWAYS)
17092 inst.pred_insn_type = INSIDE_VPT_INSN;
17093 else
17094 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17095
17096 constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
17097
17098 mve_encode_rq (et.type == NT_unsigned, et.size);
17099}
17100
7df54120
AV
17101static void
17102do_mve_vhcadd (void)
17103{
17104 enum neon_shape rs = neon_select_shape (NS_QQQI, NS_NULL);
17105 struct neon_type_el et
17106 = neon_check_type (3, rs, N_EQK, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
17107
17108 if (inst.cond > COND_ALWAYS)
17109 inst.pred_insn_type = INSIDE_VPT_INSN;
17110 else
17111 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17112
17113 unsigned rot = inst.relocs[0].exp.X_add_number;
17114 constraint (rot != 90 && rot != 270, _("immediate out of range"));
17115
17116 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
17117 as_tsktsk (_("Warning: 32-bit element size and same first and third "
17118 "operand makes instruction UNPREDICTABLE"));
17119
17120 mve_encode_qqq (0, et.size);
17121 inst.instruction |= (rot == 270) << 12;
17122 inst.is_neon = 1;
17123}
17124
c2dafc2a
AV
17125static void
17126do_mve_vadc (void)
17127{
17128 enum neon_shape rs = neon_select_shape (NS_QQQ, NS_NULL);
17129 struct neon_type_el et
17130 = neon_check_type (3, rs, N_KEY | N_I32, N_EQK, N_EQK);
17131
17132 if (et.type == NT_invtype)
17133 first_error (BAD_EL_TYPE);
17134
17135 if (inst.cond > COND_ALWAYS)
17136 inst.pred_insn_type = INSIDE_VPT_INSN;
17137 else
17138 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17139
17140 mve_encode_qqq (0, 64);
17141}
17142
17143static void
17144do_mve_vbrsr (void)
17145{
17146 enum neon_shape rs = neon_select_shape (NS_QQR, NS_NULL);
17147 struct neon_type_el et
17148 = neon_check_type (3, rs, N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
17149
17150 if (inst.cond > COND_ALWAYS)
17151 inst.pred_insn_type = INSIDE_VPT_INSN;
17152 else
17153 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17154
7df54120 17155 mve_encode_qqr (et.size, 0, 0);
c2dafc2a
AV
17156}
17157
17158static void
17159do_mve_vsbc (void)
17160{
17161 neon_check_type (3, NS_QQQ, N_EQK, N_EQK, N_I32 | N_KEY);
17162
17163 if (inst.cond > COND_ALWAYS)
17164 inst.pred_insn_type = INSIDE_VPT_INSN;
17165 else
17166 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17167
17168 mve_encode_qqq (1, 64);
17169}
17170
886e1c73
AV
17171static void
17172do_mve_vmull (void)
17173{
17174
17175 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_DDS,
17176 NS_QQS, NS_QQQ, NS_QQR, NS_NULL);
17177 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
17178 && inst.cond == COND_ALWAYS
17179 && ((unsigned)inst.instruction) == M_MNEM_vmullt)
17180 {
17181 if (rs == NS_QQQ)
17182 {
17183
17184 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
17185 N_SUF_32 | N_F64 | N_P8
17186 | N_P16 | N_I_MVE | N_KEY);
17187 if (((et.type == NT_poly) && et.size == 8
17188 && ARM_CPU_IS_ANY (cpu_variant))
17189 || (et.type == NT_integer) || (et.type == NT_float))
17190 goto neon_vmul;
17191 }
17192 else
17193 goto neon_vmul;
17194 }
17195
17196 constraint (rs != NS_QQQ, BAD_FPU);
17197 struct neon_type_el et = neon_check_type (3, rs, N_EQK , N_EQK,
17198 N_SU_32 | N_P8 | N_P16 | N_KEY);
17199
17200 /* We are dealing with MVE's vmullt. */
17201 if (et.size == 32
17202 && (inst.operands[0].reg == inst.operands[1].reg
17203 || inst.operands[0].reg == inst.operands[2].reg))
17204 as_tsktsk (BAD_MVE_SRCDEST);
17205
17206 if (inst.cond > COND_ALWAYS)
17207 inst.pred_insn_type = INSIDE_VPT_INSN;
17208 else
17209 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17210
17211 if (et.type == NT_poly)
17212 mve_encode_qqq (neon_logbits (et.size), 64);
17213 else
17214 mve_encode_qqq (et.type == NT_unsigned, et.size);
17215
17216 return;
17217
17218neon_vmul:
17219 inst.instruction = N_MNEM_vmul;
17220 inst.cond = 0xb;
17221 if (thumb_mode)
17222 inst.pred_insn_type = INSIDE_IT_INSN;
17223 do_neon_mul ();
17224}
17225
a302e574
AV
17226static void
17227do_mve_vabav (void)
17228{
17229 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
17230
17231 if (rs == NS_NULL)
17232 return;
17233
17234 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
17235 return;
17236
17237 struct neon_type_el et = neon_check_type (2, NS_NULL, N_EQK, N_KEY | N_S8
17238 | N_S16 | N_S32 | N_U8 | N_U16
17239 | N_U32);
17240
17241 if (inst.cond > COND_ALWAYS)
17242 inst.pred_insn_type = INSIDE_VPT_INSN;
17243 else
17244 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17245
17246 mve_encode_rqq (et.type == NT_unsigned, et.size);
17247}
17248
17249static void
17250do_mve_vmladav (void)
17251{
17252 enum neon_shape rs = neon_select_shape (NS_RQQ, NS_NULL);
17253 struct neon_type_el et = neon_check_type (3, rs,
17254 N_EQK, N_EQK, N_SU_MVE | N_KEY);
17255
17256 if (et.type == NT_unsigned
17257 && (inst.instruction == M_MNEM_vmladavx
17258 || inst.instruction == M_MNEM_vmladavax
17259 || inst.instruction == M_MNEM_vmlsdav
17260 || inst.instruction == M_MNEM_vmlsdava
17261 || inst.instruction == M_MNEM_vmlsdavx
17262 || inst.instruction == M_MNEM_vmlsdavax))
17263 first_error (BAD_SIMD_TYPE);
17264
17265 constraint (inst.operands[2].reg > 14,
17266 _("MVE vector register in the range [Q0..Q7] expected"));
17267
17268 if (inst.cond > COND_ALWAYS)
17269 inst.pred_insn_type = INSIDE_VPT_INSN;
17270 else
17271 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17272
17273 if (inst.instruction == M_MNEM_vmlsdav
17274 || inst.instruction == M_MNEM_vmlsdava
17275 || inst.instruction == M_MNEM_vmlsdavx
17276 || inst.instruction == M_MNEM_vmlsdavax)
17277 inst.instruction |= (et.size == 8) << 28;
17278 else
17279 inst.instruction |= (et.size == 8) << 8;
17280
17281 mve_encode_rqq (et.type == NT_unsigned, 64);
17282 inst.instruction |= (et.size == 32) << 16;
17283}
17284
93925576
AV
17285static void
17286do_mve_vmlaldav (void)
17287{
17288 enum neon_shape rs = neon_select_shape (NS_RRQQ, NS_NULL);
17289 struct neon_type_el et
17290 = neon_check_type (4, rs, N_EQK, N_EQK, N_EQK,
17291 N_S16 | N_S32 | N_U16 | N_U32 | N_KEY);
17292
17293 if (et.type == NT_unsigned
17294 && (inst.instruction == M_MNEM_vmlsldav
17295 || inst.instruction == M_MNEM_vmlsldava
17296 || inst.instruction == M_MNEM_vmlsldavx
17297 || inst.instruction == M_MNEM_vmlsldavax))
17298 first_error (BAD_SIMD_TYPE);
17299
17300 if (inst.cond > COND_ALWAYS)
17301 inst.pred_insn_type = INSIDE_VPT_INSN;
17302 else
17303 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17304
17305 mve_encode_rrqq (et.type == NT_unsigned, et.size);
17306}
17307
17308static void
17309do_mve_vrmlaldavh (void)
17310{
17311 struct neon_type_el et;
17312 if (inst.instruction == M_MNEM_vrmlsldavh
17313 || inst.instruction == M_MNEM_vrmlsldavha
17314 || inst.instruction == M_MNEM_vrmlsldavhx
17315 || inst.instruction == M_MNEM_vrmlsldavhax)
17316 {
17317 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
17318 if (inst.operands[1].reg == REG_SP)
17319 as_tsktsk (MVE_BAD_SP);
17320 }
17321 else
17322 {
17323 if (inst.instruction == M_MNEM_vrmlaldavhx
17324 || inst.instruction == M_MNEM_vrmlaldavhax)
17325 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK, N_S32 | N_KEY);
17326 else
17327 et = neon_check_type (4, NS_RRQQ, N_EQK, N_EQK, N_EQK,
17328 N_U32 | N_S32 | N_KEY);
17329 /* vrmlaldavh's encoding with SP as the second, odd, GPR operand may alias
17330 with vmax/min instructions, making the use of SP in assembly really
17331 nonsensical, so instead of issuing a warning like we do for other uses
17332 of SP for the odd register operand we error out. */
17333 constraint (inst.operands[1].reg == REG_SP, BAD_SP);
17334 }
17335
17336 /* Make sure we still check the second operand is an odd one and that PC is
17337 disallowed. This because we are parsing for any GPR operand, to be able
17338 to distinguish between giving a warning or an error for SP as described
17339 above. */
17340 constraint ((inst.operands[1].reg % 2) != 1, BAD_EVEN);
17341 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
17342
17343 if (inst.cond > COND_ALWAYS)
17344 inst.pred_insn_type = INSIDE_VPT_INSN;
17345 else
17346 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17347
17348 mve_encode_rrqq (et.type == NT_unsigned, 0);
17349}
17350
17351
8cd78170
AV
17352static void
17353do_mve_vmaxnmv (void)
17354{
17355 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
17356 struct neon_type_el et
17357 = neon_check_type (2, rs, N_EQK, N_F_MVE | N_KEY);
17358
17359 if (inst.cond > COND_ALWAYS)
17360 inst.pred_insn_type = INSIDE_VPT_INSN;
17361 else
17362 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17363
17364 if (inst.operands[0].reg == REG_SP)
17365 as_tsktsk (MVE_BAD_SP);
17366 else if (inst.operands[0].reg == REG_PC)
17367 as_tsktsk (MVE_BAD_PC);
17368
17369 mve_encode_rq (et.size == 16, 64);
17370}
17371
13ccd4c0
AV
17372static void
17373do_mve_vmaxv (void)
17374{
17375 enum neon_shape rs = neon_select_shape (NS_RQ, NS_NULL);
17376 struct neon_type_el et;
17377
17378 if (inst.instruction == M_MNEM_vmaxv || inst.instruction == M_MNEM_vminv)
17379 et = neon_check_type (2, rs, N_EQK, N_SU_MVE | N_KEY);
17380 else
17381 et = neon_check_type (2, rs, N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
17382
17383 if (inst.cond > COND_ALWAYS)
17384 inst.pred_insn_type = INSIDE_VPT_INSN;
17385 else
17386 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
17387
17388 if (inst.operands[0].reg == REG_SP)
17389 as_tsktsk (MVE_BAD_SP);
17390 else if (inst.operands[0].reg == REG_PC)
17391 as_tsktsk (MVE_BAD_PC);
17392
17393 mve_encode_rq (et.type == NT_unsigned, et.size);
17394}
17395
17396
643afb90
MW
17397static void
17398do_neon_qrdmlah (void)
17399{
17400 /* Check we're on the correct architecture. */
17401 if (!mark_feature_used (&fpu_neon_ext_armv8))
17402 inst.error =
17403 _("instruction form not available on this architecture.");
17404 else if (!mark_feature_used (&fpu_neon_ext_v8_1))
17405 {
17406 as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
17407 record_feature_use (&fpu_neon_ext_v8_1);
17408 }
17409
17410 if (inst.operands[2].isscalar)
17411 {
17412 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
17413 struct neon_type_el et = neon_check_type (3, rs,
17414 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
17415 NEON_ENCODE (SCALAR, inst);
17416 neon_mul_mac (et, neon_quad (rs));
17417 }
17418 else
17419 {
17420 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
17421 struct neon_type_el et = neon_check_type (3, rs,
17422 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
17423 NEON_ENCODE (INTEGER, inst);
17424 /* The U bit (rounding) comes from bit mask. */
17425 neon_three_same (neon_quad (rs), 0, et.size);
17426 }
17427}
17428
5287ad62
JB
17429static void
17430do_neon_fcmp_absolute (void)
17431{
037e8744 17432 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
17433 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
17434 N_F_16_32 | N_KEY);
5287ad62 17435 /* Size field comes from bit mask. */
cc933301 17436 neon_three_same (neon_quad (rs), 1, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
17437}
17438
17439static void
17440do_neon_fcmp_absolute_inv (void)
17441{
17442 neon_exchange_operands ();
17443 do_neon_fcmp_absolute ();
17444}
17445
17446static void
17447do_neon_step (void)
17448{
037e8744 17449 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
17450 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
17451 N_F_16_32 | N_KEY);
17452 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
17453}
17454
17455static void
17456do_neon_abs_neg (void)
17457{
037e8744
JB
17458 enum neon_shape rs;
17459 struct neon_type_el et;
5f4273c7 17460
037e8744
JB
17461 if (try_vfp_nsyn (2, do_vfp_nsyn_abs_neg) == SUCCESS)
17462 return;
17463
037e8744 17464 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
cc933301 17465 et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
5f4273c7 17466
485dee97
AV
17467 if (check_simd_pred_availability (et.type == NT_float,
17468 NEON_CHECK_ARCH | NEON_CHECK_CC))
17469 return;
17470
5287ad62
JB
17471 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17472 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17473 inst.instruction |= LOW4 (inst.operands[1].reg);
17474 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 17475 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
17476 inst.instruction |= (et.type == NT_float) << 10;
17477 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 17478
88714cb8 17479 neon_dp_fixup (&inst);
5287ad62
JB
17480}
17481
17482static void
17483do_neon_sli (void)
17484{
037e8744 17485 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
17486 struct neon_type_el et = neon_check_type (2, rs,
17487 N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
17488 int imm = inst.operands[2].imm;
17489 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 17490 _("immediate out of range for insert"));
037e8744 17491 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
17492}
17493
17494static void
17495do_neon_sri (void)
17496{
037e8744 17497 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
17498 struct neon_type_el et = neon_check_type (2, rs,
17499 N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
17500 int imm = inst.operands[2].imm;
17501 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 17502 _("immediate out of range for insert"));
037e8744 17503 neon_imm_shift (FALSE, 0, neon_quad (rs), et, et.size - imm);
5287ad62
JB
17504}
17505
17506static void
17507do_neon_qshlu_imm (void)
17508{
037e8744 17509 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
17510 struct neon_type_el et = neon_check_type (2, rs,
17511 N_EQK | N_UNS, N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
17512 int imm = inst.operands[2].imm;
17513 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 17514 _("immediate out of range for shift"));
5287ad62
JB
17515 /* Only encodes the 'U present' variant of the instruction.
17516 In this case, signed types have OP (bit 8) set to 0.
17517 Unsigned types have OP set to 1. */
17518 inst.instruction |= (et.type == NT_unsigned) << 8;
17519 /* The rest of the bits are the same as other immediate shifts. */
037e8744 17520 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
17521}
17522
17523static void
17524do_neon_qmovn (void)
17525{
17526 struct neon_type_el et = neon_check_type (2, NS_DQ,
17527 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
17528 /* Saturating move where operands can be signed or unsigned, and the
17529 destination has the same signedness. */
88714cb8 17530 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
17531 if (et.type == NT_unsigned)
17532 inst.instruction |= 0xc0;
17533 else
17534 inst.instruction |= 0x80;
17535 neon_two_same (0, 1, et.size / 2);
17536}
17537
17538static void
17539do_neon_qmovun (void)
17540{
17541 struct neon_type_el et = neon_check_type (2, NS_DQ,
17542 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
17543 /* Saturating move with unsigned results. Operands must be signed. */
88714cb8 17544 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
17545 neon_two_same (0, 1, et.size / 2);
17546}
17547
17548static void
17549do_neon_rshift_sat_narrow (void)
17550{
17551 /* FIXME: Types for narrowing. If operands are signed, results can be signed
17552 or unsigned. If operands are unsigned, results must also be unsigned. */
17553 struct neon_type_el et = neon_check_type (2, NS_DQI,
17554 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
17555 int imm = inst.operands[2].imm;
17556 /* This gets the bounds check, size encoding and immediate bits calculation
17557 right. */
17558 et.size /= 2;
5f4273c7 17559
5287ad62
JB
17560 /* VQ{R}SHRN.I<size> <Dd>, <Qm>, #0 is a synonym for
17561 VQMOVN.I<size> <Dd>, <Qm>. */
17562 if (imm == 0)
17563 {
17564 inst.operands[2].present = 0;
17565 inst.instruction = N_MNEM_vqmovn;
17566 do_neon_qmovn ();
17567 return;
17568 }
5f4273c7 17569
5287ad62 17570 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 17571 _("immediate out of range"));
5287ad62
JB
17572 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, et.size - imm);
17573}
17574
17575static void
17576do_neon_rshift_sat_narrow_u (void)
17577{
17578 /* FIXME: Types for narrowing. If operands are signed, results can be signed
17579 or unsigned. If operands are unsigned, results must also be unsigned. */
17580 struct neon_type_el et = neon_check_type (2, NS_DQI,
17581 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
17582 int imm = inst.operands[2].imm;
17583 /* This gets the bounds check, size encoding and immediate bits calculation
17584 right. */
17585 et.size /= 2;
17586
17587 /* VQSHRUN.I<size> <Dd>, <Qm>, #0 is a synonym for
17588 VQMOVUN.I<size> <Dd>, <Qm>. */
17589 if (imm == 0)
17590 {
17591 inst.operands[2].present = 0;
17592 inst.instruction = N_MNEM_vqmovun;
17593 do_neon_qmovun ();
17594 return;
17595 }
17596
17597 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 17598 _("immediate out of range"));
5287ad62
JB
17599 /* FIXME: The manual is kind of unclear about what value U should have in
17600 VQ{R}SHRUN instructions, but U=0, op=0 definitely encodes VRSHR, so it
17601 must be 1. */
17602 neon_imm_shift (TRUE, 1, 0, et, et.size - imm);
17603}
17604
17605static void
17606do_neon_movn (void)
17607{
17608 struct neon_type_el et = neon_check_type (2, NS_DQ,
17609 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
88714cb8 17610 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
17611 neon_two_same (0, 1, et.size / 2);
17612}
17613
17614static void
17615do_neon_rshift_narrow (void)
17616{
17617 struct neon_type_el et = neon_check_type (2, NS_DQI,
17618 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
17619 int imm = inst.operands[2].imm;
17620 /* This gets the bounds check, size encoding and immediate bits calculation
17621 right. */
17622 et.size /= 2;
5f4273c7 17623
5287ad62
JB
17624 /* If immediate is zero then we are a pseudo-instruction for
17625 VMOVN.I<size> <Dd>, <Qm> */
17626 if (imm == 0)
17627 {
17628 inst.operands[2].present = 0;
17629 inst.instruction = N_MNEM_vmovn;
17630 do_neon_movn ();
17631 return;
17632 }
5f4273c7 17633
5287ad62 17634 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 17635 _("immediate out of range for narrowing operation"));
5287ad62
JB
17636 neon_imm_shift (FALSE, 0, 0, et, et.size - imm);
17637}
17638
17639static void
17640do_neon_shll (void)
17641{
17642 /* FIXME: Type checking when lengthening. */
17643 struct neon_type_el et = neon_check_type (2, NS_QDI,
17644 N_EQK | N_DBL, N_I8 | N_I16 | N_I32 | N_KEY);
17645 unsigned imm = inst.operands[2].imm;
17646
17647 if (imm == et.size)
17648 {
17649 /* Maximum shift variant. */
88714cb8 17650 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
17651 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17652 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17653 inst.instruction |= LOW4 (inst.operands[1].reg);
17654 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
17655 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 17656
88714cb8 17657 neon_dp_fixup (&inst);
5287ad62
JB
17658 }
17659 else
17660 {
17661 /* A more-specific type check for non-max versions. */
17662 et = neon_check_type (2, NS_QDI,
477330fc 17663 N_EQK | N_DBL, N_SU_32 | N_KEY);
88714cb8 17664 NEON_ENCODE (IMMED, inst);
5287ad62
JB
17665 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, imm);
17666 }
17667}
17668
037e8744 17669/* Check the various types for the VCVT instruction, and return which version
5287ad62
JB
17670 the current instruction is. */
17671
6b9a8b67
MGD
17672#define CVT_FLAVOUR_VAR \
17673 CVT_VAR (s32_f32, N_S32, N_F32, whole_reg, "ftosls", "ftosis", "ftosizs") \
17674 CVT_VAR (u32_f32, N_U32, N_F32, whole_reg, "ftouls", "ftouis", "ftouizs") \
17675 CVT_VAR (f32_s32, N_F32, N_S32, whole_reg, "fsltos", "fsitos", NULL) \
17676 CVT_VAR (f32_u32, N_F32, N_U32, whole_reg, "fultos", "fuitos", NULL) \
17677 /* Half-precision conversions. */ \
cc933301
JW
17678 CVT_VAR (s16_f16, N_S16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
17679 CVT_VAR (u16_f16, N_U16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
17680 CVT_VAR (f16_s16, N_F16 | N_KEY, N_S16, whole_reg, NULL, NULL, NULL) \
17681 CVT_VAR (f16_u16, N_F16 | N_KEY, N_U16, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
17682 CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
17683 CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
9db2f6b4
RL
17684 /* New VCVT instructions introduced by ARMv8.2 fp16 extension. \
17685 Compared with single/double precision variants, only the co-processor \
17686 field is different, so the encoding flow is reused here. */ \
17687 CVT_VAR (f16_s32, N_F16 | N_KEY, N_S32, N_VFP, "fsltos", "fsitos", NULL) \
17688 CVT_VAR (f16_u32, N_F16 | N_KEY, N_U32, N_VFP, "fultos", "fuitos", NULL) \
17689 CVT_VAR (u32_f16, N_U32, N_F16 | N_KEY, N_VFP, "ftouls", "ftouis", "ftouizs")\
17690 CVT_VAR (s32_f16, N_S32, N_F16 | N_KEY, N_VFP, "ftosls", "ftosis", "ftosizs")\
6b9a8b67
MGD
17691 /* VFP instructions. */ \
17692 CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
17693 CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
17694 CVT_VAR (s32_f64, N_S32, N_F64 | key, N_VFP, "ftosld", "ftosid", "ftosizd") \
17695 CVT_VAR (u32_f64, N_U32, N_F64 | key, N_VFP, "ftould", "ftouid", "ftouizd") \
17696 CVT_VAR (f64_s32, N_F64 | key, N_S32, N_VFP, "fsltod", "fsitod", NULL) \
17697 CVT_VAR (f64_u32, N_F64 | key, N_U32, N_VFP, "fultod", "fuitod", NULL) \
17698 /* VFP instructions with bitshift. */ \
17699 CVT_VAR (f32_s16, N_F32 | key, N_S16, N_VFP, "fshtos", NULL, NULL) \
17700 CVT_VAR (f32_u16, N_F32 | key, N_U16, N_VFP, "fuhtos", NULL, NULL) \
17701 CVT_VAR (f64_s16, N_F64 | key, N_S16, N_VFP, "fshtod", NULL, NULL) \
17702 CVT_VAR (f64_u16, N_F64 | key, N_U16, N_VFP, "fuhtod", NULL, NULL) \
17703 CVT_VAR (s16_f32, N_S16, N_F32 | key, N_VFP, "ftoshs", NULL, NULL) \
17704 CVT_VAR (u16_f32, N_U16, N_F32 | key, N_VFP, "ftouhs", NULL, NULL) \
17705 CVT_VAR (s16_f64, N_S16, N_F64 | key, N_VFP, "ftoshd", NULL, NULL) \
17706 CVT_VAR (u16_f64, N_U16, N_F64 | key, N_VFP, "ftouhd", NULL, NULL)
17707
17708#define CVT_VAR(C, X, Y, R, BSN, CN, ZN) \
17709 neon_cvt_flavour_##C,
17710
17711/* The different types of conversions we can do. */
17712enum neon_cvt_flavour
17713{
17714 CVT_FLAVOUR_VAR
17715 neon_cvt_flavour_invalid,
17716 neon_cvt_flavour_first_fp = neon_cvt_flavour_f32_f64
17717};
17718
17719#undef CVT_VAR
17720
17721static enum neon_cvt_flavour
17722get_neon_cvt_flavour (enum neon_shape rs)
5287ad62 17723{
6b9a8b67
MGD
17724#define CVT_VAR(C,X,Y,R,BSN,CN,ZN) \
17725 et = neon_check_type (2, rs, (R) | (X), (R) | (Y)); \
17726 if (et.type != NT_invtype) \
17727 { \
17728 inst.error = NULL; \
17729 return (neon_cvt_flavour_##C); \
5287ad62 17730 }
6b9a8b67 17731
5287ad62 17732 struct neon_type_el et;
037e8744 17733 unsigned whole_reg = (rs == NS_FFI || rs == NS_FD || rs == NS_DF
477330fc 17734 || rs == NS_FF) ? N_VFP : 0;
037e8744
JB
17735 /* The instruction versions which take an immediate take one register
17736 argument, which is extended to the width of the full register. Thus the
17737 "source" and "destination" registers must have the same width. Hack that
17738 here by making the size equal to the key (wider, in this case) operand. */
17739 unsigned key = (rs == NS_QQI || rs == NS_DDI || rs == NS_FFI) ? N_KEY : 0;
5f4273c7 17740
6b9a8b67
MGD
17741 CVT_FLAVOUR_VAR;
17742
17743 return neon_cvt_flavour_invalid;
5287ad62
JB
17744#undef CVT_VAR
17745}
17746
7e8e6784
MGD
17747enum neon_cvt_mode
17748{
17749 neon_cvt_mode_a,
17750 neon_cvt_mode_n,
17751 neon_cvt_mode_p,
17752 neon_cvt_mode_m,
17753 neon_cvt_mode_z,
30bdf752
MGD
17754 neon_cvt_mode_x,
17755 neon_cvt_mode_r
7e8e6784
MGD
17756};
17757
037e8744
JB
17758/* Neon-syntax VFP conversions. */
17759
5287ad62 17760static void
6b9a8b67 17761do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
5287ad62 17762{
037e8744 17763 const char *opname = 0;
5f4273c7 17764
d54af2d0
RL
17765 if (rs == NS_DDI || rs == NS_QQI || rs == NS_FFI
17766 || rs == NS_FHI || rs == NS_HFI)
5287ad62 17767 {
037e8744
JB
17768 /* Conversions with immediate bitshift. */
17769 const char *enc[] =
477330fc 17770 {
6b9a8b67
MGD
17771#define CVT_VAR(C,A,B,R,BSN,CN,ZN) BSN,
17772 CVT_FLAVOUR_VAR
17773 NULL
17774#undef CVT_VAR
477330fc 17775 };
037e8744 17776
6b9a8b67 17777 if (flavour < (int) ARRAY_SIZE (enc))
477330fc
RM
17778 {
17779 opname = enc[flavour];
17780 constraint (inst.operands[0].reg != inst.operands[1].reg,
17781 _("operands 0 and 1 must be the same register"));
17782 inst.operands[1] = inst.operands[2];
17783 memset (&inst.operands[2], '\0', sizeof (inst.operands[2]));
17784 }
5287ad62
JB
17785 }
17786 else
17787 {
037e8744
JB
17788 /* Conversions without bitshift. */
17789 const char *enc[] =
477330fc 17790 {
6b9a8b67
MGD
17791#define CVT_VAR(C,A,B,R,BSN,CN,ZN) CN,
17792 CVT_FLAVOUR_VAR
17793 NULL
17794#undef CVT_VAR
477330fc 17795 };
037e8744 17796
6b9a8b67 17797 if (flavour < (int) ARRAY_SIZE (enc))
477330fc 17798 opname = enc[flavour];
037e8744
JB
17799 }
17800
17801 if (opname)
17802 do_vfp_nsyn_opcode (opname);
9db2f6b4
RL
17803
17804 /* ARMv8.2 fp16 VCVT instruction. */
17805 if (flavour == neon_cvt_flavour_s32_f16
17806 || flavour == neon_cvt_flavour_u32_f16
17807 || flavour == neon_cvt_flavour_f16_u32
17808 || flavour == neon_cvt_flavour_f16_s32)
17809 do_scalar_fp16_v82_encode ();
037e8744
JB
17810}
17811
17812static void
17813do_vfp_nsyn_cvtz (void)
17814{
d54af2d0 17815 enum neon_shape rs = neon_select_shape (NS_FH, NS_FF, NS_FD, NS_NULL);
6b9a8b67 17816 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744
JB
17817 const char *enc[] =
17818 {
6b9a8b67
MGD
17819#define CVT_VAR(C,A,B,R,BSN,CN,ZN) ZN,
17820 CVT_FLAVOUR_VAR
17821 NULL
17822#undef CVT_VAR
037e8744
JB
17823 };
17824
6b9a8b67 17825 if (flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
037e8744
JB
17826 do_vfp_nsyn_opcode (enc[flavour]);
17827}
f31fef98 17828
037e8744 17829static void
bacebabc 17830do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
7e8e6784
MGD
17831 enum neon_cvt_mode mode)
17832{
17833 int sz, op;
17834 int rm;
17835
a715796b
TG
17836 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
17837 D register operands. */
17838 if (flavour == neon_cvt_flavour_s32_f64
17839 || flavour == neon_cvt_flavour_u32_f64)
17840 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
17841 _(BAD_FPU));
17842
9db2f6b4
RL
17843 if (flavour == neon_cvt_flavour_s32_f16
17844 || flavour == neon_cvt_flavour_u32_f16)
17845 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
17846 _(BAD_FP16));
17847
5ee91343 17848 set_pred_insn_type (OUTSIDE_PRED_INSN);
7e8e6784
MGD
17849
17850 switch (flavour)
17851 {
17852 case neon_cvt_flavour_s32_f64:
17853 sz = 1;
827f64ff 17854 op = 1;
7e8e6784
MGD
17855 break;
17856 case neon_cvt_flavour_s32_f32:
17857 sz = 0;
17858 op = 1;
17859 break;
9db2f6b4
RL
17860 case neon_cvt_flavour_s32_f16:
17861 sz = 0;
17862 op = 1;
17863 break;
7e8e6784
MGD
17864 case neon_cvt_flavour_u32_f64:
17865 sz = 1;
17866 op = 0;
17867 break;
17868 case neon_cvt_flavour_u32_f32:
17869 sz = 0;
17870 op = 0;
17871 break;
9db2f6b4
RL
17872 case neon_cvt_flavour_u32_f16:
17873 sz = 0;
17874 op = 0;
17875 break;
7e8e6784
MGD
17876 default:
17877 first_error (_("invalid instruction shape"));
17878 return;
17879 }
17880
17881 switch (mode)
17882 {
17883 case neon_cvt_mode_a: rm = 0; break;
17884 case neon_cvt_mode_n: rm = 1; break;
17885 case neon_cvt_mode_p: rm = 2; break;
17886 case neon_cvt_mode_m: rm = 3; break;
17887 default: first_error (_("invalid rounding mode")); return;
17888 }
17889
17890 NEON_ENCODE (FPV8, inst);
17891 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
17892 encode_arm_vfp_reg (inst.operands[1].reg, sz == 1 ? VFP_REG_Dm : VFP_REG_Sm);
17893 inst.instruction |= sz << 8;
9db2f6b4
RL
17894
17895 /* ARMv8.2 fp16 VCVT instruction. */
17896 if (flavour == neon_cvt_flavour_s32_f16
17897 ||flavour == neon_cvt_flavour_u32_f16)
17898 do_scalar_fp16_v82_encode ();
7e8e6784
MGD
17899 inst.instruction |= op << 7;
17900 inst.instruction |= rm << 16;
17901 inst.instruction |= 0xf0000000;
17902 inst.is_neon = TRUE;
17903}
17904
17905static void
17906do_neon_cvt_1 (enum neon_cvt_mode mode)
037e8744
JB
17907{
17908 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
d54af2d0
RL
17909 NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ,
17910 NS_FH, NS_HF, NS_FHI, NS_HFI,
17911 NS_NULL);
6b9a8b67 17912 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744 17913
cc933301
JW
17914 if (flavour == neon_cvt_flavour_invalid)
17915 return;
17916
e3e535bc 17917 /* PR11109: Handle round-to-zero for VCVT conversions. */
7e8e6784 17918 if (mode == neon_cvt_mode_z
e3e535bc 17919 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
cc933301
JW
17920 && (flavour == neon_cvt_flavour_s16_f16
17921 || flavour == neon_cvt_flavour_u16_f16
17922 || flavour == neon_cvt_flavour_s32_f32
bacebabc
RM
17923 || flavour == neon_cvt_flavour_u32_f32
17924 || flavour == neon_cvt_flavour_s32_f64
6b9a8b67 17925 || flavour == neon_cvt_flavour_u32_f64)
e3e535bc
NC
17926 && (rs == NS_FD || rs == NS_FF))
17927 {
17928 do_vfp_nsyn_cvtz ();
17929 return;
17930 }
17931
9db2f6b4
RL
17932 /* ARMv8.2 fp16 VCVT conversions. */
17933 if (mode == neon_cvt_mode_z
17934 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16)
17935 && (flavour == neon_cvt_flavour_s32_f16
17936 || flavour == neon_cvt_flavour_u32_f16)
17937 && (rs == NS_FH))
17938 {
17939 do_vfp_nsyn_cvtz ();
17940 do_scalar_fp16_v82_encode ();
17941 return;
17942 }
17943
037e8744 17944 /* VFP rather than Neon conversions. */
6b9a8b67 17945 if (flavour >= neon_cvt_flavour_first_fp)
037e8744 17946 {
7e8e6784
MGD
17947 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
17948 do_vfp_nsyn_cvt (rs, flavour);
17949 else
17950 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
17951
037e8744
JB
17952 return;
17953 }
17954
17955 switch (rs)
17956 {
037e8744 17957 case NS_QQI:
dd9634d9
AV
17958 if (mode == neon_cvt_mode_z
17959 && (flavour == neon_cvt_flavour_f16_s16
17960 || flavour == neon_cvt_flavour_f16_u16
17961 || flavour == neon_cvt_flavour_s16_f16
17962 || flavour == neon_cvt_flavour_u16_f16
17963 || flavour == neon_cvt_flavour_f32_u32
17964 || flavour == neon_cvt_flavour_f32_s32
17965 || flavour == neon_cvt_flavour_s32_f32
17966 || flavour == neon_cvt_flavour_u32_f32))
17967 {
17968 if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH))
17969 return;
17970 }
17971 else if (mode == neon_cvt_mode_n)
17972 {
17973 /* We are dealing with vcvt with the 'ne' condition. */
17974 inst.cond = 0x1;
17975 inst.instruction = N_MNEM_vcvt;
17976 do_neon_cvt_1 (neon_cvt_mode_z);
17977 return;
17978 }
17979 /* fall through. */
17980 case NS_DDI:
037e8744 17981 {
477330fc 17982 unsigned immbits;
cc933301
JW
17983 unsigned enctab[] = {0x0000100, 0x1000100, 0x0, 0x1000000,
17984 0x0000100, 0x1000100, 0x0, 0x1000000};
35997600 17985
dd9634d9
AV
17986 if ((rs != NS_QQI || !ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
17987 && vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
17988 return;
17989
17990 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
17991 {
17992 constraint (inst.operands[2].present && inst.operands[2].imm == 0,
17993 _("immediate value out of range"));
17994 switch (flavour)
17995 {
17996 case neon_cvt_flavour_f16_s16:
17997 case neon_cvt_flavour_f16_u16:
17998 case neon_cvt_flavour_s16_f16:
17999 case neon_cvt_flavour_u16_f16:
18000 constraint (inst.operands[2].imm > 16,
18001 _("immediate value out of range"));
18002 break;
18003 case neon_cvt_flavour_f32_u32:
18004 case neon_cvt_flavour_f32_s32:
18005 case neon_cvt_flavour_s32_f32:
18006 case neon_cvt_flavour_u32_f32:
18007 constraint (inst.operands[2].imm > 32,
18008 _("immediate value out of range"));
18009 break;
18010 default:
18011 inst.error = BAD_FPU;
18012 return;
18013 }
18014 }
037e8744 18015
477330fc
RM
18016 /* Fixed-point conversion with #0 immediate is encoded as an
18017 integer conversion. */
18018 if (inst.operands[2].present && inst.operands[2].imm == 0)
18019 goto int_encode;
477330fc
RM
18020 NEON_ENCODE (IMMED, inst);
18021 if (flavour != neon_cvt_flavour_invalid)
18022 inst.instruction |= enctab[flavour];
18023 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18024 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18025 inst.instruction |= LOW4 (inst.operands[1].reg);
18026 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18027 inst.instruction |= neon_quad (rs) << 6;
18028 inst.instruction |= 1 << 21;
cc933301
JW
18029 if (flavour < neon_cvt_flavour_s16_f16)
18030 {
18031 inst.instruction |= 1 << 21;
18032 immbits = 32 - inst.operands[2].imm;
18033 inst.instruction |= immbits << 16;
18034 }
18035 else
18036 {
18037 inst.instruction |= 3 << 20;
18038 immbits = 16 - inst.operands[2].imm;
18039 inst.instruction |= immbits << 16;
18040 inst.instruction &= ~(1 << 9);
18041 }
477330fc
RM
18042
18043 neon_dp_fixup (&inst);
037e8744
JB
18044 }
18045 break;
18046
037e8744 18047 case NS_QQ:
dd9634d9
AV
18048 if ((mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
18049 || mode == neon_cvt_mode_m || mode == neon_cvt_mode_p)
18050 && (flavour == neon_cvt_flavour_s16_f16
18051 || flavour == neon_cvt_flavour_u16_f16
18052 || flavour == neon_cvt_flavour_s32_f32
18053 || flavour == neon_cvt_flavour_u32_f32))
18054 {
18055 if (check_simd_pred_availability (1,
18056 NEON_CHECK_CC | NEON_CHECK_ARCH8))
18057 return;
18058 }
18059 else if (mode == neon_cvt_mode_z
18060 && (flavour == neon_cvt_flavour_f16_s16
18061 || flavour == neon_cvt_flavour_f16_u16
18062 || flavour == neon_cvt_flavour_s16_f16
18063 || flavour == neon_cvt_flavour_u16_f16
18064 || flavour == neon_cvt_flavour_f32_u32
18065 || flavour == neon_cvt_flavour_f32_s32
18066 || flavour == neon_cvt_flavour_s32_f32
18067 || flavour == neon_cvt_flavour_u32_f32))
18068 {
18069 if (check_simd_pred_availability (1,
18070 NEON_CHECK_CC | NEON_CHECK_ARCH))
18071 return;
18072 }
18073 /* fall through. */
18074 case NS_DD:
7e8e6784
MGD
18075 if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
18076 {
7e8e6784 18077
dd9634d9
AV
18078 NEON_ENCODE (FLOAT, inst);
18079 if (check_simd_pred_availability (1,
18080 NEON_CHECK_CC | NEON_CHECK_ARCH8))
7e8e6784
MGD
18081 return;
18082
18083 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18084 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18085 inst.instruction |= LOW4 (inst.operands[1].reg);
18086 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18087 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
18088 inst.instruction |= (flavour == neon_cvt_flavour_u16_f16
18089 || flavour == neon_cvt_flavour_u32_f32) << 7;
7e8e6784 18090 inst.instruction |= mode << 8;
cc933301
JW
18091 if (flavour == neon_cvt_flavour_u16_f16
18092 || flavour == neon_cvt_flavour_s16_f16)
18093 /* Mask off the original size bits and reencode them. */
18094 inst.instruction = ((inst.instruction & 0xfff3ffff) | (1 << 18));
18095
7e8e6784
MGD
18096 if (thumb_mode)
18097 inst.instruction |= 0xfc000000;
18098 else
18099 inst.instruction |= 0xf0000000;
18100 }
18101 else
18102 {
037e8744 18103 int_encode:
7e8e6784 18104 {
cc933301
JW
18105 unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080,
18106 0x100, 0x180, 0x0, 0x080};
037e8744 18107
7e8e6784 18108 NEON_ENCODE (INTEGER, inst);
037e8744 18109
dd9634d9
AV
18110 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
18111 {
18112 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
18113 return;
18114 }
037e8744 18115
7e8e6784
MGD
18116 if (flavour != neon_cvt_flavour_invalid)
18117 inst.instruction |= enctab[flavour];
037e8744 18118
7e8e6784
MGD
18119 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18120 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18121 inst.instruction |= LOW4 (inst.operands[1].reg);
18122 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18123 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
18124 if (flavour >= neon_cvt_flavour_s16_f16
18125 && flavour <= neon_cvt_flavour_f16_u16)
18126 /* Half precision. */
18127 inst.instruction |= 1 << 18;
18128 else
18129 inst.instruction |= 2 << 18;
037e8744 18130
7e8e6784
MGD
18131 neon_dp_fixup (&inst);
18132 }
18133 }
18134 break;
037e8744 18135
8e79c3df
CM
18136 /* Half-precision conversions for Advanced SIMD -- neon. */
18137 case NS_QD:
18138 case NS_DQ:
bc52d49c
MM
18139 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
18140 return;
8e79c3df
CM
18141
18142 if ((rs == NS_DQ)
18143 && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
18144 {
18145 as_bad (_("operand size must match register width"));
18146 break;
18147 }
18148
18149 if ((rs == NS_QD)
18150 && ((inst.vectype.el[0].size != 32 || inst.vectype.el[1].size != 16)))
18151 {
18152 as_bad (_("operand size must match register width"));
18153 break;
18154 }
18155
18156 if (rs == NS_DQ)
477330fc 18157 inst.instruction = 0x3b60600;
8e79c3df
CM
18158 else
18159 inst.instruction = 0x3b60700;
18160
18161 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18162 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18163 inst.instruction |= LOW4 (inst.operands[1].reg);
18164 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
88714cb8 18165 neon_dp_fixup (&inst);
8e79c3df
CM
18166 break;
18167
037e8744
JB
18168 default:
18169 /* Some VFP conversions go here (s32 <-> f32, u32 <-> f32). */
7e8e6784
MGD
18170 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
18171 do_vfp_nsyn_cvt (rs, flavour);
18172 else
18173 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
5287ad62 18174 }
5287ad62
JB
18175}
18176
e3e535bc
NC
18177static void
18178do_neon_cvtr (void)
18179{
7e8e6784 18180 do_neon_cvt_1 (neon_cvt_mode_x);
e3e535bc
NC
18181}
18182
18183static void
18184do_neon_cvt (void)
18185{
7e8e6784
MGD
18186 do_neon_cvt_1 (neon_cvt_mode_z);
18187}
18188
18189static void
18190do_neon_cvta (void)
18191{
18192 do_neon_cvt_1 (neon_cvt_mode_a);
18193}
18194
18195static void
18196do_neon_cvtn (void)
18197{
18198 do_neon_cvt_1 (neon_cvt_mode_n);
18199}
18200
18201static void
18202do_neon_cvtp (void)
18203{
18204 do_neon_cvt_1 (neon_cvt_mode_p);
18205}
18206
18207static void
18208do_neon_cvtm (void)
18209{
18210 do_neon_cvt_1 (neon_cvt_mode_m);
e3e535bc
NC
18211}
18212
8e79c3df 18213static void
c70a8987 18214do_neon_cvttb_2 (bfd_boolean t, bfd_boolean to, bfd_boolean is_double)
8e79c3df 18215{
c70a8987
MGD
18216 if (is_double)
18217 mark_feature_used (&fpu_vfp_ext_armv8);
8e79c3df 18218
c70a8987
MGD
18219 encode_arm_vfp_reg (inst.operands[0].reg,
18220 (is_double && !to) ? VFP_REG_Dd : VFP_REG_Sd);
18221 encode_arm_vfp_reg (inst.operands[1].reg,
18222 (is_double && to) ? VFP_REG_Dm : VFP_REG_Sm);
18223 inst.instruction |= to ? 0x10000 : 0;
18224 inst.instruction |= t ? 0x80 : 0;
18225 inst.instruction |= is_double ? 0x100 : 0;
18226 do_vfp_cond_or_thumb ();
18227}
8e79c3df 18228
c70a8987
MGD
18229static void
18230do_neon_cvttb_1 (bfd_boolean t)
18231{
d54af2d0 18232 enum neon_shape rs = neon_select_shape (NS_HF, NS_HD, NS_FH, NS_FF, NS_FD,
dd9634d9 18233 NS_DF, NS_DH, NS_QQ, NS_QQI, NS_NULL);
8e79c3df 18234
c70a8987
MGD
18235 if (rs == NS_NULL)
18236 return;
dd9634d9
AV
18237 else if (rs == NS_QQ || rs == NS_QQI)
18238 {
18239 int single_to_half = 0;
18240 if (check_simd_pred_availability (1, NEON_CHECK_ARCH))
18241 return;
18242
18243 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
18244
18245 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
18246 && (flavour == neon_cvt_flavour_u16_f16
18247 || flavour == neon_cvt_flavour_s16_f16
18248 || flavour == neon_cvt_flavour_f16_s16
18249 || flavour == neon_cvt_flavour_f16_u16
18250 || flavour == neon_cvt_flavour_u32_f32
18251 || flavour == neon_cvt_flavour_s32_f32
18252 || flavour == neon_cvt_flavour_f32_s32
18253 || flavour == neon_cvt_flavour_f32_u32))
18254 {
18255 inst.cond = 0xf;
18256 inst.instruction = N_MNEM_vcvt;
18257 set_pred_insn_type (INSIDE_VPT_INSN);
18258 do_neon_cvt_1 (neon_cvt_mode_z);
18259 return;
18260 }
18261 else if (rs == NS_QQ && flavour == neon_cvt_flavour_f32_f16)
18262 single_to_half = 1;
18263 else if (rs == NS_QQ && flavour != neon_cvt_flavour_f16_f32)
18264 {
18265 first_error (BAD_FPU);
18266 return;
18267 }
18268
18269 inst.instruction = 0xee3f0e01;
18270 inst.instruction |= single_to_half << 28;
18271 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18272 inst.instruction |= LOW4 (inst.operands[0].reg) << 13;
18273 inst.instruction |= t << 12;
18274 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18275 inst.instruction |= LOW4 (inst.operands[1].reg) << 1;
18276 inst.is_neon = 1;
18277 }
c70a8987
MGD
18278 else if (neon_check_type (2, rs, N_F16, N_F32 | N_VFP).type != NT_invtype)
18279 {
18280 inst.error = NULL;
18281 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/FALSE);
18282 }
18283 else if (neon_check_type (2, rs, N_F32 | N_VFP, N_F16).type != NT_invtype)
18284 {
18285 inst.error = NULL;
18286 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/FALSE);
18287 }
18288 else if (neon_check_type (2, rs, N_F16, N_F64 | N_VFP).type != NT_invtype)
18289 {
a715796b
TG
18290 /* The VCVTB and VCVTT instructions with D-register operands
18291 don't work for SP only targets. */
18292 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18293 _(BAD_FPU));
18294
c70a8987
MGD
18295 inst.error = NULL;
18296 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/TRUE);
18297 }
18298 else if (neon_check_type (2, rs, N_F64 | N_VFP, N_F16).type != NT_invtype)
18299 {
a715796b
TG
18300 /* The VCVTB and VCVTT instructions with D-register operands
18301 don't work for SP only targets. */
18302 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18303 _(BAD_FPU));
18304
c70a8987
MGD
18305 inst.error = NULL;
18306 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/TRUE);
18307 }
18308 else
18309 return;
18310}
18311
18312static void
18313do_neon_cvtb (void)
18314{
18315 do_neon_cvttb_1 (FALSE);
8e79c3df
CM
18316}
18317
18318
18319static void
18320do_neon_cvtt (void)
18321{
c70a8987 18322 do_neon_cvttb_1 (TRUE);
8e79c3df
CM
18323}
18324
5287ad62
JB
18325static void
18326neon_move_immediate (void)
18327{
037e8744
JB
18328 enum neon_shape rs = neon_select_shape (NS_DI, NS_QI, NS_NULL);
18329 struct neon_type_el et = neon_check_type (2, rs,
18330 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
5287ad62 18331 unsigned immlo, immhi = 0, immbits;
c96612cc 18332 int op, cmode, float_p;
5287ad62 18333
037e8744 18334 constraint (et.type == NT_invtype,
477330fc 18335 _("operand size must be specified for immediate VMOV"));
037e8744 18336
5287ad62
JB
18337 /* We start out as an MVN instruction if OP = 1, MOV otherwise. */
18338 op = (inst.instruction & (1 << 5)) != 0;
18339
18340 immlo = inst.operands[1].imm;
18341 if (inst.operands[1].regisimm)
18342 immhi = inst.operands[1].reg;
18343
18344 constraint (et.size < 32 && (immlo & ~((1 << et.size) - 1)) != 0,
477330fc 18345 _("immediate has bits set outside the operand size"));
5287ad62 18346
c96612cc
JB
18347 float_p = inst.operands[1].immisfloat;
18348
18349 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits, &op,
477330fc 18350 et.size, et.type)) == FAIL)
5287ad62
JB
18351 {
18352 /* Invert relevant bits only. */
18353 neon_invert_size (&immlo, &immhi, et.size);
18354 /* Flip from VMOV/VMVN to VMVN/VMOV. Some immediate types are unavailable
477330fc
RM
18355 with one or the other; those cases are caught by
18356 neon_cmode_for_move_imm. */
5287ad62 18357 op = !op;
c96612cc
JB
18358 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits,
18359 &op, et.size, et.type)) == FAIL)
477330fc
RM
18360 {
18361 first_error (_("immediate out of range"));
18362 return;
18363 }
5287ad62
JB
18364 }
18365
18366 inst.instruction &= ~(1 << 5);
18367 inst.instruction |= op << 5;
18368
18369 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18370 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
037e8744 18371 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18372 inst.instruction |= cmode << 8;
18373
18374 neon_write_immbits (immbits);
18375}
18376
18377static void
18378do_neon_mvn (void)
18379{
18380 if (inst.operands[1].isreg)
18381 {
037e8744 18382 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5f4273c7 18383
88714cb8 18384 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18385 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18386 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18387 inst.instruction |= LOW4 (inst.operands[1].reg);
18388 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 18389 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18390 }
18391 else
18392 {
88714cb8 18393 NEON_ENCODE (IMMED, inst);
5287ad62
JB
18394 neon_move_immediate ();
18395 }
18396
88714cb8 18397 neon_dp_fixup (&inst);
5287ad62
JB
18398}
18399
18400/* Encode instructions of form:
18401
18402 |28/24|23|22|21 20|19 16|15 12|11 8|7|6|5|4|3 0|
5f4273c7 18403 | U |x |D |size | Rn | Rd |x x x x|N|x|M|x| Rm | */
5287ad62
JB
18404
18405static void
18406neon_mixed_length (struct neon_type_el et, unsigned size)
18407{
18408 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18409 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18410 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
18411 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
18412 inst.instruction |= LOW4 (inst.operands[2].reg);
18413 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
18414 inst.instruction |= (et.type == NT_unsigned) << 24;
18415 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 18416
88714cb8 18417 neon_dp_fixup (&inst);
5287ad62
JB
18418}
18419
18420static void
18421do_neon_dyadic_long (void)
18422{
5ee91343
AV
18423 enum neon_shape rs = neon_select_shape (NS_QDD, NS_QQQ, NS_QQR, NS_NULL);
18424 if (rs == NS_QDD)
18425 {
18426 if (vfp_or_neon_is_neon (NEON_CHECK_ARCH | NEON_CHECK_CC) == FAIL)
18427 return;
18428
18429 NEON_ENCODE (INTEGER, inst);
18430 /* FIXME: Type checking for lengthening op. */
18431 struct neon_type_el et = neon_check_type (3, NS_QDD,
18432 N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
18433 neon_mixed_length (et, et.size);
18434 }
18435 else if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
18436 && (inst.cond == 0xf || inst.cond == 0x10))
18437 {
18438 /* If parsing for MVE, vaddl/vsubl/vabdl{e,t} can only be vadd/vsub/vabd
18439 in an IT block with le/lt conditions. */
18440
18441 if (inst.cond == 0xf)
18442 inst.cond = 0xb;
18443 else if (inst.cond == 0x10)
18444 inst.cond = 0xd;
18445
18446 inst.pred_insn_type = INSIDE_IT_INSN;
18447
18448 if (inst.instruction == N_MNEM_vaddl)
18449 {
18450 inst.instruction = N_MNEM_vadd;
18451 do_neon_addsub_if_i ();
18452 }
18453 else if (inst.instruction == N_MNEM_vsubl)
18454 {
18455 inst.instruction = N_MNEM_vsub;
18456 do_neon_addsub_if_i ();
18457 }
18458 else if (inst.instruction == N_MNEM_vabdl)
18459 {
18460 inst.instruction = N_MNEM_vabd;
18461 do_neon_dyadic_if_su ();
18462 }
18463 }
18464 else
18465 first_error (BAD_FPU);
5287ad62
JB
18466}
18467
18468static void
18469do_neon_abal (void)
18470{
18471 struct neon_type_el et = neon_check_type (3, NS_QDD,
18472 N_EQK | N_INT | N_DBL, N_EQK, N_SU_32 | N_KEY);
18473 neon_mixed_length (et, et.size);
18474}
18475
18476static void
18477neon_mac_reg_scalar_long (unsigned regtypes, unsigned scalartypes)
18478{
18479 if (inst.operands[2].isscalar)
18480 {
dcbf9037 18481 struct neon_type_el et = neon_check_type (3, NS_QDS,
477330fc 18482 N_EQK | N_DBL, N_EQK, regtypes | N_KEY);
88714cb8 18483 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
18484 neon_mul_mac (et, et.type == NT_unsigned);
18485 }
18486 else
18487 {
18488 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 18489 N_EQK | N_DBL, N_EQK, scalartypes | N_KEY);
88714cb8 18490 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
18491 neon_mixed_length (et, et.size);
18492 }
18493}
18494
18495static void
18496do_neon_mac_maybe_scalar_long (void)
18497{
18498 neon_mac_reg_scalar_long (N_S16 | N_S32 | N_U16 | N_U32, N_SU_32);
18499}
18500
dec41383
JW
18501/* Like neon_scalar_for_mul, this function generate Rm encoding from GAS's
18502 internal SCALAR. QUAD_P is 1 if it's for Q format, otherwise it's 0. */
18503
18504static unsigned
18505neon_scalar_for_fmac_fp16_long (unsigned scalar, unsigned quad_p)
18506{
18507 unsigned regno = NEON_SCALAR_REG (scalar);
18508 unsigned elno = NEON_SCALAR_INDEX (scalar);
18509
18510 if (quad_p)
18511 {
18512 if (regno > 7 || elno > 3)
18513 goto bad_scalar;
18514
18515 return ((regno & 0x7)
18516 | ((elno & 0x1) << 3)
18517 | (((elno >> 1) & 0x1) << 5));
18518 }
18519 else
18520 {
18521 if (regno > 15 || elno > 1)
18522 goto bad_scalar;
18523
18524 return (((regno & 0x1) << 5)
18525 | ((regno >> 1) & 0x7)
18526 | ((elno & 0x1) << 3));
18527 }
18528
18529bad_scalar:
18530 first_error (_("scalar out of range for multiply instruction"));
18531 return 0;
18532}
18533
18534static void
18535do_neon_fmac_maybe_scalar_long (int subtype)
18536{
18537 enum neon_shape rs;
18538 int high8;
18539 /* NOTE: vfmal/vfmsl use slightly different NEON three-same encoding. 'size"
18540 field (bits[21:20]) has different meaning. For scalar index variant, it's
18541 used to differentiate add and subtract, otherwise it's with fixed value
18542 0x2. */
18543 int size = -1;
18544
18545 if (inst.cond != COND_ALWAYS)
18546 as_warn (_("vfmal/vfmsl with FP16 type cannot be conditional, the "
18547 "behaviour is UNPREDICTABLE"));
18548
01f48020 18549 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16_fml),
dec41383
JW
18550 _(BAD_FP16));
18551
18552 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
18553 _(BAD_FPU));
18554
18555 /* vfmal/vfmsl are in three-same D/Q register format or the third operand can
18556 be a scalar index register. */
18557 if (inst.operands[2].isscalar)
18558 {
18559 high8 = 0xfe000000;
18560 if (subtype)
18561 size = 16;
18562 rs = neon_select_shape (NS_DHS, NS_QDS, NS_NULL);
18563 }
18564 else
18565 {
18566 high8 = 0xfc000000;
18567 size = 32;
18568 if (subtype)
18569 inst.instruction |= (0x1 << 23);
18570 rs = neon_select_shape (NS_DHH, NS_QDD, NS_NULL);
18571 }
18572
18573 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16);
18574
18575 /* "opcode" from template has included "ubit", so simply pass 0 here. Also,
18576 the "S" bit in size field has been reused to differentiate vfmal and vfmsl,
18577 so we simply pass -1 as size. */
18578 unsigned quad_p = (rs == NS_QDD || rs == NS_QDS);
18579 neon_three_same (quad_p, 0, size);
18580
18581 /* Undo neon_dp_fixup. Redo the high eight bits. */
18582 inst.instruction &= 0x00ffffff;
18583 inst.instruction |= high8;
18584
18585#define LOW1(R) ((R) & 0x1)
18586#define HI4(R) (((R) >> 1) & 0xf)
18587 /* Unlike usually NEON three-same, encoding for Vn and Vm will depend on
18588 whether the instruction is in Q form and whether Vm is a scalar indexed
18589 operand. */
18590 if (inst.operands[2].isscalar)
18591 {
18592 unsigned rm
18593 = neon_scalar_for_fmac_fp16_long (inst.operands[2].reg, quad_p);
18594 inst.instruction &= 0xffffffd0;
18595 inst.instruction |= rm;
18596
18597 if (!quad_p)
18598 {
18599 /* Redo Rn as well. */
18600 inst.instruction &= 0xfff0ff7f;
18601 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
18602 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
18603 }
18604 }
18605 else if (!quad_p)
18606 {
18607 /* Redo Rn and Rm. */
18608 inst.instruction &= 0xfff0ff50;
18609 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
18610 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
18611 inst.instruction |= HI4 (inst.operands[2].reg);
18612 inst.instruction |= LOW1 (inst.operands[2].reg) << 5;
18613 }
18614}
18615
18616static void
18617do_neon_vfmal (void)
18618{
18619 return do_neon_fmac_maybe_scalar_long (0);
18620}
18621
18622static void
18623do_neon_vfmsl (void)
18624{
18625 return do_neon_fmac_maybe_scalar_long (1);
18626}
18627
5287ad62
JB
18628static void
18629do_neon_dyadic_wide (void)
18630{
18631 struct neon_type_el et = neon_check_type (3, NS_QQD,
18632 N_EQK | N_DBL, N_EQK | N_DBL, N_SU_32 | N_KEY);
18633 neon_mixed_length (et, et.size);
18634}
18635
18636static void
18637do_neon_dyadic_narrow (void)
18638{
18639 struct neon_type_el et = neon_check_type (3, NS_QDD,
18640 N_EQK | N_DBL, N_EQK, N_I16 | N_I32 | N_I64 | N_KEY);
428e3f1f
PB
18641 /* Operand sign is unimportant, and the U bit is part of the opcode,
18642 so force the operand type to integer. */
18643 et.type = NT_integer;
5287ad62
JB
18644 neon_mixed_length (et, et.size / 2);
18645}
18646
18647static void
18648do_neon_mul_sat_scalar_long (void)
18649{
18650 neon_mac_reg_scalar_long (N_S16 | N_S32, N_S16 | N_S32);
18651}
18652
18653static void
18654do_neon_vmull (void)
18655{
18656 if (inst.operands[2].isscalar)
18657 do_neon_mac_maybe_scalar_long ();
18658 else
18659 {
18660 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 18661 N_EQK | N_DBL, N_EQK, N_SU_32 | N_P8 | N_P64 | N_KEY);
4f51b4bd 18662
5287ad62 18663 if (et.type == NT_poly)
477330fc 18664 NEON_ENCODE (POLY, inst);
5287ad62 18665 else
477330fc 18666 NEON_ENCODE (INTEGER, inst);
4f51b4bd
MGD
18667
18668 /* For polynomial encoding the U bit must be zero, and the size must
18669 be 8 (encoded as 0b00) or, on ARMv8 or later 64 (encoded, non
18670 obviously, as 0b10). */
18671 if (et.size == 64)
18672 {
18673 /* Check we're on the correct architecture. */
18674 if (!mark_feature_used (&fpu_crypto_ext_armv8))
18675 inst.error =
18676 _("Instruction form not available on this architecture.");
18677
18678 et.size = 32;
18679 }
18680
5287ad62
JB
18681 neon_mixed_length (et, et.size);
18682 }
18683}
18684
18685static void
18686do_neon_ext (void)
18687{
037e8744 18688 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
5287ad62
JB
18689 struct neon_type_el et = neon_check_type (3, rs,
18690 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
18691 unsigned imm = (inst.operands[3].imm * et.size) / 8;
35997600
NC
18692
18693 constraint (imm >= (unsigned) (neon_quad (rs) ? 16 : 8),
18694 _("shift out of range"));
5287ad62
JB
18695 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18696 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18697 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
18698 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
18699 inst.instruction |= LOW4 (inst.operands[2].reg);
18700 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
037e8744 18701 inst.instruction |= neon_quad (rs) << 6;
5287ad62 18702 inst.instruction |= imm << 8;
5f4273c7 18703
88714cb8 18704 neon_dp_fixup (&inst);
5287ad62
JB
18705}
18706
18707static void
18708do_neon_rev (void)
18709{
037e8744 18710 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
18711 struct neon_type_el et = neon_check_type (2, rs,
18712 N_EQK, N_8 | N_16 | N_32 | N_KEY);
18713 unsigned op = (inst.instruction >> 7) & 3;
18714 /* N (width of reversed regions) is encoded as part of the bitmask. We
18715 extract it here to check the elements to be reversed are smaller.
18716 Otherwise we'd get a reserved instruction. */
18717 unsigned elsize = (op == 2) ? 16 : (op == 1) ? 32 : (op == 0) ? 64 : 0;
9c2799c2 18718 gas_assert (elsize != 0);
5287ad62 18719 constraint (et.size >= elsize,
477330fc 18720 _("elements must be smaller than reversal region"));
037e8744 18721 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
18722}
18723
18724static void
18725do_neon_dup (void)
18726{
18727 if (inst.operands[1].isscalar)
18728 {
b409bdb6
AV
18729 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
18730 BAD_FPU);
037e8744 18731 enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
dcbf9037 18732 struct neon_type_el et = neon_check_type (2, rs,
477330fc 18733 N_EQK, N_8 | N_16 | N_32 | N_KEY);
5287ad62 18734 unsigned sizebits = et.size >> 3;
dcbf9037 18735 unsigned dm = NEON_SCALAR_REG (inst.operands[1].reg);
5287ad62 18736 int logsize = neon_logbits (et.size);
dcbf9037 18737 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg) << logsize;
037e8744
JB
18738
18739 if (vfp_or_neon_is_neon (NEON_CHECK_CC) == FAIL)
477330fc 18740 return;
037e8744 18741
88714cb8 18742 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
18743 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18744 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18745 inst.instruction |= LOW4 (dm);
18746 inst.instruction |= HI1 (dm) << 5;
037e8744 18747 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
18748 inst.instruction |= x << 17;
18749 inst.instruction |= sizebits << 16;
5f4273c7 18750
88714cb8 18751 neon_dp_fixup (&inst);
5287ad62
JB
18752 }
18753 else
18754 {
037e8744
JB
18755 enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
18756 struct neon_type_el et = neon_check_type (2, rs,
477330fc 18757 N_8 | N_16 | N_32 | N_KEY, N_EQK);
b409bdb6
AV
18758 if (rs == NS_QR)
18759 {
18760 if (check_simd_pred_availability (0, NEON_CHECK_ARCH))
18761 return;
18762 }
18763 else
18764 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1),
18765 BAD_FPU);
18766
18767 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18768 {
18769 if (inst.operands[1].reg == REG_SP)
18770 as_tsktsk (MVE_BAD_SP);
18771 else if (inst.operands[1].reg == REG_PC)
18772 as_tsktsk (MVE_BAD_PC);
18773 }
18774
5287ad62 18775 /* Duplicate ARM register to lanes of vector. */
88714cb8 18776 NEON_ENCODE (ARMREG, inst);
5287ad62 18777 switch (et.size)
477330fc
RM
18778 {
18779 case 8: inst.instruction |= 0x400000; break;
18780 case 16: inst.instruction |= 0x000020; break;
18781 case 32: inst.instruction |= 0x000000; break;
18782 default: break;
18783 }
5287ad62
JB
18784 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
18785 inst.instruction |= LOW4 (inst.operands[0].reg) << 16;
18786 inst.instruction |= HI1 (inst.operands[0].reg) << 7;
037e8744 18787 inst.instruction |= neon_quad (rs) << 21;
5287ad62 18788 /* The encoding for this instruction is identical for the ARM and Thumb
477330fc 18789 variants, except for the condition field. */
037e8744 18790 do_vfp_cond_or_thumb ();
5287ad62
JB
18791 }
18792}
18793
57785aa2
AV
18794static void
18795do_mve_mov (int toQ)
18796{
18797 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18798 return;
18799 if (inst.cond > COND_ALWAYS)
18800 inst.pred_insn_type = MVE_UNPREDICABLE_INSN;
18801
18802 unsigned Rt = 0, Rt2 = 1, Q0 = 2, Q1 = 3;
18803 if (toQ)
18804 {
18805 Q0 = 0;
18806 Q1 = 1;
18807 Rt = 2;
18808 Rt2 = 3;
18809 }
18810
18811 constraint (inst.operands[Q0].reg != inst.operands[Q1].reg + 2,
18812 _("Index one must be [2,3] and index two must be two less than"
18813 " index one."));
18814 constraint (inst.operands[Rt].reg == inst.operands[Rt2].reg,
18815 _("General purpose registers may not be the same"));
18816 constraint (inst.operands[Rt].reg == REG_SP
18817 || inst.operands[Rt2].reg == REG_SP,
18818 BAD_SP);
18819 constraint (inst.operands[Rt].reg == REG_PC
18820 || inst.operands[Rt2].reg == REG_PC,
18821 BAD_PC);
18822
18823 inst.instruction = 0xec000f00;
18824 inst.instruction |= HI1 (inst.operands[Q1].reg / 32) << 23;
18825 inst.instruction |= !!toQ << 20;
18826 inst.instruction |= inst.operands[Rt2].reg << 16;
18827 inst.instruction |= LOW4 (inst.operands[Q1].reg / 32) << 13;
18828 inst.instruction |= (inst.operands[Q1].reg % 4) << 4;
18829 inst.instruction |= inst.operands[Rt].reg;
18830}
18831
18832static void
18833do_mve_movn (void)
18834{
18835 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18836 return;
18837
18838 if (inst.cond > COND_ALWAYS)
18839 inst.pred_insn_type = INSIDE_VPT_INSN;
18840 else
18841 inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
18842
18843 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_I16 | N_I32
18844 | N_KEY);
18845
18846 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18847 inst.instruction |= (neon_logbits (et.size) - 1) << 18;
18848 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18849 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18850 inst.instruction |= LOW4 (inst.operands[1].reg);
18851 inst.is_neon = 1;
18852
18853}
18854
5287ad62
JB
18855/* VMOV has particularly many variations. It can be one of:
18856 0. VMOV<c><q> <Qd>, <Qm>
18857 1. VMOV<c><q> <Dd>, <Dm>
18858 (Register operations, which are VORR with Rm = Rn.)
18859 2. VMOV<c><q>.<dt> <Qd>, #<imm>
18860 3. VMOV<c><q>.<dt> <Dd>, #<imm>
18861 (Immediate loads.)
18862 4. VMOV<c><q>.<size> <Dn[x]>, <Rd>
18863 (ARM register to scalar.)
18864 5. VMOV<c><q> <Dm>, <Rd>, <Rn>
18865 (Two ARM registers to vector.)
18866 6. VMOV<c><q>.<dt> <Rd>, <Dn[x]>
18867 (Scalar to ARM register.)
18868 7. VMOV<c><q> <Rd>, <Rn>, <Dm>
18869 (Vector to two ARM registers.)
037e8744
JB
18870 8. VMOV.F32 <Sd>, <Sm>
18871 9. VMOV.F64 <Dd>, <Dm>
18872 (VFP register moves.)
18873 10. VMOV.F32 <Sd>, #imm
18874 11. VMOV.F64 <Dd>, #imm
18875 (VFP float immediate load.)
18876 12. VMOV <Rd>, <Sm>
18877 (VFP single to ARM reg.)
18878 13. VMOV <Sd>, <Rm>
18879 (ARM reg to VFP single.)
18880 14. VMOV <Rd>, <Re>, <Sn>, <Sm>
18881 (Two ARM regs to two VFP singles.)
18882 15. VMOV <Sd>, <Se>, <Rn>, <Rm>
18883 (Two VFP singles to two ARM regs.)
57785aa2
AV
18884 16. VMOV<c> <Rt>, <Rt2>, <Qd[idx]>, <Qd[idx2]>
18885 17. VMOV<c> <Qd[idx]>, <Qd[idx2]>, <Rt>, <Rt2>
18886 18. VMOV<c>.<dt> <Rt>, <Qn[idx]>
18887 19. VMOV<c>.<dt> <Qd[idx]>, <Rt>
5f4273c7 18888
037e8744
JB
18889 These cases can be disambiguated using neon_select_shape, except cases 1/9
18890 and 3/11 which depend on the operand type too.
5f4273c7 18891
5287ad62 18892 All the encoded bits are hardcoded by this function.
5f4273c7 18893
b7fc2769
JB
18894 Cases 4, 6 may be used with VFPv1 and above (only 32-bit transfers!).
18895 Cases 5, 7 may be used with VFPv2 and above.
5f4273c7 18896
5287ad62 18897 FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
5f4273c7 18898 can specify a type where it doesn't make sense to, and is ignored). */
5287ad62
JB
18899
18900static void
18901do_neon_mov (void)
18902{
57785aa2
AV
18903 enum neon_shape rs = neon_select_shape (NS_RRSS, NS_SSRR, NS_RRFF, NS_FFRR,
18904 NS_DRR, NS_RRD, NS_QQ, NS_DD, NS_QI,
18905 NS_DI, NS_SR, NS_RS, NS_FF, NS_FI,
18906 NS_RF, NS_FR, NS_HR, NS_RH, NS_HI,
18907 NS_NULL);
037e8744
JB
18908 struct neon_type_el et;
18909 const char *ldconst = 0;
5287ad62 18910
037e8744 18911 switch (rs)
5287ad62 18912 {
037e8744
JB
18913 case NS_DD: /* case 1/9. */
18914 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
18915 /* It is not an error here if no type is given. */
18916 inst.error = NULL;
18917 if (et.type == NT_float && et.size == 64)
477330fc
RM
18918 {
18919 do_vfp_nsyn_opcode ("fcpyd");
18920 break;
18921 }
037e8744 18922 /* fall through. */
5287ad62 18923
037e8744
JB
18924 case NS_QQ: /* case 0/1. */
18925 {
57785aa2 18926 if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc
RM
18927 return;
18928 /* The architecture manual I have doesn't explicitly state which
18929 value the U bit should have for register->register moves, but
18930 the equivalent VORR instruction has U = 0, so do that. */
18931 inst.instruction = 0x0200110;
18932 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18933 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18934 inst.instruction |= LOW4 (inst.operands[1].reg);
18935 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18936 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
18937 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
18938 inst.instruction |= neon_quad (rs) << 6;
18939
18940 neon_dp_fixup (&inst);
037e8744
JB
18941 }
18942 break;
5f4273c7 18943
037e8744
JB
18944 case NS_DI: /* case 3/11. */
18945 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
18946 inst.error = NULL;
18947 if (et.type == NT_float && et.size == 64)
477330fc
RM
18948 {
18949 /* case 11 (fconstd). */
18950 ldconst = "fconstd";
18951 goto encode_fconstd;
18952 }
037e8744
JB
18953 /* fall through. */
18954
18955 case NS_QI: /* case 2/3. */
57785aa2 18956 if (check_simd_pred_availability (0, NEON_CHECK_CC | NEON_CHECK_ARCH))
477330fc 18957 return;
037e8744
JB
18958 inst.instruction = 0x0800010;
18959 neon_move_immediate ();
88714cb8 18960 neon_dp_fixup (&inst);
5287ad62 18961 break;
5f4273c7 18962
037e8744
JB
18963 case NS_SR: /* case 4. */
18964 {
477330fc
RM
18965 unsigned bcdebits = 0;
18966 int logsize;
18967 unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
18968 unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
037e8744 18969
05ac0ffb
JB
18970 /* .<size> is optional here, defaulting to .32. */
18971 if (inst.vectype.elems == 0
18972 && inst.operands[0].vectype.type == NT_invtype
18973 && inst.operands[1].vectype.type == NT_invtype)
18974 {
18975 inst.vectype.el[0].type = NT_untyped;
18976 inst.vectype.el[0].size = 32;
18977 inst.vectype.elems = 1;
18978 }
18979
477330fc
RM
18980 et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
18981 logsize = neon_logbits (et.size);
18982
57785aa2
AV
18983 if (et.size != 32)
18984 {
18985 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
18986 && vfp_or_neon_is_neon (NEON_CHECK_ARCH) == FAIL)
18987 return;
18988 }
18989 else
18990 {
18991 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
18992 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
18993 _(BAD_FPU));
18994 }
18995
18996 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
18997 {
18998 if (inst.operands[1].reg == REG_SP)
18999 as_tsktsk (MVE_BAD_SP);
19000 else if (inst.operands[1].reg == REG_PC)
19001 as_tsktsk (MVE_BAD_PC);
19002 }
19003 unsigned size = inst.operands[0].isscalar == 1 ? 64 : 128;
19004
477330fc 19005 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2
AV
19006 constraint (x >= size / et.size, _("scalar index out of range"));
19007
477330fc
RM
19008
19009 switch (et.size)
19010 {
19011 case 8: bcdebits = 0x8; break;
19012 case 16: bcdebits = 0x1; break;
19013 case 32: bcdebits = 0x0; break;
19014 default: ;
19015 }
19016
57785aa2 19017 bcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
19018
19019 inst.instruction = 0xe000b10;
19020 do_vfp_cond_or_thumb ();
19021 inst.instruction |= LOW4 (dn) << 16;
19022 inst.instruction |= HI1 (dn) << 7;
19023 inst.instruction |= inst.operands[1].reg << 12;
19024 inst.instruction |= (bcdebits & 3) << 5;
57785aa2
AV
19025 inst.instruction |= ((bcdebits >> 2) & 3) << 21;
19026 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
19027 }
19028 break;
5f4273c7 19029
037e8744 19030 case NS_DRR: /* case 5 (fmdrr). */
57785aa2
AV
19031 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19032 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 19033 _(BAD_FPU));
b7fc2769 19034
037e8744
JB
19035 inst.instruction = 0xc400b10;
19036 do_vfp_cond_or_thumb ();
19037 inst.instruction |= LOW4 (inst.operands[0].reg);
19038 inst.instruction |= HI1 (inst.operands[0].reg) << 5;
19039 inst.instruction |= inst.operands[1].reg << 12;
19040 inst.instruction |= inst.operands[2].reg << 16;
19041 break;
5f4273c7 19042
037e8744
JB
19043 case NS_RS: /* case 6. */
19044 {
477330fc
RM
19045 unsigned logsize;
19046 unsigned dn = NEON_SCALAR_REG (inst.operands[1].reg);
19047 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
19048 unsigned abcdebits = 0;
037e8744 19049
05ac0ffb
JB
19050 /* .<dt> is optional here, defaulting to .32. */
19051 if (inst.vectype.elems == 0
19052 && inst.operands[0].vectype.type == NT_invtype
19053 && inst.operands[1].vectype.type == NT_invtype)
19054 {
19055 inst.vectype.el[0].type = NT_untyped;
19056 inst.vectype.el[0].size = 32;
19057 inst.vectype.elems = 1;
19058 }
19059
91d6fa6a
NC
19060 et = neon_check_type (2, NS_NULL,
19061 N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
477330fc
RM
19062 logsize = neon_logbits (et.size);
19063
57785aa2
AV
19064 if (et.size != 32)
19065 {
19066 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
19067 && vfp_or_neon_is_neon (NEON_CHECK_CC
19068 | NEON_CHECK_ARCH) == FAIL)
19069 return;
19070 }
19071 else
19072 {
19073 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1)
19074 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
19075 _(BAD_FPU));
19076 }
19077
19078 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19079 {
19080 if (inst.operands[0].reg == REG_SP)
19081 as_tsktsk (MVE_BAD_SP);
19082 else if (inst.operands[0].reg == REG_PC)
19083 as_tsktsk (MVE_BAD_PC);
19084 }
19085
19086 unsigned size = inst.operands[1].isscalar == 1 ? 64 : 128;
19087
477330fc 19088 constraint (et.type == NT_invtype, _("bad type for scalar"));
57785aa2 19089 constraint (x >= size / et.size, _("scalar index out of range"));
477330fc
RM
19090
19091 switch (et.size)
19092 {
19093 case 8: abcdebits = (et.type == NT_signed) ? 0x08 : 0x18; break;
19094 case 16: abcdebits = (et.type == NT_signed) ? 0x01 : 0x11; break;
19095 case 32: abcdebits = 0x00; break;
19096 default: ;
19097 }
19098
57785aa2 19099 abcdebits |= (x & ((1 << (3-logsize)) - 1)) << logsize;
477330fc
RM
19100 inst.instruction = 0xe100b10;
19101 do_vfp_cond_or_thumb ();
19102 inst.instruction |= LOW4 (dn) << 16;
19103 inst.instruction |= HI1 (dn) << 7;
19104 inst.instruction |= inst.operands[0].reg << 12;
19105 inst.instruction |= (abcdebits & 3) << 5;
19106 inst.instruction |= (abcdebits >> 2) << 21;
57785aa2 19107 inst.instruction |= (x >> (3-logsize)) << 16;
037e8744
JB
19108 }
19109 break;
5f4273c7 19110
037e8744 19111 case NS_RRD: /* case 7 (fmrrd). */
57785aa2
AV
19112 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19113 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
477330fc 19114 _(BAD_FPU));
037e8744
JB
19115
19116 inst.instruction = 0xc500b10;
19117 do_vfp_cond_or_thumb ();
19118 inst.instruction |= inst.operands[0].reg << 12;
19119 inst.instruction |= inst.operands[1].reg << 16;
19120 inst.instruction |= LOW4 (inst.operands[2].reg);
19121 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
19122 break;
5f4273c7 19123
037e8744
JB
19124 case NS_FF: /* case 8 (fcpys). */
19125 do_vfp_nsyn_opcode ("fcpys");
19126 break;
5f4273c7 19127
9db2f6b4 19128 case NS_HI:
037e8744
JB
19129 case NS_FI: /* case 10 (fconsts). */
19130 ldconst = "fconsts";
4ef4710f 19131 encode_fconstd:
58ed5c38
TC
19132 if (!inst.operands[1].immisfloat)
19133 {
4ef4710f 19134 unsigned new_imm;
58ed5c38 19135 /* Immediate has to fit in 8 bits so float is enough. */
4ef4710f
NC
19136 float imm = (float) inst.operands[1].imm;
19137 memcpy (&new_imm, &imm, sizeof (float));
19138 /* But the assembly may have been written to provide an integer
19139 bit pattern that equates to a float, so check that the
19140 conversion has worked. */
19141 if (is_quarter_float (new_imm))
19142 {
19143 if (is_quarter_float (inst.operands[1].imm))
19144 as_warn (_("immediate constant is valid both as a bit-pattern and a floating point value (using the fp value)"));
19145
19146 inst.operands[1].imm = new_imm;
19147 inst.operands[1].immisfloat = 1;
19148 }
58ed5c38
TC
19149 }
19150
037e8744 19151 if (is_quarter_float (inst.operands[1].imm))
477330fc
RM
19152 {
19153 inst.operands[1].imm = neon_qfloat_bits (inst.operands[1].imm);
19154 do_vfp_nsyn_opcode (ldconst);
9db2f6b4
RL
19155
19156 /* ARMv8.2 fp16 vmov.f16 instruction. */
19157 if (rs == NS_HI)
19158 do_scalar_fp16_v82_encode ();
477330fc 19159 }
5287ad62 19160 else
477330fc 19161 first_error (_("immediate out of range"));
037e8744 19162 break;
5f4273c7 19163
9db2f6b4 19164 case NS_RH:
037e8744
JB
19165 case NS_RF: /* case 12 (fmrs). */
19166 do_vfp_nsyn_opcode ("fmrs");
9db2f6b4
RL
19167 /* ARMv8.2 fp16 vmov.f16 instruction. */
19168 if (rs == NS_RH)
19169 do_scalar_fp16_v82_encode ();
037e8744 19170 break;
5f4273c7 19171
9db2f6b4 19172 case NS_HR:
037e8744
JB
19173 case NS_FR: /* case 13 (fmsr). */
19174 do_vfp_nsyn_opcode ("fmsr");
9db2f6b4
RL
19175 /* ARMv8.2 fp16 vmov.f16 instruction. */
19176 if (rs == NS_HR)
19177 do_scalar_fp16_v82_encode ();
037e8744 19178 break;
5f4273c7 19179
57785aa2
AV
19180 case NS_RRSS:
19181 do_mve_mov (0);
19182 break;
19183 case NS_SSRR:
19184 do_mve_mov (1);
19185 break;
19186
037e8744
JB
19187 /* The encoders for the fmrrs and fmsrr instructions expect three operands
19188 (one of which is a list), but we have parsed four. Do some fiddling to
19189 make the operands what do_vfp_reg2_from_sp2 and do_vfp_sp2_from_reg2
19190 expect. */
19191 case NS_RRFF: /* case 14 (fmrrs). */
57785aa2
AV
19192 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19193 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
19194 _(BAD_FPU));
037e8744 19195 constraint (inst.operands[3].reg != inst.operands[2].reg + 1,
477330fc 19196 _("VFP registers must be adjacent"));
037e8744
JB
19197 inst.operands[2].imm = 2;
19198 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
19199 do_vfp_nsyn_opcode ("fmrrs");
19200 break;
5f4273c7 19201
037e8744 19202 case NS_FFRR: /* case 15 (fmsrr). */
57785aa2
AV
19203 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2)
19204 && !ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext),
19205 _(BAD_FPU));
037e8744 19206 constraint (inst.operands[1].reg != inst.operands[0].reg + 1,
477330fc 19207 _("VFP registers must be adjacent"));
037e8744
JB
19208 inst.operands[1] = inst.operands[2];
19209 inst.operands[2] = inst.operands[3];
19210 inst.operands[0].imm = 2;
19211 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
19212 do_vfp_nsyn_opcode ("fmsrr");
5287ad62 19213 break;
5f4273c7 19214
4c261dff
NC
19215 case NS_NULL:
19216 /* neon_select_shape has determined that the instruction
19217 shape is wrong and has already set the error message. */
19218 break;
19219
5287ad62
JB
19220 default:
19221 abort ();
19222 }
19223}
19224
57785aa2
AV
19225static void
19226do_mve_movl (void)
19227{
19228 if (!(inst.operands[0].present && inst.operands[0].isquad
19229 && inst.operands[1].present && inst.operands[1].isquad
19230 && !inst.operands[2].present))
19231 {
19232 inst.instruction = 0;
19233 inst.cond = 0xb;
19234 if (thumb_mode)
19235 set_pred_insn_type (INSIDE_IT_INSN);
19236 do_neon_mov ();
19237 return;
19238 }
19239
19240 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19241 return;
19242
19243 if (inst.cond != COND_ALWAYS)
19244 inst.pred_insn_type = INSIDE_VPT_INSN;
19245
19246 struct neon_type_el et = neon_check_type (2, NS_QQ, N_EQK, N_S8 | N_U8
19247 | N_S16 | N_U16 | N_KEY);
19248
19249 inst.instruction |= (et.type == NT_unsigned) << 28;
19250 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19251 inst.instruction |= (neon_logbits (et.size) + 1) << 19;
19252 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19253 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
19254 inst.instruction |= LOW4 (inst.operands[1].reg);
19255 inst.is_neon = 1;
19256}
19257
5287ad62
JB
19258static void
19259do_neon_rshift_round_imm (void)
19260{
037e8744 19261 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
19262 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
19263 int imm = inst.operands[2].imm;
19264
19265 /* imm == 0 case is encoded as VMOV for V{R}SHR. */
19266 if (imm == 0)
19267 {
19268 inst.operands[2].present = 0;
19269 do_neon_mov ();
19270 return;
19271 }
19272
19273 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 19274 _("immediate out of range for shift"));
037e8744 19275 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et,
477330fc 19276 et.size - imm);
5287ad62
JB
19277}
19278
9db2f6b4
RL
19279static void
19280do_neon_movhf (void)
19281{
19282 enum neon_shape rs = neon_select_shape (NS_HH, NS_NULL);
19283 constraint (rs != NS_HH, _("invalid suffix"));
19284
7bdf778b
ASDV
19285 if (inst.cond != COND_ALWAYS)
19286 {
19287 if (thumb_mode)
19288 {
19289 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
19290 " the behaviour is UNPREDICTABLE"));
19291 }
19292 else
19293 {
19294 inst.error = BAD_COND;
19295 return;
19296 }
19297 }
19298
9db2f6b4
RL
19299 do_vfp_sp_monadic ();
19300
19301 inst.is_neon = 1;
19302 inst.instruction |= 0xf0000000;
19303}
19304
5287ad62
JB
19305static void
19306do_neon_movl (void)
19307{
19308 struct neon_type_el et = neon_check_type (2, NS_QD,
19309 N_EQK | N_DBL, N_SU_32 | N_KEY);
19310 unsigned sizebits = et.size >> 3;
19311 inst.instruction |= sizebits << 19;
19312 neon_two_same (0, et.type == NT_unsigned, -1);
19313}
19314
19315static void
19316do_neon_trn (void)
19317{
037e8744 19318 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
19319 struct neon_type_el et = neon_check_type (2, rs,
19320 N_EQK, N_8 | N_16 | N_32 | N_KEY);
88714cb8 19321 NEON_ENCODE (INTEGER, inst);
037e8744 19322 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19323}
19324
19325static void
19326do_neon_zip_uzp (void)
19327{
037e8744 19328 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
19329 struct neon_type_el et = neon_check_type (2, rs,
19330 N_EQK, N_8 | N_16 | N_32 | N_KEY);
19331 if (rs == NS_DD && et.size == 32)
19332 {
19333 /* Special case: encode as VTRN.32 <Dd>, <Dm>. */
19334 inst.instruction = N_MNEM_vtrn;
19335 do_neon_trn ();
19336 return;
19337 }
037e8744 19338 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19339}
19340
19341static void
19342do_neon_sat_abs_neg (void)
19343{
037e8744 19344 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
19345 struct neon_type_el et = neon_check_type (2, rs,
19346 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 19347 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19348}
19349
19350static void
19351do_neon_pair_long (void)
19352{
037e8744 19353 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
19354 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
19355 /* Unsigned is encoded in OP field (bit 7) for these instruction. */
19356 inst.instruction |= (et.type == NT_unsigned) << 7;
037e8744 19357 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19358}
19359
19360static void
19361do_neon_recip_est (void)
19362{
037e8744 19363 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62 19364 struct neon_type_el et = neon_check_type (2, rs,
cc933301 19365 N_EQK | N_FLT, N_F_16_32 | N_U32 | N_KEY);
5287ad62 19366 inst.instruction |= (et.type == NT_float) << 8;
037e8744 19367 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19368}
19369
19370static void
19371do_neon_cls (void)
19372{
f30ee27c
AV
19373 if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
19374 return;
19375
19376 enum neon_shape rs;
19377 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19378 rs = neon_select_shape (NS_QQ, NS_NULL);
19379 else
19380 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
19381
5287ad62
JB
19382 struct neon_type_el et = neon_check_type (2, rs,
19383 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 19384 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19385}
19386
19387static void
19388do_neon_clz (void)
19389{
f30ee27c
AV
19390 if (check_simd_pred_availability (0, NEON_CHECK_ARCH | NEON_CHECK_CC))
19391 return;
19392
19393 enum neon_shape rs;
19394 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19395 rs = neon_select_shape (NS_QQ, NS_NULL);
19396 else
19397 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
19398
5287ad62
JB
19399 struct neon_type_el et = neon_check_type (2, rs,
19400 N_EQK, N_I8 | N_I16 | N_I32 | N_KEY);
037e8744 19401 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19402}
19403
19404static void
19405do_neon_cnt (void)
19406{
037e8744 19407 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
19408 struct neon_type_el et = neon_check_type (2, rs,
19409 N_EQK | N_INT, N_8 | N_KEY);
037e8744 19410 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
19411}
19412
19413static void
19414do_neon_swp (void)
19415{
037e8744
JB
19416 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
19417 neon_two_same (neon_quad (rs), 1, -1);
5287ad62
JB
19418}
19419
19420static void
19421do_neon_tbl_tbx (void)
19422{
19423 unsigned listlenbits;
dcbf9037 19424 neon_check_type (3, NS_DLD, N_EQK, N_EQK, N_8 | N_KEY);
5f4273c7 19425
5287ad62
JB
19426 if (inst.operands[1].imm < 1 || inst.operands[1].imm > 4)
19427 {
dcbf9037 19428 first_error (_("bad list length for table lookup"));
5287ad62
JB
19429 return;
19430 }
5f4273c7 19431
5287ad62
JB
19432 listlenbits = inst.operands[1].imm - 1;
19433 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19434 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19435 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
19436 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
19437 inst.instruction |= LOW4 (inst.operands[2].reg);
19438 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
19439 inst.instruction |= listlenbits << 8;
5f4273c7 19440
88714cb8 19441 neon_dp_fixup (&inst);
5287ad62
JB
19442}
19443
19444static void
19445do_neon_ldm_stm (void)
19446{
19447 /* P, U and L bits are part of bitmask. */
19448 int is_dbmode = (inst.instruction & (1 << 24)) != 0;
19449 unsigned offsetbits = inst.operands[1].imm * 2;
19450
037e8744
JB
19451 if (inst.operands[1].issingle)
19452 {
19453 do_vfp_nsyn_ldm_stm (is_dbmode);
19454 return;
19455 }
19456
5287ad62 19457 constraint (is_dbmode && !inst.operands[0].writeback,
477330fc 19458 _("writeback (!) must be used for VLDMDB and VSTMDB"));
5287ad62
JB
19459
19460 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
477330fc
RM
19461 _("register list must contain at least 1 and at most 16 "
19462 "registers"));
5287ad62
JB
19463
19464 inst.instruction |= inst.operands[0].reg << 16;
19465 inst.instruction |= inst.operands[0].writeback << 21;
19466 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
19467 inst.instruction |= HI1 (inst.operands[1].reg) << 22;
19468
19469 inst.instruction |= offsetbits;
5f4273c7 19470
037e8744 19471 do_vfp_cond_or_thumb ();
5287ad62
JB
19472}
19473
19474static void
19475do_neon_ldr_str (void)
19476{
5287ad62 19477 int is_ldr = (inst.instruction & (1 << 20)) != 0;
5f4273c7 19478
6844b2c2
MGD
19479 /* Use of PC in vstr in ARM mode is deprecated in ARMv7.
19480 And is UNPREDICTABLE in thumb mode. */
fa94de6b 19481 if (!is_ldr
6844b2c2 19482 && inst.operands[1].reg == REG_PC
ba86b375 19483 && (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7) || thumb_mode))
6844b2c2 19484 {
94dcf8bf 19485 if (thumb_mode)
6844b2c2 19486 inst.error = _("Use of PC here is UNPREDICTABLE");
94dcf8bf 19487 else if (warn_on_deprecated)
5c3696f8 19488 as_tsktsk (_("Use of PC here is deprecated"));
6844b2c2
MGD
19489 }
19490
037e8744
JB
19491 if (inst.operands[0].issingle)
19492 {
cd2f129f 19493 if (is_ldr)
477330fc 19494 do_vfp_nsyn_opcode ("flds");
cd2f129f 19495 else
477330fc 19496 do_vfp_nsyn_opcode ("fsts");
9db2f6b4
RL
19497
19498 /* ARMv8.2 vldr.16/vstr.16 instruction. */
19499 if (inst.vectype.el[0].size == 16)
19500 do_scalar_fp16_v82_encode ();
5287ad62
JB
19501 }
19502 else
5287ad62 19503 {
cd2f129f 19504 if (is_ldr)
477330fc 19505 do_vfp_nsyn_opcode ("fldd");
5287ad62 19506 else
477330fc 19507 do_vfp_nsyn_opcode ("fstd");
5287ad62 19508 }
5287ad62
JB
19509}
19510
32c36c3c
AV
19511static void
19512do_t_vldr_vstr_sysreg (void)
19513{
19514 int fp_vldr_bitno = 20, sysreg_vldr_bitno = 20;
19515 bfd_boolean is_vldr = ((inst.instruction & (1 << fp_vldr_bitno)) != 0);
19516
19517 /* Use of PC is UNPREDICTABLE. */
19518 if (inst.operands[1].reg == REG_PC)
19519 inst.error = _("Use of PC here is UNPREDICTABLE");
19520
19521 if (inst.operands[1].immisreg)
19522 inst.error = _("instruction does not accept register index");
19523
19524 if (!inst.operands[1].isreg)
19525 inst.error = _("instruction does not accept PC-relative addressing");
19526
19527 if (abs (inst.operands[1].imm) >= (1 << 7))
19528 inst.error = _("immediate value out of range");
19529
19530 inst.instruction = 0xec000f80;
19531 if (is_vldr)
19532 inst.instruction |= 1 << sysreg_vldr_bitno;
19533 encode_arm_cp_address (1, TRUE, FALSE, BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM);
19534 inst.instruction |= (inst.operands[0].imm & 0x7) << 13;
19535 inst.instruction |= (inst.operands[0].imm & 0x8) << 19;
19536}
19537
19538static void
19539do_vldr_vstr (void)
19540{
19541 bfd_boolean sysreg_op = !inst.operands[0].isreg;
19542
19543 /* VLDR/VSTR (System Register). */
19544 if (sysreg_op)
19545 {
19546 if (!mark_feature_used (&arm_ext_v8_1m_main))
19547 as_bad (_("Instruction not permitted on this architecture"));
19548
19549 do_t_vldr_vstr_sysreg ();
19550 }
19551 /* VLDR/VSTR. */
19552 else
19553 {
19554 if (!mark_feature_used (&fpu_vfp_ext_v1xd))
19555 as_bad (_("Instruction not permitted on this architecture"));
19556 do_neon_ldr_str ();
19557 }
19558}
19559
5287ad62
JB
19560/* "interleave" version also handles non-interleaving register VLD1/VST1
19561 instructions. */
19562
19563static void
19564do_neon_ld_st_interleave (void)
19565{
037e8744 19566 struct neon_type_el et = neon_check_type (1, NS_NULL,
477330fc 19567 N_8 | N_16 | N_32 | N_64);
5287ad62
JB
19568 unsigned alignbits = 0;
19569 unsigned idx;
19570 /* The bits in this table go:
19571 0: register stride of one (0) or two (1)
19572 1,2: register list length, minus one (1, 2, 3, 4).
19573 3,4: <n> in instruction type, minus one (VLD<n> / VST<n>).
19574 We use -1 for invalid entries. */
19575 const int typetable[] =
19576 {
19577 0x7, -1, 0xa, -1, 0x6, -1, 0x2, -1, /* VLD1 / VST1. */
19578 -1, -1, 0x8, 0x9, -1, -1, 0x3, -1, /* VLD2 / VST2. */
19579 -1, -1, -1, -1, 0x4, 0x5, -1, -1, /* VLD3 / VST3. */
19580 -1, -1, -1, -1, -1, -1, 0x0, 0x1 /* VLD4 / VST4. */
19581 };
19582 int typebits;
19583
dcbf9037
JB
19584 if (et.type == NT_invtype)
19585 return;
19586
5287ad62
JB
19587 if (inst.operands[1].immisalign)
19588 switch (inst.operands[1].imm >> 8)
19589 {
19590 case 64: alignbits = 1; break;
19591 case 128:
477330fc 19592 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2
e23c0ad8 19593 && NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
477330fc
RM
19594 goto bad_alignment;
19595 alignbits = 2;
19596 break;
5287ad62 19597 case 256:
477330fc
RM
19598 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
19599 goto bad_alignment;
19600 alignbits = 3;
19601 break;
5287ad62
JB
19602 default:
19603 bad_alignment:
477330fc
RM
19604 first_error (_("bad alignment"));
19605 return;
5287ad62
JB
19606 }
19607
19608 inst.instruction |= alignbits << 4;
19609 inst.instruction |= neon_logbits (et.size) << 6;
19610
19611 /* Bits [4:6] of the immediate in a list specifier encode register stride
19612 (minus 1) in bit 4, and list length in bits [5:6]. We put the <n> of
19613 VLD<n>/VST<n> in bits [9:8] of the initial bitmask. Suck it out here, look
19614 up the right value for "type" in a table based on this value and the given
19615 list style, then stick it back. */
19616 idx = ((inst.operands[0].imm >> 4) & 7)
477330fc 19617 | (((inst.instruction >> 8) & 3) << 3);
5287ad62
JB
19618
19619 typebits = typetable[idx];
5f4273c7 19620
5287ad62 19621 constraint (typebits == -1, _("bad list type for instruction"));
1d50d57c 19622 constraint (((inst.instruction >> 8) & 3) && et.size == 64,
35c228db 19623 BAD_EL_TYPE);
5287ad62
JB
19624
19625 inst.instruction &= ~0xf00;
19626 inst.instruction |= typebits << 8;
19627}
19628
19629/* Check alignment is valid for do_neon_ld_st_lane and do_neon_ld_dup.
19630 *DO_ALIGN is set to 1 if the relevant alignment bit should be set, 0
19631 otherwise. The variable arguments are a list of pairs of legal (size, align)
19632 values, terminated with -1. */
19633
19634static int
aa8a0863 19635neon_alignment_bit (int size, int align, int *do_alignment, ...)
5287ad62
JB
19636{
19637 va_list ap;
19638 int result = FAIL, thissize, thisalign;
5f4273c7 19639
5287ad62
JB
19640 if (!inst.operands[1].immisalign)
19641 {
aa8a0863 19642 *do_alignment = 0;
5287ad62
JB
19643 return SUCCESS;
19644 }
5f4273c7 19645
aa8a0863 19646 va_start (ap, do_alignment);
5287ad62
JB
19647
19648 do
19649 {
19650 thissize = va_arg (ap, int);
19651 if (thissize == -1)
477330fc 19652 break;
5287ad62
JB
19653 thisalign = va_arg (ap, int);
19654
19655 if (size == thissize && align == thisalign)
477330fc 19656 result = SUCCESS;
5287ad62
JB
19657 }
19658 while (result != SUCCESS);
19659
19660 va_end (ap);
19661
19662 if (result == SUCCESS)
aa8a0863 19663 *do_alignment = 1;
5287ad62 19664 else
dcbf9037 19665 first_error (_("unsupported alignment for instruction"));
5f4273c7 19666
5287ad62
JB
19667 return result;
19668}
19669
19670static void
19671do_neon_ld_st_lane (void)
19672{
037e8744 19673 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 19674 int align_good, do_alignment = 0;
5287ad62
JB
19675 int logsize = neon_logbits (et.size);
19676 int align = inst.operands[1].imm >> 8;
19677 int n = (inst.instruction >> 8) & 3;
19678 int max_el = 64 / et.size;
5f4273c7 19679
dcbf9037
JB
19680 if (et.type == NT_invtype)
19681 return;
5f4273c7 19682
5287ad62 19683 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != n + 1,
477330fc 19684 _("bad list length"));
5287ad62 19685 constraint (NEON_LANE (inst.operands[0].imm) >= max_el,
477330fc 19686 _("scalar index out of range"));
5287ad62 19687 constraint (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2
477330fc
RM
19688 && et.size == 8,
19689 _("stride of 2 unavailable when element size is 8"));
5f4273c7 19690
5287ad62
JB
19691 switch (n)
19692 {
19693 case 0: /* VLD1 / VST1. */
aa8a0863 19694 align_good = neon_alignment_bit (et.size, align, &do_alignment, 16, 16,
477330fc 19695 32, 32, -1);
5287ad62 19696 if (align_good == FAIL)
477330fc 19697 return;
aa8a0863 19698 if (do_alignment)
477330fc
RM
19699 {
19700 unsigned alignbits = 0;
19701 switch (et.size)
19702 {
19703 case 16: alignbits = 0x1; break;
19704 case 32: alignbits = 0x3; break;
19705 default: ;
19706 }
19707 inst.instruction |= alignbits << 4;
19708 }
5287ad62
JB
19709 break;
19710
19711 case 1: /* VLD2 / VST2. */
aa8a0863
TS
19712 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 16,
19713 16, 32, 32, 64, -1);
5287ad62 19714 if (align_good == FAIL)
477330fc 19715 return;
aa8a0863 19716 if (do_alignment)
477330fc 19717 inst.instruction |= 1 << 4;
5287ad62
JB
19718 break;
19719
19720 case 2: /* VLD3 / VST3. */
19721 constraint (inst.operands[1].immisalign,
477330fc 19722 _("can't use alignment with this instruction"));
5287ad62
JB
19723 break;
19724
19725 case 3: /* VLD4 / VST4. */
aa8a0863 19726 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc 19727 16, 64, 32, 64, 32, 128, -1);
5287ad62 19728 if (align_good == FAIL)
477330fc 19729 return;
aa8a0863 19730 if (do_alignment)
477330fc
RM
19731 {
19732 unsigned alignbits = 0;
19733 switch (et.size)
19734 {
19735 case 8: alignbits = 0x1; break;
19736 case 16: alignbits = 0x1; break;
19737 case 32: alignbits = (align == 64) ? 0x1 : 0x2; break;
19738 default: ;
19739 }
19740 inst.instruction |= alignbits << 4;
19741 }
5287ad62
JB
19742 break;
19743
19744 default: ;
19745 }
19746
19747 /* Reg stride of 2 is encoded in bit 5 when size==16, bit 6 when size==32. */
19748 if (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2)
19749 inst.instruction |= 1 << (4 + logsize);
5f4273c7 19750
5287ad62
JB
19751 inst.instruction |= NEON_LANE (inst.operands[0].imm) << (logsize + 5);
19752 inst.instruction |= logsize << 10;
19753}
19754
19755/* Encode single n-element structure to all lanes VLD<n> instructions. */
19756
19757static void
19758do_neon_ld_dup (void)
19759{
037e8744 19760 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 19761 int align_good, do_alignment = 0;
5287ad62 19762
dcbf9037
JB
19763 if (et.type == NT_invtype)
19764 return;
19765
5287ad62
JB
19766 switch ((inst.instruction >> 8) & 3)
19767 {
19768 case 0: /* VLD1. */
9c2799c2 19769 gas_assert (NEON_REG_STRIDE (inst.operands[0].imm) != 2);
5287ad62 19770 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863 19771 &do_alignment, 16, 16, 32, 32, -1);
5287ad62 19772 if (align_good == FAIL)
477330fc 19773 return;
5287ad62 19774 switch (NEON_REGLIST_LENGTH (inst.operands[0].imm))
477330fc
RM
19775 {
19776 case 1: break;
19777 case 2: inst.instruction |= 1 << 5; break;
19778 default: first_error (_("bad list length")); return;
19779 }
5287ad62
JB
19780 inst.instruction |= neon_logbits (et.size) << 6;
19781 break;
19782
19783 case 1: /* VLD2. */
19784 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863
TS
19785 &do_alignment, 8, 16, 16, 32, 32, 64,
19786 -1);
5287ad62 19787 if (align_good == FAIL)
477330fc 19788 return;
5287ad62 19789 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2,
477330fc 19790 _("bad list length"));
5287ad62 19791 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 19792 inst.instruction |= 1 << 5;
5287ad62
JB
19793 inst.instruction |= neon_logbits (et.size) << 6;
19794 break;
19795
19796 case 2: /* VLD3. */
19797 constraint (inst.operands[1].immisalign,
477330fc 19798 _("can't use alignment with this instruction"));
5287ad62 19799 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 3,
477330fc 19800 _("bad list length"));
5287ad62 19801 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 19802 inst.instruction |= 1 << 5;
5287ad62
JB
19803 inst.instruction |= neon_logbits (et.size) << 6;
19804 break;
19805
19806 case 3: /* VLD4. */
19807 {
477330fc 19808 int align = inst.operands[1].imm >> 8;
aa8a0863 19809 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc
RM
19810 16, 64, 32, 64, 32, 128, -1);
19811 if (align_good == FAIL)
19812 return;
19813 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4,
19814 _("bad list length"));
19815 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
19816 inst.instruction |= 1 << 5;
19817 if (et.size == 32 && align == 128)
19818 inst.instruction |= 0x3 << 6;
19819 else
19820 inst.instruction |= neon_logbits (et.size) << 6;
5287ad62
JB
19821 }
19822 break;
19823
19824 default: ;
19825 }
19826
aa8a0863 19827 inst.instruction |= do_alignment << 4;
5287ad62
JB
19828}
19829
19830/* Disambiguate VLD<n> and VST<n> instructions, and fill in common bits (those
19831 apart from bits [11:4]. */
19832
19833static void
19834do_neon_ldx_stx (void)
19835{
b1a769ed
DG
19836 if (inst.operands[1].isreg)
19837 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
19838
5287ad62
JB
19839 switch (NEON_LANE (inst.operands[0].imm))
19840 {
19841 case NEON_INTERLEAVE_LANES:
88714cb8 19842 NEON_ENCODE (INTERLV, inst);
5287ad62
JB
19843 do_neon_ld_st_interleave ();
19844 break;
5f4273c7 19845
5287ad62 19846 case NEON_ALL_LANES:
88714cb8 19847 NEON_ENCODE (DUP, inst);
2d51fb74
JB
19848 if (inst.instruction == N_INV)
19849 {
19850 first_error ("only loads support such operands");
19851 break;
19852 }
5287ad62
JB
19853 do_neon_ld_dup ();
19854 break;
5f4273c7 19855
5287ad62 19856 default:
88714cb8 19857 NEON_ENCODE (LANE, inst);
5287ad62
JB
19858 do_neon_ld_st_lane ();
19859 }
19860
19861 /* L bit comes from bit mask. */
19862 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
19863 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
19864 inst.instruction |= inst.operands[1].reg << 16;
5f4273c7 19865
5287ad62
JB
19866 if (inst.operands[1].postind)
19867 {
19868 int postreg = inst.operands[1].imm & 0xf;
19869 constraint (!inst.operands[1].immisreg,
477330fc 19870 _("post-index must be a register"));
5287ad62 19871 constraint (postreg == 0xd || postreg == 0xf,
477330fc 19872 _("bad register for post-index"));
5287ad62
JB
19873 inst.instruction |= postreg;
19874 }
4f2374c7 19875 else
5287ad62 19876 {
4f2374c7 19877 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
e2b0ab59
AV
19878 constraint (inst.relocs[0].exp.X_op != O_constant
19879 || inst.relocs[0].exp.X_add_number != 0,
4f2374c7
WN
19880 BAD_ADDR_MODE);
19881
19882 if (inst.operands[1].writeback)
19883 {
19884 inst.instruction |= 0xd;
19885 }
19886 else
19887 inst.instruction |= 0xf;
5287ad62 19888 }
5f4273c7 19889
5287ad62
JB
19890 if (thumb_mode)
19891 inst.instruction |= 0xf9000000;
19892 else
19893 inst.instruction |= 0xf4000000;
19894}
33399f07
MGD
19895
19896/* FP v8. */
19897static void
19898do_vfp_nsyn_fpv8 (enum neon_shape rs)
19899{
a715796b
TG
19900 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
19901 D register operands. */
19902 if (neon_shape_class[rs] == SC_DOUBLE)
19903 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19904 _(BAD_FPU));
19905
33399f07
MGD
19906 NEON_ENCODE (FPV8, inst);
19907
9db2f6b4
RL
19908 if (rs == NS_FFF || rs == NS_HHH)
19909 {
19910 do_vfp_sp_dyadic ();
19911
19912 /* ARMv8.2 fp16 instruction. */
19913 if (rs == NS_HHH)
19914 do_scalar_fp16_v82_encode ();
19915 }
33399f07
MGD
19916 else
19917 do_vfp_dp_rd_rn_rm ();
19918
19919 if (rs == NS_DDD)
19920 inst.instruction |= 0x100;
19921
19922 inst.instruction |= 0xf0000000;
19923}
19924
19925static void
19926do_vsel (void)
19927{
5ee91343 19928 set_pred_insn_type (OUTSIDE_PRED_INSN);
33399f07
MGD
19929
19930 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
19931 first_error (_("invalid instruction shape"));
19932}
19933
73924fbc
MGD
19934static void
19935do_vmaxnm (void)
19936{
935295b5
AV
19937 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
19938 set_pred_insn_type (OUTSIDE_PRED_INSN);
73924fbc
MGD
19939
19940 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
19941 return;
19942
935295b5 19943 if (check_simd_pred_availability (1, NEON_CHECK_CC | NEON_CHECK_ARCH8))
73924fbc
MGD
19944 return;
19945
cc933301 19946 neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
73924fbc
MGD
19947}
19948
30bdf752
MGD
19949static void
19950do_vrint_1 (enum neon_cvt_mode mode)
19951{
9db2f6b4 19952 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_QQ, NS_NULL);
30bdf752
MGD
19953 struct neon_type_el et;
19954
19955 if (rs == NS_NULL)
19956 return;
19957
a715796b
TG
19958 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
19959 D register operands. */
19960 if (neon_shape_class[rs] == SC_DOUBLE)
19961 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
19962 _(BAD_FPU));
19963
9db2f6b4
RL
19964 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY
19965 | N_VFP);
30bdf752
MGD
19966 if (et.type != NT_invtype)
19967 {
19968 /* VFP encodings. */
19969 if (mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
19970 || mode == neon_cvt_mode_p || mode == neon_cvt_mode_m)
5ee91343 19971 set_pred_insn_type (OUTSIDE_PRED_INSN);
30bdf752
MGD
19972
19973 NEON_ENCODE (FPV8, inst);
9db2f6b4 19974 if (rs == NS_FF || rs == NS_HH)
30bdf752
MGD
19975 do_vfp_sp_monadic ();
19976 else
19977 do_vfp_dp_rd_rm ();
19978
19979 switch (mode)
19980 {
19981 case neon_cvt_mode_r: inst.instruction |= 0x00000000; break;
19982 case neon_cvt_mode_z: inst.instruction |= 0x00000080; break;
19983 case neon_cvt_mode_x: inst.instruction |= 0x00010000; break;
19984 case neon_cvt_mode_a: inst.instruction |= 0xf0000000; break;
19985 case neon_cvt_mode_n: inst.instruction |= 0xf0010000; break;
19986 case neon_cvt_mode_p: inst.instruction |= 0xf0020000; break;
19987 case neon_cvt_mode_m: inst.instruction |= 0xf0030000; break;
19988 default: abort ();
19989 }
19990
19991 inst.instruction |= (rs == NS_DD) << 8;
19992 do_vfp_cond_or_thumb ();
9db2f6b4
RL
19993
19994 /* ARMv8.2 fp16 vrint instruction. */
19995 if (rs == NS_HH)
19996 do_scalar_fp16_v82_encode ();
30bdf752
MGD
19997 }
19998 else
19999 {
20000 /* Neon encodings (or something broken...). */
20001 inst.error = NULL;
cc933301 20002 et = neon_check_type (2, rs, N_EQK, N_F_16_32 | N_KEY);
30bdf752
MGD
20003
20004 if (et.type == NT_invtype)
20005 return;
20006
5ee91343 20007 set_pred_insn_type (OUTSIDE_PRED_INSN);
30bdf752
MGD
20008 NEON_ENCODE (FLOAT, inst);
20009
20010 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
20011 return;
20012
20013 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20014 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20015 inst.instruction |= LOW4 (inst.operands[1].reg);
20016 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20017 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
20018 /* Mask off the original size bits and reencode them. */
20019 inst.instruction = ((inst.instruction & 0xfff3ffff)
20020 | neon_logbits (et.size) << 18);
20021
30bdf752
MGD
20022 switch (mode)
20023 {
20024 case neon_cvt_mode_z: inst.instruction |= 3 << 7; break;
20025 case neon_cvt_mode_x: inst.instruction |= 1 << 7; break;
20026 case neon_cvt_mode_a: inst.instruction |= 2 << 7; break;
20027 case neon_cvt_mode_n: inst.instruction |= 0 << 7; break;
20028 case neon_cvt_mode_p: inst.instruction |= 7 << 7; break;
20029 case neon_cvt_mode_m: inst.instruction |= 5 << 7; break;
20030 case neon_cvt_mode_r: inst.error = _("invalid rounding mode"); break;
20031 default: abort ();
20032 }
20033
20034 if (thumb_mode)
20035 inst.instruction |= 0xfc000000;
20036 else
20037 inst.instruction |= 0xf0000000;
20038 }
20039}
20040
20041static void
20042do_vrintx (void)
20043{
20044 do_vrint_1 (neon_cvt_mode_x);
20045}
20046
20047static void
20048do_vrintz (void)
20049{
20050 do_vrint_1 (neon_cvt_mode_z);
20051}
20052
20053static void
20054do_vrintr (void)
20055{
20056 do_vrint_1 (neon_cvt_mode_r);
20057}
20058
20059static void
20060do_vrinta (void)
20061{
20062 do_vrint_1 (neon_cvt_mode_a);
20063}
20064
20065static void
20066do_vrintn (void)
20067{
20068 do_vrint_1 (neon_cvt_mode_n);
20069}
20070
20071static void
20072do_vrintp (void)
20073{
20074 do_vrint_1 (neon_cvt_mode_p);
20075}
20076
20077static void
20078do_vrintm (void)
20079{
20080 do_vrint_1 (neon_cvt_mode_m);
20081}
20082
c28eeff2
SN
20083static unsigned
20084neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
20085{
20086 unsigned regno = NEON_SCALAR_REG (opnd);
20087 unsigned elno = NEON_SCALAR_INDEX (opnd);
20088
20089 if (elsize == 16 && elno < 2 && regno < 16)
20090 return regno | (elno << 4);
20091 else if (elsize == 32 && elno == 0)
20092 return regno;
20093
20094 first_error (_("scalar out of range"));
20095 return 0;
20096}
20097
20098static void
20099do_vcmla (void)
20100{
5d281bf0
AV
20101 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext)
20102 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
20103 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
20104 constraint (inst.relocs[0].exp.X_op != O_constant,
20105 _("expression too complex"));
20106 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
20107 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
20108 _("immediate out of range"));
20109 rot /= 90;
5d281bf0
AV
20110
20111 if (check_simd_pred_availability (1, NEON_CHECK_ARCH8 | NEON_CHECK_CC))
20112 return;
20113
c28eeff2
SN
20114 if (inst.operands[2].isscalar)
20115 {
5d281bf0
AV
20116 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
20117 first_error (_("invalid instruction shape"));
c28eeff2
SN
20118 enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
20119 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
20120 N_KEY | N_F16 | N_F32).size;
20121 unsigned m = neon_scalar_for_vcmla (inst.operands[2].reg, size);
20122 inst.is_neon = 1;
20123 inst.instruction = 0xfe000800;
20124 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20125 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20126 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20127 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20128 inst.instruction |= LOW4 (m);
20129 inst.instruction |= HI1 (m) << 5;
20130 inst.instruction |= neon_quad (rs) << 6;
20131 inst.instruction |= rot << 20;
20132 inst.instruction |= (size == 32) << 23;
20133 }
20134 else
20135 {
5d281bf0
AV
20136 enum neon_shape rs;
20137 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext))
20138 rs = neon_select_shape (NS_QQQI, NS_NULL);
20139 else
20140 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
20141
c28eeff2
SN
20142 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
20143 N_KEY | N_F16 | N_F32).size;
5d281bf0
AV
20144 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext) && size == 32
20145 && (inst.operands[0].reg == inst.operands[1].reg
20146 || inst.operands[0].reg == inst.operands[2].reg))
20147 as_tsktsk (BAD_MVE_SRCDEST);
20148
c28eeff2
SN
20149 neon_three_same (neon_quad (rs), 0, -1);
20150 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
20151 inst.instruction |= 0xfc200800;
20152 inst.instruction |= rot << 23;
20153 inst.instruction |= (size == 32) << 20;
20154 }
20155}
20156
20157static void
20158do_vcadd (void)
20159{
5d281bf0
AV
20160 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext)
20161 && (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8)
20162 || !mark_feature_used (&arm_ext_v8_3)), (BAD_FPU));
e2b0ab59
AV
20163 constraint (inst.relocs[0].exp.X_op != O_constant,
20164 _("expression too complex"));
5d281bf0 20165
e2b0ab59 20166 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2 20167 constraint (rot != 90 && rot != 270, _("immediate out of range"));
5d281bf0
AV
20168 enum neon_shape rs;
20169 struct neon_type_el et;
20170 if (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20171 {
20172 rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
20173 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32);
20174 }
20175 else
20176 {
20177 rs = neon_select_shape (NS_QQQI, NS_NULL);
20178 et = neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16 | N_F32 | N_I8
20179 | N_I16 | N_I32);
20180 if (et.size == 32 && inst.operands[0].reg == inst.operands[2].reg)
20181 as_tsktsk (_("Warning: 32-bit element size and same first and third "
20182 "operand makes instruction UNPREDICTABLE"));
20183 }
20184
20185 if (et.type == NT_invtype)
20186 return;
20187
20188 if (check_simd_pred_availability (et.type == NT_float, NEON_CHECK_ARCH8
20189 | NEON_CHECK_CC))
20190 return;
20191
20192 if (et.type == NT_float)
20193 {
20194 neon_three_same (neon_quad (rs), 0, -1);
20195 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
20196 inst.instruction |= 0xfc800800;
20197 inst.instruction |= (rot == 270) << 24;
20198 inst.instruction |= (et.size == 32) << 20;
20199 }
20200 else
20201 {
20202 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
20203 inst.instruction = 0xfe000f00;
20204 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20205 inst.instruction |= neon_logbits (et.size) << 20;
20206 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
20207 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20208 inst.instruction |= (rot == 270) << 12;
20209 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
20210 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
20211 inst.instruction |= LOW4 (inst.operands[2].reg);
20212 inst.is_neon = 1;
20213 }
c28eeff2
SN
20214}
20215
c604a79a
JW
20216/* Dot Product instructions encoding support. */
20217
20218static void
20219do_neon_dotproduct (int unsigned_p)
20220{
20221 enum neon_shape rs;
20222 unsigned scalar_oprd2 = 0;
20223 int high8;
20224
20225 if (inst.cond != COND_ALWAYS)
20226 as_warn (_("Dot Product instructions cannot be conditional, the behaviour "
20227 "is UNPREDICTABLE"));
20228
20229 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
20230 _(BAD_FPU));
20231
20232 /* Dot Product instructions are in three-same D/Q register format or the third
20233 operand can be a scalar index register. */
20234 if (inst.operands[2].isscalar)
20235 {
20236 scalar_oprd2 = neon_scalar_for_mul (inst.operands[2].reg, 32);
20237 high8 = 0xfe000000;
20238 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
20239 }
20240 else
20241 {
20242 high8 = 0xfc000000;
20243 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
20244 }
20245
20246 if (unsigned_p)
20247 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_U8);
20248 else
20249 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_S8);
20250
20251 /* The "U" bit in traditional Three Same encoding is fixed to 0 for Dot
20252 Product instruction, so we pass 0 as the "ubit" parameter. And the
20253 "Size" field are fixed to 0x2, so we pass 32 as the "size" parameter. */
20254 neon_three_same (neon_quad (rs), 0, 32);
20255
20256 /* Undo neon_dp_fixup. Dot Product instructions are using a slightly
20257 different NEON three-same encoding. */
20258 inst.instruction &= 0x00ffffff;
20259 inst.instruction |= high8;
20260 /* Encode 'U' bit which indicates signedness. */
20261 inst.instruction |= (unsigned_p ? 1 : 0) << 4;
20262 /* Re-encode operand2 if it's indexed scalar operand. What has been encoded
20263 from inst.operand[2].reg in neon_three_same is GAS's internal encoding, not
20264 the instruction encoding. */
20265 if (inst.operands[2].isscalar)
20266 {
20267 inst.instruction &= 0xffffffd0;
20268 inst.instruction |= LOW4 (scalar_oprd2);
20269 inst.instruction |= HI1 (scalar_oprd2) << 5;
20270 }
20271}
20272
20273/* Dot Product instructions for signed integer. */
20274
20275static void
20276do_neon_dotproduct_s (void)
20277{
20278 return do_neon_dotproduct (0);
20279}
20280
20281/* Dot Product instructions for unsigned integer. */
20282
20283static void
20284do_neon_dotproduct_u (void)
20285{
20286 return do_neon_dotproduct (1);
20287}
20288
91ff7894
MGD
20289/* Crypto v1 instructions. */
20290static void
20291do_crypto_2op_1 (unsigned elttype, int op)
20292{
5ee91343 20293 set_pred_insn_type (OUTSIDE_PRED_INSN);
91ff7894
MGD
20294
20295 if (neon_check_type (2, NS_QQ, N_EQK | N_UNT, elttype | N_UNT | N_KEY).type
20296 == NT_invtype)
20297 return;
20298
20299 inst.error = NULL;
20300
20301 NEON_ENCODE (INTEGER, inst);
20302 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
20303 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
20304 inst.instruction |= LOW4 (inst.operands[1].reg);
20305 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
20306 if (op != -1)
20307 inst.instruction |= op << 6;
20308
20309 if (thumb_mode)
20310 inst.instruction |= 0xfc000000;
20311 else
20312 inst.instruction |= 0xf0000000;
20313}
20314
48adcd8e
MGD
20315static void
20316do_crypto_3op_1 (int u, int op)
20317{
5ee91343 20318 set_pred_insn_type (OUTSIDE_PRED_INSN);
48adcd8e
MGD
20319
20320 if (neon_check_type (3, NS_QQQ, N_EQK | N_UNT, N_EQK | N_UNT,
20321 N_32 | N_UNT | N_KEY).type == NT_invtype)
20322 return;
20323
20324 inst.error = NULL;
20325
20326 NEON_ENCODE (INTEGER, inst);
20327 neon_three_same (1, u, 8 << op);
20328}
20329
91ff7894
MGD
20330static void
20331do_aese (void)
20332{
20333 do_crypto_2op_1 (N_8, 0);
20334}
20335
20336static void
20337do_aesd (void)
20338{
20339 do_crypto_2op_1 (N_8, 1);
20340}
20341
20342static void
20343do_aesmc (void)
20344{
20345 do_crypto_2op_1 (N_8, 2);
20346}
20347
20348static void
20349do_aesimc (void)
20350{
20351 do_crypto_2op_1 (N_8, 3);
20352}
20353
48adcd8e
MGD
20354static void
20355do_sha1c (void)
20356{
20357 do_crypto_3op_1 (0, 0);
20358}
20359
20360static void
20361do_sha1p (void)
20362{
20363 do_crypto_3op_1 (0, 1);
20364}
20365
20366static void
20367do_sha1m (void)
20368{
20369 do_crypto_3op_1 (0, 2);
20370}
20371
20372static void
20373do_sha1su0 (void)
20374{
20375 do_crypto_3op_1 (0, 3);
20376}
91ff7894 20377
48adcd8e
MGD
20378static void
20379do_sha256h (void)
20380{
20381 do_crypto_3op_1 (1, 0);
20382}
20383
20384static void
20385do_sha256h2 (void)
20386{
20387 do_crypto_3op_1 (1, 1);
20388}
20389
20390static void
20391do_sha256su1 (void)
20392{
20393 do_crypto_3op_1 (1, 2);
20394}
3c9017d2
MGD
20395
20396static void
20397do_sha1h (void)
20398{
20399 do_crypto_2op_1 (N_32, -1);
20400}
20401
20402static void
20403do_sha1su1 (void)
20404{
20405 do_crypto_2op_1 (N_32, 0);
20406}
20407
20408static void
20409do_sha256su0 (void)
20410{
20411 do_crypto_2op_1 (N_32, 1);
20412}
dd5181d5
KT
20413
20414static void
20415do_crc32_1 (unsigned int poly, unsigned int sz)
20416{
20417 unsigned int Rd = inst.operands[0].reg;
20418 unsigned int Rn = inst.operands[1].reg;
20419 unsigned int Rm = inst.operands[2].reg;
20420
5ee91343 20421 set_pred_insn_type (OUTSIDE_PRED_INSN);
dd5181d5
KT
20422 inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
20423 inst.instruction |= LOW4 (Rn) << 16;
20424 inst.instruction |= LOW4 (Rm);
20425 inst.instruction |= sz << (thumb_mode ? 4 : 21);
20426 inst.instruction |= poly << (thumb_mode ? 20 : 9);
20427
20428 if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
20429 as_warn (UNPRED_REG ("r15"));
dd5181d5
KT
20430}
20431
20432static void
20433do_crc32b (void)
20434{
20435 do_crc32_1 (0, 0);
20436}
20437
20438static void
20439do_crc32h (void)
20440{
20441 do_crc32_1 (0, 1);
20442}
20443
20444static void
20445do_crc32w (void)
20446{
20447 do_crc32_1 (0, 2);
20448}
20449
20450static void
20451do_crc32cb (void)
20452{
20453 do_crc32_1 (1, 0);
20454}
20455
20456static void
20457do_crc32ch (void)
20458{
20459 do_crc32_1 (1, 1);
20460}
20461
20462static void
20463do_crc32cw (void)
20464{
20465 do_crc32_1 (1, 2);
20466}
20467
49e8a725
SN
20468static void
20469do_vjcvt (void)
20470{
20471 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
20472 _(BAD_FPU));
20473 neon_check_type (2, NS_FD, N_S32, N_F64);
20474 do_vfp_sp_dp_cvt ();
20475 do_vfp_cond_or_thumb ();
20476}
20477
5287ad62
JB
20478\f
20479/* Overall per-instruction processing. */
20480
20481/* We need to be able to fix up arbitrary expressions in some statements.
20482 This is so that we can handle symbols that are an arbitrary distance from
20483 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
20484 which returns part of an address in a form which will be valid for
20485 a data instruction. We do this by pushing the expression into a symbol
20486 in the expr_section, and creating a fix for that. */
20487
20488static void
20489fix_new_arm (fragS * frag,
20490 int where,
20491 short int size,
20492 expressionS * exp,
20493 int pc_rel,
20494 int reloc)
20495{
20496 fixS * new_fix;
20497
20498 switch (exp->X_op)
20499 {
20500 case O_constant:
6e7ce2cd
PB
20501 if (pc_rel)
20502 {
20503 /* Create an absolute valued symbol, so we have something to
477330fc
RM
20504 refer to in the object file. Unfortunately for us, gas's
20505 generic expression parsing will already have folded out
20506 any use of .set foo/.type foo %function that may have
20507 been used to set type information of the target location,
20508 that's being specified symbolically. We have to presume
20509 the user knows what they are doing. */
6e7ce2cd
PB
20510 char name[16 + 8];
20511 symbolS *symbol;
20512
20513 sprintf (name, "*ABS*0x%lx", (unsigned long)exp->X_add_number);
20514
20515 symbol = symbol_find_or_make (name);
20516 S_SET_SEGMENT (symbol, absolute_section);
20517 symbol_set_frag (symbol, &zero_address_frag);
20518 S_SET_VALUE (symbol, exp->X_add_number);
20519 exp->X_op = O_symbol;
20520 exp->X_add_symbol = symbol;
20521 exp->X_add_number = 0;
20522 }
20523 /* FALLTHROUGH */
5287ad62
JB
20524 case O_symbol:
20525 case O_add:
20526 case O_subtract:
21d799b5 20527 new_fix = fix_new_exp (frag, where, size, exp, pc_rel,
477330fc 20528 (enum bfd_reloc_code_real) reloc);
5287ad62
JB
20529 break;
20530
20531 default:
21d799b5 20532 new_fix = (fixS *) fix_new (frag, where, size, make_expr_symbol (exp), 0,
477330fc 20533 pc_rel, (enum bfd_reloc_code_real) reloc);
5287ad62
JB
20534 break;
20535 }
20536
20537 /* Mark whether the fix is to a THUMB instruction, or an ARM
20538 instruction. */
20539 new_fix->tc_fix_data = thumb_mode;
20540}
20541
20542/* Create a frg for an instruction requiring relaxation. */
20543static void
20544output_relax_insn (void)
20545{
20546 char * to;
20547 symbolS *sym;
0110f2b8
PB
20548 int offset;
20549
6e1cb1a6
PB
20550 /* The size of the instruction is unknown, so tie the debug info to the
20551 start of the instruction. */
20552 dwarf2_emit_insn (0);
6e1cb1a6 20553
e2b0ab59 20554 switch (inst.relocs[0].exp.X_op)
0110f2b8
PB
20555 {
20556 case O_symbol:
e2b0ab59
AV
20557 sym = inst.relocs[0].exp.X_add_symbol;
20558 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
20559 break;
20560 case O_constant:
20561 sym = NULL;
e2b0ab59 20562 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
20563 break;
20564 default:
e2b0ab59 20565 sym = make_expr_symbol (&inst.relocs[0].exp);
0110f2b8
PB
20566 offset = 0;
20567 break;
20568 }
20569 to = frag_var (rs_machine_dependent, INSN_SIZE, THUMB_SIZE,
20570 inst.relax, sym, offset, NULL/*offset, opcode*/);
20571 md_number_to_chars (to, inst.instruction, THUMB_SIZE);
0110f2b8
PB
20572}
20573
20574/* Write a 32-bit thumb instruction to buf. */
20575static void
20576put_thumb32_insn (char * buf, unsigned long insn)
20577{
20578 md_number_to_chars (buf, insn >> 16, THUMB_SIZE);
20579 md_number_to_chars (buf + THUMB_SIZE, insn, THUMB_SIZE);
20580}
20581
b99bd4ef 20582static void
c19d1205 20583output_inst (const char * str)
b99bd4ef 20584{
c19d1205 20585 char * to = NULL;
b99bd4ef 20586
c19d1205 20587 if (inst.error)
b99bd4ef 20588 {
c19d1205 20589 as_bad ("%s -- `%s'", inst.error, str);
b99bd4ef
NC
20590 return;
20591 }
5f4273c7
NC
20592 if (inst.relax)
20593 {
20594 output_relax_insn ();
0110f2b8 20595 return;
5f4273c7 20596 }
c19d1205
ZW
20597 if (inst.size == 0)
20598 return;
b99bd4ef 20599
c19d1205 20600 to = frag_more (inst.size);
8dc2430f
NC
20601 /* PR 9814: Record the thumb mode into the current frag so that we know
20602 what type of NOP padding to use, if necessary. We override any previous
20603 setting so that if the mode has changed then the NOPS that we use will
20604 match the encoding of the last instruction in the frag. */
cd000bff 20605 frag_now->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
c19d1205
ZW
20606
20607 if (thumb_mode && (inst.size > THUMB_SIZE))
b99bd4ef 20608 {
9c2799c2 20609 gas_assert (inst.size == (2 * THUMB_SIZE));
0110f2b8 20610 put_thumb32_insn (to, inst.instruction);
b99bd4ef 20611 }
c19d1205 20612 else if (inst.size > INSN_SIZE)
b99bd4ef 20613 {
9c2799c2 20614 gas_assert (inst.size == (2 * INSN_SIZE));
c19d1205
ZW
20615 md_number_to_chars (to, inst.instruction, INSN_SIZE);
20616 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
b99bd4ef 20617 }
c19d1205
ZW
20618 else
20619 md_number_to_chars (to, inst.instruction, inst.size);
b99bd4ef 20620
e2b0ab59
AV
20621 int r;
20622 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
20623 {
20624 if (inst.relocs[r].type != BFD_RELOC_UNUSED)
20625 fix_new_arm (frag_now, to - frag_now->fr_literal,
20626 inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
20627 inst.relocs[r].type);
20628 }
b99bd4ef 20629
c19d1205 20630 dwarf2_emit_insn (inst.size);
c19d1205 20631}
b99bd4ef 20632
e07e6e58
NC
20633static char *
20634output_it_inst (int cond, int mask, char * to)
20635{
20636 unsigned long instruction = 0xbf00;
20637
20638 mask &= 0xf;
20639 instruction |= mask;
20640 instruction |= cond << 4;
20641
20642 if (to == NULL)
20643 {
20644 to = frag_more (2);
20645#ifdef OBJ_ELF
20646 dwarf2_emit_insn (2);
20647#endif
20648 }
20649
20650 md_number_to_chars (to, instruction, 2);
20651
20652 return to;
20653}
20654
c19d1205
ZW
20655/* Tag values used in struct asm_opcode's tag field. */
20656enum opcode_tag
20657{
20658 OT_unconditional, /* Instruction cannot be conditionalized.
20659 The ARM condition field is still 0xE. */
20660 OT_unconditionalF, /* Instruction cannot be conditionalized
20661 and carries 0xF in its ARM condition field. */
20662 OT_csuffix, /* Instruction takes a conditional suffix. */
5ee91343
AV
20663 OT_csuffixF, /* Some forms of the instruction take a scalar
20664 conditional suffix, others place 0xF where the
20665 condition field would be, others take a vector
20666 conditional suffix. */
c19d1205
ZW
20667 OT_cinfix3, /* Instruction takes a conditional infix,
20668 beginning at character index 3. (In
20669 unified mode, it becomes a suffix.) */
088fa78e
KH
20670 OT_cinfix3_deprecated, /* The same as OT_cinfix3. This is used for
20671 tsts, cmps, cmns, and teqs. */
e3cb604e
PB
20672 OT_cinfix3_legacy, /* Legacy instruction takes a conditional infix at
20673 character index 3, even in unified mode. Used for
20674 legacy instructions where suffix and infix forms
20675 may be ambiguous. */
c19d1205 20676 OT_csuf_or_in3, /* Instruction takes either a conditional
e3cb604e 20677 suffix or an infix at character index 3. */
c19d1205
ZW
20678 OT_odd_infix_unc, /* This is the unconditional variant of an
20679 instruction that takes a conditional infix
20680 at an unusual position. In unified mode,
20681 this variant will accept a suffix. */
20682 OT_odd_infix_0 /* Values greater than or equal to OT_odd_infix_0
20683 are the conditional variants of instructions that
20684 take conditional infixes in unusual positions.
20685 The infix appears at character index
20686 (tag - OT_odd_infix_0). These are not accepted
20687 in unified mode. */
20688};
b99bd4ef 20689
c19d1205
ZW
20690/* Subroutine of md_assemble, responsible for looking up the primary
20691 opcode from the mnemonic the user wrote. STR points to the
20692 beginning of the mnemonic.
20693
20694 This is not simply a hash table lookup, because of conditional
20695 variants. Most instructions have conditional variants, which are
20696 expressed with a _conditional affix_ to the mnemonic. If we were
20697 to encode each conditional variant as a literal string in the opcode
20698 table, it would have approximately 20,000 entries.
20699
20700 Most mnemonics take this affix as a suffix, and in unified syntax,
20701 'most' is upgraded to 'all'. However, in the divided syntax, some
20702 instructions take the affix as an infix, notably the s-variants of
20703 the arithmetic instructions. Of those instructions, all but six
20704 have the infix appear after the third character of the mnemonic.
20705
20706 Accordingly, the algorithm for looking up primary opcodes given
20707 an identifier is:
20708
20709 1. Look up the identifier in the opcode table.
20710 If we find a match, go to step U.
20711
20712 2. Look up the last two characters of the identifier in the
20713 conditions table. If we find a match, look up the first N-2
20714 characters of the identifier in the opcode table. If we
20715 find a match, go to step CE.
20716
20717 3. Look up the fourth and fifth characters of the identifier in
20718 the conditions table. If we find a match, extract those
20719 characters from the identifier, and look up the remaining
20720 characters in the opcode table. If we find a match, go
20721 to step CM.
20722
20723 4. Fail.
20724
20725 U. Examine the tag field of the opcode structure, in case this is
20726 one of the six instructions with its conditional infix in an
20727 unusual place. If it is, the tag tells us where to find the
20728 infix; look it up in the conditions table and set inst.cond
20729 accordingly. Otherwise, this is an unconditional instruction.
20730 Again set inst.cond accordingly. Return the opcode structure.
20731
20732 CE. Examine the tag field to make sure this is an instruction that
20733 should receive a conditional suffix. If it is not, fail.
20734 Otherwise, set inst.cond from the suffix we already looked up,
20735 and return the opcode structure.
20736
20737 CM. Examine the tag field to make sure this is an instruction that
20738 should receive a conditional infix after the third character.
20739 If it is not, fail. Otherwise, undo the edits to the current
20740 line of input and proceed as for case CE. */
20741
20742static const struct asm_opcode *
20743opcode_lookup (char **str)
20744{
20745 char *end, *base;
20746 char *affix;
20747 const struct asm_opcode *opcode;
20748 const struct asm_cond *cond;
e3cb604e 20749 char save[2];
c19d1205
ZW
20750
20751 /* Scan up to the end of the mnemonic, which must end in white space,
721a8186 20752 '.' (in unified mode, or for Neon/VFP instructions), or end of string. */
c19d1205 20753 for (base = end = *str; *end != '\0'; end++)
721a8186 20754 if (*end == ' ' || *end == '.')
c19d1205 20755 break;
b99bd4ef 20756
c19d1205 20757 if (end == base)
c921be7d 20758 return NULL;
b99bd4ef 20759
5287ad62 20760 /* Handle a possible width suffix and/or Neon type suffix. */
c19d1205 20761 if (end[0] == '.')
b99bd4ef 20762 {
5287ad62 20763 int offset = 2;
5f4273c7 20764
267d2029 20765 /* The .w and .n suffixes are only valid if the unified syntax is in
477330fc 20766 use. */
267d2029 20767 if (unified_syntax && end[1] == 'w')
c19d1205 20768 inst.size_req = 4;
267d2029 20769 else if (unified_syntax && end[1] == 'n')
c19d1205
ZW
20770 inst.size_req = 2;
20771 else
477330fc 20772 offset = 0;
5287ad62
JB
20773
20774 inst.vectype.elems = 0;
20775
20776 *str = end + offset;
b99bd4ef 20777
5f4273c7 20778 if (end[offset] == '.')
5287ad62 20779 {
267d2029 20780 /* See if we have a Neon type suffix (possible in either unified or
477330fc
RM
20781 non-unified ARM syntax mode). */
20782 if (parse_neon_type (&inst.vectype, str) == FAIL)
c921be7d 20783 return NULL;
477330fc 20784 }
5287ad62 20785 else if (end[offset] != '\0' && end[offset] != ' ')
477330fc 20786 return NULL;
b99bd4ef 20787 }
c19d1205
ZW
20788 else
20789 *str = end;
b99bd4ef 20790
c19d1205 20791 /* Look for unaffixed or special-case affixed mnemonic. */
21d799b5 20792 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 20793 end - base);
c19d1205 20794 if (opcode)
b99bd4ef 20795 {
c19d1205
ZW
20796 /* step U */
20797 if (opcode->tag < OT_odd_infix_0)
b99bd4ef 20798 {
c19d1205
ZW
20799 inst.cond = COND_ALWAYS;
20800 return opcode;
b99bd4ef 20801 }
b99bd4ef 20802
278df34e 20803 if (warn_on_deprecated && unified_syntax)
5c3696f8 20804 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205 20805 affix = base + (opcode->tag - OT_odd_infix_0);
21d799b5 20806 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
9c2799c2 20807 gas_assert (cond);
b99bd4ef 20808
c19d1205
ZW
20809 inst.cond = cond->value;
20810 return opcode;
20811 }
5ee91343
AV
20812 if (ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext))
20813 {
20814 /* Cannot have a conditional suffix on a mnemonic of less than a character.
20815 */
20816 if (end - base < 2)
20817 return NULL;
20818 affix = end - 1;
20819 cond = (const struct asm_cond *) hash_find_n (arm_vcond_hsh, affix, 1);
20820 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
20821 affix - base);
20822 /* If this opcode can not be vector predicated then don't accept it with a
20823 vector predication code. */
20824 if (opcode && !opcode->mayBeVecPred)
20825 opcode = NULL;
20826 }
20827 if (!opcode || !cond)
20828 {
20829 /* Cannot have a conditional suffix on a mnemonic of less than two
20830 characters. */
20831 if (end - base < 3)
20832 return NULL;
b99bd4ef 20833
5ee91343
AV
20834 /* Look for suffixed mnemonic. */
20835 affix = end - 2;
20836 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
20837 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
20838 affix - base);
20839 }
b99bd4ef 20840
c19d1205
ZW
20841 if (opcode && cond)
20842 {
20843 /* step CE */
20844 switch (opcode->tag)
20845 {
e3cb604e
PB
20846 case OT_cinfix3_legacy:
20847 /* Ignore conditional suffixes matched on infix only mnemonics. */
20848 break;
20849
c19d1205 20850 case OT_cinfix3:
088fa78e 20851 case OT_cinfix3_deprecated:
c19d1205
ZW
20852 case OT_odd_infix_unc:
20853 if (!unified_syntax)
0198d5e6 20854 return NULL;
1a0670f3 20855 /* Fall through. */
c19d1205
ZW
20856
20857 case OT_csuffix:
477330fc 20858 case OT_csuffixF:
c19d1205
ZW
20859 case OT_csuf_or_in3:
20860 inst.cond = cond->value;
20861 return opcode;
20862
20863 case OT_unconditional:
20864 case OT_unconditionalF:
dfa9f0d5 20865 if (thumb_mode)
c921be7d 20866 inst.cond = cond->value;
dfa9f0d5
PB
20867 else
20868 {
c921be7d 20869 /* Delayed diagnostic. */
dfa9f0d5
PB
20870 inst.error = BAD_COND;
20871 inst.cond = COND_ALWAYS;
20872 }
c19d1205 20873 return opcode;
b99bd4ef 20874
c19d1205 20875 default:
c921be7d 20876 return NULL;
c19d1205
ZW
20877 }
20878 }
b99bd4ef 20879
c19d1205
ZW
20880 /* Cannot have a usual-position infix on a mnemonic of less than
20881 six characters (five would be a suffix). */
20882 if (end - base < 6)
c921be7d 20883 return NULL;
b99bd4ef 20884
c19d1205
ZW
20885 /* Look for infixed mnemonic in the usual position. */
20886 affix = base + 3;
21d799b5 20887 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
e3cb604e 20888 if (!cond)
c921be7d 20889 return NULL;
e3cb604e
PB
20890
20891 memcpy (save, affix, 2);
20892 memmove (affix, affix + 2, (end - affix) - 2);
21d799b5 20893 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 20894 (end - base) - 2);
e3cb604e
PB
20895 memmove (affix + 2, affix, (end - affix) - 2);
20896 memcpy (affix, save, 2);
20897
088fa78e
KH
20898 if (opcode
20899 && (opcode->tag == OT_cinfix3
20900 || opcode->tag == OT_cinfix3_deprecated
20901 || opcode->tag == OT_csuf_or_in3
20902 || opcode->tag == OT_cinfix3_legacy))
b99bd4ef 20903 {
c921be7d 20904 /* Step CM. */
278df34e 20905 if (warn_on_deprecated && unified_syntax
088fa78e
KH
20906 && (opcode->tag == OT_cinfix3
20907 || opcode->tag == OT_cinfix3_deprecated))
5c3696f8 20908 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205
ZW
20909
20910 inst.cond = cond->value;
20911 return opcode;
b99bd4ef
NC
20912 }
20913
c921be7d 20914 return NULL;
b99bd4ef
NC
20915}
20916
e07e6e58
NC
20917/* This function generates an initial IT instruction, leaving its block
20918 virtually open for the new instructions. Eventually,
5ee91343 20919 the mask will be updated by now_pred_add_mask () each time
e07e6e58
NC
20920 a new instruction needs to be included in the IT block.
20921 Finally, the block is closed with close_automatic_it_block ().
20922 The block closure can be requested either from md_assemble (),
20923 a tencode (), or due to a label hook. */
20924
20925static void
20926new_automatic_it_block (int cond)
20927{
5ee91343
AV
20928 now_pred.state = AUTOMATIC_PRED_BLOCK;
20929 now_pred.mask = 0x18;
20930 now_pred.cc = cond;
20931 now_pred.block_length = 1;
cd000bff 20932 mapping_state (MAP_THUMB);
5ee91343
AV
20933 now_pred.insn = output_it_inst (cond, now_pred.mask, NULL);
20934 now_pred.warn_deprecated = FALSE;
20935 now_pred.insn_cond = TRUE;
e07e6e58
NC
20936}
20937
20938/* Close an automatic IT block.
20939 See comments in new_automatic_it_block (). */
20940
20941static void
20942close_automatic_it_block (void)
20943{
5ee91343
AV
20944 now_pred.mask = 0x10;
20945 now_pred.block_length = 0;
e07e6e58
NC
20946}
20947
20948/* Update the mask of the current automatically-generated IT
20949 instruction. See comments in new_automatic_it_block (). */
20950
20951static void
5ee91343 20952now_pred_add_mask (int cond)
e07e6e58
NC
20953{
20954#define CLEAR_BIT(value, nbit) ((value) & ~(1 << (nbit)))
20955#define SET_BIT_VALUE(value, bitvalue, nbit) (CLEAR_BIT (value, nbit) \
477330fc 20956 | ((bitvalue) << (nbit)))
e07e6e58 20957 const int resulting_bit = (cond & 1);
c921be7d 20958
5ee91343
AV
20959 now_pred.mask &= 0xf;
20960 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 20961 resulting_bit,
5ee91343
AV
20962 (5 - now_pred.block_length));
20963 now_pred.mask = SET_BIT_VALUE (now_pred.mask,
477330fc 20964 1,
5ee91343
AV
20965 ((5 - now_pred.block_length) - 1));
20966 output_it_inst (now_pred.cc, now_pred.mask, now_pred.insn);
e07e6e58
NC
20967
20968#undef CLEAR_BIT
20969#undef SET_BIT_VALUE
e07e6e58
NC
20970}
20971
20972/* The IT blocks handling machinery is accessed through the these functions:
20973 it_fsm_pre_encode () from md_assemble ()
5ee91343
AV
20974 set_pred_insn_type () optional, from the tencode functions
20975 set_pred_insn_type_last () ditto
20976 in_pred_block () ditto
e07e6e58 20977 it_fsm_post_encode () from md_assemble ()
33eaf5de 20978 force_automatic_it_block_close () from label handling functions
e07e6e58
NC
20979
20980 Rationale:
20981 1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
477330fc
RM
20982 initializing the IT insn type with a generic initial value depending
20983 on the inst.condition.
e07e6e58 20984 2) During the tencode function, two things may happen:
477330fc 20985 a) The tencode function overrides the IT insn type by
5ee91343
AV
20986 calling either set_pred_insn_type (type) or
20987 set_pred_insn_type_last ().
477330fc 20988 b) The tencode function queries the IT block state by
5ee91343 20989 calling in_pred_block () (i.e. to determine narrow/not narrow mode).
477330fc 20990
5ee91343
AV
20991 Both set_pred_insn_type and in_pred_block run the internal FSM state
20992 handling function (handle_pred_state), because: a) setting the IT insn
477330fc
RM
20993 type may incur in an invalid state (exiting the function),
20994 and b) querying the state requires the FSM to be updated.
20995 Specifically we want to avoid creating an IT block for conditional
20996 branches, so it_fsm_pre_encode is actually a guess and we can't
20997 determine whether an IT block is required until the tencode () routine
20998 has decided what type of instruction this actually it.
5ee91343
AV
20999 Because of this, if set_pred_insn_type and in_pred_block have to be
21000 used, set_pred_insn_type has to be called first.
477330fc 21001
5ee91343
AV
21002 set_pred_insn_type_last () is a wrapper of set_pred_insn_type (type),
21003 that determines the insn IT type depending on the inst.cond code.
477330fc
RM
21004 When a tencode () routine encodes an instruction that can be
21005 either outside an IT block, or, in the case of being inside, has to be
5ee91343 21006 the last one, set_pred_insn_type_last () will determine the proper
477330fc 21007 IT instruction type based on the inst.cond code. Otherwise,
5ee91343 21008 set_pred_insn_type can be called for overriding that logic or
477330fc
RM
21009 for covering other cases.
21010
5ee91343
AV
21011 Calling handle_pred_state () may not transition the IT block state to
21012 OUTSIDE_PRED_BLOCK immediately, since the (current) state could be
477330fc 21013 still queried. Instead, if the FSM determines that the state should
5ee91343 21014 be transitioned to OUTSIDE_PRED_BLOCK, a flag is marked to be closed
477330fc
RM
21015 after the tencode () function: that's what it_fsm_post_encode () does.
21016
5ee91343 21017 Since in_pred_block () calls the state handling function to get an
477330fc
RM
21018 updated state, an error may occur (due to invalid insns combination).
21019 In that case, inst.error is set.
21020 Therefore, inst.error has to be checked after the execution of
21021 the tencode () routine.
e07e6e58
NC
21022
21023 3) Back in md_assemble(), it_fsm_post_encode () is called to commit
477330fc 21024 any pending state change (if any) that didn't take place in
5ee91343 21025 handle_pred_state () as explained above. */
e07e6e58
NC
21026
21027static void
21028it_fsm_pre_encode (void)
21029{
21030 if (inst.cond != COND_ALWAYS)
5ee91343 21031 inst.pred_insn_type = INSIDE_IT_INSN;
e07e6e58 21032 else
5ee91343 21033 inst.pred_insn_type = OUTSIDE_PRED_INSN;
e07e6e58 21034
5ee91343 21035 now_pred.state_handled = 0;
e07e6e58
NC
21036}
21037
21038/* IT state FSM handling function. */
5ee91343
AV
21039/* MVE instructions and non-MVE instructions are handled differently because of
21040 the introduction of VPT blocks.
21041 Specifications say that any non-MVE instruction inside a VPT block is
21042 UNPREDICTABLE, with the exception of the BKPT instruction. Whereas most MVE
21043 instructions are deemed to be UNPREDICTABLE if inside an IT block. For the
35c228db 21044 few exceptions we have MVE_UNPREDICABLE_INSN.
5ee91343
AV
21045 The error messages provided depending on the different combinations possible
21046 are described in the cases below:
21047 For 'most' MVE instructions:
21048 1) In an IT block, with an IT code: syntax error
21049 2) In an IT block, with a VPT code: error: must be in a VPT block
21050 3) In an IT block, with no code: warning: UNPREDICTABLE
21051 4) In a VPT block, with an IT code: syntax error
21052 5) In a VPT block, with a VPT code: OK!
21053 6) In a VPT block, with no code: error: missing code
21054 7) Outside a pred block, with an IT code: error: syntax error
21055 8) Outside a pred block, with a VPT code: error: should be in a VPT block
21056 9) Outside a pred block, with no code: OK!
21057 For non-MVE instructions:
21058 10) In an IT block, with an IT code: OK!
21059 11) In an IT block, with a VPT code: syntax error
21060 12) In an IT block, with no code: error: missing code
21061 13) In a VPT block, with an IT code: error: should be in an IT block
21062 14) In a VPT block, with a VPT code: syntax error
21063 15) In a VPT block, with no code: UNPREDICTABLE
21064 16) Outside a pred block, with an IT code: error: should be in an IT block
21065 17) Outside a pred block, with a VPT code: syntax error
21066 18) Outside a pred block, with no code: OK!
21067 */
21068
e07e6e58
NC
21069
21070static int
5ee91343 21071handle_pred_state (void)
e07e6e58 21072{
5ee91343
AV
21073 now_pred.state_handled = 1;
21074 now_pred.insn_cond = FALSE;
e07e6e58 21075
5ee91343 21076 switch (now_pred.state)
e07e6e58 21077 {
5ee91343
AV
21078 case OUTSIDE_PRED_BLOCK:
21079 switch (inst.pred_insn_type)
e07e6e58 21080 {
35c228db 21081 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
21082 case MVE_OUTSIDE_PRED_INSN:
21083 if (inst.cond < COND_ALWAYS)
21084 {
21085 /* Case 7: Outside a pred block, with an IT code: error: syntax
21086 error. */
21087 inst.error = BAD_SYNTAX;
21088 return FAIL;
21089 }
21090 /* Case 9: Outside a pred block, with no code: OK! */
21091 break;
21092 case OUTSIDE_PRED_INSN:
21093 if (inst.cond > COND_ALWAYS)
21094 {
21095 /* Case 17: Outside a pred block, with a VPT code: syntax error.
21096 */
21097 inst.error = BAD_SYNTAX;
21098 return FAIL;
21099 }
21100 /* Case 18: Outside a pred block, with no code: OK! */
e07e6e58
NC
21101 break;
21102
5ee91343
AV
21103 case INSIDE_VPT_INSN:
21104 /* Case 8: Outside a pred block, with a VPT code: error: should be in
21105 a VPT block. */
21106 inst.error = BAD_OUT_VPT;
21107 return FAIL;
21108
e07e6e58
NC
21109 case INSIDE_IT_INSN:
21110 case INSIDE_IT_LAST_INSN:
5ee91343 21111 if (inst.cond < COND_ALWAYS)
e07e6e58 21112 {
5ee91343
AV
21113 /* Case 16: Outside a pred block, with an IT code: error: should
21114 be in an IT block. */
21115 if (thumb_mode == 0)
e07e6e58 21116 {
5ee91343
AV
21117 if (unified_syntax
21118 && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
21119 as_tsktsk (_("Warning: conditional outside an IT block"\
21120 " for Thumb."));
e07e6e58
NC
21121 }
21122 else
21123 {
5ee91343
AV
21124 if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
21125 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
21126 {
21127 /* Automatically generate the IT instruction. */
21128 new_automatic_it_block (inst.cond);
21129 if (inst.pred_insn_type == INSIDE_IT_LAST_INSN)
21130 close_automatic_it_block ();
21131 }
21132 else
21133 {
21134 inst.error = BAD_OUT_IT;
21135 return FAIL;
21136 }
e07e6e58 21137 }
5ee91343 21138 break;
e07e6e58 21139 }
5ee91343
AV
21140 else if (inst.cond > COND_ALWAYS)
21141 {
21142 /* Case 17: Outside a pred block, with a VPT code: syntax error.
21143 */
21144 inst.error = BAD_SYNTAX;
21145 return FAIL;
21146 }
21147 else
21148 gas_assert (0);
e07e6e58
NC
21149 case IF_INSIDE_IT_LAST_INSN:
21150 case NEUTRAL_IT_INSN:
21151 break;
21152
5ee91343
AV
21153 case VPT_INSN:
21154 if (inst.cond != COND_ALWAYS)
21155 first_error (BAD_SYNTAX);
21156 now_pred.state = MANUAL_PRED_BLOCK;
21157 now_pred.block_length = 0;
21158 now_pred.type = VECTOR_PRED;
21159 now_pred.cc = 0;
21160 break;
e07e6e58 21161 case IT_INSN:
5ee91343
AV
21162 now_pred.state = MANUAL_PRED_BLOCK;
21163 now_pred.block_length = 0;
21164 now_pred.type = SCALAR_PRED;
e07e6e58
NC
21165 break;
21166 }
21167 break;
21168
5ee91343 21169 case AUTOMATIC_PRED_BLOCK:
e07e6e58
NC
21170 /* Three things may happen now:
21171 a) We should increment current it block size;
21172 b) We should close current it block (closing insn or 4 insns);
21173 c) We should close current it block and start a new one (due
21174 to incompatible conditions or
21175 4 insns-length block reached). */
21176
5ee91343 21177 switch (inst.pred_insn_type)
e07e6e58 21178 {
5ee91343
AV
21179 case INSIDE_VPT_INSN:
21180 case VPT_INSN:
35c228db 21181 case MVE_UNPREDICABLE_INSN:
5ee91343
AV
21182 case MVE_OUTSIDE_PRED_INSN:
21183 gas_assert (0);
21184 case OUTSIDE_PRED_INSN:
2b0f3761 21185 /* The closure of the block shall happen immediately,
5ee91343 21186 so any in_pred_block () call reports the block as closed. */
e07e6e58
NC
21187 force_automatic_it_block_close ();
21188 break;
21189
21190 case INSIDE_IT_INSN:
21191 case INSIDE_IT_LAST_INSN:
21192 case IF_INSIDE_IT_LAST_INSN:
5ee91343 21193 now_pred.block_length++;
e07e6e58 21194
5ee91343
AV
21195 if (now_pred.block_length > 4
21196 || !now_pred_compatible (inst.cond))
e07e6e58
NC
21197 {
21198 force_automatic_it_block_close ();
5ee91343 21199 if (inst.pred_insn_type != IF_INSIDE_IT_LAST_INSN)
e07e6e58
NC
21200 new_automatic_it_block (inst.cond);
21201 }
21202 else
21203 {
5ee91343
AV
21204 now_pred.insn_cond = TRUE;
21205 now_pred_add_mask (inst.cond);
e07e6e58
NC
21206 }
21207
5ee91343
AV
21208 if (now_pred.state == AUTOMATIC_PRED_BLOCK
21209 && (inst.pred_insn_type == INSIDE_IT_LAST_INSN
21210 || inst.pred_insn_type == IF_INSIDE_IT_LAST_INSN))
e07e6e58
NC
21211 close_automatic_it_block ();
21212 break;
21213
21214 case NEUTRAL_IT_INSN:
5ee91343
AV
21215 now_pred.block_length++;
21216 now_pred.insn_cond = TRUE;
e07e6e58 21217
5ee91343 21218 if (now_pred.block_length > 4)
e07e6e58
NC
21219 force_automatic_it_block_close ();
21220 else
5ee91343 21221 now_pred_add_mask (now_pred.cc & 1);
e07e6e58
NC
21222 break;
21223
21224 case IT_INSN:
21225 close_automatic_it_block ();
5ee91343 21226 now_pred.state = MANUAL_PRED_BLOCK;
e07e6e58
NC
21227 break;
21228 }
21229 break;
21230
5ee91343 21231 case MANUAL_PRED_BLOCK:
e07e6e58 21232 {
5ee91343
AV
21233 int cond, is_last;
21234 if (now_pred.type == SCALAR_PRED)
e07e6e58 21235 {
5ee91343
AV
21236 /* Check conditional suffixes. */
21237 cond = now_pred.cc ^ ((now_pred.mask >> 4) & 1) ^ 1;
21238 now_pred.mask <<= 1;
21239 now_pred.mask &= 0x1f;
21240 is_last = (now_pred.mask == 0x10);
21241 }
21242 else
21243 {
21244 now_pred.cc ^= (now_pred.mask >> 4);
21245 cond = now_pred.cc + 0xf;
21246 now_pred.mask <<= 1;
21247 now_pred.mask &= 0x1f;
21248 is_last = now_pred.mask == 0x10;
21249 }
21250 now_pred.insn_cond = TRUE;
e07e6e58 21251
5ee91343
AV
21252 switch (inst.pred_insn_type)
21253 {
21254 case OUTSIDE_PRED_INSN:
21255 if (now_pred.type == SCALAR_PRED)
21256 {
21257 if (inst.cond == COND_ALWAYS)
21258 {
21259 /* Case 12: In an IT block, with no code: error: missing
21260 code. */
21261 inst.error = BAD_NOT_IT;
21262 return FAIL;
21263 }
21264 else if (inst.cond > COND_ALWAYS)
21265 {
21266 /* Case 11: In an IT block, with a VPT code: syntax error.
21267 */
21268 inst.error = BAD_SYNTAX;
21269 return FAIL;
21270 }
21271 else if (thumb_mode)
21272 {
21273 /* This is for some special cases where a non-MVE
21274 instruction is not allowed in an IT block, such as cbz,
21275 but are put into one with a condition code.
21276 You could argue this should be a syntax error, but we
21277 gave the 'not allowed in IT block' diagnostic in the
21278 past so we will keep doing so. */
21279 inst.error = BAD_NOT_IT;
21280 return FAIL;
21281 }
21282 break;
21283 }
21284 else
21285 {
21286 /* Case 15: In a VPT block, with no code: UNPREDICTABLE. */
21287 as_tsktsk (MVE_NOT_VPT);
21288 return SUCCESS;
21289 }
21290 case MVE_OUTSIDE_PRED_INSN:
21291 if (now_pred.type == SCALAR_PRED)
21292 {
21293 if (inst.cond == COND_ALWAYS)
21294 {
21295 /* Case 3: In an IT block, with no code: warning:
21296 UNPREDICTABLE. */
21297 as_tsktsk (MVE_NOT_IT);
21298 return SUCCESS;
21299 }
21300 else if (inst.cond < COND_ALWAYS)
21301 {
21302 /* Case 1: In an IT block, with an IT code: syntax error.
21303 */
21304 inst.error = BAD_SYNTAX;
21305 return FAIL;
21306 }
21307 else
21308 gas_assert (0);
21309 }
21310 else
21311 {
21312 if (inst.cond < COND_ALWAYS)
21313 {
21314 /* Case 4: In a VPT block, with an IT code: syntax error.
21315 */
21316 inst.error = BAD_SYNTAX;
21317 return FAIL;
21318 }
21319 else if (inst.cond == COND_ALWAYS)
21320 {
21321 /* Case 6: In a VPT block, with no code: error: missing
21322 code. */
21323 inst.error = BAD_NOT_VPT;
21324 return FAIL;
21325 }
21326 else
21327 {
21328 gas_assert (0);
21329 }
21330 }
35c228db
AV
21331 case MVE_UNPREDICABLE_INSN:
21332 as_tsktsk (now_pred.type == SCALAR_PRED ? MVE_NOT_IT : MVE_NOT_VPT);
21333 return SUCCESS;
e07e6e58 21334 case INSIDE_IT_INSN:
5ee91343 21335 if (inst.cond > COND_ALWAYS)
e07e6e58 21336 {
5ee91343
AV
21337 /* Case 11: In an IT block, with a VPT code: syntax error. */
21338 /* Case 14: In a VPT block, with a VPT code: syntax error. */
21339 inst.error = BAD_SYNTAX;
21340 return FAIL;
21341 }
21342 else if (now_pred.type == SCALAR_PRED)
21343 {
21344 /* Case 10: In an IT block, with an IT code: OK! */
21345 if (cond != inst.cond)
21346 {
21347 inst.error = now_pred.type == SCALAR_PRED ? BAD_IT_COND :
21348 BAD_VPT_COND;
21349 return FAIL;
21350 }
21351 }
21352 else
21353 {
21354 /* Case 13: In a VPT block, with an IT code: error: should be
21355 in an IT block. */
21356 inst.error = BAD_OUT_IT;
e07e6e58
NC
21357 return FAIL;
21358 }
21359 break;
21360
5ee91343
AV
21361 case INSIDE_VPT_INSN:
21362 if (now_pred.type == SCALAR_PRED)
21363 {
21364 /* Case 2: In an IT block, with a VPT code: error: must be in a
21365 VPT block. */
21366 inst.error = BAD_OUT_VPT;
21367 return FAIL;
21368 }
21369 /* Case 5: In a VPT block, with a VPT code: OK! */
21370 else if (cond != inst.cond)
21371 {
21372 inst.error = BAD_VPT_COND;
21373 return FAIL;
21374 }
21375 break;
e07e6e58
NC
21376 case INSIDE_IT_LAST_INSN:
21377 case IF_INSIDE_IT_LAST_INSN:
5ee91343
AV
21378 if (now_pred.type == VECTOR_PRED || inst.cond > COND_ALWAYS)
21379 {
21380 /* Case 4: In a VPT block, with an IT code: syntax error. */
21381 /* Case 11: In an IT block, with a VPT code: syntax error. */
21382 inst.error = BAD_SYNTAX;
21383 return FAIL;
21384 }
21385 else if (cond != inst.cond)
e07e6e58
NC
21386 {
21387 inst.error = BAD_IT_COND;
21388 return FAIL;
21389 }
21390 if (!is_last)
21391 {
21392 inst.error = BAD_BRANCH;
21393 return FAIL;
21394 }
21395 break;
21396
21397 case NEUTRAL_IT_INSN:
5ee91343
AV
21398 /* The BKPT instruction is unconditional even in a IT or VPT
21399 block. */
e07e6e58
NC
21400 break;
21401
21402 case IT_INSN:
5ee91343
AV
21403 if (now_pred.type == SCALAR_PRED)
21404 {
21405 inst.error = BAD_IT_IT;
21406 return FAIL;
21407 }
21408 /* fall through. */
21409 case VPT_INSN:
21410 if (inst.cond == COND_ALWAYS)
21411 {
21412 /* Executing a VPT/VPST instruction inside an IT block or a
21413 VPT/VPST/IT instruction inside a VPT block is UNPREDICTABLE.
21414 */
21415 if (now_pred.type == SCALAR_PRED)
21416 as_tsktsk (MVE_NOT_IT);
21417 else
21418 as_tsktsk (MVE_NOT_VPT);
21419 return SUCCESS;
21420 }
21421 else
21422 {
21423 /* VPT/VPST do not accept condition codes. */
21424 inst.error = BAD_SYNTAX;
21425 return FAIL;
21426 }
e07e6e58 21427 }
5ee91343 21428 }
e07e6e58
NC
21429 break;
21430 }
21431
21432 return SUCCESS;
21433}
21434
5a01bb1d
MGD
21435struct depr_insn_mask
21436{
21437 unsigned long pattern;
21438 unsigned long mask;
21439 const char* description;
21440};
21441
21442/* List of 16-bit instruction patterns deprecated in an IT block in
21443 ARMv8. */
21444static const struct depr_insn_mask depr_it_insns[] = {
21445 { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
21446 { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
21447 { 0xa000, 0xb800, N_("ADR") },
21448 { 0x4800, 0xf800, N_("Literal loads") },
21449 { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
21450 { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
c8de034b
JW
21451 /* NOTE: 0x00dd is not the real encoding, instead, it is the 'tvalue'
21452 field in asm_opcode. 'tvalue' is used at the stage this check happen. */
21453 { 0x00dd, 0x7fff, N_("ADD/SUB sp, sp #imm") },
5a01bb1d
MGD
21454 { 0, 0, NULL }
21455};
21456
e07e6e58
NC
21457static void
21458it_fsm_post_encode (void)
21459{
21460 int is_last;
21461
5ee91343
AV
21462 if (!now_pred.state_handled)
21463 handle_pred_state ();
e07e6e58 21464
5ee91343
AV
21465 if (now_pred.insn_cond
21466 && !now_pred.warn_deprecated
5a01bb1d 21467 && warn_on_deprecated
df9909b8
TP
21468 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)
21469 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m))
5a01bb1d
MGD
21470 {
21471 if (inst.instruction >= 0x10000)
21472 {
5c3696f8 21473 as_tsktsk (_("IT blocks containing 32-bit Thumb instructions are "
df9909b8 21474 "performance deprecated in ARMv8-A and ARMv8-R"));
5ee91343 21475 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
21476 }
21477 else
21478 {
21479 const struct depr_insn_mask *p = depr_it_insns;
21480
21481 while (p->mask != 0)
21482 {
21483 if ((inst.instruction & p->mask) == p->pattern)
21484 {
df9909b8
TP
21485 as_tsktsk (_("IT blocks containing 16-bit Thumb "
21486 "instructions of the following class are "
21487 "performance deprecated in ARMv8-A and "
21488 "ARMv8-R: %s"), p->description);
5ee91343 21489 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
21490 break;
21491 }
21492
21493 ++p;
21494 }
21495 }
21496
5ee91343 21497 if (now_pred.block_length > 1)
5a01bb1d 21498 {
5c3696f8 21499 as_tsktsk (_("IT blocks containing more than one conditional "
df9909b8
TP
21500 "instruction are performance deprecated in ARMv8-A and "
21501 "ARMv8-R"));
5ee91343 21502 now_pred.warn_deprecated = TRUE;
5a01bb1d
MGD
21503 }
21504 }
21505
5ee91343
AV
21506 is_last = (now_pred.mask == 0x10);
21507 if (is_last)
21508 {
21509 now_pred.state = OUTSIDE_PRED_BLOCK;
21510 now_pred.mask = 0;
21511 }
e07e6e58
NC
21512}
21513
21514static void
21515force_automatic_it_block_close (void)
21516{
5ee91343 21517 if (now_pred.state == AUTOMATIC_PRED_BLOCK)
e07e6e58
NC
21518 {
21519 close_automatic_it_block ();
5ee91343
AV
21520 now_pred.state = OUTSIDE_PRED_BLOCK;
21521 now_pred.mask = 0;
e07e6e58
NC
21522 }
21523}
21524
21525static int
5ee91343 21526in_pred_block (void)
e07e6e58 21527{
5ee91343
AV
21528 if (!now_pred.state_handled)
21529 handle_pred_state ();
e07e6e58 21530
5ee91343 21531 return now_pred.state != OUTSIDE_PRED_BLOCK;
e07e6e58
NC
21532}
21533
ff8646ee
TP
21534/* Whether OPCODE only has T32 encoding. Since this function is only used by
21535 t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed
21536 here, hence the "known" in the function name. */
fc289b0a
TP
21537
21538static bfd_boolean
ff8646ee 21539known_t32_only_insn (const struct asm_opcode *opcode)
fc289b0a
TP
21540{
21541 /* Original Thumb-1 wide instruction. */
21542 if (opcode->tencode == do_t_blx
21543 || opcode->tencode == do_t_branch23
21544 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
21545 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
21546 return TRUE;
21547
16a1fa25
TP
21548 /* Wide-only instruction added to ARMv8-M Baseline. */
21549 if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m_m_only)
ff8646ee
TP
21550 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics)
21551 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m)
21552 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div))
21553 return TRUE;
21554
21555 return FALSE;
21556}
21557
21558/* Whether wide instruction variant can be used if available for a valid OPCODE
21559 in ARCH. */
21560
21561static bfd_boolean
21562t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode)
21563{
21564 if (known_t32_only_insn (opcode))
21565 return TRUE;
21566
21567 /* Instruction with narrow and wide encoding added to ARMv8-M. Availability
21568 of variant T3 of B.W is checked in do_t_branch. */
21569 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
21570 && opcode->tencode == do_t_branch)
21571 return TRUE;
21572
bada4342
JW
21573 /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */
21574 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
21575 && opcode->tencode == do_t_mov_cmp
21576 /* Make sure CMP instruction is not affected. */
21577 && opcode->aencode == do_mov)
21578 return TRUE;
21579
ff8646ee
TP
21580 /* Wide instruction variants of all instructions with narrow *and* wide
21581 variants become available with ARMv6t2. Other opcodes are either
21582 narrow-only or wide-only and are thus available if OPCODE is valid. */
21583 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2))
21584 return TRUE;
21585
21586 /* OPCODE with narrow only instruction variant or wide variant not
21587 available. */
fc289b0a
TP
21588 return FALSE;
21589}
21590
c19d1205
ZW
21591void
21592md_assemble (char *str)
b99bd4ef 21593{
c19d1205
ZW
21594 char *p = str;
21595 const struct asm_opcode * opcode;
b99bd4ef 21596
c19d1205
ZW
21597 /* Align the previous label if needed. */
21598 if (last_label_seen != NULL)
b99bd4ef 21599 {
c19d1205
ZW
21600 symbol_set_frag (last_label_seen, frag_now);
21601 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
21602 S_SET_SEGMENT (last_label_seen, now_seg);
b99bd4ef
NC
21603 }
21604
c19d1205 21605 memset (&inst, '\0', sizeof (inst));
e2b0ab59
AV
21606 int r;
21607 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
21608 inst.relocs[r].type = BFD_RELOC_UNUSED;
b99bd4ef 21609
c19d1205
ZW
21610 opcode = opcode_lookup (&p);
21611 if (!opcode)
b99bd4ef 21612 {
c19d1205 21613 /* It wasn't an instruction, but it might be a register alias of
dcbf9037 21614 the form alias .req reg, or a Neon .dn/.qn directive. */
c921be7d 21615 if (! create_register_alias (str, p)
477330fc 21616 && ! create_neon_reg_alias (str, p))
c19d1205 21617 as_bad (_("bad instruction `%s'"), str);
b99bd4ef 21618
b99bd4ef
NC
21619 return;
21620 }
21621
278df34e 21622 if (warn_on_deprecated && opcode->tag == OT_cinfix3_deprecated)
5c3696f8 21623 as_tsktsk (_("s suffix on comparison instruction is deprecated"));
088fa78e 21624
037e8744
JB
21625 /* The value which unconditional instructions should have in place of the
21626 condition field. */
21627 inst.uncond_value = (opcode->tag == OT_csuffixF) ? 0xf : -1;
21628
c19d1205 21629 if (thumb_mode)
b99bd4ef 21630 {
e74cfd16 21631 arm_feature_set variant;
8f06b2d8
PB
21632
21633 variant = cpu_variant;
21634 /* Only allow coprocessor instructions on Thumb-2 capable devices. */
e74cfd16
PB
21635 if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2))
21636 ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard);
c19d1205 21637 /* Check that this instruction is supported for this CPU. */
62b3e311
PB
21638 if (!opcode->tvariant
21639 || (thumb_mode == 1
21640 && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
b99bd4ef 21641 {
173205ca
TP
21642 if (opcode->tencode == do_t_swi)
21643 as_bad (_("SVC is not permitted on this architecture"));
21644 else
21645 as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
b99bd4ef
NC
21646 return;
21647 }
c19d1205
ZW
21648 if (inst.cond != COND_ALWAYS && !unified_syntax
21649 && opcode->tencode != do_t_branch)
b99bd4ef 21650 {
c19d1205 21651 as_bad (_("Thumb does not support conditional execution"));
b99bd4ef
NC
21652 return;
21653 }
21654
fc289b0a
TP
21655 /* Two things are addressed here:
21656 1) Implicit require narrow instructions on Thumb-1.
21657 This avoids relaxation accidentally introducing Thumb-2
21658 instructions.
21659 2) Reject wide instructions in non Thumb-2 cores.
21660
21661 Only instructions with narrow and wide variants need to be handled
21662 but selecting all non wide-only instructions is easier. */
21663 if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)
ff8646ee 21664 && !t32_insn_ok (variant, opcode))
076d447c 21665 {
fc289b0a
TP
21666 if (inst.size_req == 0)
21667 inst.size_req = 2;
21668 else if (inst.size_req == 4)
752d5da4 21669 {
ff8646ee
TP
21670 if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m))
21671 as_bad (_("selected processor does not support 32bit wide "
21672 "variant of instruction `%s'"), str);
21673 else
21674 as_bad (_("selected processor does not support `%s' in "
21675 "Thumb-2 mode"), str);
fc289b0a 21676 return;
752d5da4 21677 }
076d447c
PB
21678 }
21679
c19d1205
ZW
21680 inst.instruction = opcode->tvalue;
21681
5be8be5d 21682 if (!parse_operands (p, opcode->operands, /*thumb=*/TRUE))
477330fc 21683 {
5ee91343 21684 /* Prepare the pred_insn_type for those encodings that don't set
477330fc
RM
21685 it. */
21686 it_fsm_pre_encode ();
c19d1205 21687
477330fc 21688 opcode->tencode ();
e07e6e58 21689
477330fc
RM
21690 it_fsm_post_encode ();
21691 }
e27ec89e 21692
0110f2b8 21693 if (!(inst.error || inst.relax))
b99bd4ef 21694 {
9c2799c2 21695 gas_assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
c19d1205
ZW
21696 inst.size = (inst.instruction > 0xffff ? 4 : 2);
21697 if (inst.size_req && inst.size_req != inst.size)
b99bd4ef 21698 {
c19d1205 21699 as_bad (_("cannot honor width suffix -- `%s'"), str);
b99bd4ef
NC
21700 return;
21701 }
21702 }
076d447c
PB
21703
21704 /* Something has gone badly wrong if we try to relax a fixed size
477330fc 21705 instruction. */
9c2799c2 21706 gas_assert (inst.size_req == 0 || !inst.relax);
076d447c 21707
e74cfd16
PB
21708 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
21709 *opcode->tvariant);
ee065d83 21710 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
fc289b0a
TP
21711 set those bits when Thumb-2 32-bit instructions are seen. The impact
21712 of relaxable instructions will be considered later after we finish all
21713 relaxation. */
ff8646ee
TP
21714 if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any))
21715 variant = arm_arch_none;
21716 else
21717 variant = cpu_variant;
21718 if (inst.size == 4 && !t32_insn_ok (variant, opcode))
e74cfd16
PB
21719 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
21720 arm_ext_v6t2);
cd000bff 21721
88714cb8
DG
21722 check_neon_suffixes;
21723
cd000bff 21724 if (!inst.error)
c877a2f2
NC
21725 {
21726 mapping_state (MAP_THUMB);
21727 }
c19d1205 21728 }
3e9e4fcf 21729 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205 21730 {
845b51d6
PB
21731 bfd_boolean is_bx;
21732
21733 /* bx is allowed on v5 cores, and sometimes on v4 cores. */
21734 is_bx = (opcode->aencode == do_bx);
21735
c19d1205 21736 /* Check that this instruction is supported for this CPU. */
845b51d6
PB
21737 if (!(is_bx && fix_v4bx)
21738 && !(opcode->avariant &&
21739 ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)))
b99bd4ef 21740 {
84b52b66 21741 as_bad (_("selected processor does not support `%s' in ARM mode"), str);
c19d1205 21742 return;
b99bd4ef 21743 }
c19d1205 21744 if (inst.size_req)
b99bd4ef 21745 {
c19d1205
ZW
21746 as_bad (_("width suffixes are invalid in ARM mode -- `%s'"), str);
21747 return;
b99bd4ef
NC
21748 }
21749
c19d1205
ZW
21750 inst.instruction = opcode->avalue;
21751 if (opcode->tag == OT_unconditionalF)
eff0bc54 21752 inst.instruction |= 0xFU << 28;
c19d1205
ZW
21753 else
21754 inst.instruction |= inst.cond << 28;
21755 inst.size = INSN_SIZE;
5be8be5d 21756 if (!parse_operands (p, opcode->operands, /*thumb=*/FALSE))
477330fc
RM
21757 {
21758 it_fsm_pre_encode ();
21759 opcode->aencode ();
21760 it_fsm_post_encode ();
21761 }
ee065d83 21762 /* Arm mode bx is marked as both v4T and v5 because it's still required
477330fc 21763 on a hypothetical non-thumb v5 core. */
845b51d6 21764 if (is_bx)
e74cfd16 21765 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t);
ee065d83 21766 else
e74cfd16
PB
21767 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
21768 *opcode->avariant);
88714cb8
DG
21769
21770 check_neon_suffixes;
21771
cd000bff 21772 if (!inst.error)
c877a2f2
NC
21773 {
21774 mapping_state (MAP_ARM);
21775 }
b99bd4ef 21776 }
3e9e4fcf
JB
21777 else
21778 {
21779 as_bad (_("attempt to use an ARM instruction on a Thumb-only processor "
21780 "-- `%s'"), str);
21781 return;
21782 }
c19d1205
ZW
21783 output_inst (str);
21784}
b99bd4ef 21785
e07e6e58 21786static void
5ee91343 21787check_pred_blocks_finished (void)
e07e6e58
NC
21788{
21789#ifdef OBJ_ELF
21790 asection *sect;
21791
21792 for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
5ee91343
AV
21793 if (seg_info (sect)->tc_segment_info_data.current_pred.state
21794 == MANUAL_PRED_BLOCK)
e07e6e58 21795 {
5ee91343
AV
21796 if (now_pred.type == SCALAR_PRED)
21797 as_warn (_("section '%s' finished with an open IT block."),
21798 sect->name);
21799 else
21800 as_warn (_("section '%s' finished with an open VPT/VPST block."),
21801 sect->name);
e07e6e58
NC
21802 }
21803#else
5ee91343
AV
21804 if (now_pred.state == MANUAL_PRED_BLOCK)
21805 {
21806 if (now_pred.type == SCALAR_PRED)
21807 as_warn (_("file finished with an open IT block."));
21808 else
21809 as_warn (_("file finished with an open VPT/VPST block."));
21810 }
e07e6e58
NC
21811#endif
21812}
21813
c19d1205
ZW
21814/* Various frobbings of labels and their addresses. */
21815
21816void
21817arm_start_line_hook (void)
21818{
21819 last_label_seen = NULL;
b99bd4ef
NC
21820}
21821
c19d1205
ZW
21822void
21823arm_frob_label (symbolS * sym)
b99bd4ef 21824{
c19d1205 21825 last_label_seen = sym;
b99bd4ef 21826
c19d1205 21827 ARM_SET_THUMB (sym, thumb_mode);
b99bd4ef 21828
c19d1205
ZW
21829#if defined OBJ_COFF || defined OBJ_ELF
21830 ARM_SET_INTERWORK (sym, support_interwork);
21831#endif
b99bd4ef 21832
e07e6e58
NC
21833 force_automatic_it_block_close ();
21834
5f4273c7 21835 /* Note - do not allow local symbols (.Lxxx) to be labelled
c19d1205
ZW
21836 as Thumb functions. This is because these labels, whilst
21837 they exist inside Thumb code, are not the entry points for
21838 possible ARM->Thumb calls. Also, these labels can be used
21839 as part of a computed goto or switch statement. eg gcc
21840 can generate code that looks like this:
b99bd4ef 21841
c19d1205
ZW
21842 ldr r2, [pc, .Laaa]
21843 lsl r3, r3, #2
21844 ldr r2, [r3, r2]
21845 mov pc, r2
b99bd4ef 21846
c19d1205
ZW
21847 .Lbbb: .word .Lxxx
21848 .Lccc: .word .Lyyy
21849 ..etc...
21850 .Laaa: .word Lbbb
b99bd4ef 21851
c19d1205
ZW
21852 The first instruction loads the address of the jump table.
21853 The second instruction converts a table index into a byte offset.
21854 The third instruction gets the jump address out of the table.
21855 The fourth instruction performs the jump.
b99bd4ef 21856
c19d1205
ZW
21857 If the address stored at .Laaa is that of a symbol which has the
21858 Thumb_Func bit set, then the linker will arrange for this address
21859 to have the bottom bit set, which in turn would mean that the
21860 address computation performed by the third instruction would end
21861 up with the bottom bit set. Since the ARM is capable of unaligned
21862 word loads, the instruction would then load the incorrect address
21863 out of the jump table, and chaos would ensue. */
21864 if (label_is_thumb_function_name
21865 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
21866 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
b99bd4ef 21867 {
c19d1205
ZW
21868 /* When the address of a Thumb function is taken the bottom
21869 bit of that address should be set. This will allow
21870 interworking between Arm and Thumb functions to work
21871 correctly. */
b99bd4ef 21872
c19d1205 21873 THUMB_SET_FUNC (sym, 1);
b99bd4ef 21874
c19d1205 21875 label_is_thumb_function_name = FALSE;
b99bd4ef 21876 }
07a53e5c 21877
07a53e5c 21878 dwarf2_emit_label (sym);
b99bd4ef
NC
21879}
21880
c921be7d 21881bfd_boolean
c19d1205 21882arm_data_in_code (void)
b99bd4ef 21883{
c19d1205 21884 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
b99bd4ef 21885 {
c19d1205
ZW
21886 *input_line_pointer = '/';
21887 input_line_pointer += 5;
21888 *input_line_pointer = 0;
c921be7d 21889 return TRUE;
b99bd4ef
NC
21890 }
21891
c921be7d 21892 return FALSE;
b99bd4ef
NC
21893}
21894
c19d1205
ZW
21895char *
21896arm_canonicalize_symbol_name (char * name)
b99bd4ef 21897{
c19d1205 21898 int len;
b99bd4ef 21899
c19d1205
ZW
21900 if (thumb_mode && (len = strlen (name)) > 5
21901 && streq (name + len - 5, "/data"))
21902 *(name + len - 5) = 0;
b99bd4ef 21903
c19d1205 21904 return name;
b99bd4ef 21905}
c19d1205
ZW
21906\f
21907/* Table of all register names defined by default. The user can
21908 define additional names with .req. Note that all register names
21909 should appear in both upper and lowercase variants. Some registers
21910 also have mixed-case names. */
b99bd4ef 21911
dcbf9037 21912#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, TRUE, 0 }
c19d1205 21913#define REGNUM(p,n,t) REGDEF(p##n, n, t)
5287ad62 21914#define REGNUM2(p,n,t) REGDEF(p##n, 2 * n, t)
c19d1205
ZW
21915#define REGSET(p,t) \
21916 REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
21917 REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
21918 REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
21919 REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
5287ad62
JB
21920#define REGSETH(p,t) \
21921 REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
21922 REGNUM(p,20,t), REGNUM(p,21,t), REGNUM(p,22,t), REGNUM(p,23,t), \
21923 REGNUM(p,24,t), REGNUM(p,25,t), REGNUM(p,26,t), REGNUM(p,27,t), \
21924 REGNUM(p,28,t), REGNUM(p,29,t), REGNUM(p,30,t), REGNUM(p,31,t)
21925#define REGSET2(p,t) \
21926 REGNUM2(p, 0,t), REGNUM2(p, 1,t), REGNUM2(p, 2,t), REGNUM2(p, 3,t), \
21927 REGNUM2(p, 4,t), REGNUM2(p, 5,t), REGNUM2(p, 6,t), REGNUM2(p, 7,t), \
21928 REGNUM2(p, 8,t), REGNUM2(p, 9,t), REGNUM2(p,10,t), REGNUM2(p,11,t), \
21929 REGNUM2(p,12,t), REGNUM2(p,13,t), REGNUM2(p,14,t), REGNUM2(p,15,t)
90ec0d68
MGD
21930#define SPLRBANK(base,bank,t) \
21931 REGDEF(lr_##bank, 768|((base+0)<<16), t), \
21932 REGDEF(sp_##bank, 768|((base+1)<<16), t), \
21933 REGDEF(spsr_##bank, 768|(base<<16)|SPSR_BIT, t), \
21934 REGDEF(LR_##bank, 768|((base+0)<<16), t), \
21935 REGDEF(SP_##bank, 768|((base+1)<<16), t), \
21936 REGDEF(SPSR_##bank, 768|(base<<16)|SPSR_BIT, t)
7ed4c4c5 21937
c19d1205 21938static const struct reg_entry reg_names[] =
7ed4c4c5 21939{
c19d1205
ZW
21940 /* ARM integer registers. */
21941 REGSET(r, RN), REGSET(R, RN),
7ed4c4c5 21942
c19d1205
ZW
21943 /* ATPCS synonyms. */
21944 REGDEF(a1,0,RN), REGDEF(a2,1,RN), REGDEF(a3, 2,RN), REGDEF(a4, 3,RN),
21945 REGDEF(v1,4,RN), REGDEF(v2,5,RN), REGDEF(v3, 6,RN), REGDEF(v4, 7,RN),
21946 REGDEF(v5,8,RN), REGDEF(v6,9,RN), REGDEF(v7,10,RN), REGDEF(v8,11,RN),
7ed4c4c5 21947
c19d1205
ZW
21948 REGDEF(A1,0,RN), REGDEF(A2,1,RN), REGDEF(A3, 2,RN), REGDEF(A4, 3,RN),
21949 REGDEF(V1,4,RN), REGDEF(V2,5,RN), REGDEF(V3, 6,RN), REGDEF(V4, 7,RN),
21950 REGDEF(V5,8,RN), REGDEF(V6,9,RN), REGDEF(V7,10,RN), REGDEF(V8,11,RN),
7ed4c4c5 21951
c19d1205
ZW
21952 /* Well-known aliases. */
21953 REGDEF(wr, 7,RN), REGDEF(sb, 9,RN), REGDEF(sl,10,RN), REGDEF(fp,11,RN),
21954 REGDEF(ip,12,RN), REGDEF(sp,13,RN), REGDEF(lr,14,RN), REGDEF(pc,15,RN),
21955
21956 REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
21957 REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
21958
1b883319
AV
21959 /* Defining the new Zero register from ARMv8.1-M. */
21960 REGDEF(zr,15,ZR),
21961 REGDEF(ZR,15,ZR),
21962
c19d1205
ZW
21963 /* Coprocessor numbers. */
21964 REGSET(p, CP), REGSET(P, CP),
21965
21966 /* Coprocessor register numbers. The "cr" variants are for backward
21967 compatibility. */
21968 REGSET(c, CN), REGSET(C, CN),
21969 REGSET(cr, CN), REGSET(CR, CN),
21970
90ec0d68
MGD
21971 /* ARM banked registers. */
21972 REGDEF(R8_usr,512|(0<<16),RNB), REGDEF(r8_usr,512|(0<<16),RNB),
21973 REGDEF(R9_usr,512|(1<<16),RNB), REGDEF(r9_usr,512|(1<<16),RNB),
21974 REGDEF(R10_usr,512|(2<<16),RNB), REGDEF(r10_usr,512|(2<<16),RNB),
21975 REGDEF(R11_usr,512|(3<<16),RNB), REGDEF(r11_usr,512|(3<<16),RNB),
21976 REGDEF(R12_usr,512|(4<<16),RNB), REGDEF(r12_usr,512|(4<<16),RNB),
21977 REGDEF(SP_usr,512|(5<<16),RNB), REGDEF(sp_usr,512|(5<<16),RNB),
21978 REGDEF(LR_usr,512|(6<<16),RNB), REGDEF(lr_usr,512|(6<<16),RNB),
21979
21980 REGDEF(R8_fiq,512|(8<<16),RNB), REGDEF(r8_fiq,512|(8<<16),RNB),
21981 REGDEF(R9_fiq,512|(9<<16),RNB), REGDEF(r9_fiq,512|(9<<16),RNB),
21982 REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
21983 REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
21984 REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
1472d06f 21985 REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(sp_fiq,512|(13<<16),RNB),
90ec0d68
MGD
21986 REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
21987 REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
21988
21989 SPLRBANK(0,IRQ,RNB), SPLRBANK(0,irq,RNB),
21990 SPLRBANK(2,SVC,RNB), SPLRBANK(2,svc,RNB),
21991 SPLRBANK(4,ABT,RNB), SPLRBANK(4,abt,RNB),
21992 SPLRBANK(6,UND,RNB), SPLRBANK(6,und,RNB),
21993 SPLRBANK(12,MON,RNB), SPLRBANK(12,mon,RNB),
21994 REGDEF(elr_hyp,768|(14<<16),RNB), REGDEF(ELR_hyp,768|(14<<16),RNB),
21995 REGDEF(sp_hyp,768|(15<<16),RNB), REGDEF(SP_hyp,768|(15<<16),RNB),
fa94de6b 21996 REGDEF(spsr_hyp,768|(14<<16)|SPSR_BIT,RNB),
90ec0d68
MGD
21997 REGDEF(SPSR_hyp,768|(14<<16)|SPSR_BIT,RNB),
21998
c19d1205
ZW
21999 /* FPA registers. */
22000 REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
22001 REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
22002
22003 REGNUM(F,0,FN), REGNUM(F,1,FN), REGNUM(F,2,FN), REGNUM(F,3,FN),
22004 REGNUM(F,4,FN), REGNUM(F,5,FN), REGNUM(F,6,FN), REGNUM(F,7, FN),
22005
22006 /* VFP SP registers. */
5287ad62
JB
22007 REGSET(s,VFS), REGSET(S,VFS),
22008 REGSETH(s,VFS), REGSETH(S,VFS),
c19d1205
ZW
22009
22010 /* VFP DP Registers. */
5287ad62
JB
22011 REGSET(d,VFD), REGSET(D,VFD),
22012 /* Extra Neon DP registers. */
22013 REGSETH(d,VFD), REGSETH(D,VFD),
22014
22015 /* Neon QP registers. */
22016 REGSET2(q,NQ), REGSET2(Q,NQ),
c19d1205
ZW
22017
22018 /* VFP control registers. */
22019 REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
22020 REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
cd2cf30b
PB
22021 REGDEF(fpinst,9,VFC), REGDEF(fpinst2,10,VFC),
22022 REGDEF(FPINST,9,VFC), REGDEF(FPINST2,10,VFC),
22023 REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
22024 REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
40c7d507 22025 REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
c19d1205
ZW
22026
22027 /* Maverick DSP coprocessor registers. */
22028 REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
22029 REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
22030
22031 REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
22032 REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
22033 REGDEF(dspsc,0,DSPSC),
22034
22035 REGNUM(MVAX,0,MVAX), REGNUM(MVAX,1,MVAX),
22036 REGNUM(MVAX,2,MVAX), REGNUM(MVAX,3,MVAX),
22037 REGDEF(DSPSC,0,DSPSC),
22038
22039 /* iWMMXt data registers - p0, c0-15. */
22040 REGSET(wr,MMXWR), REGSET(wR,MMXWR), REGSET(WR, MMXWR),
22041
22042 /* iWMMXt control registers - p1, c0-3. */
22043 REGDEF(wcid, 0,MMXWC), REGDEF(wCID, 0,MMXWC), REGDEF(WCID, 0,MMXWC),
22044 REGDEF(wcon, 1,MMXWC), REGDEF(wCon, 1,MMXWC), REGDEF(WCON, 1,MMXWC),
22045 REGDEF(wcssf, 2,MMXWC), REGDEF(wCSSF, 2,MMXWC), REGDEF(WCSSF, 2,MMXWC),
22046 REGDEF(wcasf, 3,MMXWC), REGDEF(wCASF, 3,MMXWC), REGDEF(WCASF, 3,MMXWC),
22047
22048 /* iWMMXt scalar (constant/offset) registers - p1, c8-11. */
22049 REGDEF(wcgr0, 8,MMXWCG), REGDEF(wCGR0, 8,MMXWCG), REGDEF(WCGR0, 8,MMXWCG),
22050 REGDEF(wcgr1, 9,MMXWCG), REGDEF(wCGR1, 9,MMXWCG), REGDEF(WCGR1, 9,MMXWCG),
22051 REGDEF(wcgr2,10,MMXWCG), REGDEF(wCGR2,10,MMXWCG), REGDEF(WCGR2,10,MMXWCG),
22052 REGDEF(wcgr3,11,MMXWCG), REGDEF(wCGR3,11,MMXWCG), REGDEF(WCGR3,11,MMXWCG),
22053
22054 /* XScale accumulator registers. */
22055 REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
22056};
22057#undef REGDEF
22058#undef REGNUM
22059#undef REGSET
7ed4c4c5 22060
c19d1205
ZW
22061/* Table of all PSR suffixes. Bare "CPSR" and "SPSR" are handled
22062 within psr_required_here. */
22063static const struct asm_psr psrs[] =
22064{
22065 /* Backward compatibility notation. Note that "all" is no longer
22066 truly all possible PSR bits. */
22067 {"all", PSR_c | PSR_f},
22068 {"flg", PSR_f},
22069 {"ctl", PSR_c},
22070
22071 /* Individual flags. */
22072 {"f", PSR_f},
22073 {"c", PSR_c},
22074 {"x", PSR_x},
22075 {"s", PSR_s},
59b42a0d 22076
c19d1205
ZW
22077 /* Combinations of flags. */
22078 {"fs", PSR_f | PSR_s},
22079 {"fx", PSR_f | PSR_x},
22080 {"fc", PSR_f | PSR_c},
22081 {"sf", PSR_s | PSR_f},
22082 {"sx", PSR_s | PSR_x},
22083 {"sc", PSR_s | PSR_c},
22084 {"xf", PSR_x | PSR_f},
22085 {"xs", PSR_x | PSR_s},
22086 {"xc", PSR_x | PSR_c},
22087 {"cf", PSR_c | PSR_f},
22088 {"cs", PSR_c | PSR_s},
22089 {"cx", PSR_c | PSR_x},
22090 {"fsx", PSR_f | PSR_s | PSR_x},
22091 {"fsc", PSR_f | PSR_s | PSR_c},
22092 {"fxs", PSR_f | PSR_x | PSR_s},
22093 {"fxc", PSR_f | PSR_x | PSR_c},
22094 {"fcs", PSR_f | PSR_c | PSR_s},
22095 {"fcx", PSR_f | PSR_c | PSR_x},
22096 {"sfx", PSR_s | PSR_f | PSR_x},
22097 {"sfc", PSR_s | PSR_f | PSR_c},
22098 {"sxf", PSR_s | PSR_x | PSR_f},
22099 {"sxc", PSR_s | PSR_x | PSR_c},
22100 {"scf", PSR_s | PSR_c | PSR_f},
22101 {"scx", PSR_s | PSR_c | PSR_x},
22102 {"xfs", PSR_x | PSR_f | PSR_s},
22103 {"xfc", PSR_x | PSR_f | PSR_c},
22104 {"xsf", PSR_x | PSR_s | PSR_f},
22105 {"xsc", PSR_x | PSR_s | PSR_c},
22106 {"xcf", PSR_x | PSR_c | PSR_f},
22107 {"xcs", PSR_x | PSR_c | PSR_s},
22108 {"cfs", PSR_c | PSR_f | PSR_s},
22109 {"cfx", PSR_c | PSR_f | PSR_x},
22110 {"csf", PSR_c | PSR_s | PSR_f},
22111 {"csx", PSR_c | PSR_s | PSR_x},
22112 {"cxf", PSR_c | PSR_x | PSR_f},
22113 {"cxs", PSR_c | PSR_x | PSR_s},
22114 {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
22115 {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
22116 {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
22117 {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
22118 {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
22119 {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
22120 {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
22121 {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
22122 {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
22123 {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
22124 {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
22125 {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
22126 {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
22127 {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
22128 {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
22129 {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
22130 {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
22131 {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
22132 {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
22133 {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
22134 {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
22135 {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
22136 {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
22137 {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
22138};
22139
62b3e311
PB
22140/* Table of V7M psr names. */
22141static const struct asm_psr v7m_psrs[] =
22142{
1a336194
TP
22143 {"apsr", 0x0 }, {"APSR", 0x0 },
22144 {"iapsr", 0x1 }, {"IAPSR", 0x1 },
22145 {"eapsr", 0x2 }, {"EAPSR", 0x2 },
22146 {"psr", 0x3 }, {"PSR", 0x3 },
22147 {"xpsr", 0x3 }, {"XPSR", 0x3 }, {"xPSR", 3 },
22148 {"ipsr", 0x5 }, {"IPSR", 0x5 },
22149 {"epsr", 0x6 }, {"EPSR", 0x6 },
22150 {"iepsr", 0x7 }, {"IEPSR", 0x7 },
22151 {"msp", 0x8 }, {"MSP", 0x8 },
22152 {"psp", 0x9 }, {"PSP", 0x9 },
22153 {"msplim", 0xa }, {"MSPLIM", 0xa },
22154 {"psplim", 0xb }, {"PSPLIM", 0xb },
22155 {"primask", 0x10}, {"PRIMASK", 0x10},
22156 {"basepri", 0x11}, {"BASEPRI", 0x11},
22157 {"basepri_max", 0x12}, {"BASEPRI_MAX", 0x12},
1a336194
TP
22158 {"faultmask", 0x13}, {"FAULTMASK", 0x13},
22159 {"control", 0x14}, {"CONTROL", 0x14},
22160 {"msp_ns", 0x88}, {"MSP_NS", 0x88},
22161 {"psp_ns", 0x89}, {"PSP_NS", 0x89},
22162 {"msplim_ns", 0x8a}, {"MSPLIM_NS", 0x8a},
22163 {"psplim_ns", 0x8b}, {"PSPLIM_NS", 0x8b},
22164 {"primask_ns", 0x90}, {"PRIMASK_NS", 0x90},
22165 {"basepri_ns", 0x91}, {"BASEPRI_NS", 0x91},
22166 {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
22167 {"control_ns", 0x94}, {"CONTROL_NS", 0x94},
22168 {"sp_ns", 0x98}, {"SP_NS", 0x98 }
62b3e311
PB
22169};
22170
c19d1205
ZW
22171/* Table of all shift-in-operand names. */
22172static const struct asm_shift_name shift_names [] =
b99bd4ef 22173{
c19d1205
ZW
22174 { "asl", SHIFT_LSL }, { "ASL", SHIFT_LSL },
22175 { "lsl", SHIFT_LSL }, { "LSL", SHIFT_LSL },
22176 { "lsr", SHIFT_LSR }, { "LSR", SHIFT_LSR },
22177 { "asr", SHIFT_ASR }, { "ASR", SHIFT_ASR },
22178 { "ror", SHIFT_ROR }, { "ROR", SHIFT_ROR },
f5f10c66
AV
22179 { "rrx", SHIFT_RRX }, { "RRX", SHIFT_RRX },
22180 { "uxtw", SHIFT_UXTW}, { "UXTW", SHIFT_UXTW}
c19d1205 22181};
b99bd4ef 22182
c19d1205
ZW
22183/* Table of all explicit relocation names. */
22184#ifdef OBJ_ELF
22185static struct reloc_entry reloc_names[] =
22186{
22187 { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
22188 { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
22189 { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
22190 { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
22191 { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
22192 { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
22193 { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
22194 { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
22195 { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
22196 { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
b43420e6 22197 { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32},
0855e32b
NS
22198 { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL},
22199 { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC},
477330fc 22200 { "TLSDESC", BFD_RELOC_ARM_TLS_GOTDESC},
0855e32b 22201 { "tlscall", BFD_RELOC_ARM_TLS_CALL},
477330fc 22202 { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
0855e32b 22203 { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
188fd7ae
CL
22204 { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ},
22205 { "gotfuncdesc", BFD_RELOC_ARM_GOTFUNCDESC },
22206 { "GOTFUNCDESC", BFD_RELOC_ARM_GOTFUNCDESC },
22207 { "gotofffuncdesc", BFD_RELOC_ARM_GOTOFFFUNCDESC },
22208 { "GOTOFFFUNCDESC", BFD_RELOC_ARM_GOTOFFFUNCDESC },
22209 { "funcdesc", BFD_RELOC_ARM_FUNCDESC },
5c5a4843
CL
22210 { "FUNCDESC", BFD_RELOC_ARM_FUNCDESC },
22211 { "tlsgd_fdpic", BFD_RELOC_ARM_TLS_GD32_FDPIC }, { "TLSGD_FDPIC", BFD_RELOC_ARM_TLS_GD32_FDPIC },
22212 { "tlsldm_fdpic", BFD_RELOC_ARM_TLS_LDM32_FDPIC }, { "TLSLDM_FDPIC", BFD_RELOC_ARM_TLS_LDM32_FDPIC },
22213 { "gottpoff_fdpic", BFD_RELOC_ARM_TLS_IE32_FDPIC }, { "GOTTPOFF_FDIC", BFD_RELOC_ARM_TLS_IE32_FDPIC },
c19d1205
ZW
22214};
22215#endif
b99bd4ef 22216
5ee91343 22217/* Table of all conditional affixes. */
c19d1205
ZW
22218static const struct asm_cond conds[] =
22219{
22220 {"eq", 0x0},
22221 {"ne", 0x1},
22222 {"cs", 0x2}, {"hs", 0x2},
22223 {"cc", 0x3}, {"ul", 0x3}, {"lo", 0x3},
22224 {"mi", 0x4},
22225 {"pl", 0x5},
22226 {"vs", 0x6},
22227 {"vc", 0x7},
22228 {"hi", 0x8},
22229 {"ls", 0x9},
22230 {"ge", 0xa},
22231 {"lt", 0xb},
22232 {"gt", 0xc},
22233 {"le", 0xd},
22234 {"al", 0xe}
22235};
5ee91343
AV
22236static const struct asm_cond vconds[] =
22237{
22238 {"t", 0xf},
22239 {"e", 0x10}
22240};
bfae80f2 22241
e797f7e0 22242#define UL_BARRIER(L,U,CODE,FEAT) \
823d2571
TG
22243 { L, CODE, ARM_FEATURE_CORE_LOW (FEAT) }, \
22244 { U, CODE, ARM_FEATURE_CORE_LOW (FEAT) }
e797f7e0 22245
62b3e311
PB
22246static struct asm_barrier_opt barrier_opt_names[] =
22247{
e797f7e0
MGD
22248 UL_BARRIER ("sy", "SY", 0xf, ARM_EXT_BARRIER),
22249 UL_BARRIER ("st", "ST", 0xe, ARM_EXT_BARRIER),
22250 UL_BARRIER ("ld", "LD", 0xd, ARM_EXT_V8),
22251 UL_BARRIER ("ish", "ISH", 0xb, ARM_EXT_BARRIER),
22252 UL_BARRIER ("sh", "SH", 0xb, ARM_EXT_BARRIER),
22253 UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER),
22254 UL_BARRIER ("shst", "SHST", 0xa, ARM_EXT_BARRIER),
22255 UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8),
22256 UL_BARRIER ("un", "UN", 0x7, ARM_EXT_BARRIER),
22257 UL_BARRIER ("nsh", "NSH", 0x7, ARM_EXT_BARRIER),
22258 UL_BARRIER ("unst", "UNST", 0x6, ARM_EXT_BARRIER),
22259 UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER),
22260 UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8),
22261 UL_BARRIER ("osh", "OSH", 0x3, ARM_EXT_BARRIER),
22262 UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER),
22263 UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8)
62b3e311
PB
22264};
22265
e797f7e0
MGD
22266#undef UL_BARRIER
22267
c19d1205
ZW
22268/* Table of ARM-format instructions. */
22269
22270/* Macros for gluing together operand strings. N.B. In all cases
22271 other than OPS0, the trailing OP_stop comes from default
22272 zero-initialization of the unspecified elements of the array. */
22273#define OPS0() { OP_stop, }
22274#define OPS1(a) { OP_##a, }
22275#define OPS2(a,b) { OP_##a,OP_##b, }
22276#define OPS3(a,b,c) { OP_##a,OP_##b,OP_##c, }
22277#define OPS4(a,b,c,d) { OP_##a,OP_##b,OP_##c,OP_##d, }
22278#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
22279#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
22280
5be8be5d
DG
22281/* These macros are similar to the OPSn, but do not prepend the OP_ prefix.
22282 This is useful when mixing operands for ARM and THUMB, i.e. using the
22283 MIX_ARM_THUMB_OPERANDS macro.
22284 In order to use these macros, prefix the number of operands with _
22285 e.g. _3. */
22286#define OPS_1(a) { a, }
22287#define OPS_2(a,b) { a,b, }
22288#define OPS_3(a,b,c) { a,b,c, }
22289#define OPS_4(a,b,c,d) { a,b,c,d, }
22290#define OPS_5(a,b,c,d,e) { a,b,c,d,e, }
22291#define OPS_6(a,b,c,d,e,f) { a,b,c,d,e,f, }
22292
c19d1205
ZW
22293/* These macros abstract out the exact format of the mnemonic table and
22294 save some repeated characters. */
22295
22296/* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix. */
22297#define TxCE(mnem, op, top, nops, ops, ae, te) \
21d799b5 22298 { mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
5ee91343 22299 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
22300
22301/* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
22302 a T_MNEM_xyz enumerator. */
22303#define TCE(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 22304 TxCE (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 22305#define tCE(mnem, aop, top, nops, ops, ae, te) \
21d799b5 22306 TxCE (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205
ZW
22307
22308/* Second most common sort of mnemonic: has a Thumb variant, takes a conditional
22309 infix after the third character. */
22310#define TxC3(mnem, op, top, nops, ops, ae, te) \
21d799b5 22311 { mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
5ee91343 22312 THUMB_VARIANT, do_##ae, do_##te, 0 }
088fa78e 22313#define TxC3w(mnem, op, top, nops, ops, ae, te) \
21d799b5 22314 { mnem, OPS##nops ops, OT_cinfix3_deprecated, 0x##op, top, ARM_VARIANT, \
5ee91343 22315 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 22316#define TC3(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 22317 TxC3 (mnem, aop, 0x##top, nops, ops, ae, te)
088fa78e 22318#define TC3w(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 22319 TxC3w (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 22320#define tC3(mnem, aop, top, nops, ops, ae, te) \
21d799b5 22321 TxC3 (mnem, aop, T_MNEM##top, nops, ops, ae, te)
088fa78e 22322#define tC3w(mnem, aop, top, nops, ops, ae, te) \
21d799b5 22323 TxC3w (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205 22324
c19d1205 22325/* Mnemonic that cannot be conditionalized. The ARM condition-code
dfa9f0d5
PB
22326 field is still 0xE. Many of the Thumb variants can be executed
22327 conditionally, so this is checked separately. */
c19d1205 22328#define TUE(mnem, op, top, nops, ops, ae, te) \
21d799b5 22329 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 22330 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205 22331
dd5181d5
KT
22332/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
22333 Used by mnemonics that have very minimal differences in the encoding for
22334 ARM and Thumb variants and can be handled in a common function. */
22335#define TUEc(mnem, op, top, nops, ops, en) \
22336 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 22337 THUMB_VARIANT, do_##en, do_##en, 0 }
dd5181d5 22338
c19d1205
ZW
22339/* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
22340 condition code field. */
22341#define TUF(mnem, op, top, nops, ops, ae, te) \
21d799b5 22342 { mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
5ee91343 22343 THUMB_VARIANT, do_##ae, do_##te, 0 }
c19d1205
ZW
22344
22345/* ARM-only variants of all the above. */
6a86118a 22346#define CE(mnem, op, nops, ops, ae) \
5ee91343 22347 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
22348
22349#define C3(mnem, op, nops, ops, ae) \
5ee91343 22350 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 22351
cf3cf39d
TP
22352/* Thumb-only variants of TCE and TUE. */
22353#define ToC(mnem, top, nops, ops, te) \
22354 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
5ee91343 22355 do_##te, 0 }
cf3cf39d
TP
22356
22357#define ToU(mnem, top, nops, ops, te) \
22358 { mnem, OPS##nops ops, OT_unconditional, 0x0, 0x##top, 0, THUMB_VARIANT, \
5ee91343 22359 NULL, do_##te, 0 }
cf3cf39d 22360
4389b29a
AV
22361/* T_MNEM_xyz enumerator variants of ToC. */
22362#define toC(mnem, top, nops, ops, te) \
22363 { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \
5ee91343 22364 do_##te, 0 }
4389b29a 22365
f6b2b12d
AV
22366/* T_MNEM_xyz enumerator variants of ToU. */
22367#define toU(mnem, top, nops, ops, te) \
22368 { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \
5ee91343 22369 NULL, do_##te, 0 }
f6b2b12d 22370
e3cb604e
PB
22371/* Legacy mnemonics that always have conditional infix after the third
22372 character. */
22373#define CL(mnem, op, nops, ops, ae) \
21d799b5 22374 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 22375 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
e3cb604e 22376
8f06b2d8
PB
22377/* Coprocessor instructions. Isomorphic between Arm and Thumb-2. */
22378#define cCE(mnem, op, nops, ops, ae) \
5ee91343 22379 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 22380
57785aa2
AV
22381/* mov instructions that are shared between coprocessor and MVE. */
22382#define mcCE(mnem, op, nops, ops, ae) \
22383 { #mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##ae, 0 }
22384
e3cb604e
PB
22385/* Legacy coprocessor instructions where conditional infix and conditional
22386 suffix are ambiguous. For consistency this includes all FPA instructions,
22387 not just the potentially ambiguous ones. */
22388#define cCL(mnem, op, nops, ops, ae) \
21d799b5 22389 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
5ee91343 22390 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
e3cb604e
PB
22391
22392/* Coprocessor, takes either a suffix or a position-3 infix
22393 (for an FPA corner case). */
22394#define C3E(mnem, op, nops, ops, ae) \
21d799b5 22395 { mnem, OPS##nops ops, OT_csuf_or_in3, \
5ee91343 22396 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae, 0 }
8f06b2d8 22397
6a86118a 22398#define xCM_(m1, m2, m3, op, nops, ops, ae) \
21d799b5
NC
22399 { m1 #m2 m3, OPS##nops ops, \
22400 sizeof (#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof (m1) - 1, \
5ee91343 22401 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
22402
22403#define CM(m1, m2, op, nops, ops, ae) \
e07e6e58
NC
22404 xCM_ (m1, , m2, op, nops, ops, ae), \
22405 xCM_ (m1, eq, m2, op, nops, ops, ae), \
22406 xCM_ (m1, ne, m2, op, nops, ops, ae), \
22407 xCM_ (m1, cs, m2, op, nops, ops, ae), \
22408 xCM_ (m1, hs, m2, op, nops, ops, ae), \
22409 xCM_ (m1, cc, m2, op, nops, ops, ae), \
22410 xCM_ (m1, ul, m2, op, nops, ops, ae), \
22411 xCM_ (m1, lo, m2, op, nops, ops, ae), \
22412 xCM_ (m1, mi, m2, op, nops, ops, ae), \
22413 xCM_ (m1, pl, m2, op, nops, ops, ae), \
22414 xCM_ (m1, vs, m2, op, nops, ops, ae), \
22415 xCM_ (m1, vc, m2, op, nops, ops, ae), \
22416 xCM_ (m1, hi, m2, op, nops, ops, ae), \
22417 xCM_ (m1, ls, m2, op, nops, ops, ae), \
22418 xCM_ (m1, ge, m2, op, nops, ops, ae), \
22419 xCM_ (m1, lt, m2, op, nops, ops, ae), \
22420 xCM_ (m1, gt, m2, op, nops, ops, ae), \
22421 xCM_ (m1, le, m2, op, nops, ops, ae), \
22422 xCM_ (m1, al, m2, op, nops, ops, ae)
6a86118a
NC
22423
22424#define UE(mnem, op, nops, ops, ae) \
5ee91343 22425 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a
NC
22426
22427#define UF(mnem, op, nops, ops, ae) \
5ee91343 22428 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL, 0 }
6a86118a 22429
5287ad62
JB
22430/* Neon data-processing. ARM versions are unconditional with cond=0xf.
22431 The Thumb and ARM variants are mostly the same (bits 0-23 and 24/28), so we
22432 use the same encoding function for each. */
22433#define NUF(mnem, op, nops, ops, enc) \
22434 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
5ee91343 22435 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
22436
22437/* Neon data processing, version which indirects through neon_enc_tab for
22438 the various overloaded versions of opcodes. */
22439#define nUF(mnem, op, nops, ops, enc) \
21d799b5 22440 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
5ee91343 22441 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 0 }
5287ad62
JB
22442
22443/* Neon insn with conditional suffix for the ARM version, non-overloaded
22444 version. */
5ee91343 22445#define NCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
037e8744 22446 { #mnem, OPS##nops ops, tag, 0x##op, 0x##op, ARM_VARIANT, \
5ee91343 22447 THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 22448
037e8744 22449#define NCE(mnem, op, nops, ops, enc) \
5ee91343 22450 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
22451
22452#define NCEF(mnem, op, nops, ops, enc) \
5ee91343 22453 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
037e8744 22454
5287ad62 22455/* Neon insn with conditional suffix for the ARM version, overloaded types. */
5ee91343 22456#define nCE_tag(mnem, op, nops, ops, enc, tag, mve_p) \
21d799b5 22457 { #mnem, OPS##nops ops, tag, N_MNEM##op, N_MNEM##op, \
5ee91343 22458 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, mve_p }
5287ad62 22459
037e8744 22460#define nCE(mnem, op, nops, ops, enc) \
5ee91343 22461 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 0)
037e8744
JB
22462
22463#define nCEF(mnem, op, nops, ops, enc) \
5ee91343
AV
22464 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 0)
22465
22466/* */
22467#define mCEF(mnem, op, nops, ops, enc) \
a302e574 22468 { #mnem, OPS##nops ops, OT_csuffixF, M_MNEM##op, M_MNEM##op, \
5ee91343
AV
22469 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
22470
22471
22472/* nCEF but for MVE predicated instructions. */
22473#define mnCEF(mnem, op, nops, ops, enc) \
22474 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
22475
22476/* nCE but for MVE predicated instructions. */
22477#define mnCE(mnem, op, nops, ops, enc) \
22478 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
037e8744 22479
5ee91343
AV
22480/* NUF but for potentially MVE predicated instructions. */
22481#define MNUF(mnem, op, nops, ops, enc) \
22482 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
22483 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
22484
22485/* nUF but for potentially MVE predicated instructions. */
22486#define mnUF(mnem, op, nops, ops, enc) \
22487 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
22488 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc, 1 }
22489
22490/* ToC but for potentially MVE predicated instructions. */
22491#define mToC(mnem, top, nops, ops, te) \
22492 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
22493 do_##te, 1 }
22494
22495/* NCE but for MVE predicated instructions. */
22496#define MNCE(mnem, op, nops, ops, enc) \
22497 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix, 1)
22498
22499/* NCEF but for MVE predicated instructions. */
22500#define MNCEF(mnem, op, nops, ops, enc) \
22501 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF, 1)
c19d1205
ZW
22502#define do_0 0
22503
c19d1205 22504static const struct asm_opcode insns[] =
bfae80f2 22505{
74db7efb
NC
22506#define ARM_VARIANT & arm_ext_v1 /* Core ARM Instructions. */
22507#define THUMB_VARIANT & arm_ext_v4t
21d799b5
NC
22508 tCE("and", 0000000, _and, 3, (RR, oRR, SH), arit, t_arit3c),
22509 tC3("ands", 0100000, _ands, 3, (RR, oRR, SH), arit, t_arit3c),
22510 tCE("eor", 0200000, _eor, 3, (RR, oRR, SH), arit, t_arit3c),
22511 tC3("eors", 0300000, _eors, 3, (RR, oRR, SH), arit, t_arit3c),
22512 tCE("sub", 0400000, _sub, 3, (RR, oRR, SH), arit, t_add_sub),
22513 tC3("subs", 0500000, _subs, 3, (RR, oRR, SH), arit, t_add_sub),
22514 tCE("add", 0800000, _add, 3, (RR, oRR, SHG), arit, t_add_sub),
22515 tC3("adds", 0900000, _adds, 3, (RR, oRR, SHG), arit, t_add_sub),
22516 tCE("adc", 0a00000, _adc, 3, (RR, oRR, SH), arit, t_arit3c),
22517 tC3("adcs", 0b00000, _adcs, 3, (RR, oRR, SH), arit, t_arit3c),
22518 tCE("sbc", 0c00000, _sbc, 3, (RR, oRR, SH), arit, t_arit3),
22519 tC3("sbcs", 0d00000, _sbcs, 3, (RR, oRR, SH), arit, t_arit3),
22520 tCE("orr", 1800000, _orr, 3, (RR, oRR, SH), arit, t_arit3c),
22521 tC3("orrs", 1900000, _orrs, 3, (RR, oRR, SH), arit, t_arit3c),
22522 tCE("bic", 1c00000, _bic, 3, (RR, oRR, SH), arit, t_arit3),
22523 tC3("bics", 1d00000, _bics, 3, (RR, oRR, SH), arit, t_arit3),
c19d1205
ZW
22524
22525 /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
22526 for setting PSR flag bits. They are obsolete in V6 and do not
22527 have Thumb equivalents. */
21d799b5
NC
22528 tCE("tst", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
22529 tC3w("tsts", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
22530 CL("tstp", 110f000, 2, (RR, SH), cmp),
22531 tCE("cmp", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
22532 tC3w("cmps", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
22533 CL("cmpp", 150f000, 2, (RR, SH), cmp),
22534 tCE("cmn", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
22535 tC3w("cmns", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
22536 CL("cmnp", 170f000, 2, (RR, SH), cmp),
22537
22538 tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
72d98d16 22539 tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
21d799b5
NC
22540 tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
22541 tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
22542
22543 tCE("ldr", 4100000, _ldr, 2, (RR, ADDRGLDR),ldst, t_ldst),
5be8be5d
DG
22544 tC3("ldrb", 4500000, _ldrb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
22545 tCE("str", 4000000, _str, _2, (MIX_ARM_THUMB_OPERANDS (OP_RR,
22546 OP_RRnpc),
22547 OP_ADDRGLDR),ldst, t_ldst),
22548 tC3("strb", 4400000, _strb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
21d799b5
NC
22549
22550 tCE("stm", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22551 tC3("stmia", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22552 tC3("stmea", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22553 tCE("ldm", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22554 tC3("ldmia", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22555 tC3("ldmfd", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22556
21d799b5
NC
22557 tCE("b", a000000, _b, 1, (EXPr), branch, t_branch),
22558 TCE("bl", b000000, f000f800, 1, (EXPr), bl, t_branch23),
bfae80f2 22559
c19d1205 22560 /* Pseudo ops. */
21d799b5 22561 tCE("adr", 28f0000, _adr, 2, (RR, EXP), adr, t_adr),
2fc8bdac 22562 C3(adrl, 28f0000, 2, (RR, EXP), adrl),
21d799b5 22563 tCE("nop", 1a00000, _nop, 1, (oI255c), nop, t_nop),
74db7efb 22564 tCE("udf", 7f000f0, _udf, 1, (oIffffb), bkpt, t_udf),
c19d1205
ZW
22565
22566 /* Thumb-compatibility pseudo ops. */
21d799b5
NC
22567 tCE("lsl", 1a00000, _lsl, 3, (RR, oRR, SH), shift, t_shift),
22568 tC3("lsls", 1b00000, _lsls, 3, (RR, oRR, SH), shift, t_shift),
22569 tCE("lsr", 1a00020, _lsr, 3, (RR, oRR, SH), shift, t_shift),
22570 tC3("lsrs", 1b00020, _lsrs, 3, (RR, oRR, SH), shift, t_shift),
22571 tCE("asr", 1a00040, _asr, 3, (RR, oRR, SH), shift, t_shift),
22572 tC3("asrs", 1b00040, _asrs, 3, (RR, oRR, SH), shift, t_shift),
22573 tCE("ror", 1a00060, _ror, 3, (RR, oRR, SH), shift, t_shift),
22574 tC3("rors", 1b00060, _rors, 3, (RR, oRR, SH), shift, t_shift),
22575 tCE("neg", 2600000, _neg, 2, (RR, RR), rd_rn, t_neg),
22576 tC3("negs", 2700000, _negs, 2, (RR, RR), rd_rn, t_neg),
22577 tCE("push", 92d0000, _push, 1, (REGLST), push_pop, t_push_pop),
22578 tCE("pop", 8bd0000, _pop, 1, (REGLST), push_pop, t_push_pop),
c19d1205 22579
16a4cf17 22580 /* These may simplify to neg. */
21d799b5
NC
22581 TCE("rsb", 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
22582 TC3("rsbs", 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
16a4cf17 22583
173205ca
TP
22584#undef THUMB_VARIANT
22585#define THUMB_VARIANT & arm_ext_os
22586
22587 TCE("swi", f000000, df00, 1, (EXPi), swi, t_swi),
22588 TCE("svc", f000000, df00, 1, (EXPi), swi, t_swi),
22589
c921be7d
NC
22590#undef THUMB_VARIANT
22591#define THUMB_VARIANT & arm_ext_v6
22592
21d799b5 22593 TCE("cpy", 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
c19d1205
ZW
22594
22595 /* V1 instructions with no Thumb analogue prior to V6T2. */
c921be7d
NC
22596#undef THUMB_VARIANT
22597#define THUMB_VARIANT & arm_ext_v6t2
22598
21d799b5
NC
22599 TCE("teq", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
22600 TC3w("teqs", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
22601 CL("teqp", 130f000, 2, (RR, SH), cmp),
c19d1205 22602
5be8be5d
DG
22603 TC3("ldrt", 4300000, f8500e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
22604 TC3("ldrbt", 4700000, f8100e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
22605 TC3("strt", 4200000, f8400e00, 2, (RR_npcsp, ADDR), ldstt, t_ldstt),
22606 TC3("strbt", 4600000, f8000e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
c19d1205 22607
21d799b5
NC
22608 TC3("stmdb", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22609 TC3("stmfd", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205 22610
21d799b5
NC
22611 TC3("ldmdb", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
22612 TC3("ldmea", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205
ZW
22613
22614 /* V1 instructions with no Thumb analogue at all. */
21d799b5 22615 CE("rsc", 0e00000, 3, (RR, oRR, SH), arit),
c19d1205
ZW
22616 C3(rscs, 0f00000, 3, (RR, oRR, SH), arit),
22617
22618 C3(stmib, 9800000, 2, (RRw, REGLST), ldmstm),
22619 C3(stmfa, 9800000, 2, (RRw, REGLST), ldmstm),
22620 C3(stmda, 8000000, 2, (RRw, REGLST), ldmstm),
22621 C3(stmed, 8000000, 2, (RRw, REGLST), ldmstm),
22622 C3(ldmib, 9900000, 2, (RRw, REGLST), ldmstm),
22623 C3(ldmed, 9900000, 2, (RRw, REGLST), ldmstm),
22624 C3(ldmda, 8100000, 2, (RRw, REGLST), ldmstm),
22625 C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm),
22626
c921be7d
NC
22627#undef ARM_VARIANT
22628#define ARM_VARIANT & arm_ext_v2 /* ARM 2 - multiplies. */
22629#undef THUMB_VARIANT
22630#define THUMB_VARIANT & arm_ext_v4t
22631
21d799b5
NC
22632 tCE("mul", 0000090, _mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
22633 tC3("muls", 0100090, _muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
c19d1205 22634
c921be7d
NC
22635#undef THUMB_VARIANT
22636#define THUMB_VARIANT & arm_ext_v6t2
22637
21d799b5 22638 TCE("mla", 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
c19d1205
ZW
22639 C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
22640
22641 /* Generic coprocessor instructions. */
21d799b5
NC
22642 TCE("cdp", e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
22643 TCE("ldc", c100000, ec100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22644 TC3("ldcl", c500000, ec500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22645 TCE("stc", c000000, ec000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22646 TC3("stcl", c400000, ec400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22647 TCE("mcr", e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
db472d6f 22648 TCE("mrc", e100010, ee100010, 6, (RCP, I7b, APSR_RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 22649
c921be7d
NC
22650#undef ARM_VARIANT
22651#define ARM_VARIANT & arm_ext_v2s /* ARM 3 - swp instructions. */
22652
21d799b5 22653 CE("swp", 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
c19d1205
ZW
22654 C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
22655
c921be7d
NC
22656#undef ARM_VARIANT
22657#define ARM_VARIANT & arm_ext_v3 /* ARM 6 Status register instructions. */
22658#undef THUMB_VARIANT
22659#define THUMB_VARIANT & arm_ext_msr
22660
d2cd1205
JB
22661 TCE("mrs", 1000000, f3e08000, 2, (RRnpc, rPSR), mrs, t_mrs),
22662 TCE("msr", 120f000, f3808000, 2, (wPSR, RR_EXi), msr, t_msr),
c19d1205 22663
c921be7d
NC
22664#undef ARM_VARIANT
22665#define ARM_VARIANT & arm_ext_v3m /* ARM 7M long multiplies. */
22666#undef THUMB_VARIANT
22667#define THUMB_VARIANT & arm_ext_v6t2
22668
21d799b5
NC
22669 TCE("smull", 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
22670 CM("smull","s", 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
22671 TCE("umull", 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
22672 CM("umull","s", 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
22673 TCE("smlal", 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
22674 CM("smlal","s", 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
22675 TCE("umlal", 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
22676 CM("umlal","s", 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
c19d1205 22677
c921be7d
NC
22678#undef ARM_VARIANT
22679#define ARM_VARIANT & arm_ext_v4 /* ARM Architecture 4. */
22680#undef THUMB_VARIANT
22681#define THUMB_VARIANT & arm_ext_v4t
22682
5be8be5d
DG
22683 tC3("ldrh", 01000b0, _ldrh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
22684 tC3("strh", 00000b0, _strh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
22685 tC3("ldrsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
22686 tC3("ldrsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
56c0a61f
RE
22687 tC3("ldsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
22688 tC3("ldsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
c19d1205 22689
c921be7d
NC
22690#undef ARM_VARIANT
22691#define ARM_VARIANT & arm_ext_v4t_5
22692
c19d1205
ZW
22693 /* ARM Architecture 4T. */
22694 /* Note: bx (and blx) are required on V5, even if the processor does
22695 not support Thumb. */
21d799b5 22696 TCE("bx", 12fff10, 4700, 1, (RR), bx, t_bx),
c19d1205 22697
c921be7d
NC
22698#undef ARM_VARIANT
22699#define ARM_VARIANT & arm_ext_v5 /* ARM Architecture 5T. */
22700#undef THUMB_VARIANT
22701#define THUMB_VARIANT & arm_ext_v5t
22702
c19d1205
ZW
22703 /* Note: blx has 2 variants; the .value coded here is for
22704 BLX(2). Only this variant has conditional execution. */
21d799b5
NC
22705 TCE("blx", 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
22706 TUE("bkpt", 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
c19d1205 22707
c921be7d
NC
22708#undef THUMB_VARIANT
22709#define THUMB_VARIANT & arm_ext_v6t2
22710
21d799b5
NC
22711 TCE("clz", 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
22712 TUF("ldc2", c100000, fc100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22713 TUF("ldc2l", c500000, fc500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22714 TUF("stc2", c000000, fc000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22715 TUF("stc2l", c400000, fc400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
22716 TUF("cdp2", e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
22717 TUF("mcr2", e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
22718 TUF("mrc2", e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 22719
c921be7d 22720#undef ARM_VARIANT
74db7efb
NC
22721#define ARM_VARIANT & arm_ext_v5exp /* ARM Architecture 5TExP. */
22722#undef THUMB_VARIANT
22723#define THUMB_VARIANT & arm_ext_v5exp
c921be7d 22724
21d799b5
NC
22725 TCE("smlabb", 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
22726 TCE("smlatb", 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
22727 TCE("smlabt", 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
22728 TCE("smlatt", 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 22729
21d799b5
NC
22730 TCE("smlawb", 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
22731 TCE("smlawt", 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 22732
21d799b5
NC
22733 TCE("smlalbb", 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
22734 TCE("smlaltb", 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
22735 TCE("smlalbt", 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
22736 TCE("smlaltt", 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
c19d1205 22737
21d799b5
NC
22738 TCE("smulbb", 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22739 TCE("smultb", 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22740 TCE("smulbt", 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22741 TCE("smultt", 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 22742
21d799b5
NC
22743 TCE("smulwb", 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22744 TCE("smulwt", 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 22745
03ee1b7f
NC
22746 TCE("qadd", 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
22747 TCE("qdadd", 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
22748 TCE("qsub", 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
22749 TCE("qdsub", 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
c19d1205 22750
c921be7d 22751#undef ARM_VARIANT
74db7efb
NC
22752#define ARM_VARIANT & arm_ext_v5e /* ARM Architecture 5TE. */
22753#undef THUMB_VARIANT
22754#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 22755
21d799b5 22756 TUF("pld", 450f000, f810f000, 1, (ADDR), pld, t_pld),
5be8be5d
DG
22757 TC3("ldrd", 00000d0, e8500000, 3, (RRnpc_npcsp, oRRnpc_npcsp, ADDRGLDRS),
22758 ldrd, t_ldstd),
22759 TC3("strd", 00000f0, e8400000, 3, (RRnpc_npcsp, oRRnpc_npcsp,
22760 ADDRGLDRS), ldrd, t_ldstd),
c19d1205 22761
21d799b5
NC
22762 TCE("mcrr", c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
22763 TCE("mrrc", c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
c19d1205 22764
c921be7d
NC
22765#undef ARM_VARIANT
22766#define ARM_VARIANT & arm_ext_v5j /* ARM Architecture 5TEJ. */
22767
21d799b5 22768 TCE("bxj", 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
c19d1205 22769
c921be7d
NC
22770#undef ARM_VARIANT
22771#define ARM_VARIANT & arm_ext_v6 /* ARM V6. */
22772#undef THUMB_VARIANT
22773#define THUMB_VARIANT & arm_ext_v6
22774
21d799b5
NC
22775 TUF("cpsie", 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
22776 TUF("cpsid", 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
22777 tCE("rev", 6bf0f30, _rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
22778 tCE("rev16", 6bf0fb0, _rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
22779 tCE("revsh", 6ff0fb0, _revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
22780 tCE("sxth", 6bf0070, _sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
22781 tCE("uxth", 6ff0070, _uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
22782 tCE("sxtb", 6af0070, _sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
22783 tCE("uxtb", 6ef0070, _uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
22784 TUF("setend", 1010000, b650, 1, (ENDI), setend, t_setend),
c19d1205 22785
c921be7d 22786#undef THUMB_VARIANT
ff8646ee 22787#define THUMB_VARIANT & arm_ext_v6t2_v8m
c921be7d 22788
5be8be5d
DG
22789 TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
22790 TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
22791 strex, t_strex),
ff8646ee
TP
22792#undef THUMB_VARIANT
22793#define THUMB_VARIANT & arm_ext_v6t2
22794
21d799b5
NC
22795 TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
22796 TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
62b3e311 22797
21d799b5
NC
22798 TCE("ssat", 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
22799 TCE("usat", 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
62b3e311 22800
9e3c6df6 22801/* ARM V6 not included in V7M. */
c921be7d
NC
22802#undef THUMB_VARIANT
22803#define THUMB_VARIANT & arm_ext_v6_notm
9e3c6df6 22804 TUF("rfeia", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6 22805 TUF("rfe", 8900a00, e990c000, 1, (RRw), rfe, rfe),
9e3c6df6
PB
22806 UF(rfeib, 9900a00, 1, (RRw), rfe),
22807 UF(rfeda, 8100a00, 1, (RRw), rfe),
22808 TUF("rfedb", 9100a00, e810c000, 1, (RRw), rfe, rfe),
22809 TUF("rfefd", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6
RE
22810 UF(rfefa, 8100a00, 1, (RRw), rfe),
22811 TUF("rfeea", 9100a00, e810c000, 1, (RRw), rfe, rfe),
22812 UF(rfeed, 9900a00, 1, (RRw), rfe),
9e3c6df6 22813 TUF("srsia", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
d709e4e6
RE
22814 TUF("srs", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
22815 TUF("srsea", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
9e3c6df6 22816 UF(srsib, 9c00500, 2, (oRRw, I31w), srs),
d709e4e6 22817 UF(srsfa, 9c00500, 2, (oRRw, I31w), srs),
9e3c6df6 22818 UF(srsda, 8400500, 2, (oRRw, I31w), srs),
d709e4e6 22819 UF(srsed, 8400500, 2, (oRRw, I31w), srs),
9e3c6df6 22820 TUF("srsdb", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
d709e4e6 22821 TUF("srsfd", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
941c9cad 22822 TUF("cps", 1020000, f3af8100, 1, (I31b), imm0, t_cps),
c921be7d 22823
9e3c6df6
PB
22824/* ARM V6 not included in V7M (eg. integer SIMD). */
22825#undef THUMB_VARIANT
22826#define THUMB_VARIANT & arm_ext_v6_dsp
21d799b5
NC
22827 TCE("pkhbt", 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
22828 TCE("pkhtb", 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
22829 TCE("qadd16", 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22830 TCE("qadd8", 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22831 TCE("qasx", 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22832 /* Old name for QASX. */
74db7efb 22833 TCE("qaddsubx",6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 22834 TCE("qsax", 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22835 /* Old name for QSAX. */
74db7efb 22836 TCE("qsubaddx",6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
22837 TCE("qsub16", 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22838 TCE("qsub8", 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22839 TCE("sadd16", 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22840 TCE("sadd8", 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22841 TCE("sasx", 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22842 /* Old name for SASX. */
74db7efb 22843 TCE("saddsubx",6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
22844 TCE("shadd16", 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22845 TCE("shadd8", 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 22846 TCE("shasx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22847 /* Old name for SHASX. */
21d799b5 22848 TCE("shaddsubx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 22849 TCE("shsax", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22850 /* Old name for SHSAX. */
21d799b5
NC
22851 TCE("shsubaddx", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22852 TCE("shsub16", 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22853 TCE("shsub8", 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22854 TCE("ssax", 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22855 /* Old name for SSAX. */
74db7efb 22856 TCE("ssubaddx",6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
22857 TCE("ssub16", 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22858 TCE("ssub8", 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22859 TCE("uadd16", 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22860 TCE("uadd8", 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22861 TCE("uasx", 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22862 /* Old name for UASX. */
74db7efb 22863 TCE("uaddsubx",6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
22864 TCE("uhadd16", 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22865 TCE("uhadd8", 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 22866 TCE("uhasx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22867 /* Old name for UHASX. */
21d799b5
NC
22868 TCE("uhaddsubx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22869 TCE("uhsax", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22870 /* Old name for UHSAX. */
21d799b5
NC
22871 TCE("uhsubaddx", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22872 TCE("uhsub16", 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22873 TCE("uhsub8", 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22874 TCE("uqadd16", 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22875 TCE("uqadd8", 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 22876 TCE("uqasx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22877 /* Old name for UQASX. */
21d799b5
NC
22878 TCE("uqaddsubx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22879 TCE("uqsax", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22880 /* Old name for UQSAX. */
21d799b5
NC
22881 TCE("uqsubaddx", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22882 TCE("uqsub16", 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22883 TCE("uqsub8", 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22884 TCE("usub16", 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22885 TCE("usax", 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 22886 /* Old name for USAX. */
74db7efb 22887 TCE("usubaddx",6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 22888 TCE("usub8", 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
22889 TCE("sxtah", 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
22890 TCE("sxtab16", 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
22891 TCE("sxtab", 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
22892 TCE("sxtb16", 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
22893 TCE("uxtah", 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
22894 TCE("uxtab16", 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
22895 TCE("uxtab", 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
22896 TCE("uxtb16", 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
22897 TCE("sel", 6800fb0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
22898 TCE("smlad", 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
22899 TCE("smladx", 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
22900 TCE("smlald", 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
22901 TCE("smlaldx", 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
22902 TCE("smlsd", 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
22903 TCE("smlsdx", 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
22904 TCE("smlsld", 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
22905 TCE("smlsldx", 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
22906 TCE("smmla", 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
22907 TCE("smmlar", 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
22908 TCE("smmls", 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
22909 TCE("smmlsr", 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
22910 TCE("smmul", 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22911 TCE("smmulr", 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22912 TCE("smuad", 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22913 TCE("smuadx", 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22914 TCE("smusd", 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22915 TCE("smusdx", 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
21d799b5
NC
22916 TCE("ssat16", 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
22917 TCE("umaal", 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
22918 TCE("usad8", 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
22919 TCE("usada8", 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
22920 TCE("usat16", 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
c19d1205 22921
c921be7d 22922#undef ARM_VARIANT
55e8aae7 22923#define ARM_VARIANT & arm_ext_v6k_v6t2
c921be7d 22924#undef THUMB_VARIANT
55e8aae7 22925#define THUMB_VARIANT & arm_ext_v6k_v6t2
c921be7d 22926
21d799b5
NC
22927 tCE("yield", 320f001, _yield, 0, (), noargs, t_hint),
22928 tCE("wfe", 320f002, _wfe, 0, (), noargs, t_hint),
22929 tCE("wfi", 320f003, _wfi, 0, (), noargs, t_hint),
22930 tCE("sev", 320f004, _sev, 0, (), noargs, t_hint),
c19d1205 22931
c921be7d
NC
22932#undef THUMB_VARIANT
22933#define THUMB_VARIANT & arm_ext_v6_notm
5be8be5d
DG
22934 TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc_npcsp, oRRnpc_npcsp, RRnpcb),
22935 ldrexd, t_ldrexd),
22936 TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc_npcsp, RRnpc_npcsp, oRRnpc_npcsp,
22937 RRnpcb), strexd, t_strexd),
ebdca51a 22938
c921be7d 22939#undef THUMB_VARIANT
ff8646ee 22940#define THUMB_VARIANT & arm_ext_v6t2_v8m
5be8be5d
DG
22941 TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
22942 rd_rn, rd_rn),
22943 TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
22944 rd_rn, rd_rn),
22945 TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 22946 strex, t_strexbh),
5be8be5d 22947 TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 22948 strex, t_strexbh),
21d799b5 22949 TUF("clrex", 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
c19d1205 22950
c921be7d 22951#undef ARM_VARIANT
f4c65163 22952#define ARM_VARIANT & arm_ext_sec
74db7efb 22953#undef THUMB_VARIANT
f4c65163 22954#define THUMB_VARIANT & arm_ext_sec
c921be7d 22955
21d799b5 22956 TCE("smc", 1600070, f7f08000, 1, (EXPi), smc, t_smc),
c19d1205 22957
90ec0d68
MGD
22958#undef ARM_VARIANT
22959#define ARM_VARIANT & arm_ext_virt
22960#undef THUMB_VARIANT
22961#define THUMB_VARIANT & arm_ext_virt
22962
22963 TCE("hvc", 1400070, f7e08000, 1, (EXPi), hvc, t_hvc),
22964 TCE("eret", 160006e, f3de8f00, 0, (), noargs, noargs),
22965
ddfded2f
MW
22966#undef ARM_VARIANT
22967#define ARM_VARIANT & arm_ext_pan
22968#undef THUMB_VARIANT
22969#define THUMB_VARIANT & arm_ext_pan
22970
22971 TUF("setpan", 1100000, b610, 1, (I7), setpan, t_setpan),
22972
c921be7d 22973#undef ARM_VARIANT
74db7efb 22974#define ARM_VARIANT & arm_ext_v6t2
f4c65163
MGD
22975#undef THUMB_VARIANT
22976#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 22977
21d799b5
NC
22978 TCE("bfc", 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
22979 TCE("bfi", 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
22980 TCE("sbfx", 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
22981 TCE("ubfx", 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
c19d1205 22982
21d799b5 22983 TCE("mls", 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
21d799b5 22984 TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
c19d1205 22985
5be8be5d
DG
22986 TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
22987 TC3("ldrsht", 03000f0, f9300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
22988 TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
22989 TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
c19d1205 22990
91d8b670
JG
22991#undef ARM_VARIANT
22992#define ARM_VARIANT & arm_ext_v3
22993#undef THUMB_VARIANT
22994#define THUMB_VARIANT & arm_ext_v6t2
22995
22996 TUE("csdb", 320f014, f3af8014, 0, (), noargs, t_csdb),
c597cc3d
SD
22997 TUF("ssbb", 57ff040, f3bf8f40, 0, (), noargs, t_csdb),
22998 TUF("pssbb", 57ff044, f3bf8f44, 0, (), noargs, t_csdb),
91d8b670
JG
22999
23000#undef ARM_VARIANT
23001#define ARM_VARIANT & arm_ext_v6t2
ff8646ee
TP
23002#undef THUMB_VARIANT
23003#define THUMB_VARIANT & arm_ext_v6t2_v8m
23004 TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
23005 TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
23006
bf3eeda7 23007 /* Thumb-only instructions. */
74db7efb 23008#undef ARM_VARIANT
bf3eeda7
NS
23009#define ARM_VARIANT NULL
23010 TUE("cbnz", 0, b900, 2, (RR, EXP), 0, t_cbz),
23011 TUE("cbz", 0, b100, 2, (RR, EXP), 0, t_cbz),
c921be7d
NC
23012
23013 /* ARM does not really have an IT instruction, so always allow it.
23014 The opcode is copied from Thumb in order to allow warnings in
23015 -mimplicit-it=[never | arm] modes. */
23016#undef ARM_VARIANT
23017#define ARM_VARIANT & arm_ext_v1
ff8646ee
TP
23018#undef THUMB_VARIANT
23019#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 23020
21d799b5
NC
23021 TUE("it", bf08, bf08, 1, (COND), it, t_it),
23022 TUE("itt", bf0c, bf0c, 1, (COND), it, t_it),
23023 TUE("ite", bf04, bf04, 1, (COND), it, t_it),
23024 TUE("ittt", bf0e, bf0e, 1, (COND), it, t_it),
23025 TUE("itet", bf06, bf06, 1, (COND), it, t_it),
23026 TUE("itte", bf0a, bf0a, 1, (COND), it, t_it),
23027 TUE("itee", bf02, bf02, 1, (COND), it, t_it),
23028 TUE("itttt", bf0f, bf0f, 1, (COND), it, t_it),
23029 TUE("itett", bf07, bf07, 1, (COND), it, t_it),
23030 TUE("ittet", bf0b, bf0b, 1, (COND), it, t_it),
23031 TUE("iteet", bf03, bf03, 1, (COND), it, t_it),
23032 TUE("ittte", bf0d, bf0d, 1, (COND), it, t_it),
23033 TUE("itete", bf05, bf05, 1, (COND), it, t_it),
23034 TUE("ittee", bf09, bf09, 1, (COND), it, t_it),
23035 TUE("iteee", bf01, bf01, 1, (COND), it, t_it),
1c444d06 23036 /* ARM/Thumb-2 instructions with no Thumb-1 equivalent. */
21d799b5
NC
23037 TC3("rrx", 01a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rrx),
23038 TC3("rrxs", 01b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rrx),
c19d1205 23039
92e90b6e 23040 /* Thumb2 only instructions. */
c921be7d
NC
23041#undef ARM_VARIANT
23042#define ARM_VARIANT NULL
92e90b6e 23043
21d799b5
NC
23044 TCE("addw", 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
23045 TCE("subw", 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
23046 TCE("orn", 0, ea600000, 3, (RR, oRR, SH), 0, t_orn),
23047 TCE("orns", 0, ea700000, 3, (RR, oRR, SH), 0, t_orn),
23048 TCE("tbb", 0, e8d0f000, 1, (TB), 0, t_tb),
23049 TCE("tbh", 0, e8d0f010, 1, (TB), 0, t_tb),
92e90b6e 23050
eea54501
MGD
23051 /* Hardware division instructions. */
23052#undef ARM_VARIANT
23053#define ARM_VARIANT & arm_ext_adiv
c921be7d
NC
23054#undef THUMB_VARIANT
23055#define THUMB_VARIANT & arm_ext_div
23056
eea54501
MGD
23057 TCE("sdiv", 710f010, fb90f0f0, 3, (RR, oRR, RR), div, t_div),
23058 TCE("udiv", 730f010, fbb0f0f0, 3, (RR, oRR, RR), div, t_div),
62b3e311 23059
7e806470 23060 /* ARM V6M/V7 instructions. */
c921be7d
NC
23061#undef ARM_VARIANT
23062#define ARM_VARIANT & arm_ext_barrier
23063#undef THUMB_VARIANT
23064#define THUMB_VARIANT & arm_ext_barrier
23065
ccb84d65
JB
23066 TUF("dmb", 57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier, barrier),
23067 TUF("dsb", 57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier, barrier),
23068 TUF("isb", 57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier, barrier),
7e806470 23069
62b3e311 23070 /* ARM V7 instructions. */
c921be7d
NC
23071#undef ARM_VARIANT
23072#define ARM_VARIANT & arm_ext_v7
23073#undef THUMB_VARIANT
23074#define THUMB_VARIANT & arm_ext_v7
23075
21d799b5
NC
23076 TUF("pli", 450f000, f910f000, 1, (ADDR), pli, t_pld),
23077 TCE("dbg", 320f0f0, f3af80f0, 1, (I15), dbg, t_dbg),
62b3e311 23078
74db7efb 23079#undef ARM_VARIANT
60e5ef9f 23080#define ARM_VARIANT & arm_ext_mp
74db7efb 23081#undef THUMB_VARIANT
60e5ef9f
MGD
23082#define THUMB_VARIANT & arm_ext_mp
23083
23084 TUF("pldw", 410f000, f830f000, 1, (ADDR), pld, t_pld),
23085
53c4b28b
MGD
23086 /* AArchv8 instructions. */
23087#undef ARM_VARIANT
23088#define ARM_VARIANT & arm_ext_v8
4ed7ed8d
TP
23089
23090/* Instructions shared between armv8-a and armv8-m. */
53c4b28b 23091#undef THUMB_VARIANT
4ed7ed8d 23092#define THUMB_VARIANT & arm_ext_atomics
53c4b28b 23093
4ed7ed8d
TP
23094 TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23095 TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23096 TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23097 TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
23098 TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
23099 TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
4b8c8c02 23100 TCE("ldaex", 1900e9f, e8d00fef, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
4b8c8c02
RE
23101 TCE("ldaexb", 1d00e9f, e8d00fcf, 2, (RRnpc,RRnpcb), rd_rn, rd_rn),
23102 TCE("ldaexh", 1f00e9f, e8d00fdf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
23103 TCE("stlex", 1800e90, e8c00fe0, 3, (RRnpc, RRnpc, RRnpcb),
23104 stlex, t_stlex),
4b8c8c02
RE
23105 TCE("stlexb", 1c00e90, e8c00fc0, 3, (RRnpc, RRnpc, RRnpcb),
23106 stlex, t_stlex),
23107 TCE("stlexh", 1e00e90, e8c00fd0, 3, (RRnpc, RRnpc, RRnpcb),
23108 stlex, t_stlex),
4ed7ed8d
TP
23109#undef THUMB_VARIANT
23110#define THUMB_VARIANT & arm_ext_v8
53c4b28b 23111
4ed7ed8d 23112 tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
4ed7ed8d
TP
23113 TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
23114 ldrexd, t_ldrexd),
23115 TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
23116 strexd, t_strexd),
f7dd2fb2
TC
23117
23118/* Defined in V8 but is in undefined encoding space for earlier
23119 architectures. However earlier architectures are required to treat
23120 this instuction as a semihosting trap as well. Hence while not explicitly
23121 defined as such, it is in fact correct to define the instruction for all
23122 architectures. */
23123#undef THUMB_VARIANT
23124#define THUMB_VARIANT & arm_ext_v1
23125#undef ARM_VARIANT
23126#define ARM_VARIANT & arm_ext_v1
23127 TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
23128
8884b720 23129 /* ARMv8 T32 only. */
74db7efb 23130#undef ARM_VARIANT
b79f7053
MGD
23131#define ARM_VARIANT NULL
23132 TUF("dcps1", 0, f78f8001, 0, (), noargs, noargs),
23133 TUF("dcps2", 0, f78f8002, 0, (), noargs, noargs),
23134 TUF("dcps3", 0, f78f8003, 0, (), noargs, noargs),
23135
33399f07
MGD
23136 /* FP for ARMv8. */
23137#undef ARM_VARIANT
a715796b 23138#define ARM_VARIANT & fpu_vfp_ext_armv8xd
33399f07 23139#undef THUMB_VARIANT
a715796b 23140#define THUMB_VARIANT & fpu_vfp_ext_armv8xd
33399f07
MGD
23141
23142 nUF(vseleq, _vseleq, 3, (RVSD, RVSD, RVSD), vsel),
23143 nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD), vsel),
23144 nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD), vsel),
23145 nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD), vsel),
30bdf752
MGD
23146 nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ), vrintr),
23147 nCE(vrintz, _vrintr, 2, (RNSDQ, oRNSDQ), vrintz),
23148 nCE(vrintx, _vrintr, 2, (RNSDQ, oRNSDQ), vrintx),
23149 nUF(vrinta, _vrinta, 2, (RNSDQ, oRNSDQ), vrinta),
23150 nUF(vrintn, _vrinta, 2, (RNSDQ, oRNSDQ), vrintn),
23151 nUF(vrintp, _vrinta, 2, (RNSDQ, oRNSDQ), vrintp),
23152 nUF(vrintm, _vrinta, 2, (RNSDQ, oRNSDQ), vrintm),
33399f07 23153
91ff7894
MGD
23154 /* Crypto v1 extensions. */
23155#undef ARM_VARIANT
23156#define ARM_VARIANT & fpu_crypto_ext_armv8
23157#undef THUMB_VARIANT
23158#define THUMB_VARIANT & fpu_crypto_ext_armv8
23159
23160 nUF(aese, _aes, 2, (RNQ, RNQ), aese),
23161 nUF(aesd, _aes, 2, (RNQ, RNQ), aesd),
23162 nUF(aesmc, _aes, 2, (RNQ, RNQ), aesmc),
23163 nUF(aesimc, _aes, 2, (RNQ, RNQ), aesimc),
48adcd8e
MGD
23164 nUF(sha1c, _sha3op, 3, (RNQ, RNQ, RNQ), sha1c),
23165 nUF(sha1p, _sha3op, 3, (RNQ, RNQ, RNQ), sha1p),
23166 nUF(sha1m, _sha3op, 3, (RNQ, RNQ, RNQ), sha1m),
23167 nUF(sha1su0, _sha3op, 3, (RNQ, RNQ, RNQ), sha1su0),
23168 nUF(sha256h, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h),
23169 nUF(sha256h2, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h2),
23170 nUF(sha256su1, _sha3op, 3, (RNQ, RNQ, RNQ), sha256su1),
3c9017d2
MGD
23171 nUF(sha1h, _sha1h, 2, (RNQ, RNQ), sha1h),
23172 nUF(sha1su1, _sha2op, 2, (RNQ, RNQ), sha1su1),
23173 nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
91ff7894 23174
dd5181d5 23175#undef ARM_VARIANT
74db7efb 23176#define ARM_VARIANT & crc_ext_armv8
dd5181d5
KT
23177#undef THUMB_VARIANT
23178#define THUMB_VARIANT & crc_ext_armv8
23179 TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
23180 TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
23181 TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
23182 TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
23183 TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
23184 TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
23185
105bde57
MW
23186 /* ARMv8.2 RAS extension. */
23187#undef ARM_VARIANT
4d1464f2 23188#define ARM_VARIANT & arm_ext_ras
105bde57 23189#undef THUMB_VARIANT
4d1464f2 23190#define THUMB_VARIANT & arm_ext_ras
105bde57
MW
23191 TUE ("esb", 320f010, f3af8010, 0, (), noargs, noargs),
23192
49e8a725
SN
23193#undef ARM_VARIANT
23194#define ARM_VARIANT & arm_ext_v8_3
23195#undef THUMB_VARIANT
23196#define THUMB_VARIANT & arm_ext_v8_3
23197 NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
23198
c604a79a
JW
23199#undef ARM_VARIANT
23200#define ARM_VARIANT & fpu_neon_ext_dotprod
23201#undef THUMB_VARIANT
23202#define THUMB_VARIANT & fpu_neon_ext_dotprod
23203 NUF (vsdot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_s),
23204 NUF (vudot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_u),
23205
c921be7d
NC
23206#undef ARM_VARIANT
23207#define ARM_VARIANT & fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
53c4b28b
MGD
23208#undef THUMB_VARIANT
23209#define THUMB_VARIANT NULL
c921be7d 23210
21d799b5
NC
23211 cCE("wfs", e200110, 1, (RR), rd),
23212 cCE("rfs", e300110, 1, (RR), rd),
23213 cCE("wfc", e400110, 1, (RR), rd),
23214 cCE("rfc", e500110, 1, (RR), rd),
23215
23216 cCL("ldfs", c100100, 2, (RF, ADDRGLDC), rd_cpaddr),
23217 cCL("ldfd", c108100, 2, (RF, ADDRGLDC), rd_cpaddr),
23218 cCL("ldfe", c500100, 2, (RF, ADDRGLDC), rd_cpaddr),
23219 cCL("ldfp", c508100, 2, (RF, ADDRGLDC), rd_cpaddr),
23220
23221 cCL("stfs", c000100, 2, (RF, ADDRGLDC), rd_cpaddr),
23222 cCL("stfd", c008100, 2, (RF, ADDRGLDC), rd_cpaddr),
23223 cCL("stfe", c400100, 2, (RF, ADDRGLDC), rd_cpaddr),
23224 cCL("stfp", c408100, 2, (RF, ADDRGLDC), rd_cpaddr),
23225
23226 cCL("mvfs", e008100, 2, (RF, RF_IF), rd_rm),
23227 cCL("mvfsp", e008120, 2, (RF, RF_IF), rd_rm),
23228 cCL("mvfsm", e008140, 2, (RF, RF_IF), rd_rm),
23229 cCL("mvfsz", e008160, 2, (RF, RF_IF), rd_rm),
23230 cCL("mvfd", e008180, 2, (RF, RF_IF), rd_rm),
23231 cCL("mvfdp", e0081a0, 2, (RF, RF_IF), rd_rm),
23232 cCL("mvfdm", e0081c0, 2, (RF, RF_IF), rd_rm),
23233 cCL("mvfdz", e0081e0, 2, (RF, RF_IF), rd_rm),
23234 cCL("mvfe", e088100, 2, (RF, RF_IF), rd_rm),
23235 cCL("mvfep", e088120, 2, (RF, RF_IF), rd_rm),
23236 cCL("mvfem", e088140, 2, (RF, RF_IF), rd_rm),
23237 cCL("mvfez", e088160, 2, (RF, RF_IF), rd_rm),
23238
23239 cCL("mnfs", e108100, 2, (RF, RF_IF), rd_rm),
23240 cCL("mnfsp", e108120, 2, (RF, RF_IF), rd_rm),
23241 cCL("mnfsm", e108140, 2, (RF, RF_IF), rd_rm),
23242 cCL("mnfsz", e108160, 2, (RF, RF_IF), rd_rm),
23243 cCL("mnfd", e108180, 2, (RF, RF_IF), rd_rm),
23244 cCL("mnfdp", e1081a0, 2, (RF, RF_IF), rd_rm),
23245 cCL("mnfdm", e1081c0, 2, (RF, RF_IF), rd_rm),
23246 cCL("mnfdz", e1081e0, 2, (RF, RF_IF), rd_rm),
23247 cCL("mnfe", e188100, 2, (RF, RF_IF), rd_rm),
23248 cCL("mnfep", e188120, 2, (RF, RF_IF), rd_rm),
23249 cCL("mnfem", e188140, 2, (RF, RF_IF), rd_rm),
23250 cCL("mnfez", e188160, 2, (RF, RF_IF), rd_rm),
23251
23252 cCL("abss", e208100, 2, (RF, RF_IF), rd_rm),
23253 cCL("abssp", e208120, 2, (RF, RF_IF), rd_rm),
23254 cCL("abssm", e208140, 2, (RF, RF_IF), rd_rm),
23255 cCL("abssz", e208160, 2, (RF, RF_IF), rd_rm),
23256 cCL("absd", e208180, 2, (RF, RF_IF), rd_rm),
23257 cCL("absdp", e2081a0, 2, (RF, RF_IF), rd_rm),
23258 cCL("absdm", e2081c0, 2, (RF, RF_IF), rd_rm),
23259 cCL("absdz", e2081e0, 2, (RF, RF_IF), rd_rm),
23260 cCL("abse", e288100, 2, (RF, RF_IF), rd_rm),
23261 cCL("absep", e288120, 2, (RF, RF_IF), rd_rm),
23262 cCL("absem", e288140, 2, (RF, RF_IF), rd_rm),
23263 cCL("absez", e288160, 2, (RF, RF_IF), rd_rm),
23264
23265 cCL("rnds", e308100, 2, (RF, RF_IF), rd_rm),
23266 cCL("rndsp", e308120, 2, (RF, RF_IF), rd_rm),
23267 cCL("rndsm", e308140, 2, (RF, RF_IF), rd_rm),
23268 cCL("rndsz", e308160, 2, (RF, RF_IF), rd_rm),
23269 cCL("rndd", e308180, 2, (RF, RF_IF), rd_rm),
23270 cCL("rnddp", e3081a0, 2, (RF, RF_IF), rd_rm),
23271 cCL("rnddm", e3081c0, 2, (RF, RF_IF), rd_rm),
23272 cCL("rnddz", e3081e0, 2, (RF, RF_IF), rd_rm),
23273 cCL("rnde", e388100, 2, (RF, RF_IF), rd_rm),
23274 cCL("rndep", e388120, 2, (RF, RF_IF), rd_rm),
23275 cCL("rndem", e388140, 2, (RF, RF_IF), rd_rm),
23276 cCL("rndez", e388160, 2, (RF, RF_IF), rd_rm),
23277
23278 cCL("sqts", e408100, 2, (RF, RF_IF), rd_rm),
23279 cCL("sqtsp", e408120, 2, (RF, RF_IF), rd_rm),
23280 cCL("sqtsm", e408140, 2, (RF, RF_IF), rd_rm),
23281 cCL("sqtsz", e408160, 2, (RF, RF_IF), rd_rm),
23282 cCL("sqtd", e408180, 2, (RF, RF_IF), rd_rm),
23283 cCL("sqtdp", e4081a0, 2, (RF, RF_IF), rd_rm),
23284 cCL("sqtdm", e4081c0, 2, (RF, RF_IF), rd_rm),
23285 cCL("sqtdz", e4081e0, 2, (RF, RF_IF), rd_rm),
23286 cCL("sqte", e488100, 2, (RF, RF_IF), rd_rm),
23287 cCL("sqtep", e488120, 2, (RF, RF_IF), rd_rm),
23288 cCL("sqtem", e488140, 2, (RF, RF_IF), rd_rm),
23289 cCL("sqtez", e488160, 2, (RF, RF_IF), rd_rm),
23290
23291 cCL("logs", e508100, 2, (RF, RF_IF), rd_rm),
23292 cCL("logsp", e508120, 2, (RF, RF_IF), rd_rm),
23293 cCL("logsm", e508140, 2, (RF, RF_IF), rd_rm),
23294 cCL("logsz", e508160, 2, (RF, RF_IF), rd_rm),
23295 cCL("logd", e508180, 2, (RF, RF_IF), rd_rm),
23296 cCL("logdp", e5081a0, 2, (RF, RF_IF), rd_rm),
23297 cCL("logdm", e5081c0, 2, (RF, RF_IF), rd_rm),
23298 cCL("logdz", e5081e0, 2, (RF, RF_IF), rd_rm),
23299 cCL("loge", e588100, 2, (RF, RF_IF), rd_rm),
23300 cCL("logep", e588120, 2, (RF, RF_IF), rd_rm),
23301 cCL("logem", e588140, 2, (RF, RF_IF), rd_rm),
23302 cCL("logez", e588160, 2, (RF, RF_IF), rd_rm),
23303
23304 cCL("lgns", e608100, 2, (RF, RF_IF), rd_rm),
23305 cCL("lgnsp", e608120, 2, (RF, RF_IF), rd_rm),
23306 cCL("lgnsm", e608140, 2, (RF, RF_IF), rd_rm),
23307 cCL("lgnsz", e608160, 2, (RF, RF_IF), rd_rm),
23308 cCL("lgnd", e608180, 2, (RF, RF_IF), rd_rm),
23309 cCL("lgndp", e6081a0, 2, (RF, RF_IF), rd_rm),
23310 cCL("lgndm", e6081c0, 2, (RF, RF_IF), rd_rm),
23311 cCL("lgndz", e6081e0, 2, (RF, RF_IF), rd_rm),
23312 cCL("lgne", e688100, 2, (RF, RF_IF), rd_rm),
23313 cCL("lgnep", e688120, 2, (RF, RF_IF), rd_rm),
23314 cCL("lgnem", e688140, 2, (RF, RF_IF), rd_rm),
23315 cCL("lgnez", e688160, 2, (RF, RF_IF), rd_rm),
23316
23317 cCL("exps", e708100, 2, (RF, RF_IF), rd_rm),
23318 cCL("expsp", e708120, 2, (RF, RF_IF), rd_rm),
23319 cCL("expsm", e708140, 2, (RF, RF_IF), rd_rm),
23320 cCL("expsz", e708160, 2, (RF, RF_IF), rd_rm),
23321 cCL("expd", e708180, 2, (RF, RF_IF), rd_rm),
23322 cCL("expdp", e7081a0, 2, (RF, RF_IF), rd_rm),
23323 cCL("expdm", e7081c0, 2, (RF, RF_IF), rd_rm),
23324 cCL("expdz", e7081e0, 2, (RF, RF_IF), rd_rm),
23325 cCL("expe", e788100, 2, (RF, RF_IF), rd_rm),
23326 cCL("expep", e788120, 2, (RF, RF_IF), rd_rm),
23327 cCL("expem", e788140, 2, (RF, RF_IF), rd_rm),
23328 cCL("expdz", e788160, 2, (RF, RF_IF), rd_rm),
23329
23330 cCL("sins", e808100, 2, (RF, RF_IF), rd_rm),
23331 cCL("sinsp", e808120, 2, (RF, RF_IF), rd_rm),
23332 cCL("sinsm", e808140, 2, (RF, RF_IF), rd_rm),
23333 cCL("sinsz", e808160, 2, (RF, RF_IF), rd_rm),
23334 cCL("sind", e808180, 2, (RF, RF_IF), rd_rm),
23335 cCL("sindp", e8081a0, 2, (RF, RF_IF), rd_rm),
23336 cCL("sindm", e8081c0, 2, (RF, RF_IF), rd_rm),
23337 cCL("sindz", e8081e0, 2, (RF, RF_IF), rd_rm),
23338 cCL("sine", e888100, 2, (RF, RF_IF), rd_rm),
23339 cCL("sinep", e888120, 2, (RF, RF_IF), rd_rm),
23340 cCL("sinem", e888140, 2, (RF, RF_IF), rd_rm),
23341 cCL("sinez", e888160, 2, (RF, RF_IF), rd_rm),
23342
23343 cCL("coss", e908100, 2, (RF, RF_IF), rd_rm),
23344 cCL("cossp", e908120, 2, (RF, RF_IF), rd_rm),
23345 cCL("cossm", e908140, 2, (RF, RF_IF), rd_rm),
23346 cCL("cossz", e908160, 2, (RF, RF_IF), rd_rm),
23347 cCL("cosd", e908180, 2, (RF, RF_IF), rd_rm),
23348 cCL("cosdp", e9081a0, 2, (RF, RF_IF), rd_rm),
23349 cCL("cosdm", e9081c0, 2, (RF, RF_IF), rd_rm),
23350 cCL("cosdz", e9081e0, 2, (RF, RF_IF), rd_rm),
23351 cCL("cose", e988100, 2, (RF, RF_IF), rd_rm),
23352 cCL("cosep", e988120, 2, (RF, RF_IF), rd_rm),
23353 cCL("cosem", e988140, 2, (RF, RF_IF), rd_rm),
23354 cCL("cosez", e988160, 2, (RF, RF_IF), rd_rm),
23355
23356 cCL("tans", ea08100, 2, (RF, RF_IF), rd_rm),
23357 cCL("tansp", ea08120, 2, (RF, RF_IF), rd_rm),
23358 cCL("tansm", ea08140, 2, (RF, RF_IF), rd_rm),
23359 cCL("tansz", ea08160, 2, (RF, RF_IF), rd_rm),
23360 cCL("tand", ea08180, 2, (RF, RF_IF), rd_rm),
23361 cCL("tandp", ea081a0, 2, (RF, RF_IF), rd_rm),
23362 cCL("tandm", ea081c0, 2, (RF, RF_IF), rd_rm),
23363 cCL("tandz", ea081e0, 2, (RF, RF_IF), rd_rm),
23364 cCL("tane", ea88100, 2, (RF, RF_IF), rd_rm),
23365 cCL("tanep", ea88120, 2, (RF, RF_IF), rd_rm),
23366 cCL("tanem", ea88140, 2, (RF, RF_IF), rd_rm),
23367 cCL("tanez", ea88160, 2, (RF, RF_IF), rd_rm),
23368
23369 cCL("asns", eb08100, 2, (RF, RF_IF), rd_rm),
23370 cCL("asnsp", eb08120, 2, (RF, RF_IF), rd_rm),
23371 cCL("asnsm", eb08140, 2, (RF, RF_IF), rd_rm),
23372 cCL("asnsz", eb08160, 2, (RF, RF_IF), rd_rm),
23373 cCL("asnd", eb08180, 2, (RF, RF_IF), rd_rm),
23374 cCL("asndp", eb081a0, 2, (RF, RF_IF), rd_rm),
23375 cCL("asndm", eb081c0, 2, (RF, RF_IF), rd_rm),
23376 cCL("asndz", eb081e0, 2, (RF, RF_IF), rd_rm),
23377 cCL("asne", eb88100, 2, (RF, RF_IF), rd_rm),
23378 cCL("asnep", eb88120, 2, (RF, RF_IF), rd_rm),
23379 cCL("asnem", eb88140, 2, (RF, RF_IF), rd_rm),
23380 cCL("asnez", eb88160, 2, (RF, RF_IF), rd_rm),
23381
23382 cCL("acss", ec08100, 2, (RF, RF_IF), rd_rm),
23383 cCL("acssp", ec08120, 2, (RF, RF_IF), rd_rm),
23384 cCL("acssm", ec08140, 2, (RF, RF_IF), rd_rm),
23385 cCL("acssz", ec08160, 2, (RF, RF_IF), rd_rm),
23386 cCL("acsd", ec08180, 2, (RF, RF_IF), rd_rm),
23387 cCL("acsdp", ec081a0, 2, (RF, RF_IF), rd_rm),
23388 cCL("acsdm", ec081c0, 2, (RF, RF_IF), rd_rm),
23389 cCL("acsdz", ec081e0, 2, (RF, RF_IF), rd_rm),
23390 cCL("acse", ec88100, 2, (RF, RF_IF), rd_rm),
23391 cCL("acsep", ec88120, 2, (RF, RF_IF), rd_rm),
23392 cCL("acsem", ec88140, 2, (RF, RF_IF), rd_rm),
23393 cCL("acsez", ec88160, 2, (RF, RF_IF), rd_rm),
23394
23395 cCL("atns", ed08100, 2, (RF, RF_IF), rd_rm),
23396 cCL("atnsp", ed08120, 2, (RF, RF_IF), rd_rm),
23397 cCL("atnsm", ed08140, 2, (RF, RF_IF), rd_rm),
23398 cCL("atnsz", ed08160, 2, (RF, RF_IF), rd_rm),
23399 cCL("atnd", ed08180, 2, (RF, RF_IF), rd_rm),
23400 cCL("atndp", ed081a0, 2, (RF, RF_IF), rd_rm),
23401 cCL("atndm", ed081c0, 2, (RF, RF_IF), rd_rm),
23402 cCL("atndz", ed081e0, 2, (RF, RF_IF), rd_rm),
23403 cCL("atne", ed88100, 2, (RF, RF_IF), rd_rm),
23404 cCL("atnep", ed88120, 2, (RF, RF_IF), rd_rm),
23405 cCL("atnem", ed88140, 2, (RF, RF_IF), rd_rm),
23406 cCL("atnez", ed88160, 2, (RF, RF_IF), rd_rm),
23407
23408 cCL("urds", ee08100, 2, (RF, RF_IF), rd_rm),
23409 cCL("urdsp", ee08120, 2, (RF, RF_IF), rd_rm),
23410 cCL("urdsm", ee08140, 2, (RF, RF_IF), rd_rm),
23411 cCL("urdsz", ee08160, 2, (RF, RF_IF), rd_rm),
23412 cCL("urdd", ee08180, 2, (RF, RF_IF), rd_rm),
23413 cCL("urddp", ee081a0, 2, (RF, RF_IF), rd_rm),
23414 cCL("urddm", ee081c0, 2, (RF, RF_IF), rd_rm),
23415 cCL("urddz", ee081e0, 2, (RF, RF_IF), rd_rm),
23416 cCL("urde", ee88100, 2, (RF, RF_IF), rd_rm),
23417 cCL("urdep", ee88120, 2, (RF, RF_IF), rd_rm),
23418 cCL("urdem", ee88140, 2, (RF, RF_IF), rd_rm),
23419 cCL("urdez", ee88160, 2, (RF, RF_IF), rd_rm),
23420
23421 cCL("nrms", ef08100, 2, (RF, RF_IF), rd_rm),
23422 cCL("nrmsp", ef08120, 2, (RF, RF_IF), rd_rm),
23423 cCL("nrmsm", ef08140, 2, (RF, RF_IF), rd_rm),
23424 cCL("nrmsz", ef08160, 2, (RF, RF_IF), rd_rm),
23425 cCL("nrmd", ef08180, 2, (RF, RF_IF), rd_rm),
23426 cCL("nrmdp", ef081a0, 2, (RF, RF_IF), rd_rm),
23427 cCL("nrmdm", ef081c0, 2, (RF, RF_IF), rd_rm),
23428 cCL("nrmdz", ef081e0, 2, (RF, RF_IF), rd_rm),
23429 cCL("nrme", ef88100, 2, (RF, RF_IF), rd_rm),
23430 cCL("nrmep", ef88120, 2, (RF, RF_IF), rd_rm),
23431 cCL("nrmem", ef88140, 2, (RF, RF_IF), rd_rm),
23432 cCL("nrmez", ef88160, 2, (RF, RF_IF), rd_rm),
23433
23434 cCL("adfs", e000100, 3, (RF, RF, RF_IF), rd_rn_rm),
23435 cCL("adfsp", e000120, 3, (RF, RF, RF_IF), rd_rn_rm),
23436 cCL("adfsm", e000140, 3, (RF, RF, RF_IF), rd_rn_rm),
23437 cCL("adfsz", e000160, 3, (RF, RF, RF_IF), rd_rn_rm),
23438 cCL("adfd", e000180, 3, (RF, RF, RF_IF), rd_rn_rm),
23439 cCL("adfdp", e0001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23440 cCL("adfdm", e0001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23441 cCL("adfdz", e0001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23442 cCL("adfe", e080100, 3, (RF, RF, RF_IF), rd_rn_rm),
23443 cCL("adfep", e080120, 3, (RF, RF, RF_IF), rd_rn_rm),
23444 cCL("adfem", e080140, 3, (RF, RF, RF_IF), rd_rn_rm),
23445 cCL("adfez", e080160, 3, (RF, RF, RF_IF), rd_rn_rm),
23446
23447 cCL("sufs", e200100, 3, (RF, RF, RF_IF), rd_rn_rm),
23448 cCL("sufsp", e200120, 3, (RF, RF, RF_IF), rd_rn_rm),
23449 cCL("sufsm", e200140, 3, (RF, RF, RF_IF), rd_rn_rm),
23450 cCL("sufsz", e200160, 3, (RF, RF, RF_IF), rd_rn_rm),
23451 cCL("sufd", e200180, 3, (RF, RF, RF_IF), rd_rn_rm),
23452 cCL("sufdp", e2001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23453 cCL("sufdm", e2001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23454 cCL("sufdz", e2001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23455 cCL("sufe", e280100, 3, (RF, RF, RF_IF), rd_rn_rm),
23456 cCL("sufep", e280120, 3, (RF, RF, RF_IF), rd_rn_rm),
23457 cCL("sufem", e280140, 3, (RF, RF, RF_IF), rd_rn_rm),
23458 cCL("sufez", e280160, 3, (RF, RF, RF_IF), rd_rn_rm),
23459
23460 cCL("rsfs", e300100, 3, (RF, RF, RF_IF), rd_rn_rm),
23461 cCL("rsfsp", e300120, 3, (RF, RF, RF_IF), rd_rn_rm),
23462 cCL("rsfsm", e300140, 3, (RF, RF, RF_IF), rd_rn_rm),
23463 cCL("rsfsz", e300160, 3, (RF, RF, RF_IF), rd_rn_rm),
23464 cCL("rsfd", e300180, 3, (RF, RF, RF_IF), rd_rn_rm),
23465 cCL("rsfdp", e3001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23466 cCL("rsfdm", e3001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23467 cCL("rsfdz", e3001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23468 cCL("rsfe", e380100, 3, (RF, RF, RF_IF), rd_rn_rm),
23469 cCL("rsfep", e380120, 3, (RF, RF, RF_IF), rd_rn_rm),
23470 cCL("rsfem", e380140, 3, (RF, RF, RF_IF), rd_rn_rm),
23471 cCL("rsfez", e380160, 3, (RF, RF, RF_IF), rd_rn_rm),
23472
23473 cCL("mufs", e100100, 3, (RF, RF, RF_IF), rd_rn_rm),
23474 cCL("mufsp", e100120, 3, (RF, RF, RF_IF), rd_rn_rm),
23475 cCL("mufsm", e100140, 3, (RF, RF, RF_IF), rd_rn_rm),
23476 cCL("mufsz", e100160, 3, (RF, RF, RF_IF), rd_rn_rm),
23477 cCL("mufd", e100180, 3, (RF, RF, RF_IF), rd_rn_rm),
23478 cCL("mufdp", e1001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23479 cCL("mufdm", e1001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23480 cCL("mufdz", e1001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23481 cCL("mufe", e180100, 3, (RF, RF, RF_IF), rd_rn_rm),
23482 cCL("mufep", e180120, 3, (RF, RF, RF_IF), rd_rn_rm),
23483 cCL("mufem", e180140, 3, (RF, RF, RF_IF), rd_rn_rm),
23484 cCL("mufez", e180160, 3, (RF, RF, RF_IF), rd_rn_rm),
23485
23486 cCL("dvfs", e400100, 3, (RF, RF, RF_IF), rd_rn_rm),
23487 cCL("dvfsp", e400120, 3, (RF, RF, RF_IF), rd_rn_rm),
23488 cCL("dvfsm", e400140, 3, (RF, RF, RF_IF), rd_rn_rm),
23489 cCL("dvfsz", e400160, 3, (RF, RF, RF_IF), rd_rn_rm),
23490 cCL("dvfd", e400180, 3, (RF, RF, RF_IF), rd_rn_rm),
23491 cCL("dvfdp", e4001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23492 cCL("dvfdm", e4001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23493 cCL("dvfdz", e4001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23494 cCL("dvfe", e480100, 3, (RF, RF, RF_IF), rd_rn_rm),
23495 cCL("dvfep", e480120, 3, (RF, RF, RF_IF), rd_rn_rm),
23496 cCL("dvfem", e480140, 3, (RF, RF, RF_IF), rd_rn_rm),
23497 cCL("dvfez", e480160, 3, (RF, RF, RF_IF), rd_rn_rm),
23498
23499 cCL("rdfs", e500100, 3, (RF, RF, RF_IF), rd_rn_rm),
23500 cCL("rdfsp", e500120, 3, (RF, RF, RF_IF), rd_rn_rm),
23501 cCL("rdfsm", e500140, 3, (RF, RF, RF_IF), rd_rn_rm),
23502 cCL("rdfsz", e500160, 3, (RF, RF, RF_IF), rd_rn_rm),
23503 cCL("rdfd", e500180, 3, (RF, RF, RF_IF), rd_rn_rm),
23504 cCL("rdfdp", e5001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23505 cCL("rdfdm", e5001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23506 cCL("rdfdz", e5001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23507 cCL("rdfe", e580100, 3, (RF, RF, RF_IF), rd_rn_rm),
23508 cCL("rdfep", e580120, 3, (RF, RF, RF_IF), rd_rn_rm),
23509 cCL("rdfem", e580140, 3, (RF, RF, RF_IF), rd_rn_rm),
23510 cCL("rdfez", e580160, 3, (RF, RF, RF_IF), rd_rn_rm),
23511
23512 cCL("pows", e600100, 3, (RF, RF, RF_IF), rd_rn_rm),
23513 cCL("powsp", e600120, 3, (RF, RF, RF_IF), rd_rn_rm),
23514 cCL("powsm", e600140, 3, (RF, RF, RF_IF), rd_rn_rm),
23515 cCL("powsz", e600160, 3, (RF, RF, RF_IF), rd_rn_rm),
23516 cCL("powd", e600180, 3, (RF, RF, RF_IF), rd_rn_rm),
23517 cCL("powdp", e6001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23518 cCL("powdm", e6001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23519 cCL("powdz", e6001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23520 cCL("powe", e680100, 3, (RF, RF, RF_IF), rd_rn_rm),
23521 cCL("powep", e680120, 3, (RF, RF, RF_IF), rd_rn_rm),
23522 cCL("powem", e680140, 3, (RF, RF, RF_IF), rd_rn_rm),
23523 cCL("powez", e680160, 3, (RF, RF, RF_IF), rd_rn_rm),
23524
23525 cCL("rpws", e700100, 3, (RF, RF, RF_IF), rd_rn_rm),
23526 cCL("rpwsp", e700120, 3, (RF, RF, RF_IF), rd_rn_rm),
23527 cCL("rpwsm", e700140, 3, (RF, RF, RF_IF), rd_rn_rm),
23528 cCL("rpwsz", e700160, 3, (RF, RF, RF_IF), rd_rn_rm),
23529 cCL("rpwd", e700180, 3, (RF, RF, RF_IF), rd_rn_rm),
23530 cCL("rpwdp", e7001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23531 cCL("rpwdm", e7001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23532 cCL("rpwdz", e7001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23533 cCL("rpwe", e780100, 3, (RF, RF, RF_IF), rd_rn_rm),
23534 cCL("rpwep", e780120, 3, (RF, RF, RF_IF), rd_rn_rm),
23535 cCL("rpwem", e780140, 3, (RF, RF, RF_IF), rd_rn_rm),
23536 cCL("rpwez", e780160, 3, (RF, RF, RF_IF), rd_rn_rm),
23537
23538 cCL("rmfs", e800100, 3, (RF, RF, RF_IF), rd_rn_rm),
23539 cCL("rmfsp", e800120, 3, (RF, RF, RF_IF), rd_rn_rm),
23540 cCL("rmfsm", e800140, 3, (RF, RF, RF_IF), rd_rn_rm),
23541 cCL("rmfsz", e800160, 3, (RF, RF, RF_IF), rd_rn_rm),
23542 cCL("rmfd", e800180, 3, (RF, RF, RF_IF), rd_rn_rm),
23543 cCL("rmfdp", e8001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23544 cCL("rmfdm", e8001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23545 cCL("rmfdz", e8001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23546 cCL("rmfe", e880100, 3, (RF, RF, RF_IF), rd_rn_rm),
23547 cCL("rmfep", e880120, 3, (RF, RF, RF_IF), rd_rn_rm),
23548 cCL("rmfem", e880140, 3, (RF, RF, RF_IF), rd_rn_rm),
23549 cCL("rmfez", e880160, 3, (RF, RF, RF_IF), rd_rn_rm),
23550
23551 cCL("fmls", e900100, 3, (RF, RF, RF_IF), rd_rn_rm),
23552 cCL("fmlsp", e900120, 3, (RF, RF, RF_IF), rd_rn_rm),
23553 cCL("fmlsm", e900140, 3, (RF, RF, RF_IF), rd_rn_rm),
23554 cCL("fmlsz", e900160, 3, (RF, RF, RF_IF), rd_rn_rm),
23555 cCL("fmld", e900180, 3, (RF, RF, RF_IF), rd_rn_rm),
23556 cCL("fmldp", e9001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23557 cCL("fmldm", e9001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23558 cCL("fmldz", e9001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23559 cCL("fmle", e980100, 3, (RF, RF, RF_IF), rd_rn_rm),
23560 cCL("fmlep", e980120, 3, (RF, RF, RF_IF), rd_rn_rm),
23561 cCL("fmlem", e980140, 3, (RF, RF, RF_IF), rd_rn_rm),
23562 cCL("fmlez", e980160, 3, (RF, RF, RF_IF), rd_rn_rm),
23563
23564 cCL("fdvs", ea00100, 3, (RF, RF, RF_IF), rd_rn_rm),
23565 cCL("fdvsp", ea00120, 3, (RF, RF, RF_IF), rd_rn_rm),
23566 cCL("fdvsm", ea00140, 3, (RF, RF, RF_IF), rd_rn_rm),
23567 cCL("fdvsz", ea00160, 3, (RF, RF, RF_IF), rd_rn_rm),
23568 cCL("fdvd", ea00180, 3, (RF, RF, RF_IF), rd_rn_rm),
23569 cCL("fdvdp", ea001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23570 cCL("fdvdm", ea001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23571 cCL("fdvdz", ea001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23572 cCL("fdve", ea80100, 3, (RF, RF, RF_IF), rd_rn_rm),
23573 cCL("fdvep", ea80120, 3, (RF, RF, RF_IF), rd_rn_rm),
23574 cCL("fdvem", ea80140, 3, (RF, RF, RF_IF), rd_rn_rm),
23575 cCL("fdvez", ea80160, 3, (RF, RF, RF_IF), rd_rn_rm),
23576
23577 cCL("frds", eb00100, 3, (RF, RF, RF_IF), rd_rn_rm),
23578 cCL("frdsp", eb00120, 3, (RF, RF, RF_IF), rd_rn_rm),
23579 cCL("frdsm", eb00140, 3, (RF, RF, RF_IF), rd_rn_rm),
23580 cCL("frdsz", eb00160, 3, (RF, RF, RF_IF), rd_rn_rm),
23581 cCL("frdd", eb00180, 3, (RF, RF, RF_IF), rd_rn_rm),
23582 cCL("frddp", eb001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23583 cCL("frddm", eb001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23584 cCL("frddz", eb001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23585 cCL("frde", eb80100, 3, (RF, RF, RF_IF), rd_rn_rm),
23586 cCL("frdep", eb80120, 3, (RF, RF, RF_IF), rd_rn_rm),
23587 cCL("frdem", eb80140, 3, (RF, RF, RF_IF), rd_rn_rm),
23588 cCL("frdez", eb80160, 3, (RF, RF, RF_IF), rd_rn_rm),
23589
23590 cCL("pols", ec00100, 3, (RF, RF, RF_IF), rd_rn_rm),
23591 cCL("polsp", ec00120, 3, (RF, RF, RF_IF), rd_rn_rm),
23592 cCL("polsm", ec00140, 3, (RF, RF, RF_IF), rd_rn_rm),
23593 cCL("polsz", ec00160, 3, (RF, RF, RF_IF), rd_rn_rm),
23594 cCL("pold", ec00180, 3, (RF, RF, RF_IF), rd_rn_rm),
23595 cCL("poldp", ec001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
23596 cCL("poldm", ec001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
23597 cCL("poldz", ec001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
23598 cCL("pole", ec80100, 3, (RF, RF, RF_IF), rd_rn_rm),
23599 cCL("polep", ec80120, 3, (RF, RF, RF_IF), rd_rn_rm),
23600 cCL("polem", ec80140, 3, (RF, RF, RF_IF), rd_rn_rm),
23601 cCL("polez", ec80160, 3, (RF, RF, RF_IF), rd_rn_rm),
23602
23603 cCE("cmf", e90f110, 2, (RF, RF_IF), fpa_cmp),
23604 C3E("cmfe", ed0f110, 2, (RF, RF_IF), fpa_cmp),
23605 cCE("cnf", eb0f110, 2, (RF, RF_IF), fpa_cmp),
23606 C3E("cnfe", ef0f110, 2, (RF, RF_IF), fpa_cmp),
23607
23608 cCL("flts", e000110, 2, (RF, RR), rn_rd),
23609 cCL("fltsp", e000130, 2, (RF, RR), rn_rd),
23610 cCL("fltsm", e000150, 2, (RF, RR), rn_rd),
23611 cCL("fltsz", e000170, 2, (RF, RR), rn_rd),
23612 cCL("fltd", e000190, 2, (RF, RR), rn_rd),
23613 cCL("fltdp", e0001b0, 2, (RF, RR), rn_rd),
23614 cCL("fltdm", e0001d0, 2, (RF, RR), rn_rd),
23615 cCL("fltdz", e0001f0, 2, (RF, RR), rn_rd),
23616 cCL("flte", e080110, 2, (RF, RR), rn_rd),
23617 cCL("fltep", e080130, 2, (RF, RR), rn_rd),
23618 cCL("fltem", e080150, 2, (RF, RR), rn_rd),
23619 cCL("fltez", e080170, 2, (RF, RR), rn_rd),
b99bd4ef 23620
c19d1205
ZW
23621 /* The implementation of the FIX instruction is broken on some
23622 assemblers, in that it accepts a precision specifier as well as a
23623 rounding specifier, despite the fact that this is meaningless.
23624 To be more compatible, we accept it as well, though of course it
23625 does not set any bits. */
21d799b5
NC
23626 cCE("fix", e100110, 2, (RR, RF), rd_rm),
23627 cCL("fixp", e100130, 2, (RR, RF), rd_rm),
23628 cCL("fixm", e100150, 2, (RR, RF), rd_rm),
23629 cCL("fixz", e100170, 2, (RR, RF), rd_rm),
23630 cCL("fixsp", e100130, 2, (RR, RF), rd_rm),
23631 cCL("fixsm", e100150, 2, (RR, RF), rd_rm),
23632 cCL("fixsz", e100170, 2, (RR, RF), rd_rm),
23633 cCL("fixdp", e100130, 2, (RR, RF), rd_rm),
23634 cCL("fixdm", e100150, 2, (RR, RF), rd_rm),
23635 cCL("fixdz", e100170, 2, (RR, RF), rd_rm),
23636 cCL("fixep", e100130, 2, (RR, RF), rd_rm),
23637 cCL("fixem", e100150, 2, (RR, RF), rd_rm),
23638 cCL("fixez", e100170, 2, (RR, RF), rd_rm),
bfae80f2 23639
c19d1205 23640 /* Instructions that were new with the real FPA, call them V2. */
c921be7d
NC
23641#undef ARM_VARIANT
23642#define ARM_VARIANT & fpu_fpa_ext_v2
23643
21d799b5
NC
23644 cCE("lfm", c100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
23645 cCL("lfmfd", c900200, 3, (RF, I4b, ADDR), fpa_ldmstm),
23646 cCL("lfmea", d100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
23647 cCE("sfm", c000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
23648 cCL("sfmfd", d000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
23649 cCL("sfmea", c800200, 3, (RF, I4b, ADDR), fpa_ldmstm),
c19d1205 23650
c921be7d
NC
23651#undef ARM_VARIANT
23652#define ARM_VARIANT & fpu_vfp_ext_v1xd /* VFP V1xD (single precision). */
23653
c19d1205 23654 /* Moves and type conversions. */
21d799b5 23655 cCE("fmstat", ef1fa10, 0, (), noargs),
7465e07a
NC
23656 cCE("vmrs", ef00a10, 2, (APSR_RR, RVC), vmrs),
23657 cCE("vmsr", ee00a10, 2, (RVC, RR), vmsr),
21d799b5
NC
23658 cCE("fsitos", eb80ac0, 2, (RVS, RVS), vfp_sp_monadic),
23659 cCE("fuitos", eb80a40, 2, (RVS, RVS), vfp_sp_monadic),
23660 cCE("ftosis", ebd0a40, 2, (RVS, RVS), vfp_sp_monadic),
23661 cCE("ftosizs", ebd0ac0, 2, (RVS, RVS), vfp_sp_monadic),
23662 cCE("ftouis", ebc0a40, 2, (RVS, RVS), vfp_sp_monadic),
23663 cCE("ftouizs", ebc0ac0, 2, (RVS, RVS), vfp_sp_monadic),
23664 cCE("fmrx", ef00a10, 2, (RR, RVC), rd_rn),
23665 cCE("fmxr", ee00a10, 2, (RVC, RR), rn_rd),
c19d1205
ZW
23666
23667 /* Memory operations. */
21d799b5
NC
23668 cCE("flds", d100a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
23669 cCE("fsts", d000a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
55881a11
MGD
23670 cCE("fldmias", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
23671 cCE("fldmfds", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
23672 cCE("fldmdbs", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
23673 cCE("fldmeas", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
23674 cCE("fldmiax", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
23675 cCE("fldmfdx", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
23676 cCE("fldmdbx", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
23677 cCE("fldmeax", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
23678 cCE("fstmias", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
23679 cCE("fstmeas", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
23680 cCE("fstmdbs", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
23681 cCE("fstmfds", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
23682 cCE("fstmiax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
23683 cCE("fstmeax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
23684 cCE("fstmdbx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
23685 cCE("fstmfdx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
bfae80f2 23686
c19d1205 23687 /* Monadic operations. */
21d799b5
NC
23688 cCE("fabss", eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
23689 cCE("fnegs", eb10a40, 2, (RVS, RVS), vfp_sp_monadic),
23690 cCE("fsqrts", eb10ac0, 2, (RVS, RVS), vfp_sp_monadic),
c19d1205
ZW
23691
23692 /* Dyadic operations. */
21d799b5
NC
23693 cCE("fadds", e300a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23694 cCE("fsubs", e300a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23695 cCE("fmuls", e200a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23696 cCE("fdivs", e800a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23697 cCE("fmacs", e000a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23698 cCE("fmscs", e100a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23699 cCE("fnmuls", e200a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23700 cCE("fnmacs", e000a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
23701 cCE("fnmscs", e100a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
b99bd4ef 23702
c19d1205 23703 /* Comparisons. */
21d799b5
NC
23704 cCE("fcmps", eb40a40, 2, (RVS, RVS), vfp_sp_monadic),
23705 cCE("fcmpzs", eb50a40, 1, (RVS), vfp_sp_compare_z),
23706 cCE("fcmpes", eb40ac0, 2, (RVS, RVS), vfp_sp_monadic),
23707 cCE("fcmpezs", eb50ac0, 1, (RVS), vfp_sp_compare_z),
b99bd4ef 23708
62f3b8c8
PB
23709 /* Double precision load/store are still present on single precision
23710 implementations. */
23711 cCE("fldd", d100b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
23712 cCE("fstd", d000b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
55881a11
MGD
23713 cCE("fldmiad", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
23714 cCE("fldmfdd", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
23715 cCE("fldmdbd", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
23716 cCE("fldmead", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
23717 cCE("fstmiad", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
23718 cCE("fstmead", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
23719 cCE("fstmdbd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
23720 cCE("fstmfdd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
62f3b8c8 23721
c921be7d
NC
23722#undef ARM_VARIANT
23723#define ARM_VARIANT & fpu_vfp_ext_v1 /* VFP V1 (Double precision). */
23724
c19d1205 23725 /* Moves and type conversions. */
21d799b5
NC
23726 cCE("fcvtds", eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt),
23727 cCE("fcvtsd", eb70bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
23728 cCE("fmdhr", e200b10, 2, (RVD, RR), vfp_dp_rn_rd),
23729 cCE("fmdlr", e000b10, 2, (RVD, RR), vfp_dp_rn_rd),
23730 cCE("fmrdh", e300b10, 2, (RR, RVD), vfp_dp_rd_rn),
23731 cCE("fmrdl", e100b10, 2, (RR, RVD), vfp_dp_rd_rn),
23732 cCE("fsitod", eb80bc0, 2, (RVD, RVS), vfp_dp_sp_cvt),
23733 cCE("fuitod", eb80b40, 2, (RVD, RVS), vfp_dp_sp_cvt),
23734 cCE("ftosid", ebd0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
23735 cCE("ftosizd", ebd0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
23736 cCE("ftouid", ebc0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
23737 cCE("ftouizd", ebc0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
c19d1205 23738
c19d1205 23739 /* Monadic operations. */
21d799b5
NC
23740 cCE("fabsd", eb00bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
23741 cCE("fnegd", eb10b40, 2, (RVD, RVD), vfp_dp_rd_rm),
23742 cCE("fsqrtd", eb10bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
c19d1205
ZW
23743
23744 /* Dyadic operations. */
21d799b5
NC
23745 cCE("faddd", e300b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23746 cCE("fsubd", e300b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23747 cCE("fmuld", e200b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23748 cCE("fdivd", e800b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23749 cCE("fmacd", e000b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23750 cCE("fmscd", e100b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23751 cCE("fnmuld", e200b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23752 cCE("fnmacd", e000b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
23753 cCE("fnmscd", e100b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
b99bd4ef 23754
c19d1205 23755 /* Comparisons. */
21d799b5
NC
23756 cCE("fcmpd", eb40b40, 2, (RVD, RVD), vfp_dp_rd_rm),
23757 cCE("fcmpzd", eb50b40, 1, (RVD), vfp_dp_rd),
23758 cCE("fcmped", eb40bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
23759 cCE("fcmpezd", eb50bc0, 1, (RVD), vfp_dp_rd),
c19d1205 23760
037e8744
JB
23761/* Instructions which may belong to either the Neon or VFP instruction sets.
23762 Individual encoder functions perform additional architecture checks. */
c921be7d
NC
23763#undef ARM_VARIANT
23764#define ARM_VARIANT & fpu_vfp_ext_v1xd
23765#undef THUMB_VARIANT
23766#define THUMB_VARIANT & fpu_vfp_ext_v1xd
23767
037e8744
JB
23768 /* These mnemonics are unique to VFP. */
23769 NCE(vsqrt, 0, 2, (RVSD, RVSD), vfp_nsyn_sqrt),
23770 NCE(vdiv, 0, 3, (RVSD, RVSD, RVSD), vfp_nsyn_div),
21d799b5
NC
23771 nCE(vnmul, _vnmul, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
23772 nCE(vnmla, _vnmla, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
23773 nCE(vnmls, _vnmls, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
037e8744
JB
23774 NCE(vpush, 0, 1, (VRSDLST), vfp_nsyn_push),
23775 NCE(vpop, 0, 1, (VRSDLST), vfp_nsyn_pop),
23776 NCE(vcvtz, 0, 2, (RVSD, RVSD), vfp_nsyn_cvtz),
23777
23778 /* Mnemonics shared by Neon and VFP. */
21d799b5
NC
23779 nCEF(vmul, _vmul, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mul),
23780 nCEF(vmla, _vmla, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
23781 nCEF(vmls, _vmls, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
037e8744 23782
55881a11
MGD
23783 NCE(vldm, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
23784 NCE(vldmia, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
23785 NCE(vldmdb, d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
23786 NCE(vstm, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
23787 NCE(vstmia, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
23788 NCE(vstmdb, d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
037e8744 23789
dd9634d9 23790 mnCEF(vcvt, _vcvt, 3, (RNSDQMQ, RNSDQMQ, oI32z), neon_cvt),
e3e535bc 23791 nCEF(vcvtr, _vcvt, 2, (RNSDQ, RNSDQ), neon_cvtr),
dd9634d9
AV
23792 MNCEF(vcvtb, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtb),
23793 MNCEF(vcvtt, eb20a40, 3, (RVSDMQ, RVSDMQ, oI32b), neon_cvtt),
f31fef98 23794
037e8744
JB
23795
23796 /* NOTE: All VMOV encoding is special-cased! */
037e8744
JB
23797 NCE(vmovq, 0, 1, (VMOV), neon_mov),
23798
32c36c3c
AV
23799#undef THUMB_VARIANT
23800/* Could be either VLDR/VSTR or VLDR/VSTR (system register) which are guarded
23801 by different feature bits. Since we are setting the Thumb guard, we can
23802 require Thumb-1 which makes it a nop guard and set the right feature bit in
23803 do_vldr_vstr (). */
23804#define THUMB_VARIANT & arm_ext_v4t
23805 NCE(vldr, d100b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
23806 NCE(vstr, d000b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
23807
9db2f6b4
RL
23808#undef ARM_VARIANT
23809#define ARM_VARIANT & arm_ext_fp16
23810#undef THUMB_VARIANT
23811#define THUMB_VARIANT & arm_ext_fp16
23812 /* New instructions added from v8.2, allowing the extraction and insertion of
23813 the upper 16 bits of a 32-bit vector register. */
23814 NCE (vmovx, eb00a40, 2, (RVS, RVS), neon_movhf),
23815 NCE (vins, eb00ac0, 2, (RVS, RVS), neon_movhf),
23816
dec41383
JW
23817 /* New backported fma/fms instructions optional in v8.2. */
23818 NCE (vfmal, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmal),
23819 NCE (vfmsl, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmsl),
23820
c921be7d
NC
23821#undef THUMB_VARIANT
23822#define THUMB_VARIANT & fpu_neon_ext_v1
23823#undef ARM_VARIANT
23824#define ARM_VARIANT & fpu_neon_ext_v1
23825
5287ad62
JB
23826 /* Data processing with three registers of the same length. */
23827 /* integer ops, valid types S8 S16 S32 U8 U16 U32. */
23828 NUF(vaba, 0000710, 3, (RNDQ, RNDQ, RNDQ), neon_dyadic_i_su),
23829 NUF(vabaq, 0000710, 3, (RNQ, RNQ, RNQ), neon_dyadic_i_su),
5287ad62 23830 NUF(vhaddq, 0000000, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62 23831 NUF(vrhaddq, 0000100, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
5287ad62
JB
23832 NUF(vhsubq, 0000200, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
23833 /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64. */
23834 NUF(vqadd, 0000010, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
23835 NUF(vqaddq, 0000010, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
23836 NUF(vqsub, 0000210, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
23837 NUF(vqsubq, 0000210, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
627907b7
JB
23838 NUF(vrshl, 0000500, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
23839 NUF(vrshlq, 0000500, 3, (RNQ, oRNQ, RNQ), neon_rshl),
23840 NUF(vqrshl, 0000510, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
23841 NUF(vqrshlq, 0000510, 3, (RNQ, oRNQ, RNQ), neon_rshl),
5287ad62
JB
23842 /* If not immediate, fall back to neon_dyadic_i64_su.
23843 shl_imm should accept I8 I16 I32 I64,
23844 qshl_imm should accept S8 S16 S32 S64 U8 U16 U32 U64. */
21d799b5
NC
23845 nUF(vshl, _vshl, 3, (RNDQ, oRNDQ, RNDQ_I63b), neon_shl_imm),
23846 nUF(vshlq, _vshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_shl_imm),
23847 nUF(vqshl, _vqshl, 3, (RNDQ, oRNDQ, RNDQ_I63b), neon_qshl_imm),
23848 nUF(vqshlq, _vqshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_qshl_imm),
5287ad62 23849 /* Logic ops, types optional & ignored. */
4316f0d2 23850 nUF(vandq, _vand, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 23851 nUF(vbicq, _vbic, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 23852 nUF(vorrq, _vorr, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 23853 nUF(vornq, _vorn, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
4316f0d2 23854 nUF(veorq, _veor, 3, (RNQ, oRNQ, RNQ), neon_logic),
5287ad62
JB
23855 /* Bitfield ops, untyped. */
23856 NUF(vbsl, 1100110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
23857 NUF(vbslq, 1100110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
23858 NUF(vbit, 1200110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
23859 NUF(vbitq, 1200110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
23860 NUF(vbif, 1300110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
23861 NUF(vbifq, 1300110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
cc933301 23862 /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32. */
21d799b5 23863 nUF(vabdq, _vabd, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 23864 nUF(vmaxq, _vmax, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21d799b5 23865 nUF(vminq, _vmin, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
5287ad62
JB
23866 /* Comparisons. Types S8 S16 S32 U8 U16 U32 F32. Non-immediate versions fall
23867 back to neon_dyadic_if_su. */
21d799b5
NC
23868 nUF(vcge, _vcge, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
23869 nUF(vcgeq, _vcge, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
23870 nUF(vcgt, _vcgt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
23871 nUF(vcgtq, _vcgt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
23872 nUF(vclt, _vclt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
23873 nUF(vcltq, _vclt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
23874 nUF(vcle, _vcle, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
23875 nUF(vcleq, _vcle, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
428e3f1f 23876 /* Comparison. Type I8 I16 I32 F32. */
21d799b5
NC
23877 nUF(vceq, _vceq, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_ceq),
23878 nUF(vceqq, _vceq, 3, (RNQ, oRNQ, RNDQ_I0), neon_ceq),
5287ad62 23879 /* As above, D registers only. */
21d799b5
NC
23880 nUF(vpmax, _vpmax, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
23881 nUF(vpmin, _vpmin, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
5287ad62 23882 /* Int and float variants, signedness unimportant. */
21d799b5
NC
23883 nUF(vmlaq, _vmla, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
23884 nUF(vmlsq, _vmls, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
23885 nUF(vpadd, _vpadd, 3, (RND, oRND, RND), neon_dyadic_if_i_d),
5287ad62 23886 /* Add/sub take types I8 I16 I32 I64 F32. */
21d799b5
NC
23887 nUF(vaddq, _vadd, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
23888 nUF(vsubq, _vsub, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
5287ad62
JB
23889 /* vtst takes sizes 8, 16, 32. */
23890 NUF(vtst, 0000810, 3, (RNDQ, oRNDQ, RNDQ), neon_tst),
23891 NUF(vtstq, 0000810, 3, (RNQ, oRNQ, RNQ), neon_tst),
23892 /* VMUL takes I8 I16 I32 F32 P8. */
21d799b5 23893 nUF(vmulq, _vmul, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mul),
5287ad62 23894 /* VQD{R}MULH takes S16 S32. */
21d799b5
NC
23895 nUF(vqdmulh, _vqdmulh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qdmulh),
23896 nUF(vqdmulhq, _vqdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
23897 nUF(vqrdmulh, _vqrdmulh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qdmulh),
23898 nUF(vqrdmulhq, _vqrdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
5287ad62
JB
23899 NUF(vacge, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
23900 NUF(vacgeq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
23901 NUF(vacgt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
23902 NUF(vacgtq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
92559b5b
PB
23903 NUF(vaclt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
23904 NUF(vacltq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
23905 NUF(vacle, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
23906 NUF(vacleq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
5287ad62
JB
23907 NUF(vrecps, 0000f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
23908 NUF(vrecpsq, 0000f10, 3, (RNQ, oRNQ, RNQ), neon_step),
23909 NUF(vrsqrts, 0200f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
23910 NUF(vrsqrtsq, 0200f10, 3, (RNQ, oRNQ, RNQ), neon_step),
d6b4b13e 23911 /* ARM v8.1 extension. */
643afb90
MW
23912 nUF (vqrdmlah, _vqrdmlah, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
23913 nUF (vqrdmlahq, _vqrdmlah, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
23914 nUF (vqrdmlsh, _vqrdmlsh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
23915 nUF (vqrdmlshq, _vqrdmlsh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
5287ad62
JB
23916
23917 /* Two address, int/float. Types S8 S16 S32 F32. */
5287ad62 23918 NUF(vabsq, 1b10300, 2, (RNQ, RNQ), neon_abs_neg),
5287ad62
JB
23919 NUF(vnegq, 1b10380, 2, (RNQ, RNQ), neon_abs_neg),
23920
23921 /* Data processing with two registers and a shift amount. */
23922 /* Right shifts, and variants with rounding.
23923 Types accepted S8 S16 S32 S64 U8 U16 U32 U64. */
23924 NUF(vshr, 0800010, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
23925 NUF(vshrq, 0800010, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
23926 NUF(vrshr, 0800210, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
23927 NUF(vrshrq, 0800210, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
23928 NUF(vsra, 0800110, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
23929 NUF(vsraq, 0800110, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
23930 NUF(vrsra, 0800310, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
23931 NUF(vrsraq, 0800310, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
23932 /* Shift and insert. Sizes accepted 8 16 32 64. */
23933 NUF(vsli, 1800510, 3, (RNDQ, oRNDQ, I63), neon_sli),
23934 NUF(vsliq, 1800510, 3, (RNQ, oRNQ, I63), neon_sli),
23935 NUF(vsri, 1800410, 3, (RNDQ, oRNDQ, I64), neon_sri),
23936 NUF(vsriq, 1800410, 3, (RNQ, oRNQ, I64), neon_sri),
23937 /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64. */
23938 NUF(vqshlu, 1800610, 3, (RNDQ, oRNDQ, I63), neon_qshlu_imm),
23939 NUF(vqshluq, 1800610, 3, (RNQ, oRNQ, I63), neon_qshlu_imm),
23940 /* Right shift immediate, saturating & narrowing, with rounding variants.
23941 Types accepted S16 S32 S64 U16 U32 U64. */
23942 NUF(vqshrn, 0800910, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
23943 NUF(vqrshrn, 0800950, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
23944 /* As above, unsigned. Types accepted S16 S32 S64. */
23945 NUF(vqshrun, 0800810, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
23946 NUF(vqrshrun, 0800850, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
23947 /* Right shift narrowing. Types accepted I16 I32 I64. */
23948 NUF(vshrn, 0800810, 3, (RND, RNQ, I32z), neon_rshift_narrow),
23949 NUF(vrshrn, 0800850, 3, (RND, RNQ, I32z), neon_rshift_narrow),
23950 /* Special case. Types S8 S16 S32 U8 U16 U32. Handles max shift variant. */
21d799b5 23951 nUF(vshll, _vshll, 3, (RNQ, RND, I32), neon_shll),
5287ad62 23952 /* CVT with optional immediate for fixed-point variant. */
21d799b5 23953 nUF(vcvtq, _vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
b7fc2769 23954
4316f0d2
DG
23955 nUF(vmvn, _vmvn, 2, (RNDQ, RNDQ_Ibig), neon_mvn),
23956 nUF(vmvnq, _vmvn, 2, (RNQ, RNDQ_Ibig), neon_mvn),
5287ad62
JB
23957
23958 /* Data processing, three registers of different lengths. */
23959 /* Dyadic, long insns. Types S8 S16 S32 U8 U16 U32. */
23960 NUF(vabal, 0800500, 3, (RNQ, RND, RND), neon_abal),
5287ad62
JB
23961 /* If not scalar, fall back to neon_dyadic_long.
23962 Vector types as above, scalar types S16 S32 U16 U32. */
21d799b5
NC
23963 nUF(vmlal, _vmlal, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
23964 nUF(vmlsl, _vmlsl, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
5287ad62
JB
23965 /* Dyadic, widening insns. Types S8 S16 S32 U8 U16 U32. */
23966 NUF(vaddw, 0800100, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
23967 NUF(vsubw, 0800300, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
23968 /* Dyadic, narrowing insns. Types I16 I32 I64. */
23969 NUF(vaddhn, 0800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
23970 NUF(vraddhn, 1800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
23971 NUF(vsubhn, 0800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
23972 NUF(vrsubhn, 1800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
23973 /* Saturating doubling multiplies. Types S16 S32. */
21d799b5
NC
23974 nUF(vqdmlal, _vqdmlal, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
23975 nUF(vqdmlsl, _vqdmlsl, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
23976 nUF(vqdmull, _vqdmull, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
5287ad62
JB
23977 /* VMULL. Vector types S8 S16 S32 U8 U16 U32 P8, scalar types
23978 S16 S32 U16 U32. */
21d799b5 23979 nUF(vmull, _vmull, 3, (RNQ, RND, RND_RNSC), neon_vmull),
5287ad62
JB
23980
23981 /* Extract. Size 8. */
3b8d421e
PB
23982 NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I15), neon_ext),
23983 NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I15), neon_ext),
5287ad62
JB
23984
23985 /* Two registers, miscellaneous. */
23986 /* Reverse. Sizes 8 16 32 (must be < size in opcode). */
23987 NUF(vrev64, 1b00000, 2, (RNDQ, RNDQ), neon_rev),
23988 NUF(vrev64q, 1b00000, 2, (RNQ, RNQ), neon_rev),
23989 NUF(vrev32, 1b00080, 2, (RNDQ, RNDQ), neon_rev),
23990 NUF(vrev32q, 1b00080, 2, (RNQ, RNQ), neon_rev),
23991 NUF(vrev16, 1b00100, 2, (RNDQ, RNDQ), neon_rev),
23992 NUF(vrev16q, 1b00100, 2, (RNQ, RNQ), neon_rev),
23993 /* Vector replicate. Sizes 8 16 32. */
21d799b5 23994 nCE(vdupq, _vdup, 2, (RNQ, RR_RNSC), neon_dup),
5287ad62
JB
23995 /* VMOVL. Types S8 S16 S32 U8 U16 U32. */
23996 NUF(vmovl, 0800a10, 2, (RNQ, RND), neon_movl),
23997 /* VMOVN. Types I16 I32 I64. */
21d799b5 23998 nUF(vmovn, _vmovn, 2, (RND, RNQ), neon_movn),
5287ad62 23999 /* VQMOVN. Types S16 S32 S64 U16 U32 U64. */
21d799b5 24000 nUF(vqmovn, _vqmovn, 2, (RND, RNQ), neon_qmovn),
5287ad62 24001 /* VQMOVUN. Types S16 S32 S64. */
21d799b5 24002 nUF(vqmovun, _vqmovun, 2, (RND, RNQ), neon_qmovun),
5287ad62
JB
24003 /* VZIP / VUZP. Sizes 8 16 32. */
24004 NUF(vzip, 1b20180, 2, (RNDQ, RNDQ), neon_zip_uzp),
24005 NUF(vzipq, 1b20180, 2, (RNQ, RNQ), neon_zip_uzp),
24006 NUF(vuzp, 1b20100, 2, (RNDQ, RNDQ), neon_zip_uzp),
24007 NUF(vuzpq, 1b20100, 2, (RNQ, RNQ), neon_zip_uzp),
24008 /* VQABS / VQNEG. Types S8 S16 S32. */
24009 NUF(vqabs, 1b00700, 2, (RNDQ, RNDQ), neon_sat_abs_neg),
24010 NUF(vqabsq, 1b00700, 2, (RNQ, RNQ), neon_sat_abs_neg),
24011 NUF(vqneg, 1b00780, 2, (RNDQ, RNDQ), neon_sat_abs_neg),
24012 NUF(vqnegq, 1b00780, 2, (RNQ, RNQ), neon_sat_abs_neg),
24013 /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32. */
24014 NUF(vpadal, 1b00600, 2, (RNDQ, RNDQ), neon_pair_long),
24015 NUF(vpadalq, 1b00600, 2, (RNQ, RNQ), neon_pair_long),
24016 NUF(vpaddl, 1b00200, 2, (RNDQ, RNDQ), neon_pair_long),
24017 NUF(vpaddlq, 1b00200, 2, (RNQ, RNQ), neon_pair_long),
cc933301 24018 /* Reciprocal estimates. Types U32 F16 F32. */
5287ad62
JB
24019 NUF(vrecpe, 1b30400, 2, (RNDQ, RNDQ), neon_recip_est),
24020 NUF(vrecpeq, 1b30400, 2, (RNQ, RNQ), neon_recip_est),
24021 NUF(vrsqrte, 1b30480, 2, (RNDQ, RNDQ), neon_recip_est),
24022 NUF(vrsqrteq, 1b30480, 2, (RNQ, RNQ), neon_recip_est),
24023 /* VCLS. Types S8 S16 S32. */
5287ad62
JB
24024 NUF(vclsq, 1b00400, 2, (RNQ, RNQ), neon_cls),
24025 /* VCLZ. Types I8 I16 I32. */
5287ad62
JB
24026 NUF(vclzq, 1b00480, 2, (RNQ, RNQ), neon_clz),
24027 /* VCNT. Size 8. */
24028 NUF(vcnt, 1b00500, 2, (RNDQ, RNDQ), neon_cnt),
24029 NUF(vcntq, 1b00500, 2, (RNQ, RNQ), neon_cnt),
24030 /* Two address, untyped. */
24031 NUF(vswp, 1b20000, 2, (RNDQ, RNDQ), neon_swp),
24032 NUF(vswpq, 1b20000, 2, (RNQ, RNQ), neon_swp),
24033 /* VTRN. Sizes 8 16 32. */
21d799b5
NC
24034 nUF(vtrn, _vtrn, 2, (RNDQ, RNDQ), neon_trn),
24035 nUF(vtrnq, _vtrn, 2, (RNQ, RNQ), neon_trn),
5287ad62
JB
24036
24037 /* Table lookup. Size 8. */
24038 NUF(vtbl, 1b00800, 3, (RND, NRDLST, RND), neon_tbl_tbx),
24039 NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
24040
c921be7d
NC
24041#undef THUMB_VARIANT
24042#define THUMB_VARIANT & fpu_vfp_v3_or_neon_ext
24043#undef ARM_VARIANT
24044#define ARM_VARIANT & fpu_vfp_v3_or_neon_ext
24045
5287ad62 24046 /* Neon element/structure load/store. */
21d799b5
NC
24047 nUF(vld1, _vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
24048 nUF(vst1, _vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
24049 nUF(vld2, _vld2, 2, (NSTRLST, ADDR), neon_ldx_stx),
24050 nUF(vst2, _vst2, 2, (NSTRLST, ADDR), neon_ldx_stx),
24051 nUF(vld3, _vld3, 2, (NSTRLST, ADDR), neon_ldx_stx),
24052 nUF(vst3, _vst3, 2, (NSTRLST, ADDR), neon_ldx_stx),
24053 nUF(vld4, _vld4, 2, (NSTRLST, ADDR), neon_ldx_stx),
24054 nUF(vst4, _vst4, 2, (NSTRLST, ADDR), neon_ldx_stx),
5287ad62 24055
c921be7d 24056#undef THUMB_VARIANT
74db7efb
NC
24057#define THUMB_VARIANT & fpu_vfp_ext_v3xd
24058#undef ARM_VARIANT
24059#define ARM_VARIANT & fpu_vfp_ext_v3xd
62f3b8c8
PB
24060 cCE("fconsts", eb00a00, 2, (RVS, I255), vfp_sp_const),
24061 cCE("fshtos", eba0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24062 cCE("fsltos", eba0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24063 cCE("fuhtos", ebb0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24064 cCE("fultos", ebb0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24065 cCE("ftoshs", ebe0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24066 cCE("ftosls", ebe0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24067 cCE("ftouhs", ebf0a40, 2, (RVS, I16z), vfp_sp_conv_16),
24068 cCE("ftouls", ebf0ac0, 2, (RVS, I32), vfp_sp_conv_32),
24069
74db7efb 24070#undef THUMB_VARIANT
c921be7d
NC
24071#define THUMB_VARIANT & fpu_vfp_ext_v3
24072#undef ARM_VARIANT
24073#define ARM_VARIANT & fpu_vfp_ext_v3
24074
21d799b5 24075 cCE("fconstd", eb00b00, 2, (RVD, I255), vfp_dp_const),
21d799b5 24076 cCE("fshtod", eba0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24077 cCE("fsltod", eba0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 24078 cCE("fuhtod", ebb0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24079 cCE("fultod", ebb0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 24080 cCE("ftoshd", ebe0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24081 cCE("ftosld", ebe0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 24082 cCE("ftouhd", ebf0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 24083 cCE("ftould", ebf0bc0, 2, (RVD, I32), vfp_dp_conv_32),
c19d1205 24084
74db7efb
NC
24085#undef ARM_VARIANT
24086#define ARM_VARIANT & fpu_vfp_ext_fma
24087#undef THUMB_VARIANT
24088#define THUMB_VARIANT & fpu_vfp_ext_fma
d58196e0 24089 /* Mnemonics shared by Neon, VFP and MVE. These are included in the
62f3b8c8
PB
24090 VFP FMA variant; NEON and VFP FMA always includes the NEON
24091 FMA instructions. */
d58196e0
AV
24092 mnCEF(vfma, _vfma, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_fmac),
24093 mnCEF(vfms, _vfms, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), neon_fmac),
24094
62f3b8c8
PB
24095 /* ffmas/ffmad/ffmss/ffmsd are dummy mnemonics to satisfy gas;
24096 the v form should always be used. */
24097 cCE("ffmas", ea00a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24098 cCE("ffnmas", ea00a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
24099 cCE("ffmad", ea00b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24100 cCE("ffnmad", ea00b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
24101 nCE(vfnma, _vfnma, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
24102 nCE(vfnms, _vfnms, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
24103
5287ad62 24104#undef THUMB_VARIANT
c921be7d
NC
24105#undef ARM_VARIANT
24106#define ARM_VARIANT & arm_cext_xscale /* Intel XScale extensions. */
24107
21d799b5
NC
24108 cCE("mia", e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24109 cCE("miaph", e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24110 cCE("miabb", e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24111 cCE("miabt", e2d0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24112 cCE("miatb", e2e0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24113 cCE("miatt", e2f0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
24114 cCE("mar", c400000, 3, (RXA, RRnpc, RRnpc), xsc_mar),
24115 cCE("mra", c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra),
c19d1205 24116
c921be7d
NC
24117#undef ARM_VARIANT
24118#define ARM_VARIANT & arm_cext_iwmmxt /* Intel Wireless MMX technology. */
24119
21d799b5
NC
24120 cCE("tandcb", e13f130, 1, (RR), iwmmxt_tandorc),
24121 cCE("tandch", e53f130, 1, (RR), iwmmxt_tandorc),
24122 cCE("tandcw", e93f130, 1, (RR), iwmmxt_tandorc),
24123 cCE("tbcstb", e400010, 2, (RIWR, RR), rn_rd),
24124 cCE("tbcsth", e400050, 2, (RIWR, RR), rn_rd),
24125 cCE("tbcstw", e400090, 2, (RIWR, RR), rn_rd),
24126 cCE("textrcb", e130170, 2, (RR, I7), iwmmxt_textrc),
24127 cCE("textrch", e530170, 2, (RR, I7), iwmmxt_textrc),
24128 cCE("textrcw", e930170, 2, (RR, I7), iwmmxt_textrc),
74db7efb
NC
24129 cCE("textrmub",e100070, 3, (RR, RIWR, I7), iwmmxt_textrm),
24130 cCE("textrmuh",e500070, 3, (RR, RIWR, I7), iwmmxt_textrm),
24131 cCE("textrmuw",e900070, 3, (RR, RIWR, I7), iwmmxt_textrm),
24132 cCE("textrmsb",e100078, 3, (RR, RIWR, I7), iwmmxt_textrm),
24133 cCE("textrmsh",e500078, 3, (RR, RIWR, I7), iwmmxt_textrm),
24134 cCE("textrmsw",e900078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21d799b5
NC
24135 cCE("tinsrb", e600010, 3, (RIWR, RR, I7), iwmmxt_tinsr),
24136 cCE("tinsrh", e600050, 3, (RIWR, RR, I7), iwmmxt_tinsr),
24137 cCE("tinsrw", e600090, 3, (RIWR, RR, I7), iwmmxt_tinsr),
24138 cCE("tmcr", e000110, 2, (RIWC_RIWG, RR), rn_rd),
24139 cCE("tmcrr", c400000, 3, (RIWR, RR, RR), rm_rd_rn),
24140 cCE("tmia", e200010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24141 cCE("tmiaph", e280010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24142 cCE("tmiabb", e2c0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24143 cCE("tmiabt", e2d0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24144 cCE("tmiatb", e2e0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
24145 cCE("tmiatt", e2f0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
74db7efb
NC
24146 cCE("tmovmskb",e100030, 2, (RR, RIWR), rd_rn),
24147 cCE("tmovmskh",e500030, 2, (RR, RIWR), rd_rn),
24148 cCE("tmovmskw",e900030, 2, (RR, RIWR), rd_rn),
21d799b5
NC
24149 cCE("tmrc", e100110, 2, (RR, RIWC_RIWG), rd_rn),
24150 cCE("tmrrc", c500000, 3, (RR, RR, RIWR), rd_rn_rm),
24151 cCE("torcb", e13f150, 1, (RR), iwmmxt_tandorc),
24152 cCE("torch", e53f150, 1, (RR), iwmmxt_tandorc),
24153 cCE("torcw", e93f150, 1, (RR), iwmmxt_tandorc),
24154 cCE("waccb", e0001c0, 2, (RIWR, RIWR), rd_rn),
24155 cCE("wacch", e4001c0, 2, (RIWR, RIWR), rd_rn),
24156 cCE("waccw", e8001c0, 2, (RIWR, RIWR), rd_rn),
24157 cCE("waddbss", e300180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24158 cCE("waddb", e000180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24159 cCE("waddbus", e100180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24160 cCE("waddhss", e700180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24161 cCE("waddh", e400180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24162 cCE("waddhus", e500180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24163 cCE("waddwss", eb00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24164 cCE("waddw", e800180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24165 cCE("waddwus", e900180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24166 cCE("waligni", e000020, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_waligni),
74db7efb
NC
24167 cCE("walignr0",e800020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24168 cCE("walignr1",e900020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24169 cCE("walignr2",ea00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24170 cCE("walignr3",eb00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
24171 cCE("wand", e200000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24172 cCE("wandn", e300000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24173 cCE("wavg2b", e800000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24174 cCE("wavg2br", e900000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24175 cCE("wavg2h", ec00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24176 cCE("wavg2hr", ed00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24177 cCE("wcmpeqb", e000060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24178 cCE("wcmpeqh", e400060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24179 cCE("wcmpeqw", e800060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
24180 cCE("wcmpgtub",e100060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24181 cCE("wcmpgtuh",e500060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24182 cCE("wcmpgtuw",e900060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24183 cCE("wcmpgtsb",e300060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24184 cCE("wcmpgtsh",e700060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24185 cCE("wcmpgtsw",eb00060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
24186 cCE("wldrb", c100000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24187 cCE("wldrh", c500000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24188 cCE("wldrw", c100100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
24189 cCE("wldrd", c500100, 2, (RIWR, ADDR), iwmmxt_wldstd),
24190 cCE("wmacs", e600100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24191 cCE("wmacsz", e700100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24192 cCE("wmacu", e400100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24193 cCE("wmacuz", e500100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24194 cCE("wmadds", ea00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24195 cCE("wmaddu", e800100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24196 cCE("wmaxsb", e200160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24197 cCE("wmaxsh", e600160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24198 cCE("wmaxsw", ea00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24199 cCE("wmaxub", e000160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24200 cCE("wmaxuh", e400160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24201 cCE("wmaxuw", e800160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24202 cCE("wminsb", e300160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24203 cCE("wminsh", e700160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24204 cCE("wminsw", eb00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24205 cCE("wminub", e100160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24206 cCE("wminuh", e500160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24207 cCE("wminuw", e900160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24208 cCE("wmov", e000000, 2, (RIWR, RIWR), iwmmxt_wmov),
24209 cCE("wmulsm", e300100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24210 cCE("wmulsl", e200100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24211 cCE("wmulum", e100100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24212 cCE("wmulul", e000100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24213 cCE("wor", e000000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
24214 cCE("wpackhss",e700080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24215 cCE("wpackhus",e500080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24216 cCE("wpackwss",eb00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24217 cCE("wpackwus",e900080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24218 cCE("wpackdss",ef00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24219 cCE("wpackdus",ed00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
24220 cCE("wrorh", e700040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24221 cCE("wrorhg", e700148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24222 cCE("wrorw", eb00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24223 cCE("wrorwg", eb00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24224 cCE("wrord", ef00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24225 cCE("wrordg", ef00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24226 cCE("wsadb", e000120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24227 cCE("wsadbz", e100120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24228 cCE("wsadh", e400120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24229 cCE("wsadhz", e500120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24230 cCE("wshufh", e0001e0, 3, (RIWR, RIWR, I255), iwmmxt_wshufh),
24231 cCE("wsllh", e500040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24232 cCE("wsllhg", e500148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24233 cCE("wsllw", e900040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24234 cCE("wsllwg", e900148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24235 cCE("wslld", ed00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24236 cCE("wslldg", ed00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24237 cCE("wsrah", e400040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24238 cCE("wsrahg", e400148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24239 cCE("wsraw", e800040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24240 cCE("wsrawg", e800148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24241 cCE("wsrad", ec00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24242 cCE("wsradg", ec00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24243 cCE("wsrlh", e600040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24244 cCE("wsrlhg", e600148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24245 cCE("wsrlw", ea00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24246 cCE("wsrlwg", ea00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24247 cCE("wsrld", ee00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
24248 cCE("wsrldg", ee00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
24249 cCE("wstrb", c000000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24250 cCE("wstrh", c400000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
24251 cCE("wstrw", c000100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
24252 cCE("wstrd", c400100, 2, (RIWR, ADDR), iwmmxt_wldstd),
24253 cCE("wsubbss", e3001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24254 cCE("wsubb", e0001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24255 cCE("wsubbus", e1001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24256 cCE("wsubhss", e7001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24257 cCE("wsubh", e4001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24258 cCE("wsubhus", e5001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24259 cCE("wsubwss", eb001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24260 cCE("wsubw", e8001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24261 cCE("wsubwus", e9001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24262 cCE("wunpckehub",e0000c0, 2, (RIWR, RIWR), rd_rn),
24263 cCE("wunpckehuh",e4000c0, 2, (RIWR, RIWR), rd_rn),
24264 cCE("wunpckehuw",e8000c0, 2, (RIWR, RIWR), rd_rn),
24265 cCE("wunpckehsb",e2000c0, 2, (RIWR, RIWR), rd_rn),
24266 cCE("wunpckehsh",e6000c0, 2, (RIWR, RIWR), rd_rn),
24267 cCE("wunpckehsw",ea000c0, 2, (RIWR, RIWR), rd_rn),
24268 cCE("wunpckihb", e1000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24269 cCE("wunpckihh", e5000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24270 cCE("wunpckihw", e9000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24271 cCE("wunpckelub",e0000e0, 2, (RIWR, RIWR), rd_rn),
24272 cCE("wunpckeluh",e4000e0, 2, (RIWR, RIWR), rd_rn),
24273 cCE("wunpckeluw",e8000e0, 2, (RIWR, RIWR), rd_rn),
24274 cCE("wunpckelsb",e2000e0, 2, (RIWR, RIWR), rd_rn),
24275 cCE("wunpckelsh",e6000e0, 2, (RIWR, RIWR), rd_rn),
24276 cCE("wunpckelsw",ea000e0, 2, (RIWR, RIWR), rd_rn),
24277 cCE("wunpckilb", e1000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24278 cCE("wunpckilh", e5000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24279 cCE("wunpckilw", e9000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24280 cCE("wxor", e100000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24281 cCE("wzero", e300000, 1, (RIWR), iwmmxt_wzero),
c19d1205 24282
c921be7d
NC
24283#undef ARM_VARIANT
24284#define ARM_VARIANT & arm_cext_iwmmxt2 /* Intel Wireless MMX technology, version 2. */
24285
21d799b5
NC
24286 cCE("torvscb", e12f190, 1, (RR), iwmmxt_tandorc),
24287 cCE("torvsch", e52f190, 1, (RR), iwmmxt_tandorc),
24288 cCE("torvscw", e92f190, 1, (RR), iwmmxt_tandorc),
24289 cCE("wabsb", e2001c0, 2, (RIWR, RIWR), rd_rn),
24290 cCE("wabsh", e6001c0, 2, (RIWR, RIWR), rd_rn),
24291 cCE("wabsw", ea001c0, 2, (RIWR, RIWR), rd_rn),
24292 cCE("wabsdiffb", e1001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24293 cCE("wabsdiffh", e5001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24294 cCE("wabsdiffw", e9001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24295 cCE("waddbhusl", e2001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24296 cCE("waddbhusm", e6001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24297 cCE("waddhc", e600180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24298 cCE("waddwc", ea00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24299 cCE("waddsubhx", ea001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24300 cCE("wavg4", e400000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24301 cCE("wavg4r", e500000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24302 cCE("wmaddsn", ee00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24303 cCE("wmaddsx", eb00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24304 cCE("wmaddun", ec00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24305 cCE("wmaddux", e900100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24306 cCE("wmerge", e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
24307 cCE("wmiabb", e0000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24308 cCE("wmiabt", e1000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24309 cCE("wmiatb", e2000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24310 cCE("wmiatt", e3000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24311 cCE("wmiabbn", e4000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24312 cCE("wmiabtn", e5000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24313 cCE("wmiatbn", e6000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24314 cCE("wmiattn", e7000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24315 cCE("wmiawbb", e800120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24316 cCE("wmiawbt", e900120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24317 cCE("wmiawtb", ea00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24318 cCE("wmiawtt", eb00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24319 cCE("wmiawbbn", ec00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24320 cCE("wmiawbtn", ed00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24321 cCE("wmiawtbn", ee00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24322 cCE("wmiawttn", ef00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24323 cCE("wmulsmr", ef00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24324 cCE("wmulumr", ed00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24325 cCE("wmulwumr", ec000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24326 cCE("wmulwsmr", ee000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24327 cCE("wmulwum", ed000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24328 cCE("wmulwsm", ef000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24329 cCE("wmulwl", eb000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24330 cCE("wqmiabb", e8000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24331 cCE("wqmiabt", e9000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24332 cCE("wqmiatb", ea000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24333 cCE("wqmiatt", eb000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24334 cCE("wqmiabbn", ec000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24335 cCE("wqmiabtn", ed000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24336 cCE("wqmiatbn", ee000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24337 cCE("wqmiattn", ef000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24338 cCE("wqmulm", e100080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24339 cCE("wqmulmr", e300080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24340 cCE("wqmulwm", ec000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24341 cCE("wqmulwmr", ee000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
24342 cCE("wsubaddhx", ed001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
2d447fca 24343
c921be7d
NC
24344#undef ARM_VARIANT
24345#define ARM_VARIANT & arm_cext_maverick /* Cirrus Maverick instructions. */
24346
21d799b5
NC
24347 cCE("cfldrs", c100400, 2, (RMF, ADDRGLDC), rd_cpaddr),
24348 cCE("cfldrd", c500400, 2, (RMD, ADDRGLDC), rd_cpaddr),
24349 cCE("cfldr32", c100500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
24350 cCE("cfldr64", c500500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
24351 cCE("cfstrs", c000400, 2, (RMF, ADDRGLDC), rd_cpaddr),
24352 cCE("cfstrd", c400400, 2, (RMD, ADDRGLDC), rd_cpaddr),
24353 cCE("cfstr32", c000500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
24354 cCE("cfstr64", c400500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
24355 cCE("cfmvsr", e000450, 2, (RMF, RR), rn_rd),
24356 cCE("cfmvrs", e100450, 2, (RR, RMF), rd_rn),
24357 cCE("cfmvdlr", e000410, 2, (RMD, RR), rn_rd),
24358 cCE("cfmvrdl", e100410, 2, (RR, RMD), rd_rn),
24359 cCE("cfmvdhr", e000430, 2, (RMD, RR), rn_rd),
24360 cCE("cfmvrdh", e100430, 2, (RR, RMD), rd_rn),
74db7efb
NC
24361 cCE("cfmv64lr",e000510, 2, (RMDX, RR), rn_rd),
24362 cCE("cfmvr64l",e100510, 2, (RR, RMDX), rd_rn),
24363 cCE("cfmv64hr",e000530, 2, (RMDX, RR), rn_rd),
24364 cCE("cfmvr64h",e100530, 2, (RR, RMDX), rd_rn),
24365 cCE("cfmval32",e200440, 2, (RMAX, RMFX), rd_rn),
24366 cCE("cfmv32al",e100440, 2, (RMFX, RMAX), rd_rn),
24367 cCE("cfmvam32",e200460, 2, (RMAX, RMFX), rd_rn),
24368 cCE("cfmv32am",e100460, 2, (RMFX, RMAX), rd_rn),
24369 cCE("cfmvah32",e200480, 2, (RMAX, RMFX), rd_rn),
24370 cCE("cfmv32ah",e100480, 2, (RMFX, RMAX), rd_rn),
21d799b5
NC
24371 cCE("cfmva32", e2004a0, 2, (RMAX, RMFX), rd_rn),
24372 cCE("cfmv32a", e1004a0, 2, (RMFX, RMAX), rd_rn),
24373 cCE("cfmva64", e2004c0, 2, (RMAX, RMDX), rd_rn),
24374 cCE("cfmv64a", e1004c0, 2, (RMDX, RMAX), rd_rn),
74db7efb
NC
24375 cCE("cfmvsc32",e2004e0, 2, (RMDS, RMDX), mav_dspsc),
24376 cCE("cfmv32sc",e1004e0, 2, (RMDX, RMDS), rd),
21d799b5
NC
24377 cCE("cfcpys", e000400, 2, (RMF, RMF), rd_rn),
24378 cCE("cfcpyd", e000420, 2, (RMD, RMD), rd_rn),
24379 cCE("cfcvtsd", e000460, 2, (RMD, RMF), rd_rn),
24380 cCE("cfcvtds", e000440, 2, (RMF, RMD), rd_rn),
74db7efb
NC
24381 cCE("cfcvt32s",e000480, 2, (RMF, RMFX), rd_rn),
24382 cCE("cfcvt32d",e0004a0, 2, (RMD, RMFX), rd_rn),
24383 cCE("cfcvt64s",e0004c0, 2, (RMF, RMDX), rd_rn),
24384 cCE("cfcvt64d",e0004e0, 2, (RMD, RMDX), rd_rn),
24385 cCE("cfcvts32",e100580, 2, (RMFX, RMF), rd_rn),
24386 cCE("cfcvtd32",e1005a0, 2, (RMFX, RMD), rd_rn),
21d799b5
NC
24387 cCE("cftruncs32",e1005c0, 2, (RMFX, RMF), rd_rn),
24388 cCE("cftruncd32",e1005e0, 2, (RMFX, RMD), rd_rn),
74db7efb
NC
24389 cCE("cfrshl32",e000550, 3, (RMFX, RMFX, RR), mav_triple),
24390 cCE("cfrshl64",e000570, 3, (RMDX, RMDX, RR), mav_triple),
21d799b5
NC
24391 cCE("cfsh32", e000500, 3, (RMFX, RMFX, I63s), mav_shift),
24392 cCE("cfsh64", e200500, 3, (RMDX, RMDX, I63s), mav_shift),
24393 cCE("cfcmps", e100490, 3, (RR, RMF, RMF), rd_rn_rm),
24394 cCE("cfcmpd", e1004b0, 3, (RR, RMD, RMD), rd_rn_rm),
24395 cCE("cfcmp32", e100590, 3, (RR, RMFX, RMFX), rd_rn_rm),
24396 cCE("cfcmp64", e1005b0, 3, (RR, RMDX, RMDX), rd_rn_rm),
24397 cCE("cfabss", e300400, 2, (RMF, RMF), rd_rn),
24398 cCE("cfabsd", e300420, 2, (RMD, RMD), rd_rn),
24399 cCE("cfnegs", e300440, 2, (RMF, RMF), rd_rn),
24400 cCE("cfnegd", e300460, 2, (RMD, RMD), rd_rn),
24401 cCE("cfadds", e300480, 3, (RMF, RMF, RMF), rd_rn_rm),
24402 cCE("cfaddd", e3004a0, 3, (RMD, RMD, RMD), rd_rn_rm),
24403 cCE("cfsubs", e3004c0, 3, (RMF, RMF, RMF), rd_rn_rm),
24404 cCE("cfsubd", e3004e0, 3, (RMD, RMD, RMD), rd_rn_rm),
24405 cCE("cfmuls", e100400, 3, (RMF, RMF, RMF), rd_rn_rm),
24406 cCE("cfmuld", e100420, 3, (RMD, RMD, RMD), rd_rn_rm),
24407 cCE("cfabs32", e300500, 2, (RMFX, RMFX), rd_rn),
24408 cCE("cfabs64", e300520, 2, (RMDX, RMDX), rd_rn),
24409 cCE("cfneg32", e300540, 2, (RMFX, RMFX), rd_rn),
24410 cCE("cfneg64", e300560, 2, (RMDX, RMDX), rd_rn),
24411 cCE("cfadd32", e300580, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
24412 cCE("cfadd64", e3005a0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
24413 cCE("cfsub32", e3005c0, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
24414 cCE("cfsub64", e3005e0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
24415 cCE("cfmul32", e100500, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
24416 cCE("cfmul64", e100520, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
24417 cCE("cfmac32", e100540, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
24418 cCE("cfmsc32", e100560, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
74db7efb
NC
24419 cCE("cfmadd32",e000600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
24420 cCE("cfmsub32",e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21d799b5
NC
24421 cCE("cfmadda32", e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
24422 cCE("cfmsuba32", e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
4ed7ed8d 24423
7fadb25d
SD
24424 /* ARMv8.5-A instructions. */
24425#undef ARM_VARIANT
24426#define ARM_VARIANT & arm_ext_sb
24427#undef THUMB_VARIANT
24428#define THUMB_VARIANT & arm_ext_sb
24429 TUF("sb", 57ff070, f3bf8f70, 0, (), noargs, noargs),
24430
dad0c3bf
SD
24431#undef ARM_VARIANT
24432#define ARM_VARIANT & arm_ext_predres
24433#undef THUMB_VARIANT
24434#define THUMB_VARIANT & arm_ext_predres
24435 CE("cfprctx", e070f93, 1, (RRnpc), rd),
24436 CE("dvprctx", e070fb3, 1, (RRnpc), rd),
24437 CE("cpprctx", e070ff3, 1, (RRnpc), rd),
24438
16a1fa25 24439 /* ARMv8-M instructions. */
4ed7ed8d
TP
24440#undef ARM_VARIANT
24441#define ARM_VARIANT NULL
24442#undef THUMB_VARIANT
24443#define THUMB_VARIANT & arm_ext_v8m
cf3cf39d
TP
24444 ToU("sg", e97fe97f, 0, (), noargs),
24445 ToC("blxns", 4784, 1, (RRnpc), t_blx),
24446 ToC("bxns", 4704, 1, (RRnpc), t_bx),
24447 ToC("tt", e840f000, 2, (RRnpc, RRnpc), tt),
24448 ToC("ttt", e840f040, 2, (RRnpc, RRnpc), tt),
24449 ToC("tta", e840f080, 2, (RRnpc, RRnpc), tt),
24450 ToC("ttat", e840f0c0, 2, (RRnpc, RRnpc), tt),
16a1fa25
TP
24451
24452 /* FP for ARMv8-M Mainline. Enabled for ARMv8-M Mainline because the
24453 instructions behave as nop if no VFP is present. */
24454#undef THUMB_VARIANT
24455#define THUMB_VARIANT & arm_ext_v8m_main
cf3cf39d
TP
24456 ToC("vlldm", ec300a00, 1, (RRnpc), rn),
24457 ToC("vlstm", ec200a00, 1, (RRnpc), rn),
4389b29a
AV
24458
24459 /* Armv8.1-M Mainline instructions. */
24460#undef THUMB_VARIANT
24461#define THUMB_VARIANT & arm_ext_v8_1m_main
24462 toC("bf", _bf, 2, (EXPs, EXPs), t_branch_future),
f6b2b12d 24463 toU("bfcsel", _bfcsel, 4, (EXPs, EXPs, EXPs, COND), t_branch_future),
f1c7f421 24464 toC("bfx", _bfx, 2, (EXPs, RRnpcsp), t_branch_future),
65d1bc05 24465 toC("bfl", _bfl, 2, (EXPs, EXPs), t_branch_future),
f1c7f421 24466 toC("bflx", _bflx, 2, (EXPs, RRnpcsp), t_branch_future),
60f993ce
AV
24467
24468 toU("dls", _dls, 2, (LR, RRnpcsp), t_loloop),
24469 toU("wls", _wls, 3, (LR, RRnpcsp, EXP), t_loloop),
24470 toU("le", _le, 2, (oLR, EXP), t_loloop),
4b5a202f 24471
efd6b359 24472 ToC("clrm", e89f0000, 1, (CLRMLST), t_clrm),
5ee91343
AV
24473 ToC("vscclrm", ec9f0a00, 1, (VRSDVLST), t_vscclrm),
24474
24475#undef THUMB_VARIANT
24476#define THUMB_VARIANT & mve_ext
1b883319
AV
24477
24478 ToC("vpt", ee410f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24479 ToC("vptt", ee018f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24480 ToC("vpte", ee418f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24481 ToC("vpttt", ee014f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24482 ToC("vptte", ee01cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24483 ToC("vptet", ee41cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24484 ToC("vptee", ee414f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24485 ToC("vptttt", ee012f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24486 ToC("vpttte", ee016f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24487 ToC("vpttet", ee01ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24488 ToC("vpttee", ee01af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24489 ToC("vptett", ee41af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24490 ToC("vptete", ee41ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24491 ToC("vpteet", ee416f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24492 ToC("vpteee", ee412f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
24493
5ee91343
AV
24494 ToC("vpst", fe710f4d, 0, (), mve_vpt),
24495 ToC("vpstt", fe318f4d, 0, (), mve_vpt),
24496 ToC("vpste", fe718f4d, 0, (), mve_vpt),
24497 ToC("vpsttt", fe314f4d, 0, (), mve_vpt),
24498 ToC("vpstte", fe31cf4d, 0, (), mve_vpt),
24499 ToC("vpstet", fe71cf4d, 0, (), mve_vpt),
24500 ToC("vpstee", fe714f4d, 0, (), mve_vpt),
24501 ToC("vpstttt", fe312f4d, 0, (), mve_vpt),
24502 ToC("vpsttte", fe316f4d, 0, (), mve_vpt),
24503 ToC("vpsttet", fe31ef4d, 0, (), mve_vpt),
24504 ToC("vpsttee", fe31af4d, 0, (), mve_vpt),
24505 ToC("vpstett", fe71af4d, 0, (), mve_vpt),
24506 ToC("vpstete", fe71ef4d, 0, (), mve_vpt),
24507 ToC("vpsteet", fe716f4d, 0, (), mve_vpt),
24508 ToC("vpsteee", fe712f4d, 0, (), mve_vpt),
24509
a302e574 24510 /* MVE and MVE FP only. */
7df54120 24511 mToC("vhcadd", ee000f00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vhcadd),
c2dafc2a
AV
24512 mCEF(vadc, _vadc, 3, (RMQ, RMQ, RMQ), mve_vadc),
24513 mCEF(vadci, _vadci, 3, (RMQ, RMQ, RMQ), mve_vadc),
24514 mToC("vsbc", fe300f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
24515 mToC("vsbci", fe301f00, 3, (RMQ, RMQ, RMQ), mve_vsbc),
886e1c73 24516 mCEF(vmullb, _vmullb, 3, (RMQ, RMQ, RMQ), mve_vmull),
a302e574
AV
24517 mCEF(vabav, _vabav, 3, (RRnpcsp, RMQ, RMQ), mve_vabav),
24518 mCEF(vmladav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
24519 mCEF(vmladava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
24520 mCEF(vmladavx, _vmladavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
24521 mCEF(vmladavax, _vmladavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
24522 mCEF(vmlav, _vmladav, 3, (RRe, RMQ, RMQ), mve_vmladav),
24523 mCEF(vmlava, _vmladava, 3, (RRe, RMQ, RMQ), mve_vmladav),
24524 mCEF(vmlsdav, _vmlsdav, 3, (RRe, RMQ, RMQ), mve_vmladav),
24525 mCEF(vmlsdava, _vmlsdava, 3, (RRe, RMQ, RMQ), mve_vmladav),
24526 mCEF(vmlsdavx, _vmlsdavx, 3, (RRe, RMQ, RMQ), mve_vmladav),
24527 mCEF(vmlsdavax, _vmlsdavax, 3, (RRe, RMQ, RMQ), mve_vmladav),
24528
35c228db
AV
24529 mCEF(vst20, _vst20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
24530 mCEF(vst21, _vst21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
24531 mCEF(vst40, _vst40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24532 mCEF(vst41, _vst41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24533 mCEF(vst42, _vst42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24534 mCEF(vst43, _vst43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24535 mCEF(vld20, _vld20, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
24536 mCEF(vld21, _vld21, 2, (MSTRLST2, ADDRMVE), mve_vst_vld),
24537 mCEF(vld40, _vld40, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24538 mCEF(vld41, _vld41, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24539 mCEF(vld42, _vld42, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
24540 mCEF(vld43, _vld43, 2, (MSTRLST4, ADDRMVE), mve_vst_vld),
f5f10c66
AV
24541 mCEF(vstrb, _vstrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24542 mCEF(vstrh, _vstrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24543 mCEF(vstrw, _vstrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24544 mCEF(vstrd, _vstrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24545 mCEF(vldrb, _vldrb, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24546 mCEF(vldrh, _vldrh, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24547 mCEF(vldrw, _vldrw, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
24548 mCEF(vldrd, _vldrd, 2, (RMQ, ADDRMVE), mve_vstr_vldr),
35c228db 24549
57785aa2
AV
24550 mCEF(vmovnt, _vmovnt, 2, (RMQ, RMQ), mve_movn),
24551 mCEF(vmovnb, _vmovnb, 2, (RMQ, RMQ), mve_movn),
c2dafc2a 24552 mCEF(vbrsr, _vbrsr, 3, (RMQ, RMQ, RR), mve_vbrsr),
26c1e780
AV
24553 mCEF(vaddlv, _vaddlv, 3, (RRe, RRo, RMQ), mve_vaddlv),
24554 mCEF(vaddlva, _vaddlva, 3, (RRe, RRo, RMQ), mve_vaddlv),
24555 mCEF(vaddv, _vaddv, 2, (RRe, RMQ), mve_vaddv),
24556 mCEF(vaddva, _vaddva, 2, (RRe, RMQ), mve_vaddv),
b409bdb6
AV
24557 mCEF(vddup, _vddup, 3, (RMQ, RRe, EXPi), mve_viddup),
24558 mCEF(vdwdup, _vdwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
24559 mCEF(vidup, _vidup, 3, (RMQ, RRe, EXPi), mve_viddup),
24560 mCEF(viwdup, _viwdup, 4, (RMQ, RRe, RR, EXPi), mve_viddup),
935295b5
AV
24561 mToC("vmaxa", ee330e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
24562 mToC("vmina", ee331e81, 2, (RMQ, RMQ), mve_vmaxa_vmina),
13ccd4c0
AV
24563 mCEF(vmaxv, _vmaxv, 2, (RR, RMQ), mve_vmaxv),
24564 mCEF(vmaxav, _vmaxav, 2, (RR, RMQ), mve_vmaxv),
24565 mCEF(vminv, _vminv, 2, (RR, RMQ), mve_vmaxv),
24566 mCEF(vminav, _vminav, 2, (RR, RMQ), mve_vmaxv),
57785aa2 24567
93925576
AV
24568 mCEF(vmlaldav, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24569 mCEF(vmlaldava, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24570 mCEF(vmlaldavx, _vmlaldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24571 mCEF(vmlaldavax, _vmlaldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24572 mCEF(vmlalv, _vmlaldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24573 mCEF(vmlalva, _vmlaldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24574 mCEF(vmlsldav, _vmlsldav, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24575 mCEF(vmlsldava, _vmlsldava, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24576 mCEF(vmlsldavx, _vmlsldavx, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24577 mCEF(vmlsldavax, _vmlsldavax, 4, (RRe, RRo, RMQ, RMQ), mve_vmlaldav),
24578 mToC("vrmlaldavh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24579 mToC("vrmlaldavha",ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24580 mCEF(vrmlaldavhx, _vrmlaldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24581 mCEF(vrmlaldavhax, _vrmlaldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24582 mToC("vrmlalvh", ee800f00, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24583 mToC("vrmlalvha", ee800f20, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24584 mCEF(vrmlsldavh, _vrmlsldavh, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24585 mCEF(vrmlsldavha, _vrmlsldavha, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24586 mCEF(vrmlsldavhx, _vrmlsldavhx, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24587 mCEF(vrmlsldavhax, _vrmlsldavhax, 4, (RRe, RR, RMQ, RMQ), mve_vrmlaldavh),
24588
5d281bf0
AV
24589#undef THUMB_VARIANT
24590#define THUMB_VARIANT & mve_fp_ext
24591 mToC("vcmul", ee300e00, 4, (RMQ, RMQ, RMQ, EXPi), mve_vcmul),
f30ee27c 24592 mToC("vfmas", ee311e40, 3, (RMQ, RMQ, RR), mve_vfmas),
935295b5
AV
24593 mToC("vmaxnma", ee3f0e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
24594 mToC("vminnma", ee3f1e81, 2, (RMQ, RMQ), mve_vmaxnma_vminnma),
8cd78170
AV
24595 mToC("vmaxnmv", eeee0f00, 2, (RR, RMQ), mve_vmaxnmv),
24596 mToC("vmaxnmav",eeec0f00, 2, (RR, RMQ), mve_vmaxnmv),
24597 mToC("vminnmv", eeee0f80, 2, (RR, RMQ), mve_vmaxnmv),
24598 mToC("vminnmav",eeec0f80, 2, (RR, RMQ), mve_vmaxnmv),
5d281bf0 24599
5ee91343 24600#undef ARM_VARIANT
57785aa2 24601#define ARM_VARIANT & fpu_vfp_ext_v1
5ee91343
AV
24602#undef THUMB_VARIANT
24603#define THUMB_VARIANT & arm_ext_v6t2
24604
57785aa2
AV
24605 mcCE(fcpyd, eb00b40, 2, (RVD, RVD), vfp_dp_rd_rm),
24606
24607#undef ARM_VARIANT
24608#define ARM_VARIANT & fpu_vfp_ext_v1xd
24609
24610 MNCE(vmov, 0, 1, (VMOV), neon_mov),
24611 mcCE(fmrs, e100a10, 2, (RR, RVS), vfp_reg_from_sp),
24612 mcCE(fmsr, e000a10, 2, (RVS, RR), vfp_sp_from_reg),
24613 mcCE(fcpys, eb00a40, 2, (RVS, RVS), vfp_sp_monadic),
24614
886e1c73
AV
24615 mCEF(vmullt, _vmullt, 3, (RNSDQMQ, oRNSDQMQ, RNSDQ_RNSC_MQ), mve_vmull),
24616 mnCEF(vadd, _vadd, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
24617 mnCEF(vsub, _vsub, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQR), neon_addsub_if_i),
5ee91343 24618
485dee97
AV
24619 MNCEF(vabs, 1b10300, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
24620 MNCEF(vneg, 1b10380, 2, (RNSDQMQ, RNSDQMQ), neon_abs_neg),
24621
57785aa2
AV
24622 mCEF(vmovlt, _vmovlt, 1, (VMOV), mve_movl),
24623 mCEF(vmovlb, _vmovlb, 1, (VMOV), mve_movl),
24624
1b883319
AV
24625 mnCE(vcmp, _vcmp, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
24626 mnCE(vcmpe, _vcmpe, 3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ), vfp_nsyn_cmp),
24627
57785aa2
AV
24628#undef ARM_VARIANT
24629#define ARM_VARIANT & fpu_vfp_ext_v2
24630
24631 mcCE(fmsrr, c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
24632 mcCE(fmrrs, c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
24633 mcCE(fmdrr, c400b10, 3, (RVD, RR, RR), vfp_dp_rm_rd_rn),
24634 mcCE(fmrrd, c500b10, 3, (RR, RR, RVD), vfp_dp_rd_rn_rm),
24635
dd9634d9
AV
24636#undef ARM_VARIANT
24637#define ARM_VARIANT & fpu_vfp_ext_armv8xd
24638 mnUF(vcvta, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvta),
24639 mnUF(vcvtp, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtp),
24640 mnUF(vcvtn, _vcvta, 3, (RNSDQMQ, oRNSDQMQ, oI32z), neon_cvtn),
24641 mnUF(vcvtm, _vcvta, 2, (RNSDQMQ, oRNSDQMQ), neon_cvtm),
935295b5
AV
24642 mnUF(vmaxnm, _vmaxnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
24643 mnUF(vminnm, _vminnm, 3, (RNSDQMQ, oRNSDQMQ, RNSDQMQ), vmaxnm),
dd9634d9
AV
24644
24645#undef ARM_VARIANT
5ee91343 24646#define ARM_VARIANT & fpu_neon_ext_v1
f601a00c 24647 mnUF(vabd, _vabd, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
5ee91343
AV
24648 mnUF(vabdl, _vabdl, 3, (RNQMQ, RNDMQ, RNDMQ), neon_dyadic_long),
24649 mnUF(vaddl, _vaddl, 3, (RNQMQ, RNDMQ, RNDMQR), neon_dyadic_long),
24650 mnUF(vsubl, _vsubl, 3, (RNQMQ, RNDMQ, RNDMQR), neon_dyadic_long),
f601a00c
AV
24651 mnUF(vand, _vand, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
24652 mnUF(vbic, _vbic, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
24653 mnUF(vorr, _vorr, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
24654 mnUF(vorn, _vorn, 3, (RNDQMQ, oRNDQMQ, RNDQMQ_Ibig), neon_logic),
24655 mnUF(veor, _veor, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_logic),
f30ee27c
AV
24656 MNUF(vcls, 1b00400, 2, (RNDQMQ, RNDQMQ), neon_cls),
24657 MNUF(vclz, 1b00480, 2, (RNDQMQ, RNDQMQ), neon_clz),
b409bdb6 24658 mnCE(vdup, _vdup, 2, (RNDQMQ, RR_RNSC), neon_dup),
7df54120
AV
24659 MNUF(vhadd, 00000000, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
24660 MNUF(vrhadd, 00000100, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_i_su),
24661 MNUF(vhsub, 00000200, 3, (RNDQMQ, oRNDQMQ, RNDQMQR), neon_dyadic_i_su),
935295b5
AV
24662 mnUF(vmin, _vmin, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
24663 mnUF(vmax, _vmax, 3, (RNDQMQ, oRNDQMQ, RNDQMQ), neon_dyadic_if_su),
5d281bf0
AV
24664
24665#undef ARM_VARIANT
24666#define ARM_VARIANT & arm_ext_v8_3
24667#undef THUMB_VARIANT
24668#define THUMB_VARIANT & arm_ext_v6t2_v8m
24669 MNUF (vcadd, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ, EXPi), vcadd),
24670 MNUF (vcmla, 0, 4, (RNDQMQ, RNDQMQ, RNDQMQ_RNSC, EXPi), vcmla),
c19d1205
ZW
24671};
24672#undef ARM_VARIANT
24673#undef THUMB_VARIANT
24674#undef TCE
c19d1205
ZW
24675#undef TUE
24676#undef TUF
24677#undef TCC
8f06b2d8 24678#undef cCE
e3cb604e
PB
24679#undef cCL
24680#undef C3E
4389b29a 24681#undef C3
c19d1205
ZW
24682#undef CE
24683#undef CM
4389b29a 24684#undef CL
c19d1205
ZW
24685#undef UE
24686#undef UF
24687#undef UT
5287ad62
JB
24688#undef NUF
24689#undef nUF
24690#undef NCE
24691#undef nCE
c19d1205
ZW
24692#undef OPS0
24693#undef OPS1
24694#undef OPS2
24695#undef OPS3
24696#undef OPS4
24697#undef OPS5
24698#undef OPS6
24699#undef do_0
4389b29a
AV
24700#undef ToC
24701#undef toC
24702#undef ToU
f6b2b12d 24703#undef toU
c19d1205
ZW
24704\f
24705/* MD interface: bits in the object file. */
bfae80f2 24706
c19d1205
ZW
24707/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
24708 for use in the a.out file, and stores them in the array pointed to by buf.
24709 This knows about the endian-ness of the target machine and does
24710 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
24711 2 (short) and 4 (long) Floating numbers are put out as a series of
24712 LITTLENUMS (shorts, here at least). */
b99bd4ef 24713
c19d1205
ZW
24714void
24715md_number_to_chars (char * buf, valueT val, int n)
24716{
24717 if (target_big_endian)
24718 number_to_chars_bigendian (buf, val, n);
24719 else
24720 number_to_chars_littleendian (buf, val, n);
bfae80f2
RE
24721}
24722
c19d1205
ZW
24723static valueT
24724md_chars_to_number (char * buf, int n)
bfae80f2 24725{
c19d1205
ZW
24726 valueT result = 0;
24727 unsigned char * where = (unsigned char *) buf;
bfae80f2 24728
c19d1205 24729 if (target_big_endian)
b99bd4ef 24730 {
c19d1205
ZW
24731 while (n--)
24732 {
24733 result <<= 8;
24734 result |= (*where++ & 255);
24735 }
b99bd4ef 24736 }
c19d1205 24737 else
b99bd4ef 24738 {
c19d1205
ZW
24739 while (n--)
24740 {
24741 result <<= 8;
24742 result |= (where[n] & 255);
24743 }
bfae80f2 24744 }
b99bd4ef 24745
c19d1205 24746 return result;
bfae80f2 24747}
b99bd4ef 24748
c19d1205 24749/* MD interface: Sections. */
b99bd4ef 24750
fa94de6b
RM
24751/* Calculate the maximum variable size (i.e., excluding fr_fix)
24752 that an rs_machine_dependent frag may reach. */
24753
24754unsigned int
24755arm_frag_max_var (fragS *fragp)
24756{
24757 /* We only use rs_machine_dependent for variable-size Thumb instructions,
24758 which are either THUMB_SIZE (2) or INSN_SIZE (4).
24759
24760 Note that we generate relaxable instructions even for cases that don't
24761 really need it, like an immediate that's a trivial constant. So we're
24762 overestimating the instruction size for some of those cases. Rather
24763 than putting more intelligence here, it would probably be better to
24764 avoid generating a relaxation frag in the first place when it can be
24765 determined up front that a short instruction will suffice. */
24766
24767 gas_assert (fragp->fr_type == rs_machine_dependent);
24768 return INSN_SIZE;
24769}
24770
0110f2b8
PB
24771/* Estimate the size of a frag before relaxing. Assume everything fits in
24772 2 bytes. */
24773
c19d1205 24774int
0110f2b8 24775md_estimate_size_before_relax (fragS * fragp,
c19d1205
ZW
24776 segT segtype ATTRIBUTE_UNUSED)
24777{
0110f2b8
PB
24778 fragp->fr_var = 2;
24779 return 2;
24780}
24781
24782/* Convert a machine dependent frag. */
24783
24784void
24785md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
24786{
24787 unsigned long insn;
24788 unsigned long old_op;
24789 char *buf;
24790 expressionS exp;
24791 fixS *fixp;
24792 int reloc_type;
24793 int pc_rel;
24794 int opcode;
24795
24796 buf = fragp->fr_literal + fragp->fr_fix;
24797
24798 old_op = bfd_get_16(abfd, buf);
5f4273c7
NC
24799 if (fragp->fr_symbol)
24800 {
0110f2b8
PB
24801 exp.X_op = O_symbol;
24802 exp.X_add_symbol = fragp->fr_symbol;
5f4273c7
NC
24803 }
24804 else
24805 {
0110f2b8 24806 exp.X_op = O_constant;
5f4273c7 24807 }
0110f2b8
PB
24808 exp.X_add_number = fragp->fr_offset;
24809 opcode = fragp->fr_subtype;
24810 switch (opcode)
24811 {
24812 case T_MNEM_ldr_pc:
24813 case T_MNEM_ldr_pc2:
24814 case T_MNEM_ldr_sp:
24815 case T_MNEM_str_sp:
24816 case T_MNEM_ldr:
24817 case T_MNEM_ldrb:
24818 case T_MNEM_ldrh:
24819 case T_MNEM_str:
24820 case T_MNEM_strb:
24821 case T_MNEM_strh:
24822 if (fragp->fr_var == 4)
24823 {
5f4273c7 24824 insn = THUMB_OP32 (opcode);
0110f2b8
PB
24825 if ((old_op >> 12) == 4 || (old_op >> 12) == 9)
24826 {
24827 insn |= (old_op & 0x700) << 4;
24828 }
24829 else
24830 {
24831 insn |= (old_op & 7) << 12;
24832 insn |= (old_op & 0x38) << 13;
24833 }
24834 insn |= 0x00000c00;
24835 put_thumb32_insn (buf, insn);
24836 reloc_type = BFD_RELOC_ARM_T32_OFFSET_IMM;
24837 }
24838 else
24839 {
24840 reloc_type = BFD_RELOC_ARM_THUMB_OFFSET;
24841 }
24842 pc_rel = (opcode == T_MNEM_ldr_pc2);
24843 break;
24844 case T_MNEM_adr:
24845 if (fragp->fr_var == 4)
24846 {
24847 insn = THUMB_OP32 (opcode);
24848 insn |= (old_op & 0xf0) << 4;
24849 put_thumb32_insn (buf, insn);
24850 reloc_type = BFD_RELOC_ARM_T32_ADD_PC12;
24851 }
24852 else
24853 {
24854 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
24855 exp.X_add_number -= 4;
24856 }
24857 pc_rel = 1;
24858 break;
24859 case T_MNEM_mov:
24860 case T_MNEM_movs:
24861 case T_MNEM_cmp:
24862 case T_MNEM_cmn:
24863 if (fragp->fr_var == 4)
24864 {
24865 int r0off = (opcode == T_MNEM_mov
24866 || opcode == T_MNEM_movs) ? 0 : 8;
24867 insn = THUMB_OP32 (opcode);
24868 insn = (insn & 0xe1ffffff) | 0x10000000;
24869 insn |= (old_op & 0x700) << r0off;
24870 put_thumb32_insn (buf, insn);
24871 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
24872 }
24873 else
24874 {
24875 reloc_type = BFD_RELOC_ARM_THUMB_IMM;
24876 }
24877 pc_rel = 0;
24878 break;
24879 case T_MNEM_b:
24880 if (fragp->fr_var == 4)
24881 {
24882 insn = THUMB_OP32(opcode);
24883 put_thumb32_insn (buf, insn);
24884 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH25;
24885 }
24886 else
24887 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH12;
24888 pc_rel = 1;
24889 break;
24890 case T_MNEM_bcond:
24891 if (fragp->fr_var == 4)
24892 {
24893 insn = THUMB_OP32(opcode);
24894 insn |= (old_op & 0xf00) << 14;
24895 put_thumb32_insn (buf, insn);
24896 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH20;
24897 }
24898 else
24899 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH9;
24900 pc_rel = 1;
24901 break;
24902 case T_MNEM_add_sp:
24903 case T_MNEM_add_pc:
24904 case T_MNEM_inc_sp:
24905 case T_MNEM_dec_sp:
24906 if (fragp->fr_var == 4)
24907 {
24908 /* ??? Choose between add and addw. */
24909 insn = THUMB_OP32 (opcode);
24910 insn |= (old_op & 0xf0) << 4;
24911 put_thumb32_insn (buf, insn);
16805f35
PB
24912 if (opcode == T_MNEM_add_pc)
24913 reloc_type = BFD_RELOC_ARM_T32_IMM12;
24914 else
24915 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
0110f2b8
PB
24916 }
24917 else
24918 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
24919 pc_rel = 0;
24920 break;
24921
24922 case T_MNEM_addi:
24923 case T_MNEM_addis:
24924 case T_MNEM_subi:
24925 case T_MNEM_subis:
24926 if (fragp->fr_var == 4)
24927 {
24928 insn = THUMB_OP32 (opcode);
24929 insn |= (old_op & 0xf0) << 4;
24930 insn |= (old_op & 0xf) << 16;
24931 put_thumb32_insn (buf, insn);
16805f35
PB
24932 if (insn & (1 << 20))
24933 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
24934 else
24935 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8
PB
24936 }
24937 else
24938 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
24939 pc_rel = 0;
24940 break;
24941 default:
5f4273c7 24942 abort ();
0110f2b8
PB
24943 }
24944 fixp = fix_new_exp (fragp, fragp->fr_fix, fragp->fr_var, &exp, pc_rel,
21d799b5 24945 (enum bfd_reloc_code_real) reloc_type);
0110f2b8
PB
24946 fixp->fx_file = fragp->fr_file;
24947 fixp->fx_line = fragp->fr_line;
24948 fragp->fr_fix += fragp->fr_var;
3cfdb781
TG
24949
24950 /* Set whether we use thumb-2 ISA based on final relaxation results. */
24951 if (thumb_mode && fragp->fr_var == 4 && no_cpu_selected ()
24952 && !ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2))
24953 ARM_MERGE_FEATURE_SETS (arm_arch_used, thumb_arch_used, arm_ext_v6t2);
0110f2b8
PB
24954}
24955
24956/* Return the size of a relaxable immediate operand instruction.
24957 SHIFT and SIZE specify the form of the allowable immediate. */
24958static int
24959relax_immediate (fragS *fragp, int size, int shift)
24960{
24961 offsetT offset;
24962 offsetT mask;
24963 offsetT low;
24964
24965 /* ??? Should be able to do better than this. */
24966 if (fragp->fr_symbol)
24967 return 4;
24968
24969 low = (1 << shift) - 1;
24970 mask = (1 << (shift + size)) - (1 << shift);
24971 offset = fragp->fr_offset;
24972 /* Force misaligned offsets to 32-bit variant. */
24973 if (offset & low)
5e77afaa 24974 return 4;
0110f2b8
PB
24975 if (offset & ~mask)
24976 return 4;
24977 return 2;
24978}
24979
5e77afaa
PB
24980/* Get the address of a symbol during relaxation. */
24981static addressT
5f4273c7 24982relaxed_symbol_addr (fragS *fragp, long stretch)
5e77afaa
PB
24983{
24984 fragS *sym_frag;
24985 addressT addr;
24986 symbolS *sym;
24987
24988 sym = fragp->fr_symbol;
24989 sym_frag = symbol_get_frag (sym);
24990 know (S_GET_SEGMENT (sym) != absolute_section
24991 || sym_frag == &zero_address_frag);
24992 addr = S_GET_VALUE (sym) + fragp->fr_offset;
24993
24994 /* If frag has yet to be reached on this pass, assume it will
24995 move by STRETCH just as we did. If this is not so, it will
24996 be because some frag between grows, and that will force
24997 another pass. */
24998
24999 if (stretch != 0
25000 && sym_frag->relax_marker != fragp->relax_marker)
4396b686
PB
25001 {
25002 fragS *f;
25003
25004 /* Adjust stretch for any alignment frag. Note that if have
25005 been expanding the earlier code, the symbol may be
25006 defined in what appears to be an earlier frag. FIXME:
25007 This doesn't handle the fr_subtype field, which specifies
25008 a maximum number of bytes to skip when doing an
25009 alignment. */
25010 for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
25011 {
25012 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
25013 {
25014 if (stretch < 0)
25015 stretch = - ((- stretch)
25016 & ~ ((1 << (int) f->fr_offset) - 1));
25017 else
25018 stretch &= ~ ((1 << (int) f->fr_offset) - 1);
25019 if (stretch == 0)
25020 break;
25021 }
25022 }
25023 if (f != NULL)
25024 addr += stretch;
25025 }
5e77afaa
PB
25026
25027 return addr;
25028}
25029
0110f2b8
PB
25030/* Return the size of a relaxable adr pseudo-instruction or PC-relative
25031 load. */
25032static int
5e77afaa 25033relax_adr (fragS *fragp, asection *sec, long stretch)
0110f2b8
PB
25034{
25035 addressT addr;
25036 offsetT val;
25037
25038 /* Assume worst case for symbols not known to be in the same section. */
974da60d
NC
25039 if (fragp->fr_symbol == NULL
25040 || !S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
25041 || sec != S_GET_SEGMENT (fragp->fr_symbol)
25042 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
25043 return 4;
25044
5f4273c7 25045 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
25046 addr = fragp->fr_address + fragp->fr_fix;
25047 addr = (addr + 4) & ~3;
5e77afaa 25048 /* Force misaligned targets to 32-bit variant. */
0110f2b8 25049 if (val & 3)
5e77afaa 25050 return 4;
0110f2b8
PB
25051 val -= addr;
25052 if (val < 0 || val > 1020)
25053 return 4;
25054 return 2;
25055}
25056
25057/* Return the size of a relaxable add/sub immediate instruction. */
25058static int
25059relax_addsub (fragS *fragp, asection *sec)
25060{
25061 char *buf;
25062 int op;
25063
25064 buf = fragp->fr_literal + fragp->fr_fix;
25065 op = bfd_get_16(sec->owner, buf);
25066 if ((op & 0xf) == ((op >> 4) & 0xf))
25067 return relax_immediate (fragp, 8, 0);
25068 else
25069 return relax_immediate (fragp, 3, 0);
25070}
25071
e83a675f
RE
25072/* Return TRUE iff the definition of symbol S could be pre-empted
25073 (overridden) at link or load time. */
25074static bfd_boolean
25075symbol_preemptible (symbolS *s)
25076{
25077 /* Weak symbols can always be pre-empted. */
25078 if (S_IS_WEAK (s))
25079 return TRUE;
25080
25081 /* Non-global symbols cannot be pre-empted. */
25082 if (! S_IS_EXTERNAL (s))
25083 return FALSE;
25084
25085#ifdef OBJ_ELF
25086 /* In ELF, a global symbol can be marked protected, or private. In that
25087 case it can't be pre-empted (other definitions in the same link unit
25088 would violate the ODR). */
25089 if (ELF_ST_VISIBILITY (S_GET_OTHER (s)) > STV_DEFAULT)
25090 return FALSE;
25091#endif
25092
25093 /* Other global symbols might be pre-empted. */
25094 return TRUE;
25095}
0110f2b8
PB
25096
25097/* Return the size of a relaxable branch instruction. BITS is the
25098 size of the offset field in the narrow instruction. */
25099
25100static int
5e77afaa 25101relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
0110f2b8
PB
25102{
25103 addressT addr;
25104 offsetT val;
25105 offsetT limit;
25106
25107 /* Assume worst case for symbols not known to be in the same section. */
5f4273c7 25108 if (!S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
25109 || sec != S_GET_SEGMENT (fragp->fr_symbol)
25110 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
25111 return 4;
25112
267bf995 25113#ifdef OBJ_ELF
e83a675f 25114 /* A branch to a function in ARM state will require interworking. */
267bf995
RR
25115 if (S_IS_DEFINED (fragp->fr_symbol)
25116 && ARM_IS_FUNC (fragp->fr_symbol))
25117 return 4;
e83a675f 25118#endif
0d9b4b55 25119
e83a675f 25120 if (symbol_preemptible (fragp->fr_symbol))
0d9b4b55 25121 return 4;
267bf995 25122
5f4273c7 25123 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
25124 addr = fragp->fr_address + fragp->fr_fix + 4;
25125 val -= addr;
25126
25127 /* Offset is a signed value *2 */
25128 limit = 1 << bits;
25129 if (val >= limit || val < -limit)
25130 return 4;
25131 return 2;
25132}
25133
25134
25135/* Relax a machine dependent frag. This returns the amount by which
25136 the current size of the frag should change. */
25137
25138int
5e77afaa 25139arm_relax_frag (asection *sec, fragS *fragp, long stretch)
0110f2b8
PB
25140{
25141 int oldsize;
25142 int newsize;
25143
25144 oldsize = fragp->fr_var;
25145 switch (fragp->fr_subtype)
25146 {
25147 case T_MNEM_ldr_pc2:
5f4273c7 25148 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
25149 break;
25150 case T_MNEM_ldr_pc:
25151 case T_MNEM_ldr_sp:
25152 case T_MNEM_str_sp:
5f4273c7 25153 newsize = relax_immediate (fragp, 8, 2);
0110f2b8
PB
25154 break;
25155 case T_MNEM_ldr:
25156 case T_MNEM_str:
5f4273c7 25157 newsize = relax_immediate (fragp, 5, 2);
0110f2b8
PB
25158 break;
25159 case T_MNEM_ldrh:
25160 case T_MNEM_strh:
5f4273c7 25161 newsize = relax_immediate (fragp, 5, 1);
0110f2b8
PB
25162 break;
25163 case T_MNEM_ldrb:
25164 case T_MNEM_strb:
5f4273c7 25165 newsize = relax_immediate (fragp, 5, 0);
0110f2b8
PB
25166 break;
25167 case T_MNEM_adr:
5f4273c7 25168 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
25169 break;
25170 case T_MNEM_mov:
25171 case T_MNEM_movs:
25172 case T_MNEM_cmp:
25173 case T_MNEM_cmn:
5f4273c7 25174 newsize = relax_immediate (fragp, 8, 0);
0110f2b8
PB
25175 break;
25176 case T_MNEM_b:
5f4273c7 25177 newsize = relax_branch (fragp, sec, 11, stretch);
0110f2b8
PB
25178 break;
25179 case T_MNEM_bcond:
5f4273c7 25180 newsize = relax_branch (fragp, sec, 8, stretch);
0110f2b8
PB
25181 break;
25182 case T_MNEM_add_sp:
25183 case T_MNEM_add_pc:
25184 newsize = relax_immediate (fragp, 8, 2);
25185 break;
25186 case T_MNEM_inc_sp:
25187 case T_MNEM_dec_sp:
25188 newsize = relax_immediate (fragp, 7, 2);
25189 break;
25190 case T_MNEM_addi:
25191 case T_MNEM_addis:
25192 case T_MNEM_subi:
25193 case T_MNEM_subis:
25194 newsize = relax_addsub (fragp, sec);
25195 break;
25196 default:
5f4273c7 25197 abort ();
0110f2b8 25198 }
5e77afaa
PB
25199
25200 fragp->fr_var = newsize;
25201 /* Freeze wide instructions that are at or before the same location as
25202 in the previous pass. This avoids infinite loops.
5f4273c7
NC
25203 Don't freeze them unconditionally because targets may be artificially
25204 misaligned by the expansion of preceding frags. */
5e77afaa 25205 if (stretch <= 0 && newsize > 2)
0110f2b8 25206 {
0110f2b8 25207 md_convert_frag (sec->owner, sec, fragp);
5f4273c7 25208 frag_wane (fragp);
0110f2b8 25209 }
5e77afaa 25210
0110f2b8 25211 return newsize - oldsize;
c19d1205 25212}
b99bd4ef 25213
c19d1205 25214/* Round up a section size to the appropriate boundary. */
b99bd4ef 25215
c19d1205
ZW
25216valueT
25217md_section_align (segT segment ATTRIBUTE_UNUSED,
25218 valueT size)
25219{
6844c0cc 25220 return size;
bfae80f2 25221}
b99bd4ef 25222
c19d1205
ZW
25223/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
25224 of an rs_align_code fragment. */
25225
25226void
25227arm_handle_align (fragS * fragP)
bfae80f2 25228{
d9235011 25229 static unsigned char const arm_noop[2][2][4] =
e7495e45
NS
25230 {
25231 { /* ARMv1 */
25232 {0x00, 0x00, 0xa0, 0xe1}, /* LE */
25233 {0xe1, 0xa0, 0x00, 0x00}, /* BE */
25234 },
25235 { /* ARMv6k */
25236 {0x00, 0xf0, 0x20, 0xe3}, /* LE */
25237 {0xe3, 0x20, 0xf0, 0x00}, /* BE */
25238 },
25239 };
d9235011 25240 static unsigned char const thumb_noop[2][2][2] =
e7495e45
NS
25241 {
25242 { /* Thumb-1 */
25243 {0xc0, 0x46}, /* LE */
25244 {0x46, 0xc0}, /* BE */
25245 },
25246 { /* Thumb-2 */
25247 {0x00, 0xbf}, /* LE */
25248 {0xbf, 0x00} /* BE */
25249 }
25250 };
d9235011 25251 static unsigned char const wide_thumb_noop[2][4] =
e7495e45
NS
25252 { /* Wide Thumb-2 */
25253 {0xaf, 0xf3, 0x00, 0x80}, /* LE */
25254 {0xf3, 0xaf, 0x80, 0x00}, /* BE */
25255 };
c921be7d 25256
e7495e45 25257 unsigned bytes, fix, noop_size;
c19d1205 25258 char * p;
d9235011
TS
25259 const unsigned char * noop;
25260 const unsigned char *narrow_noop = NULL;
cd000bff
DJ
25261#ifdef OBJ_ELF
25262 enum mstate state;
25263#endif
bfae80f2 25264
c19d1205 25265 if (fragP->fr_type != rs_align_code)
bfae80f2
RE
25266 return;
25267
c19d1205
ZW
25268 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
25269 p = fragP->fr_literal + fragP->fr_fix;
25270 fix = 0;
bfae80f2 25271
c19d1205
ZW
25272 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
25273 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
bfae80f2 25274
cd000bff 25275 gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
8dc2430f 25276
cd000bff 25277 if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
a737bd4d 25278 {
7f78eb34
JW
25279 if (ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
25280 ? selected_cpu : arm_arch_none, arm_ext_v6t2))
e7495e45
NS
25281 {
25282 narrow_noop = thumb_noop[1][target_big_endian];
25283 noop = wide_thumb_noop[target_big_endian];
25284 }
c19d1205 25285 else
e7495e45
NS
25286 noop = thumb_noop[0][target_big_endian];
25287 noop_size = 2;
cd000bff
DJ
25288#ifdef OBJ_ELF
25289 state = MAP_THUMB;
25290#endif
7ed4c4c5
NC
25291 }
25292 else
25293 {
7f78eb34
JW
25294 noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
25295 ? selected_cpu : arm_arch_none,
25296 arm_ext_v6k) != 0]
e7495e45
NS
25297 [target_big_endian];
25298 noop_size = 4;
cd000bff
DJ
25299#ifdef OBJ_ELF
25300 state = MAP_ARM;
25301#endif
7ed4c4c5 25302 }
c921be7d 25303
e7495e45 25304 fragP->fr_var = noop_size;
c921be7d 25305
c19d1205 25306 if (bytes & (noop_size - 1))
7ed4c4c5 25307 {
c19d1205 25308 fix = bytes & (noop_size - 1);
cd000bff
DJ
25309#ifdef OBJ_ELF
25310 insert_data_mapping_symbol (state, fragP->fr_fix, fragP, fix);
25311#endif
c19d1205
ZW
25312 memset (p, 0, fix);
25313 p += fix;
25314 bytes -= fix;
a737bd4d 25315 }
a737bd4d 25316
e7495e45
NS
25317 if (narrow_noop)
25318 {
25319 if (bytes & noop_size)
25320 {
25321 /* Insert a narrow noop. */
25322 memcpy (p, narrow_noop, noop_size);
25323 p += noop_size;
25324 bytes -= noop_size;
25325 fix += noop_size;
25326 }
25327
25328 /* Use wide noops for the remainder */
25329 noop_size = 4;
25330 }
25331
c19d1205 25332 while (bytes >= noop_size)
a737bd4d 25333 {
c19d1205
ZW
25334 memcpy (p, noop, noop_size);
25335 p += noop_size;
25336 bytes -= noop_size;
25337 fix += noop_size;
a737bd4d
NC
25338 }
25339
c19d1205 25340 fragP->fr_fix += fix;
a737bd4d
NC
25341}
25342
c19d1205
ZW
25343/* Called from md_do_align. Used to create an alignment
25344 frag in a code section. */
25345
25346void
25347arm_frag_align_code (int n, int max)
bfae80f2 25348{
c19d1205 25349 char * p;
7ed4c4c5 25350
c19d1205 25351 /* We assume that there will never be a requirement
6ec8e702 25352 to support alignments greater than MAX_MEM_FOR_RS_ALIGN_CODE bytes. */
c19d1205 25353 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
6ec8e702
NC
25354 {
25355 char err_msg[128];
25356
fa94de6b 25357 sprintf (err_msg,
477330fc
RM
25358 _("alignments greater than %d bytes not supported in .text sections."),
25359 MAX_MEM_FOR_RS_ALIGN_CODE + 1);
20203fb9 25360 as_fatal ("%s", err_msg);
6ec8e702 25361 }
bfae80f2 25362
c19d1205
ZW
25363 p = frag_var (rs_align_code,
25364 MAX_MEM_FOR_RS_ALIGN_CODE,
25365 1,
25366 (relax_substateT) max,
25367 (symbolS *) NULL,
25368 (offsetT) n,
25369 (char *) NULL);
25370 *p = 0;
25371}
bfae80f2 25372
8dc2430f
NC
25373/* Perform target specific initialisation of a frag.
25374 Note - despite the name this initialisation is not done when the frag
25375 is created, but only when its type is assigned. A frag can be created
25376 and used a long time before its type is set, so beware of assuming that
33eaf5de 25377 this initialisation is performed first. */
bfae80f2 25378
cd000bff
DJ
25379#ifndef OBJ_ELF
25380void
25381arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
25382{
25383 /* Record whether this frag is in an ARM or a THUMB area. */
2e98972e 25384 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
cd000bff
DJ
25385}
25386
25387#else /* OBJ_ELF is defined. */
c19d1205 25388void
cd000bff 25389arm_init_frag (fragS * fragP, int max_chars)
c19d1205 25390{
e8d84ca1 25391 bfd_boolean frag_thumb_mode;
b968d18a 25392
8dc2430f
NC
25393 /* If the current ARM vs THUMB mode has not already
25394 been recorded into this frag then do so now. */
cd000bff 25395 if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
b968d18a
JW
25396 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
25397
e8d84ca1
NC
25398 /* PR 21809: Do not set a mapping state for debug sections
25399 - it just confuses other tools. */
25400 if (bfd_get_section_flags (NULL, now_seg) & SEC_DEBUGGING)
25401 return;
25402
b968d18a 25403 frag_thumb_mode = fragP->tc_frag_data.thumb_mode ^ MODE_RECORDED;
cd000bff 25404
f9c1b181
RL
25405 /* Record a mapping symbol for alignment frags. We will delete this
25406 later if the alignment ends up empty. */
25407 switch (fragP->fr_type)
25408 {
25409 case rs_align:
25410 case rs_align_test:
25411 case rs_fill:
25412 mapping_state_2 (MAP_DATA, max_chars);
25413 break;
25414 case rs_align_code:
b968d18a 25415 mapping_state_2 (frag_thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
f9c1b181
RL
25416 break;
25417 default:
25418 break;
cd000bff 25419 }
bfae80f2
RE
25420}
25421
c19d1205
ZW
25422/* When we change sections we need to issue a new mapping symbol. */
25423
25424void
25425arm_elf_change_section (void)
bfae80f2 25426{
c19d1205
ZW
25427 /* Link an unlinked unwind index table section to the .text section. */
25428 if (elf_section_type (now_seg) == SHT_ARM_EXIDX
25429 && elf_linked_to_section (now_seg) == NULL)
25430 elf_linked_to_section (now_seg) = text_section;
bfae80f2
RE
25431}
25432
c19d1205
ZW
25433int
25434arm_elf_section_type (const char * str, size_t len)
e45d0630 25435{
c19d1205
ZW
25436 if (len == 5 && strncmp (str, "exidx", 5) == 0)
25437 return SHT_ARM_EXIDX;
e45d0630 25438
c19d1205
ZW
25439 return -1;
25440}
25441\f
25442/* Code to deal with unwinding tables. */
e45d0630 25443
c19d1205 25444static void add_unwind_adjustsp (offsetT);
e45d0630 25445
5f4273c7 25446/* Generate any deferred unwind frame offset. */
e45d0630 25447
bfae80f2 25448static void
c19d1205 25449flush_pending_unwind (void)
bfae80f2 25450{
c19d1205 25451 offsetT offset;
bfae80f2 25452
c19d1205
ZW
25453 offset = unwind.pending_offset;
25454 unwind.pending_offset = 0;
25455 if (offset != 0)
25456 add_unwind_adjustsp (offset);
bfae80f2
RE
25457}
25458
c19d1205
ZW
25459/* Add an opcode to this list for this function. Two-byte opcodes should
25460 be passed as op[0] << 8 | op[1]. The list of opcodes is built in reverse
25461 order. */
25462
bfae80f2 25463static void
c19d1205 25464add_unwind_opcode (valueT op, int length)
bfae80f2 25465{
c19d1205
ZW
25466 /* Add any deferred stack adjustment. */
25467 if (unwind.pending_offset)
25468 flush_pending_unwind ();
bfae80f2 25469
c19d1205 25470 unwind.sp_restored = 0;
bfae80f2 25471
c19d1205 25472 if (unwind.opcode_count + length > unwind.opcode_alloc)
bfae80f2 25473 {
c19d1205
ZW
25474 unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
25475 if (unwind.opcodes)
325801bd
TS
25476 unwind.opcodes = XRESIZEVEC (unsigned char, unwind.opcodes,
25477 unwind.opcode_alloc);
c19d1205 25478 else
325801bd 25479 unwind.opcodes = XNEWVEC (unsigned char, unwind.opcode_alloc);
bfae80f2 25480 }
c19d1205 25481 while (length > 0)
bfae80f2 25482 {
c19d1205
ZW
25483 length--;
25484 unwind.opcodes[unwind.opcode_count] = op & 0xff;
25485 op >>= 8;
25486 unwind.opcode_count++;
bfae80f2 25487 }
bfae80f2
RE
25488}
25489
c19d1205
ZW
25490/* Add unwind opcodes to adjust the stack pointer. */
25491
bfae80f2 25492static void
c19d1205 25493add_unwind_adjustsp (offsetT offset)
bfae80f2 25494{
c19d1205 25495 valueT op;
bfae80f2 25496
c19d1205 25497 if (offset > 0x200)
bfae80f2 25498 {
c19d1205
ZW
25499 /* We need at most 5 bytes to hold a 32-bit value in a uleb128. */
25500 char bytes[5];
25501 int n;
25502 valueT o;
bfae80f2 25503
c19d1205
ZW
25504 /* Long form: 0xb2, uleb128. */
25505 /* This might not fit in a word so add the individual bytes,
25506 remembering the list is built in reverse order. */
25507 o = (valueT) ((offset - 0x204) >> 2);
25508 if (o == 0)
25509 add_unwind_opcode (0, 1);
bfae80f2 25510
c19d1205
ZW
25511 /* Calculate the uleb128 encoding of the offset. */
25512 n = 0;
25513 while (o)
25514 {
25515 bytes[n] = o & 0x7f;
25516 o >>= 7;
25517 if (o)
25518 bytes[n] |= 0x80;
25519 n++;
25520 }
25521 /* Add the insn. */
25522 for (; n; n--)
25523 add_unwind_opcode (bytes[n - 1], 1);
25524 add_unwind_opcode (0xb2, 1);
25525 }
25526 else if (offset > 0x100)
bfae80f2 25527 {
c19d1205
ZW
25528 /* Two short opcodes. */
25529 add_unwind_opcode (0x3f, 1);
25530 op = (offset - 0x104) >> 2;
25531 add_unwind_opcode (op, 1);
bfae80f2 25532 }
c19d1205
ZW
25533 else if (offset > 0)
25534 {
25535 /* Short opcode. */
25536 op = (offset - 4) >> 2;
25537 add_unwind_opcode (op, 1);
25538 }
25539 else if (offset < 0)
bfae80f2 25540 {
c19d1205
ZW
25541 offset = -offset;
25542 while (offset > 0x100)
bfae80f2 25543 {
c19d1205
ZW
25544 add_unwind_opcode (0x7f, 1);
25545 offset -= 0x100;
bfae80f2 25546 }
c19d1205
ZW
25547 op = ((offset - 4) >> 2) | 0x40;
25548 add_unwind_opcode (op, 1);
bfae80f2 25549 }
bfae80f2
RE
25550}
25551
c19d1205 25552/* Finish the list of unwind opcodes for this function. */
0198d5e6 25553
c19d1205
ZW
25554static void
25555finish_unwind_opcodes (void)
bfae80f2 25556{
c19d1205 25557 valueT op;
bfae80f2 25558
c19d1205 25559 if (unwind.fp_used)
bfae80f2 25560 {
708587a4 25561 /* Adjust sp as necessary. */
c19d1205
ZW
25562 unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
25563 flush_pending_unwind ();
bfae80f2 25564
c19d1205
ZW
25565 /* After restoring sp from the frame pointer. */
25566 op = 0x90 | unwind.fp_reg;
25567 add_unwind_opcode (op, 1);
25568 }
25569 else
25570 flush_pending_unwind ();
bfae80f2
RE
25571}
25572
bfae80f2 25573
c19d1205
ZW
25574/* Start an exception table entry. If idx is nonzero this is an index table
25575 entry. */
bfae80f2
RE
25576
25577static void
c19d1205 25578start_unwind_section (const segT text_seg, int idx)
bfae80f2 25579{
c19d1205
ZW
25580 const char * text_name;
25581 const char * prefix;
25582 const char * prefix_once;
25583 const char * group_name;
c19d1205 25584 char * sec_name;
c19d1205
ZW
25585 int type;
25586 int flags;
25587 int linkonce;
bfae80f2 25588
c19d1205 25589 if (idx)
bfae80f2 25590 {
c19d1205
ZW
25591 prefix = ELF_STRING_ARM_unwind;
25592 prefix_once = ELF_STRING_ARM_unwind_once;
25593 type = SHT_ARM_EXIDX;
bfae80f2 25594 }
c19d1205 25595 else
bfae80f2 25596 {
c19d1205
ZW
25597 prefix = ELF_STRING_ARM_unwind_info;
25598 prefix_once = ELF_STRING_ARM_unwind_info_once;
25599 type = SHT_PROGBITS;
bfae80f2
RE
25600 }
25601
c19d1205
ZW
25602 text_name = segment_name (text_seg);
25603 if (streq (text_name, ".text"))
25604 text_name = "";
25605
25606 if (strncmp (text_name, ".gnu.linkonce.t.",
25607 strlen (".gnu.linkonce.t.")) == 0)
bfae80f2 25608 {
c19d1205
ZW
25609 prefix = prefix_once;
25610 text_name += strlen (".gnu.linkonce.t.");
bfae80f2
RE
25611 }
25612
29a2809e 25613 sec_name = concat (prefix, text_name, (char *) NULL);
bfae80f2 25614
c19d1205
ZW
25615 flags = SHF_ALLOC;
25616 linkonce = 0;
25617 group_name = 0;
bfae80f2 25618
c19d1205
ZW
25619 /* Handle COMDAT group. */
25620 if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
bfae80f2 25621 {
c19d1205
ZW
25622 group_name = elf_group_name (text_seg);
25623 if (group_name == NULL)
25624 {
bd3ba5d1 25625 as_bad (_("Group section `%s' has no group signature"),
c19d1205
ZW
25626 segment_name (text_seg));
25627 ignore_rest_of_line ();
25628 return;
25629 }
25630 flags |= SHF_GROUP;
25631 linkonce = 1;
bfae80f2
RE
25632 }
25633
a91e1603
L
25634 obj_elf_change_section (sec_name, type, 0, flags, 0, group_name,
25635 linkonce, 0);
bfae80f2 25636
5f4273c7 25637 /* Set the section link for index tables. */
c19d1205
ZW
25638 if (idx)
25639 elf_linked_to_section (now_seg) = text_seg;
bfae80f2
RE
25640}
25641
bfae80f2 25642
c19d1205
ZW
25643/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
25644 personality routine data. Returns zero, or the index table value for
cad0da33 25645 an inline entry. */
c19d1205
ZW
25646
25647static valueT
25648create_unwind_entry (int have_data)
bfae80f2 25649{
c19d1205
ZW
25650 int size;
25651 addressT where;
25652 char *ptr;
25653 /* The current word of data. */
25654 valueT data;
25655 /* The number of bytes left in this word. */
25656 int n;
bfae80f2 25657
c19d1205 25658 finish_unwind_opcodes ();
bfae80f2 25659
c19d1205
ZW
25660 /* Remember the current text section. */
25661 unwind.saved_seg = now_seg;
25662 unwind.saved_subseg = now_subseg;
bfae80f2 25663
c19d1205 25664 start_unwind_section (now_seg, 0);
bfae80f2 25665
c19d1205 25666 if (unwind.personality_routine == NULL)
bfae80f2 25667 {
c19d1205
ZW
25668 if (unwind.personality_index == -2)
25669 {
25670 if (have_data)
5f4273c7 25671 as_bad (_("handlerdata in cantunwind frame"));
c19d1205
ZW
25672 return 1; /* EXIDX_CANTUNWIND. */
25673 }
bfae80f2 25674
c19d1205
ZW
25675 /* Use a default personality routine if none is specified. */
25676 if (unwind.personality_index == -1)
25677 {
25678 if (unwind.opcode_count > 3)
25679 unwind.personality_index = 1;
25680 else
25681 unwind.personality_index = 0;
25682 }
bfae80f2 25683
c19d1205
ZW
25684 /* Space for the personality routine entry. */
25685 if (unwind.personality_index == 0)
25686 {
25687 if (unwind.opcode_count > 3)
25688 as_bad (_("too many unwind opcodes for personality routine 0"));
bfae80f2 25689
c19d1205
ZW
25690 if (!have_data)
25691 {
25692 /* All the data is inline in the index table. */
25693 data = 0x80;
25694 n = 3;
25695 while (unwind.opcode_count > 0)
25696 {
25697 unwind.opcode_count--;
25698 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
25699 n--;
25700 }
bfae80f2 25701
c19d1205
ZW
25702 /* Pad with "finish" opcodes. */
25703 while (n--)
25704 data = (data << 8) | 0xb0;
bfae80f2 25705
c19d1205
ZW
25706 return data;
25707 }
25708 size = 0;
25709 }
25710 else
25711 /* We get two opcodes "free" in the first word. */
25712 size = unwind.opcode_count - 2;
25713 }
25714 else
5011093d 25715 {
cad0da33
NC
25716 /* PR 16765: Missing or misplaced unwind directives can trigger this. */
25717 if (unwind.personality_index != -1)
25718 {
25719 as_bad (_("attempt to recreate an unwind entry"));
25720 return 1;
25721 }
5011093d
NC
25722
25723 /* An extra byte is required for the opcode count. */
25724 size = unwind.opcode_count + 1;
25725 }
bfae80f2 25726
c19d1205
ZW
25727 size = (size + 3) >> 2;
25728 if (size > 0xff)
25729 as_bad (_("too many unwind opcodes"));
bfae80f2 25730
c19d1205
ZW
25731 frag_align (2, 0, 0);
25732 record_alignment (now_seg, 2);
25733 unwind.table_entry = expr_build_dot ();
25734
25735 /* Allocate the table entry. */
25736 ptr = frag_more ((size << 2) + 4);
74929e7b
NC
25737 /* PR 13449: Zero the table entries in case some of them are not used. */
25738 memset (ptr, 0, (size << 2) + 4);
c19d1205 25739 where = frag_now_fix () - ((size << 2) + 4);
bfae80f2 25740
c19d1205 25741 switch (unwind.personality_index)
bfae80f2 25742 {
c19d1205
ZW
25743 case -1:
25744 /* ??? Should this be a PLT generating relocation? */
25745 /* Custom personality routine. */
25746 fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
25747 BFD_RELOC_ARM_PREL31);
bfae80f2 25748
c19d1205
ZW
25749 where += 4;
25750 ptr += 4;
bfae80f2 25751
c19d1205 25752 /* Set the first byte to the number of additional words. */
5011093d 25753 data = size > 0 ? size - 1 : 0;
c19d1205
ZW
25754 n = 3;
25755 break;
bfae80f2 25756
c19d1205
ZW
25757 /* ABI defined personality routines. */
25758 case 0:
25759 /* Three opcodes bytes are packed into the first word. */
25760 data = 0x80;
25761 n = 3;
25762 break;
bfae80f2 25763
c19d1205
ZW
25764 case 1:
25765 case 2:
25766 /* The size and first two opcode bytes go in the first word. */
25767 data = ((0x80 + unwind.personality_index) << 8) | size;
25768 n = 2;
25769 break;
bfae80f2 25770
c19d1205
ZW
25771 default:
25772 /* Should never happen. */
25773 abort ();
25774 }
bfae80f2 25775
c19d1205
ZW
25776 /* Pack the opcodes into words (MSB first), reversing the list at the same
25777 time. */
25778 while (unwind.opcode_count > 0)
25779 {
25780 if (n == 0)
25781 {
25782 md_number_to_chars (ptr, data, 4);
25783 ptr += 4;
25784 n = 4;
25785 data = 0;
25786 }
25787 unwind.opcode_count--;
25788 n--;
25789 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
25790 }
25791
25792 /* Finish off the last word. */
25793 if (n < 4)
25794 {
25795 /* Pad with "finish" opcodes. */
25796 while (n--)
25797 data = (data << 8) | 0xb0;
25798
25799 md_number_to_chars (ptr, data, 4);
25800 }
25801
25802 if (!have_data)
25803 {
25804 /* Add an empty descriptor if there is no user-specified data. */
25805 ptr = frag_more (4);
25806 md_number_to_chars (ptr, 0, 4);
25807 }
25808
25809 return 0;
bfae80f2
RE
25810}
25811
f0927246
NC
25812
25813/* Initialize the DWARF-2 unwind information for this procedure. */
25814
25815void
25816tc_arm_frame_initial_instructions (void)
25817{
25818 cfi_add_CFA_def_cfa (REG_SP, 0);
25819}
25820#endif /* OBJ_ELF */
25821
c19d1205
ZW
25822/* Convert REGNAME to a DWARF-2 register number. */
25823
25824int
1df69f4f 25825tc_arm_regname_to_dw2regnum (char *regname)
bfae80f2 25826{
1df69f4f 25827 int reg = arm_reg_parse (&regname, REG_TYPE_RN);
1f5afe1c
NC
25828 if (reg != FAIL)
25829 return reg;
c19d1205 25830
1f5afe1c
NC
25831 /* PR 16694: Allow VFP registers as well. */
25832 reg = arm_reg_parse (&regname, REG_TYPE_VFS);
25833 if (reg != FAIL)
25834 return 64 + reg;
c19d1205 25835
1f5afe1c
NC
25836 reg = arm_reg_parse (&regname, REG_TYPE_VFD);
25837 if (reg != FAIL)
25838 return reg + 256;
25839
0198d5e6 25840 return FAIL;
bfae80f2
RE
25841}
25842
f0927246 25843#ifdef TE_PE
c19d1205 25844void
f0927246 25845tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
bfae80f2 25846{
91d6fa6a 25847 expressionS exp;
bfae80f2 25848
91d6fa6a
NC
25849 exp.X_op = O_secrel;
25850 exp.X_add_symbol = symbol;
25851 exp.X_add_number = 0;
25852 emit_expr (&exp, size);
f0927246
NC
25853}
25854#endif
bfae80f2 25855
c19d1205 25856/* MD interface: Symbol and relocation handling. */
bfae80f2 25857
2fc8bdac
ZW
25858/* Return the address within the segment that a PC-relative fixup is
25859 relative to. For ARM, PC-relative fixups applied to instructions
25860 are generally relative to the location of the fixup plus 8 bytes.
25861 Thumb branches are offset by 4, and Thumb loads relative to PC
25862 require special handling. */
bfae80f2 25863
c19d1205 25864long
2fc8bdac 25865md_pcrel_from_section (fixS * fixP, segT seg)
bfae80f2 25866{
2fc8bdac
ZW
25867 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
25868
25869 /* If this is pc-relative and we are going to emit a relocation
25870 then we just want to put out any pipeline compensation that the linker
53baae48
NC
25871 will need. Otherwise we want to use the calculated base.
25872 For WinCE we skip the bias for externals as well, since this
25873 is how the MS ARM-CE assembler behaves and we want to be compatible. */
5f4273c7 25874 if (fixP->fx_pcrel
2fc8bdac 25875 && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
53baae48
NC
25876 || (arm_force_relocation (fixP)
25877#ifdef TE_WINCE
25878 && !S_IS_EXTERNAL (fixP->fx_addsy)
25879#endif
25880 )))
2fc8bdac 25881 base = 0;
bfae80f2 25882
267bf995 25883
c19d1205 25884 switch (fixP->fx_r_type)
bfae80f2 25885 {
2fc8bdac
ZW
25886 /* PC relative addressing on the Thumb is slightly odd as the
25887 bottom two bits of the PC are forced to zero for the
25888 calculation. This happens *after* application of the
25889 pipeline offset. However, Thumb adrl already adjusts for
25890 this, so we need not do it again. */
c19d1205 25891 case BFD_RELOC_ARM_THUMB_ADD:
2fc8bdac 25892 return base & ~3;
c19d1205
ZW
25893
25894 case BFD_RELOC_ARM_THUMB_OFFSET:
25895 case BFD_RELOC_ARM_T32_OFFSET_IMM:
e9f89963 25896 case BFD_RELOC_ARM_T32_ADD_PC12:
8f06b2d8 25897 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
2fc8bdac 25898 return (base + 4) & ~3;
c19d1205 25899
2fc8bdac 25900 /* Thumb branches are simply offset by +4. */
e12437dc 25901 case BFD_RELOC_THUMB_PCREL_BRANCH5:
2fc8bdac
ZW
25902 case BFD_RELOC_THUMB_PCREL_BRANCH7:
25903 case BFD_RELOC_THUMB_PCREL_BRANCH9:
25904 case BFD_RELOC_THUMB_PCREL_BRANCH12:
25905 case BFD_RELOC_THUMB_PCREL_BRANCH20:
2fc8bdac 25906 case BFD_RELOC_THUMB_PCREL_BRANCH25:
f6b2b12d 25907 case BFD_RELOC_THUMB_PCREL_BFCSEL:
e5d6e09e 25908 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 25909 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 25910 case BFD_RELOC_ARM_THUMB_BF13:
60f993ce 25911 case BFD_RELOC_ARM_THUMB_LOOP12:
2fc8bdac 25912 return base + 4;
bfae80f2 25913
267bf995 25914 case BFD_RELOC_THUMB_PCREL_BRANCH23:
486499d0
CL
25915 if (fixP->fx_addsy
25916 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 25917 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995 25918 && ARM_IS_FUNC (fixP->fx_addsy)
477330fc
RM
25919 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
25920 base = fixP->fx_where + fixP->fx_frag->fr_address;
267bf995
RR
25921 return base + 4;
25922
00adf2d4
JB
25923 /* BLX is like branches above, but forces the low two bits of PC to
25924 zero. */
486499d0
CL
25925 case BFD_RELOC_THUMB_PCREL_BLX:
25926 if (fixP->fx_addsy
25927 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 25928 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
25929 && THUMB_IS_FUNC (fixP->fx_addsy)
25930 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
25931 base = fixP->fx_where + fixP->fx_frag->fr_address;
00adf2d4
JB
25932 return (base + 4) & ~3;
25933
2fc8bdac
ZW
25934 /* ARM mode branches are offset by +8. However, the Windows CE
25935 loader expects the relocation not to take this into account. */
267bf995 25936 case BFD_RELOC_ARM_PCREL_BLX:
486499d0
CL
25937 if (fixP->fx_addsy
25938 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 25939 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
25940 && ARM_IS_FUNC (fixP->fx_addsy)
25941 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
25942 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 25943 return base + 8;
267bf995 25944
486499d0
CL
25945 case BFD_RELOC_ARM_PCREL_CALL:
25946 if (fixP->fx_addsy
25947 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 25948 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
25949 && THUMB_IS_FUNC (fixP->fx_addsy)
25950 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
25951 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 25952 return base + 8;
267bf995 25953
2fc8bdac 25954 case BFD_RELOC_ARM_PCREL_BRANCH:
39b41c9c 25955 case BFD_RELOC_ARM_PCREL_JUMP:
2fc8bdac 25956 case BFD_RELOC_ARM_PLT32:
c19d1205 25957#ifdef TE_WINCE
5f4273c7 25958 /* When handling fixups immediately, because we have already
477330fc 25959 discovered the value of a symbol, or the address of the frag involved
53baae48 25960 we must account for the offset by +8, as the OS loader will never see the reloc.
477330fc
RM
25961 see fixup_segment() in write.c
25962 The S_IS_EXTERNAL test handles the case of global symbols.
25963 Those need the calculated base, not just the pipe compensation the linker will need. */
53baae48
NC
25964 if (fixP->fx_pcrel
25965 && fixP->fx_addsy != NULL
25966 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25967 && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP)))
25968 return base + 8;
2fc8bdac 25969 return base;
c19d1205 25970#else
2fc8bdac 25971 return base + 8;
c19d1205 25972#endif
2fc8bdac 25973
267bf995 25974
2fc8bdac
ZW
25975 /* ARM mode loads relative to PC are also offset by +8. Unlike
25976 branches, the Windows CE loader *does* expect the relocation
25977 to take this into account. */
25978 case BFD_RELOC_ARM_OFFSET_IMM:
25979 case BFD_RELOC_ARM_OFFSET_IMM8:
25980 case BFD_RELOC_ARM_HWLITERAL:
25981 case BFD_RELOC_ARM_LITERAL:
25982 case BFD_RELOC_ARM_CP_OFF_IMM:
25983 return base + 8;
25984
25985
25986 /* Other PC-relative relocations are un-offset. */
25987 default:
25988 return base;
25989 }
bfae80f2
RE
25990}
25991
8b2d793c
NC
25992static bfd_boolean flag_warn_syms = TRUE;
25993
ae8714c2
NC
25994bfd_boolean
25995arm_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char * name)
bfae80f2 25996{
8b2d793c
NC
25997 /* PR 18347 - Warn if the user attempts to create a symbol with the same
25998 name as an ARM instruction. Whilst strictly speaking it is allowed, it
25999 does mean that the resulting code might be very confusing to the reader.
26000 Also this warning can be triggered if the user omits an operand before
26001 an immediate address, eg:
26002
26003 LDR =foo
26004
26005 GAS treats this as an assignment of the value of the symbol foo to a
26006 symbol LDR, and so (without this code) it will not issue any kind of
26007 warning or error message.
26008
26009 Note - ARM instructions are case-insensitive but the strings in the hash
26010 table are all stored in lower case, so we must first ensure that name is
ae8714c2
NC
26011 lower case too. */
26012 if (flag_warn_syms && arm_ops_hsh)
8b2d793c
NC
26013 {
26014 char * nbuf = strdup (name);
26015 char * p;
26016
26017 for (p = nbuf; *p; p++)
26018 *p = TOLOWER (*p);
26019 if (hash_find (arm_ops_hsh, nbuf) != NULL)
26020 {
26021 static struct hash_control * already_warned = NULL;
26022
26023 if (already_warned == NULL)
26024 already_warned = hash_new ();
26025 /* Only warn about the symbol once. To keep the code
26026 simple we let hash_insert do the lookup for us. */
3076e594 26027 if (hash_insert (already_warned, nbuf, NULL) == NULL)
ae8714c2 26028 as_warn (_("[-mwarn-syms]: Assignment makes a symbol match an ARM instruction: %s"), name);
8b2d793c
NC
26029 }
26030 else
26031 free (nbuf);
26032 }
3739860c 26033
ae8714c2
NC
26034 return FALSE;
26035}
26036
26037/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
26038 Otherwise we have no need to default values of symbols. */
26039
26040symbolS *
26041md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
26042{
26043#ifdef OBJ_ELF
26044 if (name[0] == '_' && name[1] == 'G'
26045 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
26046 {
26047 if (!GOT_symbol)
26048 {
26049 if (symbol_find (name))
26050 as_bad (_("GOT already in the symbol table"));
26051
26052 GOT_symbol = symbol_new (name, undefined_section,
26053 (valueT) 0, & zero_address_frag);
26054 }
26055
26056 return GOT_symbol;
26057 }
26058#endif
26059
c921be7d 26060 return NULL;
bfae80f2
RE
26061}
26062
55cf6793 26063/* Subroutine of md_apply_fix. Check to see if an immediate can be
c19d1205
ZW
26064 computed as two separate immediate values, added together. We
26065 already know that this value cannot be computed by just one ARM
26066 instruction. */
26067
26068static unsigned int
26069validate_immediate_twopart (unsigned int val,
26070 unsigned int * highpart)
bfae80f2 26071{
c19d1205
ZW
26072 unsigned int a;
26073 unsigned int i;
bfae80f2 26074
c19d1205
ZW
26075 for (i = 0; i < 32; i += 2)
26076 if (((a = rotate_left (val, i)) & 0xff) != 0)
26077 {
26078 if (a & 0xff00)
26079 {
26080 if (a & ~ 0xffff)
26081 continue;
26082 * highpart = (a >> 8) | ((i + 24) << 7);
26083 }
26084 else if (a & 0xff0000)
26085 {
26086 if (a & 0xff000000)
26087 continue;
26088 * highpart = (a >> 16) | ((i + 16) << 7);
26089 }
26090 else
26091 {
9c2799c2 26092 gas_assert (a & 0xff000000);
c19d1205
ZW
26093 * highpart = (a >> 24) | ((i + 8) << 7);
26094 }
bfae80f2 26095
c19d1205
ZW
26096 return (a & 0xff) | (i << 7);
26097 }
bfae80f2 26098
c19d1205 26099 return FAIL;
bfae80f2
RE
26100}
26101
c19d1205
ZW
26102static int
26103validate_offset_imm (unsigned int val, int hwse)
26104{
26105 if ((hwse && val > 255) || val > 4095)
26106 return FAIL;
26107 return val;
26108}
bfae80f2 26109
55cf6793 26110/* Subroutine of md_apply_fix. Do those data_ops which can take a
c19d1205
ZW
26111 negative immediate constant by altering the instruction. A bit of
26112 a hack really.
26113 MOV <-> MVN
26114 AND <-> BIC
26115 ADC <-> SBC
26116 by inverting the second operand, and
26117 ADD <-> SUB
26118 CMP <-> CMN
26119 by negating the second operand. */
bfae80f2 26120
c19d1205
ZW
26121static int
26122negate_data_op (unsigned long * instruction,
26123 unsigned long value)
bfae80f2 26124{
c19d1205
ZW
26125 int op, new_inst;
26126 unsigned long negated, inverted;
bfae80f2 26127
c19d1205
ZW
26128 negated = encode_arm_immediate (-value);
26129 inverted = encode_arm_immediate (~value);
bfae80f2 26130
c19d1205
ZW
26131 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
26132 switch (op)
bfae80f2 26133 {
c19d1205
ZW
26134 /* First negates. */
26135 case OPCODE_SUB: /* ADD <-> SUB */
26136 new_inst = OPCODE_ADD;
26137 value = negated;
26138 break;
bfae80f2 26139
c19d1205
ZW
26140 case OPCODE_ADD:
26141 new_inst = OPCODE_SUB;
26142 value = negated;
26143 break;
bfae80f2 26144
c19d1205
ZW
26145 case OPCODE_CMP: /* CMP <-> CMN */
26146 new_inst = OPCODE_CMN;
26147 value = negated;
26148 break;
bfae80f2 26149
c19d1205
ZW
26150 case OPCODE_CMN:
26151 new_inst = OPCODE_CMP;
26152 value = negated;
26153 break;
bfae80f2 26154
c19d1205
ZW
26155 /* Now Inverted ops. */
26156 case OPCODE_MOV: /* MOV <-> MVN */
26157 new_inst = OPCODE_MVN;
26158 value = inverted;
26159 break;
bfae80f2 26160
c19d1205
ZW
26161 case OPCODE_MVN:
26162 new_inst = OPCODE_MOV;
26163 value = inverted;
26164 break;
bfae80f2 26165
c19d1205
ZW
26166 case OPCODE_AND: /* AND <-> BIC */
26167 new_inst = OPCODE_BIC;
26168 value = inverted;
26169 break;
bfae80f2 26170
c19d1205
ZW
26171 case OPCODE_BIC:
26172 new_inst = OPCODE_AND;
26173 value = inverted;
26174 break;
bfae80f2 26175
c19d1205
ZW
26176 case OPCODE_ADC: /* ADC <-> SBC */
26177 new_inst = OPCODE_SBC;
26178 value = inverted;
26179 break;
bfae80f2 26180
c19d1205
ZW
26181 case OPCODE_SBC:
26182 new_inst = OPCODE_ADC;
26183 value = inverted;
26184 break;
bfae80f2 26185
c19d1205
ZW
26186 /* We cannot do anything. */
26187 default:
26188 return FAIL;
b99bd4ef
NC
26189 }
26190
c19d1205
ZW
26191 if (value == (unsigned) FAIL)
26192 return FAIL;
26193
26194 *instruction &= OPCODE_MASK;
26195 *instruction |= new_inst << DATA_OP_SHIFT;
26196 return value;
b99bd4ef
NC
26197}
26198
ef8d22e6
PB
26199/* Like negate_data_op, but for Thumb-2. */
26200
26201static unsigned int
16dd5e42 26202thumb32_negate_data_op (offsetT *instruction, unsigned int value)
ef8d22e6
PB
26203{
26204 int op, new_inst;
26205 int rd;
16dd5e42 26206 unsigned int negated, inverted;
ef8d22e6
PB
26207
26208 negated = encode_thumb32_immediate (-value);
26209 inverted = encode_thumb32_immediate (~value);
26210
26211 rd = (*instruction >> 8) & 0xf;
26212 op = (*instruction >> T2_DATA_OP_SHIFT) & 0xf;
26213 switch (op)
26214 {
26215 /* ADD <-> SUB. Includes CMP <-> CMN. */
26216 case T2_OPCODE_SUB:
26217 new_inst = T2_OPCODE_ADD;
26218 value = negated;
26219 break;
26220
26221 case T2_OPCODE_ADD:
26222 new_inst = T2_OPCODE_SUB;
26223 value = negated;
26224 break;
26225
26226 /* ORR <-> ORN. Includes MOV <-> MVN. */
26227 case T2_OPCODE_ORR:
26228 new_inst = T2_OPCODE_ORN;
26229 value = inverted;
26230 break;
26231
26232 case T2_OPCODE_ORN:
26233 new_inst = T2_OPCODE_ORR;
26234 value = inverted;
26235 break;
26236
26237 /* AND <-> BIC. TST has no inverted equivalent. */
26238 case T2_OPCODE_AND:
26239 new_inst = T2_OPCODE_BIC;
26240 if (rd == 15)
26241 value = FAIL;
26242 else
26243 value = inverted;
26244 break;
26245
26246 case T2_OPCODE_BIC:
26247 new_inst = T2_OPCODE_AND;
26248 value = inverted;
26249 break;
26250
26251 /* ADC <-> SBC */
26252 case T2_OPCODE_ADC:
26253 new_inst = T2_OPCODE_SBC;
26254 value = inverted;
26255 break;
26256
26257 case T2_OPCODE_SBC:
26258 new_inst = T2_OPCODE_ADC;
26259 value = inverted;
26260 break;
26261
26262 /* We cannot do anything. */
26263 default:
26264 return FAIL;
26265 }
26266
16dd5e42 26267 if (value == (unsigned int)FAIL)
ef8d22e6
PB
26268 return FAIL;
26269
26270 *instruction &= T2_OPCODE_MASK;
26271 *instruction |= new_inst << T2_DATA_OP_SHIFT;
26272 return value;
26273}
26274
8f06b2d8 26275/* Read a 32-bit thumb instruction from buf. */
0198d5e6 26276
8f06b2d8
PB
26277static unsigned long
26278get_thumb32_insn (char * buf)
26279{
26280 unsigned long insn;
26281 insn = md_chars_to_number (buf, THUMB_SIZE) << 16;
26282 insn |= md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
26283
26284 return insn;
26285}
26286
a8bc6c78
PB
26287/* We usually want to set the low bit on the address of thumb function
26288 symbols. In particular .word foo - . should have the low bit set.
26289 Generic code tries to fold the difference of two symbols to
26290 a constant. Prevent this and force a relocation when the first symbols
26291 is a thumb function. */
c921be7d
NC
26292
26293bfd_boolean
a8bc6c78
PB
26294arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
26295{
26296 if (op == O_subtract
26297 && l->X_op == O_symbol
26298 && r->X_op == O_symbol
26299 && THUMB_IS_FUNC (l->X_add_symbol))
26300 {
26301 l->X_op = O_subtract;
26302 l->X_op_symbol = r->X_add_symbol;
26303 l->X_add_number -= r->X_add_number;
c921be7d 26304 return TRUE;
a8bc6c78 26305 }
c921be7d 26306
a8bc6c78 26307 /* Process as normal. */
c921be7d 26308 return FALSE;
a8bc6c78
PB
26309}
26310
4a42ebbc
RR
26311/* Encode Thumb2 unconditional branches and calls. The encoding
26312 for the 2 are identical for the immediate values. */
26313
26314static void
26315encode_thumb2_b_bl_offset (char * buf, offsetT value)
26316{
26317#define T2I1I2MASK ((1 << 13) | (1 << 11))
26318 offsetT newval;
26319 offsetT newval2;
26320 addressT S, I1, I2, lo, hi;
26321
26322 S = (value >> 24) & 0x01;
26323 I1 = (value >> 23) & 0x01;
26324 I2 = (value >> 22) & 0x01;
26325 hi = (value >> 12) & 0x3ff;
fa94de6b 26326 lo = (value >> 1) & 0x7ff;
4a42ebbc
RR
26327 newval = md_chars_to_number (buf, THUMB_SIZE);
26328 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
26329 newval |= (S << 10) | hi;
26330 newval2 &= ~T2I1I2MASK;
26331 newval2 |= (((I1 ^ S) << 13) | ((I2 ^ S) << 11) | lo) ^ T2I1I2MASK;
26332 md_number_to_chars (buf, newval, THUMB_SIZE);
26333 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
26334}
26335
c19d1205 26336void
55cf6793 26337md_apply_fix (fixS * fixP,
c19d1205
ZW
26338 valueT * valP,
26339 segT seg)
26340{
26341 offsetT value = * valP;
26342 offsetT newval;
26343 unsigned int newimm;
26344 unsigned long temp;
26345 int sign;
26346 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
b99bd4ef 26347
9c2799c2 26348 gas_assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
b99bd4ef 26349
c19d1205 26350 /* Note whether this will delete the relocation. */
4962c51a 26351
c19d1205
ZW
26352 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
26353 fixP->fx_done = 1;
b99bd4ef 26354
adbaf948 26355 /* On a 64-bit host, silently truncate 'value' to 32 bits for
5f4273c7 26356 consistency with the behaviour on 32-bit hosts. Remember value
adbaf948
ZW
26357 for emit_reloc. */
26358 value &= 0xffffffff;
26359 value ^= 0x80000000;
5f4273c7 26360 value -= 0x80000000;
adbaf948
ZW
26361
26362 *valP = value;
c19d1205 26363 fixP->fx_addnumber = value;
b99bd4ef 26364
adbaf948
ZW
26365 /* Same treatment for fixP->fx_offset. */
26366 fixP->fx_offset &= 0xffffffff;
26367 fixP->fx_offset ^= 0x80000000;
26368 fixP->fx_offset -= 0x80000000;
26369
c19d1205 26370 switch (fixP->fx_r_type)
b99bd4ef 26371 {
c19d1205
ZW
26372 case BFD_RELOC_NONE:
26373 /* This will need to go in the object file. */
26374 fixP->fx_done = 0;
26375 break;
b99bd4ef 26376
c19d1205
ZW
26377 case BFD_RELOC_ARM_IMMEDIATE:
26378 /* We claim that this fixup has been processed here,
26379 even if in fact we generate an error because we do
26380 not have a reloc for it, so tc_gen_reloc will reject it. */
26381 fixP->fx_done = 1;
b99bd4ef 26382
77db8e2e 26383 if (fixP->fx_addsy)
b99bd4ef 26384 {
77db8e2e 26385 const char *msg = 0;
b99bd4ef 26386
77db8e2e
NC
26387 if (! S_IS_DEFINED (fixP->fx_addsy))
26388 msg = _("undefined symbol %s used as an immediate value");
26389 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
26390 msg = _("symbol %s is in a different section");
26391 else if (S_IS_WEAK (fixP->fx_addsy))
26392 msg = _("symbol %s is weak and may be overridden later");
26393
26394 if (msg)
26395 {
26396 as_bad_where (fixP->fx_file, fixP->fx_line,
26397 msg, S_GET_NAME (fixP->fx_addsy));
26398 break;
26399 }
42e5fcbf
AS
26400 }
26401
c19d1205
ZW
26402 temp = md_chars_to_number (buf, INSN_SIZE);
26403
5e73442d
SL
26404 /* If the offset is negative, we should use encoding A2 for ADR. */
26405 if ((temp & 0xfff0000) == 0x28f0000 && value < 0)
26406 newimm = negate_data_op (&temp, value);
26407 else
26408 {
26409 newimm = encode_arm_immediate (value);
26410
26411 /* If the instruction will fail, see if we can fix things up by
26412 changing the opcode. */
26413 if (newimm == (unsigned int) FAIL)
26414 newimm = negate_data_op (&temp, value);
bada4342
JW
26415 /* MOV accepts both ARM modified immediate (A1 encoding) and
26416 UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
26417 When disassembling, MOV is preferred when there is no encoding
26418 overlap. */
26419 if (newimm == (unsigned int) FAIL
26420 && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
26421 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
26422 && !((temp >> SBIT_SHIFT) & 0x1)
26423 && value >= 0 && value <= 0xffff)
26424 {
26425 /* Clear bits[23:20] to change encoding from A1 to A2. */
26426 temp &= 0xff0fffff;
26427 /* Encoding high 4bits imm. Code below will encode the remaining
26428 low 12bits. */
26429 temp |= (value & 0x0000f000) << 4;
26430 newimm = value & 0x00000fff;
26431 }
5e73442d
SL
26432 }
26433
26434 if (newimm == (unsigned int) FAIL)
b99bd4ef 26435 {
c19d1205
ZW
26436 as_bad_where (fixP->fx_file, fixP->fx_line,
26437 _("invalid constant (%lx) after fixup"),
26438 (unsigned long) value);
26439 break;
b99bd4ef 26440 }
b99bd4ef 26441
c19d1205
ZW
26442 newimm |= (temp & 0xfffff000);
26443 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
26444 break;
b99bd4ef 26445
c19d1205
ZW
26446 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
26447 {
26448 unsigned int highpart = 0;
26449 unsigned int newinsn = 0xe1a00000; /* nop. */
b99bd4ef 26450
77db8e2e 26451 if (fixP->fx_addsy)
42e5fcbf 26452 {
77db8e2e 26453 const char *msg = 0;
42e5fcbf 26454
77db8e2e
NC
26455 if (! S_IS_DEFINED (fixP->fx_addsy))
26456 msg = _("undefined symbol %s used as an immediate value");
26457 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
26458 msg = _("symbol %s is in a different section");
26459 else if (S_IS_WEAK (fixP->fx_addsy))
26460 msg = _("symbol %s is weak and may be overridden later");
42e5fcbf 26461
77db8e2e
NC
26462 if (msg)
26463 {
26464 as_bad_where (fixP->fx_file, fixP->fx_line,
26465 msg, S_GET_NAME (fixP->fx_addsy));
26466 break;
26467 }
26468 }
fa94de6b 26469
c19d1205
ZW
26470 newimm = encode_arm_immediate (value);
26471 temp = md_chars_to_number (buf, INSN_SIZE);
b99bd4ef 26472
c19d1205
ZW
26473 /* If the instruction will fail, see if we can fix things up by
26474 changing the opcode. */
26475 if (newimm == (unsigned int) FAIL
26476 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
26477 {
26478 /* No ? OK - try using two ADD instructions to generate
26479 the value. */
26480 newimm = validate_immediate_twopart (value, & highpart);
b99bd4ef 26481
c19d1205
ZW
26482 /* Yes - then make sure that the second instruction is
26483 also an add. */
26484 if (newimm != (unsigned int) FAIL)
26485 newinsn = temp;
26486 /* Still No ? Try using a negated value. */
26487 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
26488 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
26489 /* Otherwise - give up. */
26490 else
26491 {
26492 as_bad_where (fixP->fx_file, fixP->fx_line,
26493 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
26494 (long) value);
26495 break;
26496 }
b99bd4ef 26497
c19d1205
ZW
26498 /* Replace the first operand in the 2nd instruction (which
26499 is the PC) with the destination register. We have
26500 already added in the PC in the first instruction and we
26501 do not want to do it again. */
26502 newinsn &= ~ 0xf0000;
26503 newinsn |= ((newinsn & 0x0f000) << 4);
26504 }
b99bd4ef 26505
c19d1205
ZW
26506 newimm |= (temp & 0xfffff000);
26507 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
b99bd4ef 26508
c19d1205
ZW
26509 highpart |= (newinsn & 0xfffff000);
26510 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
26511 }
26512 break;
b99bd4ef 26513
c19d1205 26514 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
26515 if (!fixP->fx_done && seg->use_rela_p)
26516 value = 0;
1a0670f3 26517 /* Fall through. */
00a97672 26518
c19d1205 26519 case BFD_RELOC_ARM_LITERAL:
26d97720 26520 sign = value > 0;
b99bd4ef 26521
c19d1205
ZW
26522 if (value < 0)
26523 value = - value;
b99bd4ef 26524
c19d1205 26525 if (validate_offset_imm (value, 0) == FAIL)
f03698e6 26526 {
c19d1205
ZW
26527 if (fixP->fx_r_type == BFD_RELOC_ARM_LITERAL)
26528 as_bad_where (fixP->fx_file, fixP->fx_line,
26529 _("invalid literal constant: pool needs to be closer"));
26530 else
26531 as_bad_where (fixP->fx_file, fixP->fx_line,
26532 _("bad immediate value for offset (%ld)"),
26533 (long) value);
26534 break;
f03698e6
RE
26535 }
26536
c19d1205 26537 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
26538 if (value == 0)
26539 newval &= 0xfffff000;
26540 else
26541 {
26542 newval &= 0xff7ff000;
26543 newval |= value | (sign ? INDEX_UP : 0);
26544 }
c19d1205
ZW
26545 md_number_to_chars (buf, newval, INSN_SIZE);
26546 break;
b99bd4ef 26547
c19d1205
ZW
26548 case BFD_RELOC_ARM_OFFSET_IMM8:
26549 case BFD_RELOC_ARM_HWLITERAL:
26d97720 26550 sign = value > 0;
b99bd4ef 26551
c19d1205
ZW
26552 if (value < 0)
26553 value = - value;
b99bd4ef 26554
c19d1205 26555 if (validate_offset_imm (value, 1) == FAIL)
b99bd4ef 26556 {
c19d1205
ZW
26557 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
26558 as_bad_where (fixP->fx_file, fixP->fx_line,
26559 _("invalid literal constant: pool needs to be closer"));
26560 else
427d0db6
RM
26561 as_bad_where (fixP->fx_file, fixP->fx_line,
26562 _("bad immediate value for 8-bit offset (%ld)"),
26563 (long) value);
c19d1205 26564 break;
b99bd4ef
NC
26565 }
26566
c19d1205 26567 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
26568 if (value == 0)
26569 newval &= 0xfffff0f0;
26570 else
26571 {
26572 newval &= 0xff7ff0f0;
26573 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
26574 }
c19d1205
ZW
26575 md_number_to_chars (buf, newval, INSN_SIZE);
26576 break;
b99bd4ef 26577
c19d1205
ZW
26578 case BFD_RELOC_ARM_T32_OFFSET_U8:
26579 if (value < 0 || value > 1020 || value % 4 != 0)
26580 as_bad_where (fixP->fx_file, fixP->fx_line,
26581 _("bad immediate value for offset (%ld)"), (long) value);
26582 value /= 4;
b99bd4ef 26583
c19d1205 26584 newval = md_chars_to_number (buf+2, THUMB_SIZE);
c19d1205
ZW
26585 newval |= value;
26586 md_number_to_chars (buf+2, newval, THUMB_SIZE);
26587 break;
b99bd4ef 26588
c19d1205
ZW
26589 case BFD_RELOC_ARM_T32_OFFSET_IMM:
26590 /* This is a complicated relocation used for all varieties of Thumb32
26591 load/store instruction with immediate offset:
26592
26593 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
477330fc 26594 *4, optional writeback(W)
c19d1205
ZW
26595 (doubleword load/store)
26596
26597 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
26598 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
26599 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
26600 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
26601 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
26602
26603 Uppercase letters indicate bits that are already encoded at
26604 this point. Lowercase letters are our problem. For the
26605 second block of instructions, the secondary opcode nybble
26606 (bits 8..11) is present, and bit 23 is zero, even if this is
26607 a PC-relative operation. */
26608 newval = md_chars_to_number (buf, THUMB_SIZE);
26609 newval <<= 16;
26610 newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
b99bd4ef 26611
c19d1205 26612 if ((newval & 0xf0000000) == 0xe0000000)
b99bd4ef 26613 {
c19d1205
ZW
26614 /* Doubleword load/store: 8-bit offset, scaled by 4. */
26615 if (value >= 0)
26616 newval |= (1 << 23);
26617 else
26618 value = -value;
26619 if (value % 4 != 0)
26620 {
26621 as_bad_where (fixP->fx_file, fixP->fx_line,
26622 _("offset not a multiple of 4"));
26623 break;
26624 }
26625 value /= 4;
216d22bc 26626 if (value > 0xff)
c19d1205
ZW
26627 {
26628 as_bad_where (fixP->fx_file, fixP->fx_line,
26629 _("offset out of range"));
26630 break;
26631 }
26632 newval &= ~0xff;
b99bd4ef 26633 }
c19d1205 26634 else if ((newval & 0x000f0000) == 0x000f0000)
b99bd4ef 26635 {
c19d1205
ZW
26636 /* PC-relative, 12-bit offset. */
26637 if (value >= 0)
26638 newval |= (1 << 23);
26639 else
26640 value = -value;
216d22bc 26641 if (value > 0xfff)
c19d1205
ZW
26642 {
26643 as_bad_where (fixP->fx_file, fixP->fx_line,
26644 _("offset out of range"));
26645 break;
26646 }
26647 newval &= ~0xfff;
b99bd4ef 26648 }
c19d1205 26649 else if ((newval & 0x00000100) == 0x00000100)
b99bd4ef 26650 {
c19d1205
ZW
26651 /* Writeback: 8-bit, +/- offset. */
26652 if (value >= 0)
26653 newval |= (1 << 9);
26654 else
26655 value = -value;
216d22bc 26656 if (value > 0xff)
c19d1205
ZW
26657 {
26658 as_bad_where (fixP->fx_file, fixP->fx_line,
26659 _("offset out of range"));
26660 break;
26661 }
26662 newval &= ~0xff;
b99bd4ef 26663 }
c19d1205 26664 else if ((newval & 0x00000f00) == 0x00000e00)
b99bd4ef 26665 {
c19d1205 26666 /* T-instruction: positive 8-bit offset. */
216d22bc 26667 if (value < 0 || value > 0xff)
b99bd4ef 26668 {
c19d1205
ZW
26669 as_bad_where (fixP->fx_file, fixP->fx_line,
26670 _("offset out of range"));
26671 break;
b99bd4ef 26672 }
c19d1205
ZW
26673 newval &= ~0xff;
26674 newval |= value;
b99bd4ef
NC
26675 }
26676 else
b99bd4ef 26677 {
c19d1205
ZW
26678 /* Positive 12-bit or negative 8-bit offset. */
26679 int limit;
26680 if (value >= 0)
b99bd4ef 26681 {
c19d1205
ZW
26682 newval |= (1 << 23);
26683 limit = 0xfff;
26684 }
26685 else
26686 {
26687 value = -value;
26688 limit = 0xff;
26689 }
26690 if (value > limit)
26691 {
26692 as_bad_where (fixP->fx_file, fixP->fx_line,
26693 _("offset out of range"));
26694 break;
b99bd4ef 26695 }
c19d1205 26696 newval &= ~limit;
b99bd4ef 26697 }
b99bd4ef 26698
c19d1205
ZW
26699 newval |= value;
26700 md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
26701 md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
26702 break;
404ff6b5 26703
c19d1205
ZW
26704 case BFD_RELOC_ARM_SHIFT_IMM:
26705 newval = md_chars_to_number (buf, INSN_SIZE);
26706 if (((unsigned long) value) > 32
26707 || (value == 32
26708 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
26709 {
26710 as_bad_where (fixP->fx_file, fixP->fx_line,
26711 _("shift expression is too large"));
26712 break;
26713 }
404ff6b5 26714
c19d1205
ZW
26715 if (value == 0)
26716 /* Shifts of zero must be done as lsl. */
26717 newval &= ~0x60;
26718 else if (value == 32)
26719 value = 0;
26720 newval &= 0xfffff07f;
26721 newval |= (value & 0x1f) << 7;
26722 md_number_to_chars (buf, newval, INSN_SIZE);
26723 break;
404ff6b5 26724
c19d1205 26725 case BFD_RELOC_ARM_T32_IMMEDIATE:
16805f35 26726 case BFD_RELOC_ARM_T32_ADD_IMM:
92e90b6e 26727 case BFD_RELOC_ARM_T32_IMM12:
e9f89963 26728 case BFD_RELOC_ARM_T32_ADD_PC12:
c19d1205
ZW
26729 /* We claim that this fixup has been processed here,
26730 even if in fact we generate an error because we do
26731 not have a reloc for it, so tc_gen_reloc will reject it. */
26732 fixP->fx_done = 1;
404ff6b5 26733
c19d1205
ZW
26734 if (fixP->fx_addsy
26735 && ! S_IS_DEFINED (fixP->fx_addsy))
26736 {
26737 as_bad_where (fixP->fx_file, fixP->fx_line,
26738 _("undefined symbol %s used as an immediate value"),
26739 S_GET_NAME (fixP->fx_addsy));
26740 break;
26741 }
404ff6b5 26742
c19d1205
ZW
26743 newval = md_chars_to_number (buf, THUMB_SIZE);
26744 newval <<= 16;
26745 newval |= md_chars_to_number (buf+2, THUMB_SIZE);
404ff6b5 26746
16805f35 26747 newimm = FAIL;
bada4342
JW
26748 if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
26749 /* ARMv8-M Baseline MOV will reach here, but it doesn't support
26750 Thumb2 modified immediate encoding (T2). */
26751 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
16805f35 26752 || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
ef8d22e6
PB
26753 {
26754 newimm = encode_thumb32_immediate (value);
26755 if (newimm == (unsigned int) FAIL)
26756 newimm = thumb32_negate_data_op (&newval, value);
26757 }
bada4342 26758 if (newimm == (unsigned int) FAIL)
92e90b6e 26759 {
bada4342 26760 if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
e9f89963 26761 {
bada4342
JW
26762 /* Turn add/sum into addw/subw. */
26763 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
26764 newval = (newval & 0xfeffffff) | 0x02000000;
26765 /* No flat 12-bit imm encoding for addsw/subsw. */
26766 if ((newval & 0x00100000) == 0)
40f246e3 26767 {
bada4342
JW
26768 /* 12 bit immediate for addw/subw. */
26769 if (value < 0)
26770 {
26771 value = -value;
26772 newval ^= 0x00a00000;
26773 }
26774 if (value > 0xfff)
26775 newimm = (unsigned int) FAIL;
26776 else
26777 newimm = value;
26778 }
26779 }
26780 else
26781 {
26782 /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
26783 UINT16 (T3 encoding), MOVW only accepts UINT16. When
26784 disassembling, MOV is preferred when there is no encoding
db7bf105 26785 overlap. */
bada4342 26786 if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
db7bf105
NC
26787 /* NOTE: MOV uses the ORR opcode in Thumb 2 mode
26788 but with the Rn field [19:16] set to 1111. */
26789 && (((newval >> 16) & 0xf) == 0xf)
bada4342
JW
26790 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
26791 && !((newval >> T2_SBIT_SHIFT) & 0x1)
db7bf105 26792 && value >= 0 && value <= 0xffff)
bada4342
JW
26793 {
26794 /* Toggle bit[25] to change encoding from T2 to T3. */
26795 newval ^= 1 << 25;
26796 /* Clear bits[19:16]. */
26797 newval &= 0xfff0ffff;
26798 /* Encoding high 4bits imm. Code below will encode the
26799 remaining low 12bits. */
26800 newval |= (value & 0x0000f000) << 4;
26801 newimm = value & 0x00000fff;
40f246e3 26802 }
e9f89963 26803 }
92e90b6e 26804 }
cc8a6dd0 26805
c19d1205 26806 if (newimm == (unsigned int)FAIL)
3631a3c8 26807 {
c19d1205
ZW
26808 as_bad_where (fixP->fx_file, fixP->fx_line,
26809 _("invalid constant (%lx) after fixup"),
26810 (unsigned long) value);
26811 break;
3631a3c8
NC
26812 }
26813
c19d1205
ZW
26814 newval |= (newimm & 0x800) << 15;
26815 newval |= (newimm & 0x700) << 4;
26816 newval |= (newimm & 0x0ff);
cc8a6dd0 26817
c19d1205
ZW
26818 md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
26819 md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
26820 break;
a737bd4d 26821
3eb17e6b 26822 case BFD_RELOC_ARM_SMC:
c19d1205
ZW
26823 if (((unsigned long) value) > 0xffff)
26824 as_bad_where (fixP->fx_file, fixP->fx_line,
3eb17e6b 26825 _("invalid smc expression"));
2fc8bdac 26826 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
26827 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
26828 md_number_to_chars (buf, newval, INSN_SIZE);
26829 break;
a737bd4d 26830
90ec0d68
MGD
26831 case BFD_RELOC_ARM_HVC:
26832 if (((unsigned long) value) > 0xffff)
26833 as_bad_where (fixP->fx_file, fixP->fx_line,
26834 _("invalid hvc expression"));
26835 newval = md_chars_to_number (buf, INSN_SIZE);
26836 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
26837 md_number_to_chars (buf, newval, INSN_SIZE);
26838 break;
26839
c19d1205 26840 case BFD_RELOC_ARM_SWI:
adbaf948 26841 if (fixP->tc_fix_data != 0)
c19d1205
ZW
26842 {
26843 if (((unsigned long) value) > 0xff)
26844 as_bad_where (fixP->fx_file, fixP->fx_line,
26845 _("invalid swi expression"));
2fc8bdac 26846 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205
ZW
26847 newval |= value;
26848 md_number_to_chars (buf, newval, THUMB_SIZE);
26849 }
26850 else
26851 {
26852 if (((unsigned long) value) > 0x00ffffff)
26853 as_bad_where (fixP->fx_file, fixP->fx_line,
26854 _("invalid swi expression"));
2fc8bdac 26855 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
26856 newval |= value;
26857 md_number_to_chars (buf, newval, INSN_SIZE);
26858 }
26859 break;
a737bd4d 26860
c19d1205
ZW
26861 case BFD_RELOC_ARM_MULTI:
26862 if (((unsigned long) value) > 0xffff)
26863 as_bad_where (fixP->fx_file, fixP->fx_line,
26864 _("invalid expression in load/store multiple"));
26865 newval = value | md_chars_to_number (buf, INSN_SIZE);
26866 md_number_to_chars (buf, newval, INSN_SIZE);
26867 break;
a737bd4d 26868
c19d1205 26869#ifdef OBJ_ELF
39b41c9c 26870 case BFD_RELOC_ARM_PCREL_CALL:
267bf995
RR
26871
26872 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
26873 && fixP->fx_addsy
34e77a92 26874 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
26875 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
26876 && THUMB_IS_FUNC (fixP->fx_addsy))
26877 /* Flip the bl to blx. This is a simple flip
26878 bit here because we generate PCREL_CALL for
26879 unconditional bls. */
26880 {
26881 newval = md_chars_to_number (buf, INSN_SIZE);
26882 newval = newval | 0x10000000;
26883 md_number_to_chars (buf, newval, INSN_SIZE);
26884 temp = 1;
26885 fixP->fx_done = 1;
26886 }
39b41c9c
PB
26887 else
26888 temp = 3;
26889 goto arm_branch_common;
26890
26891 case BFD_RELOC_ARM_PCREL_JUMP:
267bf995
RR
26892 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
26893 && fixP->fx_addsy
34e77a92 26894 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
26895 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
26896 && THUMB_IS_FUNC (fixP->fx_addsy))
26897 {
26898 /* This would map to a bl<cond>, b<cond>,
26899 b<always> to a Thumb function. We
26900 need to force a relocation for this particular
26901 case. */
26902 newval = md_chars_to_number (buf, INSN_SIZE);
26903 fixP->fx_done = 0;
26904 }
1a0670f3 26905 /* Fall through. */
267bf995 26906
2fc8bdac 26907 case BFD_RELOC_ARM_PLT32:
c19d1205 26908#endif
39b41c9c
PB
26909 case BFD_RELOC_ARM_PCREL_BRANCH:
26910 temp = 3;
26911 goto arm_branch_common;
a737bd4d 26912
39b41c9c 26913 case BFD_RELOC_ARM_PCREL_BLX:
267bf995 26914
39b41c9c 26915 temp = 1;
267bf995
RR
26916 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
26917 && fixP->fx_addsy
34e77a92 26918 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
26919 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
26920 && ARM_IS_FUNC (fixP->fx_addsy))
26921 {
26922 /* Flip the blx to a bl and warn. */
26923 const char *name = S_GET_NAME (fixP->fx_addsy);
26924 newval = 0xeb000000;
26925 as_warn_where (fixP->fx_file, fixP->fx_line,
26926 _("blx to '%s' an ARM ISA state function changed to bl"),
26927 name);
26928 md_number_to_chars (buf, newval, INSN_SIZE);
26929 temp = 3;
26930 fixP->fx_done = 1;
26931 }
26932
26933#ifdef OBJ_ELF
26934 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
477330fc 26935 fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
267bf995
RR
26936#endif
26937
39b41c9c 26938 arm_branch_common:
c19d1205 26939 /* We are going to store value (shifted right by two) in the
39b41c9c
PB
26940 instruction, in a 24 bit, signed field. Bits 26 through 32 either
26941 all clear or all set and bit 0 must be clear. For B/BL bit 1 must
de194d85 26942 also be clear. */
39b41c9c 26943 if (value & temp)
c19d1205 26944 as_bad_where (fixP->fx_file, fixP->fx_line,
2fc8bdac
ZW
26945 _("misaligned branch destination"));
26946 if ((value & (offsetT)0xfe000000) != (offsetT)0
26947 && (value & (offsetT)0xfe000000) != (offsetT)0xfe000000)
08f10d51 26948 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 26949
2fc8bdac 26950 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 26951 {
2fc8bdac
ZW
26952 newval = md_chars_to_number (buf, INSN_SIZE);
26953 newval |= (value >> 2) & 0x00ffffff;
7ae2971b
PB
26954 /* Set the H bit on BLX instructions. */
26955 if (temp == 1)
26956 {
26957 if (value & 2)
26958 newval |= 0x01000000;
26959 else
26960 newval &= ~0x01000000;
26961 }
2fc8bdac 26962 md_number_to_chars (buf, newval, INSN_SIZE);
c19d1205 26963 }
c19d1205 26964 break;
a737bd4d 26965
25fe350b
MS
26966 case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CBZ */
26967 /* CBZ can only branch forward. */
a737bd4d 26968
738755b0 26969 /* Attempts to use CBZ to branch to the next instruction
477330fc
RM
26970 (which, strictly speaking, are prohibited) will be turned into
26971 no-ops.
738755b0
MS
26972
26973 FIXME: It may be better to remove the instruction completely and
26974 perform relaxation. */
26975 if (value == -2)
2fc8bdac
ZW
26976 {
26977 newval = md_chars_to_number (buf, THUMB_SIZE);
738755b0 26978 newval = 0xbf00; /* NOP encoding T1 */
2fc8bdac
ZW
26979 md_number_to_chars (buf, newval, THUMB_SIZE);
26980 }
738755b0
MS
26981 else
26982 {
26983 if (value & ~0x7e)
08f10d51 26984 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
738755b0 26985
477330fc 26986 if (fixP->fx_done || !seg->use_rela_p)
738755b0
MS
26987 {
26988 newval = md_chars_to_number (buf, THUMB_SIZE);
26989 newval |= ((value & 0x3e) << 2) | ((value & 0x40) << 3);
26990 md_number_to_chars (buf, newval, THUMB_SIZE);
26991 }
26992 }
c19d1205 26993 break;
a737bd4d 26994
c19d1205 26995 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
2fc8bdac 26996 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
08f10d51 26997 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 26998
2fc8bdac
ZW
26999 if (fixP->fx_done || !seg->use_rela_p)
27000 {
27001 newval = md_chars_to_number (buf, THUMB_SIZE);
27002 newval |= (value & 0x1ff) >> 1;
27003 md_number_to_chars (buf, newval, THUMB_SIZE);
27004 }
c19d1205 27005 break;
a737bd4d 27006
c19d1205 27007 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
2fc8bdac 27008 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
08f10d51 27009 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 27010
2fc8bdac
ZW
27011 if (fixP->fx_done || !seg->use_rela_p)
27012 {
27013 newval = md_chars_to_number (buf, THUMB_SIZE);
27014 newval |= (value & 0xfff) >> 1;
27015 md_number_to_chars (buf, newval, THUMB_SIZE);
27016 }
c19d1205 27017 break;
a737bd4d 27018
c19d1205 27019 case BFD_RELOC_THUMB_PCREL_BRANCH20:
267bf995
RR
27020 if (fixP->fx_addsy
27021 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 27022 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27023 && ARM_IS_FUNC (fixP->fx_addsy)
27024 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
27025 {
27026 /* Force a relocation for a branch 20 bits wide. */
27027 fixP->fx_done = 0;
27028 }
08f10d51 27029 if ((value & ~0x1fffff) && ((value & ~0x0fffff) != ~0x0fffff))
2fc8bdac
ZW
27030 as_bad_where (fixP->fx_file, fixP->fx_line,
27031 _("conditional branch out of range"));
404ff6b5 27032
2fc8bdac
ZW
27033 if (fixP->fx_done || !seg->use_rela_p)
27034 {
27035 offsetT newval2;
27036 addressT S, J1, J2, lo, hi;
404ff6b5 27037
2fc8bdac
ZW
27038 S = (value & 0x00100000) >> 20;
27039 J2 = (value & 0x00080000) >> 19;
27040 J1 = (value & 0x00040000) >> 18;
27041 hi = (value & 0x0003f000) >> 12;
27042 lo = (value & 0x00000ffe) >> 1;
6c43fab6 27043
2fc8bdac
ZW
27044 newval = md_chars_to_number (buf, THUMB_SIZE);
27045 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27046 newval |= (S << 10) | hi;
27047 newval2 |= (J1 << 13) | (J2 << 11) | lo;
27048 md_number_to_chars (buf, newval, THUMB_SIZE);
27049 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
27050 }
c19d1205 27051 break;
6c43fab6 27052
c19d1205 27053 case BFD_RELOC_THUMB_PCREL_BLX:
267bf995
RR
27054 /* If there is a blx from a thumb state function to
27055 another thumb function flip this to a bl and warn
27056 about it. */
27057
27058 if (fixP->fx_addsy
34e77a92 27059 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27060 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27061 && THUMB_IS_FUNC (fixP->fx_addsy))
27062 {
27063 const char *name = S_GET_NAME (fixP->fx_addsy);
27064 as_warn_where (fixP->fx_file, fixP->fx_line,
27065 _("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
27066 name);
27067 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27068 newval = newval | 0x1000;
27069 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
27070 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
27071 fixP->fx_done = 1;
27072 }
27073
27074
27075 goto thumb_bl_common;
27076
c19d1205 27077 case BFD_RELOC_THUMB_PCREL_BRANCH23:
267bf995
RR
27078 /* A bl from Thumb state ISA to an internal ARM state function
27079 is converted to a blx. */
27080 if (fixP->fx_addsy
27081 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 27082 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
27083 && ARM_IS_FUNC (fixP->fx_addsy)
27084 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
27085 {
27086 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27087 newval = newval & ~0x1000;
27088 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
27089 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
27090 fixP->fx_done = 1;
27091 }
27092
27093 thumb_bl_common:
27094
2fc8bdac
ZW
27095 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
27096 /* For a BLX instruction, make sure that the relocation is rounded up
27097 to a word boundary. This follows the semantics of the instruction
27098 which specifies that bit 1 of the target address will come from bit
27099 1 of the base address. */
d406f3e4
JB
27100 value = (value + 3) & ~ 3;
27101
27102#ifdef OBJ_ELF
27103 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
27104 && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
27105 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
27106#endif
404ff6b5 27107
2b2f5df9
NC
27108 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
27109 {
fc289b0a 27110 if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)))
2b2f5df9
NC
27111 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
27112 else if ((value & ~0x1ffffff)
27113 && ((value & ~0x1ffffff) != ~0x1ffffff))
27114 as_bad_where (fixP->fx_file, fixP->fx_line,
27115 _("Thumb2 branch out of range"));
27116 }
4a42ebbc
RR
27117
27118 if (fixP->fx_done || !seg->use_rela_p)
27119 encode_thumb2_b_bl_offset (buf, value);
27120
c19d1205 27121 break;
404ff6b5 27122
c19d1205 27123 case BFD_RELOC_THUMB_PCREL_BRANCH25:
08f10d51
NC
27124 if ((value & ~0x0ffffff) && ((value & ~0x0ffffff) != ~0x0ffffff))
27125 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
6c43fab6 27126
2fc8bdac 27127 if (fixP->fx_done || !seg->use_rela_p)
4a42ebbc 27128 encode_thumb2_b_bl_offset (buf, value);
6c43fab6 27129
2fc8bdac 27130 break;
a737bd4d 27131
2fc8bdac
ZW
27132 case BFD_RELOC_8:
27133 if (fixP->fx_done || !seg->use_rela_p)
4b1a927e 27134 *buf = value;
c19d1205 27135 break;
a737bd4d 27136
c19d1205 27137 case BFD_RELOC_16:
2fc8bdac 27138 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 27139 md_number_to_chars (buf, value, 2);
c19d1205 27140 break;
a737bd4d 27141
c19d1205 27142#ifdef OBJ_ELF
0855e32b
NS
27143 case BFD_RELOC_ARM_TLS_CALL:
27144 case BFD_RELOC_ARM_THM_TLS_CALL:
27145 case BFD_RELOC_ARM_TLS_DESCSEQ:
27146 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
0855e32b 27147 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205
ZW
27148 case BFD_RELOC_ARM_TLS_GD32:
27149 case BFD_RELOC_ARM_TLS_LE32:
27150 case BFD_RELOC_ARM_TLS_IE32:
27151 case BFD_RELOC_ARM_TLS_LDM32:
27152 case BFD_RELOC_ARM_TLS_LDO32:
27153 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4b1a927e 27154 break;
6c43fab6 27155
5c5a4843
CL
27156 /* Same handling as above, but with the arm_fdpic guard. */
27157 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
27158 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
27159 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
27160 if (arm_fdpic)
27161 {
27162 S_SET_THREAD_LOCAL (fixP->fx_addsy);
27163 }
27164 else
27165 {
27166 as_bad_where (fixP->fx_file, fixP->fx_line,
27167 _("Relocation supported only in FDPIC mode"));
27168 }
27169 break;
27170
c19d1205
ZW
27171 case BFD_RELOC_ARM_GOT32:
27172 case BFD_RELOC_ARM_GOTOFF:
c19d1205 27173 break;
b43420e6
NC
27174
27175 case BFD_RELOC_ARM_GOT_PREL:
27176 if (fixP->fx_done || !seg->use_rela_p)
477330fc 27177 md_number_to_chars (buf, value, 4);
b43420e6
NC
27178 break;
27179
9a6f4e97
NS
27180 case BFD_RELOC_ARM_TARGET2:
27181 /* TARGET2 is not partial-inplace, so we need to write the
477330fc
RM
27182 addend here for REL targets, because it won't be written out
27183 during reloc processing later. */
9a6f4e97
NS
27184 if (fixP->fx_done || !seg->use_rela_p)
27185 md_number_to_chars (buf, fixP->fx_offset, 4);
27186 break;
188fd7ae
CL
27187
27188 /* Relocations for FDPIC. */
27189 case BFD_RELOC_ARM_GOTFUNCDESC:
27190 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
27191 case BFD_RELOC_ARM_FUNCDESC:
27192 if (arm_fdpic)
27193 {
27194 if (fixP->fx_done || !seg->use_rela_p)
27195 md_number_to_chars (buf, 0, 4);
27196 }
27197 else
27198 {
27199 as_bad_where (fixP->fx_file, fixP->fx_line,
27200 _("Relocation supported only in FDPIC mode"));
27201 }
27202 break;
c19d1205 27203#endif
6c43fab6 27204
c19d1205
ZW
27205 case BFD_RELOC_RVA:
27206 case BFD_RELOC_32:
27207 case BFD_RELOC_ARM_TARGET1:
27208 case BFD_RELOC_ARM_ROSEGREL32:
27209 case BFD_RELOC_ARM_SBREL32:
27210 case BFD_RELOC_32_PCREL:
f0927246
NC
27211#ifdef TE_PE
27212 case BFD_RELOC_32_SECREL:
27213#endif
2fc8bdac 27214 if (fixP->fx_done || !seg->use_rela_p)
53baae48
NC
27215#ifdef TE_WINCE
27216 /* For WinCE we only do this for pcrel fixups. */
27217 if (fixP->fx_done || fixP->fx_pcrel)
27218#endif
27219 md_number_to_chars (buf, value, 4);
c19d1205 27220 break;
6c43fab6 27221
c19d1205
ZW
27222#ifdef OBJ_ELF
27223 case BFD_RELOC_ARM_PREL31:
2fc8bdac 27224 if (fixP->fx_done || !seg->use_rela_p)
c19d1205
ZW
27225 {
27226 newval = md_chars_to_number (buf, 4) & 0x80000000;
27227 if ((value ^ (value >> 1)) & 0x40000000)
27228 {
27229 as_bad_where (fixP->fx_file, fixP->fx_line,
27230 _("rel31 relocation overflow"));
27231 }
27232 newval |= value & 0x7fffffff;
27233 md_number_to_chars (buf, newval, 4);
27234 }
27235 break;
c19d1205 27236#endif
a737bd4d 27237
c19d1205 27238 case BFD_RELOC_ARM_CP_OFF_IMM:
8f06b2d8 27239 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
32c36c3c 27240 case BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM:
9db2f6b4
RL
27241 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
27242 newval = md_chars_to_number (buf, INSN_SIZE);
27243 else
27244 newval = get_thumb32_insn (buf);
27245 if ((newval & 0x0f200f00) == 0x0d000900)
27246 {
27247 /* This is a fp16 vstr/vldr. The immediate offset in the mnemonic
27248 has permitted values that are multiples of 2, in the range 0
27249 to 510. */
27250 if (value < -510 || value > 510 || (value & 1))
27251 as_bad_where (fixP->fx_file, fixP->fx_line,
27252 _("co-processor offset out of range"));
27253 }
32c36c3c
AV
27254 else if ((newval & 0xfe001f80) == 0xec000f80)
27255 {
27256 if (value < -511 || value > 512 || (value & 3))
27257 as_bad_where (fixP->fx_file, fixP->fx_line,
27258 _("co-processor offset out of range"));
27259 }
9db2f6b4 27260 else if (value < -1023 || value > 1023 || (value & 3))
c19d1205
ZW
27261 as_bad_where (fixP->fx_file, fixP->fx_line,
27262 _("co-processor offset out of range"));
27263 cp_off_common:
26d97720 27264 sign = value > 0;
c19d1205
ZW
27265 if (value < 0)
27266 value = -value;
8f06b2d8
PB
27267 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
27268 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
27269 newval = md_chars_to_number (buf, INSN_SIZE);
27270 else
27271 newval = get_thumb32_insn (buf);
26d97720 27272 if (value == 0)
32c36c3c
AV
27273 {
27274 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
27275 newval &= 0xffffff80;
27276 else
27277 newval &= 0xffffff00;
27278 }
26d97720
NS
27279 else
27280 {
32c36c3c
AV
27281 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
27282 newval &= 0xff7fff80;
27283 else
27284 newval &= 0xff7fff00;
9db2f6b4
RL
27285 if ((newval & 0x0f200f00) == 0x0d000900)
27286 {
27287 /* This is a fp16 vstr/vldr.
27288
27289 It requires the immediate offset in the instruction is shifted
27290 left by 1 to be a half-word offset.
27291
27292 Here, left shift by 1 first, and later right shift by 2
27293 should get the right offset. */
27294 value <<= 1;
27295 }
26d97720
NS
27296 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
27297 }
8f06b2d8
PB
27298 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
27299 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
27300 md_number_to_chars (buf, newval, INSN_SIZE);
27301 else
27302 put_thumb32_insn (buf, newval);
c19d1205 27303 break;
a737bd4d 27304
c19d1205 27305 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
8f06b2d8 27306 case BFD_RELOC_ARM_T32_CP_OFF_IMM_S2:
c19d1205
ZW
27307 if (value < -255 || value > 255)
27308 as_bad_where (fixP->fx_file, fixP->fx_line,
27309 _("co-processor offset out of range"));
df7849c5 27310 value *= 4;
c19d1205 27311 goto cp_off_common;
6c43fab6 27312
c19d1205
ZW
27313 case BFD_RELOC_ARM_THUMB_OFFSET:
27314 newval = md_chars_to_number (buf, THUMB_SIZE);
27315 /* Exactly what ranges, and where the offset is inserted depends
27316 on the type of instruction, we can establish this from the
27317 top 4 bits. */
27318 switch (newval >> 12)
27319 {
27320 case 4: /* PC load. */
27321 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
27322 forced to zero for these loads; md_pcrel_from has already
27323 compensated for this. */
27324 if (value & 3)
27325 as_bad_where (fixP->fx_file, fixP->fx_line,
27326 _("invalid offset, target not word aligned (0x%08lX)"),
0359e808
NC
27327 (((unsigned long) fixP->fx_frag->fr_address
27328 + (unsigned long) fixP->fx_where) & ~3)
27329 + (unsigned long) value);
a737bd4d 27330
c19d1205
ZW
27331 if (value & ~0x3fc)
27332 as_bad_where (fixP->fx_file, fixP->fx_line,
27333 _("invalid offset, value too big (0x%08lX)"),
27334 (long) value);
a737bd4d 27335
c19d1205
ZW
27336 newval |= value >> 2;
27337 break;
a737bd4d 27338
c19d1205
ZW
27339 case 9: /* SP load/store. */
27340 if (value & ~0x3fc)
27341 as_bad_where (fixP->fx_file, fixP->fx_line,
27342 _("invalid offset, value too big (0x%08lX)"),
27343 (long) value);
27344 newval |= value >> 2;
27345 break;
6c43fab6 27346
c19d1205
ZW
27347 case 6: /* Word load/store. */
27348 if (value & ~0x7c)
27349 as_bad_where (fixP->fx_file, fixP->fx_line,
27350 _("invalid offset, value too big (0x%08lX)"),
27351 (long) value);
27352 newval |= value << 4; /* 6 - 2. */
27353 break;
a737bd4d 27354
c19d1205
ZW
27355 case 7: /* Byte load/store. */
27356 if (value & ~0x1f)
27357 as_bad_where (fixP->fx_file, fixP->fx_line,
27358 _("invalid offset, value too big (0x%08lX)"),
27359 (long) value);
27360 newval |= value << 6;
27361 break;
a737bd4d 27362
c19d1205
ZW
27363 case 8: /* Halfword load/store. */
27364 if (value & ~0x3e)
27365 as_bad_where (fixP->fx_file, fixP->fx_line,
27366 _("invalid offset, value too big (0x%08lX)"),
27367 (long) value);
27368 newval |= value << 5; /* 6 - 1. */
27369 break;
a737bd4d 27370
c19d1205
ZW
27371 default:
27372 as_bad_where (fixP->fx_file, fixP->fx_line,
27373 "Unable to process relocation for thumb opcode: %lx",
27374 (unsigned long) newval);
27375 break;
27376 }
27377 md_number_to_chars (buf, newval, THUMB_SIZE);
27378 break;
a737bd4d 27379
c19d1205
ZW
27380 case BFD_RELOC_ARM_THUMB_ADD:
27381 /* This is a complicated relocation, since we use it for all of
27382 the following immediate relocations:
a737bd4d 27383
c19d1205
ZW
27384 3bit ADD/SUB
27385 8bit ADD/SUB
27386 9bit ADD/SUB SP word-aligned
27387 10bit ADD PC/SP word-aligned
a737bd4d 27388
c19d1205
ZW
27389 The type of instruction being processed is encoded in the
27390 instruction field:
a737bd4d 27391
c19d1205
ZW
27392 0x8000 SUB
27393 0x00F0 Rd
27394 0x000F Rs
27395 */
27396 newval = md_chars_to_number (buf, THUMB_SIZE);
27397 {
27398 int rd = (newval >> 4) & 0xf;
27399 int rs = newval & 0xf;
27400 int subtract = !!(newval & 0x8000);
a737bd4d 27401
c19d1205
ZW
27402 /* Check for HI regs, only very restricted cases allowed:
27403 Adjusting SP, and using PC or SP to get an address. */
27404 if ((rd > 7 && (rd != REG_SP || rs != REG_SP))
27405 || (rs > 7 && rs != REG_SP && rs != REG_PC))
27406 as_bad_where (fixP->fx_file, fixP->fx_line,
27407 _("invalid Hi register with immediate"));
a737bd4d 27408
c19d1205
ZW
27409 /* If value is negative, choose the opposite instruction. */
27410 if (value < 0)
27411 {
27412 value = -value;
27413 subtract = !subtract;
27414 if (value < 0)
27415 as_bad_where (fixP->fx_file, fixP->fx_line,
27416 _("immediate value out of range"));
27417 }
a737bd4d 27418
c19d1205
ZW
27419 if (rd == REG_SP)
27420 {
75c11999 27421 if (value & ~0x1fc)
c19d1205
ZW
27422 as_bad_where (fixP->fx_file, fixP->fx_line,
27423 _("invalid immediate for stack address calculation"));
27424 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
27425 newval |= value >> 2;
27426 }
27427 else if (rs == REG_PC || rs == REG_SP)
27428 {
c12d2c9d
NC
27429 /* PR gas/18541. If the addition is for a defined symbol
27430 within range of an ADR instruction then accept it. */
27431 if (subtract
27432 && value == 4
27433 && fixP->fx_addsy != NULL)
27434 {
27435 subtract = 0;
27436
27437 if (! S_IS_DEFINED (fixP->fx_addsy)
27438 || S_GET_SEGMENT (fixP->fx_addsy) != seg
27439 || S_IS_WEAK (fixP->fx_addsy))
27440 {
27441 as_bad_where (fixP->fx_file, fixP->fx_line,
27442 _("address calculation needs a strongly defined nearby symbol"));
27443 }
27444 else
27445 {
27446 offsetT v = fixP->fx_where + fixP->fx_frag->fr_address;
27447
27448 /* Round up to the next 4-byte boundary. */
27449 if (v & 3)
27450 v = (v + 3) & ~ 3;
27451 else
27452 v += 4;
27453 v = S_GET_VALUE (fixP->fx_addsy) - v;
27454
27455 if (v & ~0x3fc)
27456 {
27457 as_bad_where (fixP->fx_file, fixP->fx_line,
27458 _("symbol too far away"));
27459 }
27460 else
27461 {
27462 fixP->fx_done = 1;
27463 value = v;
27464 }
27465 }
27466 }
27467
c19d1205
ZW
27468 if (subtract || value & ~0x3fc)
27469 as_bad_where (fixP->fx_file, fixP->fx_line,
27470 _("invalid immediate for address calculation (value = 0x%08lX)"),
5fc177c8 27471 (unsigned long) (subtract ? - value : value));
c19d1205
ZW
27472 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
27473 newval |= rd << 8;
27474 newval |= value >> 2;
27475 }
27476 else if (rs == rd)
27477 {
27478 if (value & ~0xff)
27479 as_bad_where (fixP->fx_file, fixP->fx_line,
27480 _("immediate value out of range"));
27481 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
27482 newval |= (rd << 8) | value;
27483 }
27484 else
27485 {
27486 if (value & ~0x7)
27487 as_bad_where (fixP->fx_file, fixP->fx_line,
27488 _("immediate value out of range"));
27489 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
27490 newval |= rd | (rs << 3) | (value << 6);
27491 }
27492 }
27493 md_number_to_chars (buf, newval, THUMB_SIZE);
27494 break;
a737bd4d 27495
c19d1205
ZW
27496 case BFD_RELOC_ARM_THUMB_IMM:
27497 newval = md_chars_to_number (buf, THUMB_SIZE);
27498 if (value < 0 || value > 255)
27499 as_bad_where (fixP->fx_file, fixP->fx_line,
4e6e072b 27500 _("invalid immediate: %ld is out of range"),
c19d1205
ZW
27501 (long) value);
27502 newval |= value;
27503 md_number_to_chars (buf, newval, THUMB_SIZE);
27504 break;
a737bd4d 27505
c19d1205
ZW
27506 case BFD_RELOC_ARM_THUMB_SHIFT:
27507 /* 5bit shift value (0..32). LSL cannot take 32. */
27508 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf83f;
27509 temp = newval & 0xf800;
27510 if (value < 0 || value > 32 || (value == 32 && temp == T_OPCODE_LSL_I))
27511 as_bad_where (fixP->fx_file, fixP->fx_line,
27512 _("invalid shift value: %ld"), (long) value);
27513 /* Shifts of zero must be encoded as LSL. */
27514 if (value == 0)
27515 newval = (newval & 0x003f) | T_OPCODE_LSL_I;
27516 /* Shifts of 32 are encoded as zero. */
27517 else if (value == 32)
27518 value = 0;
27519 newval |= value << 6;
27520 md_number_to_chars (buf, newval, THUMB_SIZE);
27521 break;
a737bd4d 27522
c19d1205
ZW
27523 case BFD_RELOC_VTABLE_INHERIT:
27524 case BFD_RELOC_VTABLE_ENTRY:
27525 fixP->fx_done = 0;
27526 return;
6c43fab6 27527
b6895b4f
PB
27528 case BFD_RELOC_ARM_MOVW:
27529 case BFD_RELOC_ARM_MOVT:
27530 case BFD_RELOC_ARM_THUMB_MOVW:
27531 case BFD_RELOC_ARM_THUMB_MOVT:
27532 if (fixP->fx_done || !seg->use_rela_p)
27533 {
27534 /* REL format relocations are limited to a 16-bit addend. */
27535 if (!fixP->fx_done)
27536 {
39623e12 27537 if (value < -0x8000 || value > 0x7fff)
b6895b4f 27538 as_bad_where (fixP->fx_file, fixP->fx_line,
ff5075ca 27539 _("offset out of range"));
b6895b4f
PB
27540 }
27541 else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT
27542 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
27543 {
27544 value >>= 16;
27545 }
27546
27547 if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
27548 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
27549 {
27550 newval = get_thumb32_insn (buf);
27551 newval &= 0xfbf08f00;
27552 newval |= (value & 0xf000) << 4;
27553 newval |= (value & 0x0800) << 15;
27554 newval |= (value & 0x0700) << 4;
27555 newval |= (value & 0x00ff);
27556 put_thumb32_insn (buf, newval);
27557 }
27558 else
27559 {
27560 newval = md_chars_to_number (buf, 4);
27561 newval &= 0xfff0f000;
27562 newval |= value & 0x0fff;
27563 newval |= (value & 0xf000) << 4;
27564 md_number_to_chars (buf, newval, 4);
27565 }
27566 }
27567 return;
27568
72d98d16
MG
27569 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
27570 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
27571 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
27572 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
27573 gas_assert (!fixP->fx_done);
27574 {
27575 bfd_vma insn;
27576 bfd_boolean is_mov;
27577 bfd_vma encoded_addend = value;
27578
27579 /* Check that addend can be encoded in instruction. */
27580 if (!seg->use_rela_p && (value < 0 || value > 255))
27581 as_bad_where (fixP->fx_file, fixP->fx_line,
27582 _("the offset 0x%08lX is not representable"),
27583 (unsigned long) encoded_addend);
27584
27585 /* Extract the instruction. */
27586 insn = md_chars_to_number (buf, THUMB_SIZE);
27587 is_mov = (insn & 0xf800) == 0x2000;
27588
27589 /* Encode insn. */
27590 if (is_mov)
27591 {
27592 if (!seg->use_rela_p)
27593 insn |= encoded_addend;
27594 }
27595 else
27596 {
27597 int rd, rs;
27598
27599 /* Extract the instruction. */
27600 /* Encoding is the following
27601 0x8000 SUB
27602 0x00F0 Rd
27603 0x000F Rs
27604 */
27605 /* The following conditions must be true :
27606 - ADD
27607 - Rd == Rs
27608 - Rd <= 7
27609 */
27610 rd = (insn >> 4) & 0xf;
27611 rs = insn & 0xf;
27612 if ((insn & 0x8000) || (rd != rs) || rd > 7)
27613 as_bad_where (fixP->fx_file, fixP->fx_line,
27614 _("Unable to process relocation for thumb opcode: %lx"),
27615 (unsigned long) insn);
27616
27617 /* Encode as ADD immediate8 thumb 1 code. */
27618 insn = 0x3000 | (rd << 8);
27619
27620 /* Place the encoded addend into the first 8 bits of the
27621 instruction. */
27622 if (!seg->use_rela_p)
27623 insn |= encoded_addend;
27624 }
27625
27626 /* Update the instruction. */
27627 md_number_to_chars (buf, insn, THUMB_SIZE);
27628 }
27629 break;
27630
4962c51a
MS
27631 case BFD_RELOC_ARM_ALU_PC_G0_NC:
27632 case BFD_RELOC_ARM_ALU_PC_G0:
27633 case BFD_RELOC_ARM_ALU_PC_G1_NC:
27634 case BFD_RELOC_ARM_ALU_PC_G1:
27635 case BFD_RELOC_ARM_ALU_PC_G2:
27636 case BFD_RELOC_ARM_ALU_SB_G0_NC:
27637 case BFD_RELOC_ARM_ALU_SB_G0:
27638 case BFD_RELOC_ARM_ALU_SB_G1_NC:
27639 case BFD_RELOC_ARM_ALU_SB_G1:
27640 case BFD_RELOC_ARM_ALU_SB_G2:
9c2799c2 27641 gas_assert (!fixP->fx_done);
4962c51a
MS
27642 if (!seg->use_rela_p)
27643 {
477330fc
RM
27644 bfd_vma insn;
27645 bfd_vma encoded_addend;
3ca4a8ec 27646 bfd_vma addend_abs = llabs (value);
477330fc
RM
27647
27648 /* Check that the absolute value of the addend can be
27649 expressed as an 8-bit constant plus a rotation. */
27650 encoded_addend = encode_arm_immediate (addend_abs);
27651 if (encoded_addend == (unsigned int) FAIL)
4962c51a 27652 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
27653 _("the offset 0x%08lX is not representable"),
27654 (unsigned long) addend_abs);
27655
27656 /* Extract the instruction. */
27657 insn = md_chars_to_number (buf, INSN_SIZE);
27658
27659 /* If the addend is positive, use an ADD instruction.
27660 Otherwise use a SUB. Take care not to destroy the S bit. */
27661 insn &= 0xff1fffff;
27662 if (value < 0)
27663 insn |= 1 << 22;
27664 else
27665 insn |= 1 << 23;
27666
27667 /* Place the encoded addend into the first 12 bits of the
27668 instruction. */
27669 insn &= 0xfffff000;
27670 insn |= encoded_addend;
27671
27672 /* Update the instruction. */
27673 md_number_to_chars (buf, insn, INSN_SIZE);
4962c51a
MS
27674 }
27675 break;
27676
27677 case BFD_RELOC_ARM_LDR_PC_G0:
27678 case BFD_RELOC_ARM_LDR_PC_G1:
27679 case BFD_RELOC_ARM_LDR_PC_G2:
27680 case BFD_RELOC_ARM_LDR_SB_G0:
27681 case BFD_RELOC_ARM_LDR_SB_G1:
27682 case BFD_RELOC_ARM_LDR_SB_G2:
9c2799c2 27683 gas_assert (!fixP->fx_done);
4962c51a 27684 if (!seg->use_rela_p)
477330fc
RM
27685 {
27686 bfd_vma insn;
3ca4a8ec 27687 bfd_vma addend_abs = llabs (value);
4962c51a 27688
477330fc
RM
27689 /* Check that the absolute value of the addend can be
27690 encoded in 12 bits. */
27691 if (addend_abs >= 0x1000)
4962c51a 27692 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
27693 _("bad offset 0x%08lX (only 12 bits available for the magnitude)"),
27694 (unsigned long) addend_abs);
27695
27696 /* Extract the instruction. */
27697 insn = md_chars_to_number (buf, INSN_SIZE);
27698
27699 /* If the addend is negative, clear bit 23 of the instruction.
27700 Otherwise set it. */
27701 if (value < 0)
27702 insn &= ~(1 << 23);
27703 else
27704 insn |= 1 << 23;
27705
27706 /* Place the absolute value of the addend into the first 12 bits
27707 of the instruction. */
27708 insn &= 0xfffff000;
27709 insn |= addend_abs;
27710
27711 /* Update the instruction. */
27712 md_number_to_chars (buf, insn, INSN_SIZE);
27713 }
4962c51a
MS
27714 break;
27715
27716 case BFD_RELOC_ARM_LDRS_PC_G0:
27717 case BFD_RELOC_ARM_LDRS_PC_G1:
27718 case BFD_RELOC_ARM_LDRS_PC_G2:
27719 case BFD_RELOC_ARM_LDRS_SB_G0:
27720 case BFD_RELOC_ARM_LDRS_SB_G1:
27721 case BFD_RELOC_ARM_LDRS_SB_G2:
9c2799c2 27722 gas_assert (!fixP->fx_done);
4962c51a 27723 if (!seg->use_rela_p)
477330fc
RM
27724 {
27725 bfd_vma insn;
3ca4a8ec 27726 bfd_vma addend_abs = llabs (value);
4962c51a 27727
477330fc
RM
27728 /* Check that the absolute value of the addend can be
27729 encoded in 8 bits. */
27730 if (addend_abs >= 0x100)
4962c51a 27731 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
27732 _("bad offset 0x%08lX (only 8 bits available for the magnitude)"),
27733 (unsigned long) addend_abs);
27734
27735 /* Extract the instruction. */
27736 insn = md_chars_to_number (buf, INSN_SIZE);
27737
27738 /* If the addend is negative, clear bit 23 of the instruction.
27739 Otherwise set it. */
27740 if (value < 0)
27741 insn &= ~(1 << 23);
27742 else
27743 insn |= 1 << 23;
27744
27745 /* Place the first four bits of the absolute value of the addend
27746 into the first 4 bits of the instruction, and the remaining
27747 four into bits 8 .. 11. */
27748 insn &= 0xfffff0f0;
27749 insn |= (addend_abs & 0xf) | ((addend_abs & 0xf0) << 4);
27750
27751 /* Update the instruction. */
27752 md_number_to_chars (buf, insn, INSN_SIZE);
27753 }
4962c51a
MS
27754 break;
27755
27756 case BFD_RELOC_ARM_LDC_PC_G0:
27757 case BFD_RELOC_ARM_LDC_PC_G1:
27758 case BFD_RELOC_ARM_LDC_PC_G2:
27759 case BFD_RELOC_ARM_LDC_SB_G0:
27760 case BFD_RELOC_ARM_LDC_SB_G1:
27761 case BFD_RELOC_ARM_LDC_SB_G2:
9c2799c2 27762 gas_assert (!fixP->fx_done);
4962c51a 27763 if (!seg->use_rela_p)
477330fc
RM
27764 {
27765 bfd_vma insn;
3ca4a8ec 27766 bfd_vma addend_abs = llabs (value);
4962c51a 27767
477330fc
RM
27768 /* Check that the absolute value of the addend is a multiple of
27769 four and, when divided by four, fits in 8 bits. */
27770 if (addend_abs & 0x3)
4962c51a 27771 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
27772 _("bad offset 0x%08lX (must be word-aligned)"),
27773 (unsigned long) addend_abs);
4962c51a 27774
477330fc 27775 if ((addend_abs >> 2) > 0xff)
4962c51a 27776 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
27777 _("bad offset 0x%08lX (must be an 8-bit number of words)"),
27778 (unsigned long) addend_abs);
27779
27780 /* Extract the instruction. */
27781 insn = md_chars_to_number (buf, INSN_SIZE);
27782
27783 /* If the addend is negative, clear bit 23 of the instruction.
27784 Otherwise set it. */
27785 if (value < 0)
27786 insn &= ~(1 << 23);
27787 else
27788 insn |= 1 << 23;
27789
27790 /* Place the addend (divided by four) into the first eight
27791 bits of the instruction. */
27792 insn &= 0xfffffff0;
27793 insn |= addend_abs >> 2;
27794
27795 /* Update the instruction. */
27796 md_number_to_chars (buf, insn, INSN_SIZE);
27797 }
4962c51a
MS
27798 break;
27799
e12437dc
AV
27800 case BFD_RELOC_THUMB_PCREL_BRANCH5:
27801 if (fixP->fx_addsy
27802 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27803 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
27804 && ARM_IS_FUNC (fixP->fx_addsy)
27805 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
27806 {
27807 /* Force a relocation for a branch 5 bits wide. */
27808 fixP->fx_done = 0;
27809 }
27810 if (v8_1_branch_value_check (value, 5, FALSE) == FAIL)
27811 as_bad_where (fixP->fx_file, fixP->fx_line,
27812 BAD_BRANCH_OFF);
27813
27814 if (fixP->fx_done || !seg->use_rela_p)
27815 {
27816 addressT boff = value >> 1;
27817
27818 newval = md_chars_to_number (buf, THUMB_SIZE);
27819 newval |= (boff << 7);
27820 md_number_to_chars (buf, newval, THUMB_SIZE);
27821 }
27822 break;
27823
f6b2b12d
AV
27824 case BFD_RELOC_THUMB_PCREL_BFCSEL:
27825 if (fixP->fx_addsy
27826 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27827 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
27828 && ARM_IS_FUNC (fixP->fx_addsy)
27829 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
27830 {
27831 fixP->fx_done = 0;
27832 }
27833 if ((value & ~0x7f) && ((value & ~0x3f) != ~0x3f))
27834 as_bad_where (fixP->fx_file, fixP->fx_line,
27835 _("branch out of range"));
27836
27837 if (fixP->fx_done || !seg->use_rela_p)
27838 {
27839 newval = md_chars_to_number (buf, THUMB_SIZE);
27840
27841 addressT boff = ((newval & 0x0780) >> 7) << 1;
27842 addressT diff = value - boff;
27843
27844 if (diff == 4)
27845 {
27846 newval |= 1 << 1; /* T bit. */
27847 }
27848 else if (diff != 2)
27849 {
27850 as_bad_where (fixP->fx_file, fixP->fx_line,
27851 _("out of range label-relative fixup value"));
27852 }
27853 md_number_to_chars (buf, newval, THUMB_SIZE);
27854 }
27855 break;
27856
e5d6e09e
AV
27857 case BFD_RELOC_ARM_THUMB_BF17:
27858 if (fixP->fx_addsy
27859 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27860 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
27861 && ARM_IS_FUNC (fixP->fx_addsy)
27862 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
27863 {
27864 /* Force a relocation for a branch 17 bits wide. */
27865 fixP->fx_done = 0;
27866 }
27867
27868 if (v8_1_branch_value_check (value, 17, TRUE) == FAIL)
27869 as_bad_where (fixP->fx_file, fixP->fx_line,
27870 BAD_BRANCH_OFF);
27871
27872 if (fixP->fx_done || !seg->use_rela_p)
27873 {
27874 offsetT newval2;
27875 addressT immA, immB, immC;
27876
27877 immA = (value & 0x0001f000) >> 12;
27878 immB = (value & 0x00000ffc) >> 2;
27879 immC = (value & 0x00000002) >> 1;
27880
27881 newval = md_chars_to_number (buf, THUMB_SIZE);
27882 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27883 newval |= immA;
27884 newval2 |= (immC << 11) | (immB << 1);
27885 md_number_to_chars (buf, newval, THUMB_SIZE);
27886 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
27887 }
27888 break;
27889
1caf72a5
AV
27890 case BFD_RELOC_ARM_THUMB_BF19:
27891 if (fixP->fx_addsy
27892 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27893 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
27894 && ARM_IS_FUNC (fixP->fx_addsy)
27895 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
27896 {
27897 /* Force a relocation for a branch 19 bits wide. */
27898 fixP->fx_done = 0;
27899 }
27900
27901 if (v8_1_branch_value_check (value, 19, TRUE) == FAIL)
27902 as_bad_where (fixP->fx_file, fixP->fx_line,
27903 BAD_BRANCH_OFF);
27904
27905 if (fixP->fx_done || !seg->use_rela_p)
27906 {
27907 offsetT newval2;
27908 addressT immA, immB, immC;
27909
27910 immA = (value & 0x0007f000) >> 12;
27911 immB = (value & 0x00000ffc) >> 2;
27912 immC = (value & 0x00000002) >> 1;
27913
27914 newval = md_chars_to_number (buf, THUMB_SIZE);
27915 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27916 newval |= immA;
27917 newval2 |= (immC << 11) | (immB << 1);
27918 md_number_to_chars (buf, newval, THUMB_SIZE);
27919 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
27920 }
27921 break;
27922
1889da70
AV
27923 case BFD_RELOC_ARM_THUMB_BF13:
27924 if (fixP->fx_addsy
27925 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27926 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
27927 && ARM_IS_FUNC (fixP->fx_addsy)
27928 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
27929 {
27930 /* Force a relocation for a branch 13 bits wide. */
27931 fixP->fx_done = 0;
27932 }
27933
27934 if (v8_1_branch_value_check (value, 13, TRUE) == FAIL)
27935 as_bad_where (fixP->fx_file, fixP->fx_line,
27936 BAD_BRANCH_OFF);
27937
27938 if (fixP->fx_done || !seg->use_rela_p)
27939 {
27940 offsetT newval2;
27941 addressT immA, immB, immC;
27942
27943 immA = (value & 0x00001000) >> 12;
27944 immB = (value & 0x00000ffc) >> 2;
27945 immC = (value & 0x00000002) >> 1;
27946
27947 newval = md_chars_to_number (buf, THUMB_SIZE);
27948 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27949 newval |= immA;
27950 newval2 |= (immC << 11) | (immB << 1);
27951 md_number_to_chars (buf, newval, THUMB_SIZE);
27952 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
27953 }
27954 break;
27955
60f993ce
AV
27956 case BFD_RELOC_ARM_THUMB_LOOP12:
27957 if (fixP->fx_addsy
27958 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
27959 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
27960 && ARM_IS_FUNC (fixP->fx_addsy)
27961 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
27962 {
27963 /* Force a relocation for a branch 12 bits wide. */
27964 fixP->fx_done = 0;
27965 }
27966
27967 bfd_vma insn = get_thumb32_insn (buf);
27968 /* le lr, <label> or le <label> */
27969 if (((insn & 0xffffffff) == 0xf00fc001)
27970 || ((insn & 0xffffffff) == 0xf02fc001))
27971 value = -value;
27972
27973 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
27974 as_bad_where (fixP->fx_file, fixP->fx_line,
27975 BAD_BRANCH_OFF);
27976 if (fixP->fx_done || !seg->use_rela_p)
27977 {
27978 addressT imml, immh;
27979
27980 immh = (value & 0x00000ffc) >> 2;
27981 imml = (value & 0x00000002) >> 1;
27982
27983 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
27984 newval |= (imml << 11) | (immh << 1);
27985 md_number_to_chars (buf + THUMB_SIZE, newval, THUMB_SIZE);
27986 }
27987 break;
27988
845b51d6
PB
27989 case BFD_RELOC_ARM_V4BX:
27990 /* This will need to go in the object file. */
27991 fixP->fx_done = 0;
27992 break;
27993
c19d1205
ZW
27994 case BFD_RELOC_UNUSED:
27995 default:
27996 as_bad_where (fixP->fx_file, fixP->fx_line,
27997 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
27998 }
6c43fab6
RE
27999}
28000
c19d1205
ZW
28001/* Translate internal representation of relocation info to BFD target
28002 format. */
a737bd4d 28003
c19d1205 28004arelent *
00a97672 28005tc_gen_reloc (asection *section, fixS *fixp)
a737bd4d 28006{
c19d1205
ZW
28007 arelent * reloc;
28008 bfd_reloc_code_real_type code;
a737bd4d 28009
325801bd 28010 reloc = XNEW (arelent);
a737bd4d 28011
325801bd 28012 reloc->sym_ptr_ptr = XNEW (asymbol *);
c19d1205
ZW
28013 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
28014 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
a737bd4d 28015
2fc8bdac 28016 if (fixp->fx_pcrel)
00a97672
RS
28017 {
28018 if (section->use_rela_p)
28019 fixp->fx_offset -= md_pcrel_from_section (fixp, section);
28020 else
28021 fixp->fx_offset = reloc->address;
28022 }
c19d1205 28023 reloc->addend = fixp->fx_offset;
a737bd4d 28024
c19d1205 28025 switch (fixp->fx_r_type)
a737bd4d 28026 {
c19d1205
ZW
28027 case BFD_RELOC_8:
28028 if (fixp->fx_pcrel)
28029 {
28030 code = BFD_RELOC_8_PCREL;
28031 break;
28032 }
1a0670f3 28033 /* Fall through. */
a737bd4d 28034
c19d1205
ZW
28035 case BFD_RELOC_16:
28036 if (fixp->fx_pcrel)
28037 {
28038 code = BFD_RELOC_16_PCREL;
28039 break;
28040 }
1a0670f3 28041 /* Fall through. */
6c43fab6 28042
c19d1205
ZW
28043 case BFD_RELOC_32:
28044 if (fixp->fx_pcrel)
28045 {
28046 code = BFD_RELOC_32_PCREL;
28047 break;
28048 }
1a0670f3 28049 /* Fall through. */
a737bd4d 28050
b6895b4f
PB
28051 case BFD_RELOC_ARM_MOVW:
28052 if (fixp->fx_pcrel)
28053 {
28054 code = BFD_RELOC_ARM_MOVW_PCREL;
28055 break;
28056 }
1a0670f3 28057 /* Fall through. */
b6895b4f
PB
28058
28059 case BFD_RELOC_ARM_MOVT:
28060 if (fixp->fx_pcrel)
28061 {
28062 code = BFD_RELOC_ARM_MOVT_PCREL;
28063 break;
28064 }
1a0670f3 28065 /* Fall through. */
b6895b4f
PB
28066
28067 case BFD_RELOC_ARM_THUMB_MOVW:
28068 if (fixp->fx_pcrel)
28069 {
28070 code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
28071 break;
28072 }
1a0670f3 28073 /* Fall through. */
b6895b4f
PB
28074
28075 case BFD_RELOC_ARM_THUMB_MOVT:
28076 if (fixp->fx_pcrel)
28077 {
28078 code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
28079 break;
28080 }
1a0670f3 28081 /* Fall through. */
b6895b4f 28082
c19d1205
ZW
28083 case BFD_RELOC_NONE:
28084 case BFD_RELOC_ARM_PCREL_BRANCH:
28085 case BFD_RELOC_ARM_PCREL_BLX:
28086 case BFD_RELOC_RVA:
28087 case BFD_RELOC_THUMB_PCREL_BRANCH7:
28088 case BFD_RELOC_THUMB_PCREL_BRANCH9:
28089 case BFD_RELOC_THUMB_PCREL_BRANCH12:
28090 case BFD_RELOC_THUMB_PCREL_BRANCH20:
28091 case BFD_RELOC_THUMB_PCREL_BRANCH23:
28092 case BFD_RELOC_THUMB_PCREL_BRANCH25:
c19d1205
ZW
28093 case BFD_RELOC_VTABLE_ENTRY:
28094 case BFD_RELOC_VTABLE_INHERIT:
f0927246
NC
28095#ifdef TE_PE
28096 case BFD_RELOC_32_SECREL:
28097#endif
c19d1205
ZW
28098 code = fixp->fx_r_type;
28099 break;
a737bd4d 28100
00adf2d4
JB
28101 case BFD_RELOC_THUMB_PCREL_BLX:
28102#ifdef OBJ_ELF
28103 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
28104 code = BFD_RELOC_THUMB_PCREL_BRANCH23;
28105 else
28106#endif
28107 code = BFD_RELOC_THUMB_PCREL_BLX;
28108 break;
28109
c19d1205
ZW
28110 case BFD_RELOC_ARM_LITERAL:
28111 case BFD_RELOC_ARM_HWLITERAL:
28112 /* If this is called then the a literal has
28113 been referenced across a section boundary. */
28114 as_bad_where (fixp->fx_file, fixp->fx_line,
28115 _("literal referenced across section boundary"));
28116 return NULL;
a737bd4d 28117
c19d1205 28118#ifdef OBJ_ELF
0855e32b
NS
28119 case BFD_RELOC_ARM_TLS_CALL:
28120 case BFD_RELOC_ARM_THM_TLS_CALL:
28121 case BFD_RELOC_ARM_TLS_DESCSEQ:
28122 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
c19d1205
ZW
28123 case BFD_RELOC_ARM_GOT32:
28124 case BFD_RELOC_ARM_GOTOFF:
b43420e6 28125 case BFD_RELOC_ARM_GOT_PREL:
c19d1205
ZW
28126 case BFD_RELOC_ARM_PLT32:
28127 case BFD_RELOC_ARM_TARGET1:
28128 case BFD_RELOC_ARM_ROSEGREL32:
28129 case BFD_RELOC_ARM_SBREL32:
28130 case BFD_RELOC_ARM_PREL31:
28131 case BFD_RELOC_ARM_TARGET2:
c19d1205 28132 case BFD_RELOC_ARM_TLS_LDO32:
39b41c9c
PB
28133 case BFD_RELOC_ARM_PCREL_CALL:
28134 case BFD_RELOC_ARM_PCREL_JUMP:
4962c51a
MS
28135 case BFD_RELOC_ARM_ALU_PC_G0_NC:
28136 case BFD_RELOC_ARM_ALU_PC_G0:
28137 case BFD_RELOC_ARM_ALU_PC_G1_NC:
28138 case BFD_RELOC_ARM_ALU_PC_G1:
28139 case BFD_RELOC_ARM_ALU_PC_G2:
28140 case BFD_RELOC_ARM_LDR_PC_G0:
28141 case BFD_RELOC_ARM_LDR_PC_G1:
28142 case BFD_RELOC_ARM_LDR_PC_G2:
28143 case BFD_RELOC_ARM_LDRS_PC_G0:
28144 case BFD_RELOC_ARM_LDRS_PC_G1:
28145 case BFD_RELOC_ARM_LDRS_PC_G2:
28146 case BFD_RELOC_ARM_LDC_PC_G0:
28147 case BFD_RELOC_ARM_LDC_PC_G1:
28148 case BFD_RELOC_ARM_LDC_PC_G2:
28149 case BFD_RELOC_ARM_ALU_SB_G0_NC:
28150 case BFD_RELOC_ARM_ALU_SB_G0:
28151 case BFD_RELOC_ARM_ALU_SB_G1_NC:
28152 case BFD_RELOC_ARM_ALU_SB_G1:
28153 case BFD_RELOC_ARM_ALU_SB_G2:
28154 case BFD_RELOC_ARM_LDR_SB_G0:
28155 case BFD_RELOC_ARM_LDR_SB_G1:
28156 case BFD_RELOC_ARM_LDR_SB_G2:
28157 case BFD_RELOC_ARM_LDRS_SB_G0:
28158 case BFD_RELOC_ARM_LDRS_SB_G1:
28159 case BFD_RELOC_ARM_LDRS_SB_G2:
28160 case BFD_RELOC_ARM_LDC_SB_G0:
28161 case BFD_RELOC_ARM_LDC_SB_G1:
28162 case BFD_RELOC_ARM_LDC_SB_G2:
845b51d6 28163 case BFD_RELOC_ARM_V4BX:
72d98d16
MG
28164 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
28165 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
28166 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
28167 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
188fd7ae
CL
28168 case BFD_RELOC_ARM_GOTFUNCDESC:
28169 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
28170 case BFD_RELOC_ARM_FUNCDESC:
e5d6e09e 28171 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 28172 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 28173 case BFD_RELOC_ARM_THUMB_BF13:
c19d1205
ZW
28174 code = fixp->fx_r_type;
28175 break;
a737bd4d 28176
0855e32b 28177 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205 28178 case BFD_RELOC_ARM_TLS_GD32:
5c5a4843 28179 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
75c11999 28180 case BFD_RELOC_ARM_TLS_LE32:
c19d1205 28181 case BFD_RELOC_ARM_TLS_IE32:
5c5a4843 28182 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
c19d1205 28183 case BFD_RELOC_ARM_TLS_LDM32:
5c5a4843 28184 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
c19d1205
ZW
28185 /* BFD will include the symbol's address in the addend.
28186 But we don't want that, so subtract it out again here. */
28187 if (!S_IS_COMMON (fixp->fx_addsy))
28188 reloc->addend -= (*reloc->sym_ptr_ptr)->value;
28189 code = fixp->fx_r_type;
28190 break;
28191#endif
a737bd4d 28192
c19d1205
ZW
28193 case BFD_RELOC_ARM_IMMEDIATE:
28194 as_bad_where (fixp->fx_file, fixp->fx_line,
28195 _("internal relocation (type: IMMEDIATE) not fixed up"));
28196 return NULL;
a737bd4d 28197
c19d1205
ZW
28198 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
28199 as_bad_where (fixp->fx_file, fixp->fx_line,
28200 _("ADRL used for a symbol not defined in the same file"));
28201 return NULL;
a737bd4d 28202
e12437dc 28203 case BFD_RELOC_THUMB_PCREL_BRANCH5:
f6b2b12d 28204 case BFD_RELOC_THUMB_PCREL_BFCSEL:
60f993ce 28205 case BFD_RELOC_ARM_THUMB_LOOP12:
e12437dc
AV
28206 as_bad_where (fixp->fx_file, fixp->fx_line,
28207 _("%s used for a symbol not defined in the same file"),
28208 bfd_get_reloc_code_name (fixp->fx_r_type));
28209 return NULL;
28210
c19d1205 28211 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
28212 if (section->use_rela_p)
28213 {
28214 code = fixp->fx_r_type;
28215 break;
28216 }
28217
c19d1205
ZW
28218 if (fixp->fx_addsy != NULL
28219 && !S_IS_DEFINED (fixp->fx_addsy)
28220 && S_IS_LOCAL (fixp->fx_addsy))
a737bd4d 28221 {
c19d1205
ZW
28222 as_bad_where (fixp->fx_file, fixp->fx_line,
28223 _("undefined local label `%s'"),
28224 S_GET_NAME (fixp->fx_addsy));
28225 return NULL;
a737bd4d
NC
28226 }
28227
c19d1205
ZW
28228 as_bad_where (fixp->fx_file, fixp->fx_line,
28229 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
28230 return NULL;
a737bd4d 28231
c19d1205
ZW
28232 default:
28233 {
e0471c16 28234 const char * type;
6c43fab6 28235
c19d1205
ZW
28236 switch (fixp->fx_r_type)
28237 {
28238 case BFD_RELOC_NONE: type = "NONE"; break;
28239 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
28240 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
3eb17e6b 28241 case BFD_RELOC_ARM_SMC: type = "SMC"; break;
c19d1205
ZW
28242 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
28243 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
28244 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
db187cb9 28245 case BFD_RELOC_ARM_T32_OFFSET_IMM: type = "T32_OFFSET_IMM"; break;
8f06b2d8 28246 case BFD_RELOC_ARM_T32_CP_OFF_IMM: type = "T32_CP_OFF_IMM"; break;
c19d1205
ZW
28247 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
28248 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
28249 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
28250 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
28251 default: type = _("<unknown>"); break;
28252 }
28253 as_bad_where (fixp->fx_file, fixp->fx_line,
28254 _("cannot represent %s relocation in this object file format"),
28255 type);
28256 return NULL;
28257 }
a737bd4d 28258 }
6c43fab6 28259
c19d1205
ZW
28260#ifdef OBJ_ELF
28261 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
28262 && GOT_symbol
28263 && fixp->fx_addsy == GOT_symbol)
28264 {
28265 code = BFD_RELOC_ARM_GOTPC;
28266 reloc->addend = fixp->fx_offset = reloc->address;
28267 }
28268#endif
6c43fab6 28269
c19d1205 28270 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6c43fab6 28271
c19d1205
ZW
28272 if (reloc->howto == NULL)
28273 {
28274 as_bad_where (fixp->fx_file, fixp->fx_line,
28275 _("cannot represent %s relocation in this object file format"),
28276 bfd_get_reloc_code_name (code));
28277 return NULL;
28278 }
6c43fab6 28279
c19d1205
ZW
28280 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
28281 vtable entry to be used in the relocation's section offset. */
28282 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
28283 reloc->address = fixp->fx_offset;
6c43fab6 28284
c19d1205 28285 return reloc;
6c43fab6
RE
28286}
28287
c19d1205 28288/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6c43fab6 28289
c19d1205
ZW
28290void
28291cons_fix_new_arm (fragS * frag,
28292 int where,
28293 int size,
62ebcb5c
AM
28294 expressionS * exp,
28295 bfd_reloc_code_real_type reloc)
6c43fab6 28296{
c19d1205 28297 int pcrel = 0;
6c43fab6 28298
c19d1205
ZW
28299 /* Pick a reloc.
28300 FIXME: @@ Should look at CPU word size. */
28301 switch (size)
28302 {
28303 case 1:
62ebcb5c 28304 reloc = BFD_RELOC_8;
c19d1205
ZW
28305 break;
28306 case 2:
62ebcb5c 28307 reloc = BFD_RELOC_16;
c19d1205
ZW
28308 break;
28309 case 4:
28310 default:
62ebcb5c 28311 reloc = BFD_RELOC_32;
c19d1205
ZW
28312 break;
28313 case 8:
62ebcb5c 28314 reloc = BFD_RELOC_64;
c19d1205
ZW
28315 break;
28316 }
6c43fab6 28317
f0927246
NC
28318#ifdef TE_PE
28319 if (exp->X_op == O_secrel)
28320 {
28321 exp->X_op = O_symbol;
62ebcb5c 28322 reloc = BFD_RELOC_32_SECREL;
f0927246
NC
28323 }
28324#endif
28325
62ebcb5c 28326 fix_new_exp (frag, where, size, exp, pcrel, reloc);
c19d1205 28327}
6c43fab6 28328
4343666d 28329#if defined (OBJ_COFF)
c19d1205
ZW
28330void
28331arm_validate_fix (fixS * fixP)
6c43fab6 28332{
c19d1205
ZW
28333 /* If the destination of the branch is a defined symbol which does not have
28334 the THUMB_FUNC attribute, then we must be calling a function which has
28335 the (interfacearm) attribute. We look for the Thumb entry point to that
28336 function and change the branch to refer to that function instead. */
28337 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
28338 && fixP->fx_addsy != NULL
28339 && S_IS_DEFINED (fixP->fx_addsy)
28340 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6c43fab6 28341 {
c19d1205 28342 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6c43fab6 28343 }
c19d1205
ZW
28344}
28345#endif
6c43fab6 28346
267bf995 28347
c19d1205
ZW
28348int
28349arm_force_relocation (struct fix * fixp)
28350{
28351#if defined (OBJ_COFF) && defined (TE_PE)
28352 if (fixp->fx_r_type == BFD_RELOC_RVA)
28353 return 1;
28354#endif
6c43fab6 28355
267bf995
RR
28356 /* In case we have a call or a branch to a function in ARM ISA mode from
28357 a thumb function or vice-versa force the relocation. These relocations
28358 are cleared off for some cores that might have blx and simple transformations
28359 are possible. */
28360
28361#ifdef OBJ_ELF
28362 switch (fixp->fx_r_type)
28363 {
28364 case BFD_RELOC_ARM_PCREL_JUMP:
28365 case BFD_RELOC_ARM_PCREL_CALL:
28366 case BFD_RELOC_THUMB_PCREL_BLX:
28367 if (THUMB_IS_FUNC (fixp->fx_addsy))
28368 return 1;
28369 break;
28370
28371 case BFD_RELOC_ARM_PCREL_BLX:
28372 case BFD_RELOC_THUMB_PCREL_BRANCH25:
28373 case BFD_RELOC_THUMB_PCREL_BRANCH20:
28374 case BFD_RELOC_THUMB_PCREL_BRANCH23:
28375 if (ARM_IS_FUNC (fixp->fx_addsy))
28376 return 1;
28377 break;
28378
28379 default:
28380 break;
28381 }
28382#endif
28383
b5884301
PB
28384 /* Resolve these relocations even if the symbol is extern or weak.
28385 Technically this is probably wrong due to symbol preemption.
28386 In practice these relocations do not have enough range to be useful
28387 at dynamic link time, and some code (e.g. in the Linux kernel)
28388 expects these references to be resolved. */
c19d1205
ZW
28389 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
28390 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
b5884301 28391 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM8
0110f2b8 28392 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
b5884301
PB
28393 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
28394 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2
28395 || fixp->fx_r_type == BFD_RELOC_ARM_THUMB_OFFSET
16805f35 28396 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
0110f2b8
PB
28397 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
28398 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
b5884301
PB
28399 || fixp->fx_r_type == BFD_RELOC_ARM_T32_OFFSET_IMM
28400 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12
28401 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM
28402 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM_S2)
c19d1205 28403 return 0;
a737bd4d 28404
4962c51a
MS
28405 /* Always leave these relocations for the linker. */
28406 if ((fixp->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
28407 && fixp->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
28408 || fixp->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
28409 return 1;
28410
f0291e4c
PB
28411 /* Always generate relocations against function symbols. */
28412 if (fixp->fx_r_type == BFD_RELOC_32
28413 && fixp->fx_addsy
28414 && (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION))
28415 return 1;
28416
c19d1205 28417 return generic_force_reloc (fixp);
404ff6b5
AH
28418}
28419
0ffdc86c 28420#if defined (OBJ_ELF) || defined (OBJ_COFF)
e28387c3
PB
28421/* Relocations against function names must be left unadjusted,
28422 so that the linker can use this information to generate interworking
28423 stubs. The MIPS version of this function
c19d1205
ZW
28424 also prevents relocations that are mips-16 specific, but I do not
28425 know why it does this.
404ff6b5 28426
c19d1205
ZW
28427 FIXME:
28428 There is one other problem that ought to be addressed here, but
28429 which currently is not: Taking the address of a label (rather
28430 than a function) and then later jumping to that address. Such
28431 addresses also ought to have their bottom bit set (assuming that
28432 they reside in Thumb code), but at the moment they will not. */
404ff6b5 28433
c19d1205
ZW
28434bfd_boolean
28435arm_fix_adjustable (fixS * fixP)
404ff6b5 28436{
c19d1205
ZW
28437 if (fixP->fx_addsy == NULL)
28438 return 1;
404ff6b5 28439
e28387c3
PB
28440 /* Preserve relocations against symbols with function type. */
28441 if (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION)
c921be7d 28442 return FALSE;
e28387c3 28443
c19d1205
ZW
28444 if (THUMB_IS_FUNC (fixP->fx_addsy)
28445 && fixP->fx_subsy == NULL)
c921be7d 28446 return FALSE;
a737bd4d 28447
c19d1205
ZW
28448 /* We need the symbol name for the VTABLE entries. */
28449 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
28450 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
c921be7d 28451 return FALSE;
404ff6b5 28452
c19d1205
ZW
28453 /* Don't allow symbols to be discarded on GOT related relocs. */
28454 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
28455 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
28456 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
28457 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
5c5a4843 28458 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32_FDPIC
c19d1205
ZW
28459 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
28460 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
5c5a4843 28461 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32_FDPIC
c19d1205 28462 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
5c5a4843 28463 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32_FDPIC
c19d1205 28464 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
0855e32b
NS
28465 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GOTDESC
28466 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
28467 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_CALL
28468 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
28469 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_DESCSEQ
c19d1205 28470 || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
c921be7d 28471 return FALSE;
a737bd4d 28472
4962c51a
MS
28473 /* Similarly for group relocations. */
28474 if ((fixP->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
28475 && fixP->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
28476 || fixP->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
c921be7d 28477 return FALSE;
4962c51a 28478
79947c54
CD
28479 /* MOVW/MOVT REL relocations have limited offsets, so keep the symbols. */
28480 if (fixP->fx_r_type == BFD_RELOC_ARM_MOVW
28481 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT
28482 || fixP->fx_r_type == BFD_RELOC_ARM_MOVW_PCREL
28483 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT_PCREL
28484 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
28485 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT
28486 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW_PCREL
28487 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
c921be7d 28488 return FALSE;
79947c54 28489
72d98d16
MG
28490 /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
28491 offsets, so keep these symbols. */
28492 if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
28493 && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
28494 return FALSE;
28495
c921be7d 28496 return TRUE;
a737bd4d 28497}
0ffdc86c
NC
28498#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
28499
28500#ifdef OBJ_ELF
c19d1205
ZW
28501const char *
28502elf32_arm_target_format (void)
404ff6b5 28503{
c19d1205
ZW
28504#ifdef TE_SYMBIAN
28505 return (target_big_endian
28506 ? "elf32-bigarm-symbian"
28507 : "elf32-littlearm-symbian");
28508#elif defined (TE_VXWORKS)
28509 return (target_big_endian
28510 ? "elf32-bigarm-vxworks"
28511 : "elf32-littlearm-vxworks");
b38cadfb
NC
28512#elif defined (TE_NACL)
28513 return (target_big_endian
28514 ? "elf32-bigarm-nacl"
28515 : "elf32-littlearm-nacl");
c19d1205 28516#else
18a20338
CL
28517 if (arm_fdpic)
28518 {
28519 if (target_big_endian)
28520 return "elf32-bigarm-fdpic";
28521 else
28522 return "elf32-littlearm-fdpic";
28523 }
c19d1205 28524 else
18a20338
CL
28525 {
28526 if (target_big_endian)
28527 return "elf32-bigarm";
28528 else
28529 return "elf32-littlearm";
28530 }
c19d1205 28531#endif
404ff6b5
AH
28532}
28533
c19d1205
ZW
28534void
28535armelf_frob_symbol (symbolS * symp,
28536 int * puntp)
404ff6b5 28537{
c19d1205
ZW
28538 elf_frob_symbol (symp, puntp);
28539}
28540#endif
404ff6b5 28541
c19d1205 28542/* MD interface: Finalization. */
a737bd4d 28543
c19d1205
ZW
28544void
28545arm_cleanup (void)
28546{
28547 literal_pool * pool;
a737bd4d 28548
5ee91343
AV
28549 /* Ensure that all the predication blocks are properly closed. */
28550 check_pred_blocks_finished ();
e07e6e58 28551
c19d1205
ZW
28552 for (pool = list_of_pools; pool; pool = pool->next)
28553 {
5f4273c7 28554 /* Put it at the end of the relevant section. */
c19d1205
ZW
28555 subseg_set (pool->section, pool->sub_section);
28556#ifdef OBJ_ELF
28557 arm_elf_change_section ();
28558#endif
28559 s_ltorg (0);
28560 }
404ff6b5
AH
28561}
28562
cd000bff
DJ
28563#ifdef OBJ_ELF
28564/* Remove any excess mapping symbols generated for alignment frags in
28565 SEC. We may have created a mapping symbol before a zero byte
28566 alignment; remove it if there's a mapping symbol after the
28567 alignment. */
28568static void
28569check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
28570 void *dummy ATTRIBUTE_UNUSED)
28571{
28572 segment_info_type *seginfo = seg_info (sec);
28573 fragS *fragp;
28574
28575 if (seginfo == NULL || seginfo->frchainP == NULL)
28576 return;
28577
28578 for (fragp = seginfo->frchainP->frch_root;
28579 fragp != NULL;
28580 fragp = fragp->fr_next)
28581 {
28582 symbolS *sym = fragp->tc_frag_data.last_map;
28583 fragS *next = fragp->fr_next;
28584
28585 /* Variable-sized frags have been converted to fixed size by
28586 this point. But if this was variable-sized to start with,
28587 there will be a fixed-size frag after it. So don't handle
28588 next == NULL. */
28589 if (sym == NULL || next == NULL)
28590 continue;
28591
28592 if (S_GET_VALUE (sym) < next->fr_address)
28593 /* Not at the end of this frag. */
28594 continue;
28595 know (S_GET_VALUE (sym) == next->fr_address);
28596
28597 do
28598 {
28599 if (next->tc_frag_data.first_map != NULL)
28600 {
28601 /* Next frag starts with a mapping symbol. Discard this
28602 one. */
28603 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
28604 break;
28605 }
28606
28607 if (next->fr_next == NULL)
28608 {
28609 /* This mapping symbol is at the end of the section. Discard
28610 it. */
28611 know (next->fr_fix == 0 && next->fr_var == 0);
28612 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
28613 break;
28614 }
28615
28616 /* As long as we have empty frags without any mapping symbols,
28617 keep looking. */
28618 /* If the next frag is non-empty and does not start with a
28619 mapping symbol, then this mapping symbol is required. */
28620 if (next->fr_address != next->fr_next->fr_address)
28621 break;
28622
28623 next = next->fr_next;
28624 }
28625 while (next != NULL);
28626 }
28627}
28628#endif
28629
c19d1205
ZW
28630/* Adjust the symbol table. This marks Thumb symbols as distinct from
28631 ARM ones. */
404ff6b5 28632
c19d1205
ZW
28633void
28634arm_adjust_symtab (void)
404ff6b5 28635{
c19d1205
ZW
28636#ifdef OBJ_COFF
28637 symbolS * sym;
404ff6b5 28638
c19d1205
ZW
28639 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
28640 {
28641 if (ARM_IS_THUMB (sym))
28642 {
28643 if (THUMB_IS_FUNC (sym))
28644 {
28645 /* Mark the symbol as a Thumb function. */
28646 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
28647 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
28648 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
404ff6b5 28649
c19d1205
ZW
28650 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
28651 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
28652 else
28653 as_bad (_("%s: unexpected function type: %d"),
28654 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
28655 }
28656 else switch (S_GET_STORAGE_CLASS (sym))
28657 {
28658 case C_EXT:
28659 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
28660 break;
28661 case C_STAT:
28662 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
28663 break;
28664 case C_LABEL:
28665 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
28666 break;
28667 default:
28668 /* Do nothing. */
28669 break;
28670 }
28671 }
a737bd4d 28672
c19d1205
ZW
28673 if (ARM_IS_INTERWORK (sym))
28674 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
404ff6b5 28675 }
c19d1205
ZW
28676#endif
28677#ifdef OBJ_ELF
28678 symbolS * sym;
28679 char bind;
404ff6b5 28680
c19d1205 28681 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
404ff6b5 28682 {
c19d1205
ZW
28683 if (ARM_IS_THUMB (sym))
28684 {
28685 elf_symbol_type * elf_sym;
404ff6b5 28686
c19d1205
ZW
28687 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
28688 bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
404ff6b5 28689
b0796911
PB
28690 if (! bfd_is_arm_special_symbol_name (elf_sym->symbol.name,
28691 BFD_ARM_SPECIAL_SYM_TYPE_ANY))
c19d1205
ZW
28692 {
28693 /* If it's a .thumb_func, declare it as so,
28694 otherwise tag label as .code 16. */
28695 if (THUMB_IS_FUNC (sym))
39d911fc
TP
28696 ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
28697 ST_BRANCH_TO_THUMB);
3ba67470 28698 else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
c19d1205
ZW
28699 elf_sym->internal_elf_sym.st_info =
28700 ELF_ST_INFO (bind, STT_ARM_16BIT);
28701 }
28702 }
28703 }
cd000bff
DJ
28704
28705 /* Remove any overlapping mapping symbols generated by alignment frags. */
28706 bfd_map_over_sections (stdoutput, check_mapping_symbols, (char *) 0);
709001e9
MM
28707 /* Now do generic ELF adjustments. */
28708 elf_adjust_symtab ();
c19d1205 28709#endif
404ff6b5
AH
28710}
28711
c19d1205 28712/* MD interface: Initialization. */
404ff6b5 28713
a737bd4d 28714static void
c19d1205 28715set_constant_flonums (void)
a737bd4d 28716{
c19d1205 28717 int i;
404ff6b5 28718
c19d1205
ZW
28719 for (i = 0; i < NUM_FLOAT_VALS; i++)
28720 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
28721 abort ();
a737bd4d 28722}
404ff6b5 28723
3e9e4fcf
JB
28724/* Auto-select Thumb mode if it's the only available instruction set for the
28725 given architecture. */
28726
28727static void
28728autoselect_thumb_from_cpu_variant (void)
28729{
28730 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
28731 opcode_select (16);
28732}
28733
c19d1205
ZW
28734void
28735md_begin (void)
a737bd4d 28736{
c19d1205
ZW
28737 unsigned mach;
28738 unsigned int i;
404ff6b5 28739
c19d1205
ZW
28740 if ( (arm_ops_hsh = hash_new ()) == NULL
28741 || (arm_cond_hsh = hash_new ()) == NULL
5ee91343 28742 || (arm_vcond_hsh = hash_new ()) == NULL
c19d1205
ZW
28743 || (arm_shift_hsh = hash_new ()) == NULL
28744 || (arm_psr_hsh = hash_new ()) == NULL
62b3e311 28745 || (arm_v7m_psr_hsh = hash_new ()) == NULL
c19d1205 28746 || (arm_reg_hsh = hash_new ()) == NULL
62b3e311
PB
28747 || (arm_reloc_hsh = hash_new ()) == NULL
28748 || (arm_barrier_opt_hsh = hash_new ()) == NULL)
c19d1205
ZW
28749 as_fatal (_("virtual memory exhausted"));
28750
28751 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
d3ce72d0 28752 hash_insert (arm_ops_hsh, insns[i].template_name, (void *) (insns + i));
c19d1205 28753 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
d3ce72d0 28754 hash_insert (arm_cond_hsh, conds[i].template_name, (void *) (conds + i));
5ee91343
AV
28755 for (i = 0; i < sizeof (vconds) / sizeof (struct asm_cond); i++)
28756 hash_insert (arm_vcond_hsh, vconds[i].template_name, (void *) (vconds + i));
c19d1205 28757 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
5a49b8ac 28758 hash_insert (arm_shift_hsh, shift_names[i].name, (void *) (shift_names + i));
c19d1205 28759 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 28760 hash_insert (arm_psr_hsh, psrs[i].template_name, (void *) (psrs + i));
62b3e311 28761 for (i = 0; i < sizeof (v7m_psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 28762 hash_insert (arm_v7m_psr_hsh, v7m_psrs[i].template_name,
477330fc 28763 (void *) (v7m_psrs + i));
c19d1205 28764 for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
5a49b8ac 28765 hash_insert (arm_reg_hsh, reg_names[i].name, (void *) (reg_names + i));
62b3e311
PB
28766 for (i = 0;
28767 i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
28768 i++)
d3ce72d0 28769 hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
5a49b8ac 28770 (void *) (barrier_opt_names + i));
c19d1205 28771#ifdef OBJ_ELF
3da1d841
NC
28772 for (i = 0; i < ARRAY_SIZE (reloc_names); i++)
28773 {
28774 struct reloc_entry * entry = reloc_names + i;
28775
28776 if (arm_is_eabi() && entry->reloc == BFD_RELOC_ARM_PLT32)
28777 /* This makes encode_branch() use the EABI versions of this relocation. */
28778 entry->reloc = BFD_RELOC_UNUSED;
28779
28780 hash_insert (arm_reloc_hsh, entry->name, (void *) entry);
28781 }
c19d1205
ZW
28782#endif
28783
28784 set_constant_flonums ();
404ff6b5 28785
c19d1205
ZW
28786 /* Set the cpu variant based on the command-line options. We prefer
28787 -mcpu= over -march= if both are set (as for GCC); and we prefer
28788 -mfpu= over any other way of setting the floating point unit.
28789 Use of legacy options with new options are faulted. */
e74cfd16 28790 if (legacy_cpu)
404ff6b5 28791 {
e74cfd16 28792 if (mcpu_cpu_opt || march_cpu_opt)
c19d1205
ZW
28793 as_bad (_("use of old and new-style options to set CPU type"));
28794
4d354d8b 28795 selected_arch = *legacy_cpu;
404ff6b5 28796 }
4d354d8b
TP
28797 else if (mcpu_cpu_opt)
28798 {
28799 selected_arch = *mcpu_cpu_opt;
28800 selected_ext = *mcpu_ext_opt;
28801 }
28802 else if (march_cpu_opt)
c168ce07 28803 {
4d354d8b
TP
28804 selected_arch = *march_cpu_opt;
28805 selected_ext = *march_ext_opt;
c168ce07 28806 }
4d354d8b 28807 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
404ff6b5 28808
e74cfd16 28809 if (legacy_fpu)
c19d1205 28810 {
e74cfd16 28811 if (mfpu_opt)
c19d1205 28812 as_bad (_("use of old and new-style options to set FPU type"));
03b1477f 28813
4d354d8b 28814 selected_fpu = *legacy_fpu;
03b1477f 28815 }
4d354d8b
TP
28816 else if (mfpu_opt)
28817 selected_fpu = *mfpu_opt;
28818 else
03b1477f 28819 {
45eb4c1b
NS
28820#if !(defined (EABI_DEFAULT) || defined (TE_LINUX) \
28821 || defined (TE_NetBSD) || defined (TE_VXWORKS))
39c2da32
RE
28822 /* Some environments specify a default FPU. If they don't, infer it
28823 from the processor. */
e74cfd16 28824 if (mcpu_fpu_opt)
4d354d8b 28825 selected_fpu = *mcpu_fpu_opt;
e7da50fa 28826 else if (march_fpu_opt)
4d354d8b 28827 selected_fpu = *march_fpu_opt;
39c2da32 28828#else
4d354d8b 28829 selected_fpu = fpu_default;
39c2da32 28830#endif
03b1477f
RE
28831 }
28832
4d354d8b 28833 if (ARM_FEATURE_ZERO (selected_fpu))
03b1477f 28834 {
4d354d8b
TP
28835 if (!no_cpu_selected ())
28836 selected_fpu = fpu_default;
03b1477f 28837 else
4d354d8b 28838 selected_fpu = fpu_arch_fpa;
03b1477f
RE
28839 }
28840
ee065d83 28841#ifdef CPU_DEFAULT
4d354d8b 28842 if (ARM_FEATURE_ZERO (selected_arch))
ee065d83 28843 {
4d354d8b
TP
28844 selected_arch = cpu_default;
28845 selected_cpu = selected_arch;
ee065d83 28846 }
4d354d8b 28847 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
e74cfd16 28848#else
4d354d8b
TP
28849 /* Autodection of feature mode: allow all features in cpu_variant but leave
28850 selected_cpu unset. It will be set in aeabi_set_public_attributes ()
28851 after all instruction have been processed and we can decide what CPU
28852 should be selected. */
28853 if (ARM_FEATURE_ZERO (selected_arch))
28854 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
ee065d83 28855 else
4d354d8b 28856 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 28857#endif
03b1477f 28858
3e9e4fcf
JB
28859 autoselect_thumb_from_cpu_variant ();
28860
e74cfd16 28861 arm_arch_used = thumb_arch_used = arm_arch_none;
ee065d83 28862
f17c130b 28863#if defined OBJ_COFF || defined OBJ_ELF
b99bd4ef 28864 {
7cc69913
NC
28865 unsigned int flags = 0;
28866
28867#if defined OBJ_ELF
28868 flags = meabi_flags;
d507cf36
PB
28869
28870 switch (meabi_flags)
33a392fb 28871 {
d507cf36 28872 case EF_ARM_EABI_UNKNOWN:
7cc69913 28873#endif
d507cf36
PB
28874 /* Set the flags in the private structure. */
28875 if (uses_apcs_26) flags |= F_APCS26;
28876 if (support_interwork) flags |= F_INTERWORK;
28877 if (uses_apcs_float) flags |= F_APCS_FLOAT;
c19d1205 28878 if (pic_code) flags |= F_PIC;
e74cfd16 28879 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_any_hard))
7cc69913
NC
28880 flags |= F_SOFT_FLOAT;
28881
d507cf36
PB
28882 switch (mfloat_abi_opt)
28883 {
28884 case ARM_FLOAT_ABI_SOFT:
28885 case ARM_FLOAT_ABI_SOFTFP:
28886 flags |= F_SOFT_FLOAT;
28887 break;
33a392fb 28888
d507cf36
PB
28889 case ARM_FLOAT_ABI_HARD:
28890 if (flags & F_SOFT_FLOAT)
28891 as_bad (_("hard-float conflicts with specified fpu"));
28892 break;
28893 }
03b1477f 28894
e74cfd16
PB
28895 /* Using pure-endian doubles (even if soft-float). */
28896 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
7cc69913 28897 flags |= F_VFP_FLOAT;
f17c130b 28898
fde78edd 28899#if defined OBJ_ELF
e74cfd16 28900 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_maverick))
d507cf36 28901 flags |= EF_ARM_MAVERICK_FLOAT;
d507cf36
PB
28902 break;
28903
8cb51566 28904 case EF_ARM_EABI_VER4:
3a4a14e9 28905 case EF_ARM_EABI_VER5:
c19d1205 28906 /* No additional flags to set. */
d507cf36
PB
28907 break;
28908
28909 default:
28910 abort ();
28911 }
7cc69913 28912#endif
b99bd4ef
NC
28913 bfd_set_private_flags (stdoutput, flags);
28914
28915 /* We have run out flags in the COFF header to encode the
28916 status of ATPCS support, so instead we create a dummy,
c19d1205 28917 empty, debug section called .arm.atpcs. */
b99bd4ef
NC
28918 if (atpcs)
28919 {
28920 asection * sec;
28921
28922 sec = bfd_make_section (stdoutput, ".arm.atpcs");
28923
28924 if (sec != NULL)
28925 {
28926 bfd_set_section_flags
28927 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
28928 bfd_set_section_size (stdoutput, sec, 0);
28929 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
28930 }
28931 }
7cc69913 28932 }
f17c130b 28933#endif
b99bd4ef
NC
28934
28935 /* Record the CPU type as well. */
2d447fca
JM
28936 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
28937 mach = bfd_mach_arm_iWMMXt2;
28938 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
e16bb312 28939 mach = bfd_mach_arm_iWMMXt;
e74cfd16 28940 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
b99bd4ef 28941 mach = bfd_mach_arm_XScale;
e74cfd16 28942 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick))
fde78edd 28943 mach = bfd_mach_arm_ep9312;
e74cfd16 28944 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5e))
b99bd4ef 28945 mach = bfd_mach_arm_5TE;
e74cfd16 28946 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5))
b99bd4ef 28947 {
e74cfd16 28948 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
28949 mach = bfd_mach_arm_5T;
28950 else
28951 mach = bfd_mach_arm_5;
28952 }
e74cfd16 28953 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4))
b99bd4ef 28954 {
e74cfd16 28955 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
28956 mach = bfd_mach_arm_4T;
28957 else
28958 mach = bfd_mach_arm_4;
28959 }
e74cfd16 28960 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3m))
b99bd4ef 28961 mach = bfd_mach_arm_3M;
e74cfd16
PB
28962 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3))
28963 mach = bfd_mach_arm_3;
28964 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2s))
28965 mach = bfd_mach_arm_2a;
28966 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2))
28967 mach = bfd_mach_arm_2;
28968 else
28969 mach = bfd_mach_arm_unknown;
b99bd4ef
NC
28970
28971 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
28972}
28973
c19d1205 28974/* Command line processing. */
b99bd4ef 28975
c19d1205
ZW
28976/* md_parse_option
28977 Invocation line includes a switch not recognized by the base assembler.
28978 See if it's a processor-specific option.
b99bd4ef 28979
c19d1205
ZW
28980 This routine is somewhat complicated by the need for backwards
28981 compatibility (since older releases of gcc can't be changed).
28982 The new options try to make the interface as compatible as
28983 possible with GCC.
b99bd4ef 28984
c19d1205 28985 New options (supported) are:
b99bd4ef 28986
c19d1205
ZW
28987 -mcpu=<cpu name> Assemble for selected processor
28988 -march=<architecture name> Assemble for selected architecture
28989 -mfpu=<fpu architecture> Assemble for selected FPU.
28990 -EB/-mbig-endian Big-endian
28991 -EL/-mlittle-endian Little-endian
28992 -k Generate PIC code
28993 -mthumb Start in Thumb mode
28994 -mthumb-interwork Code supports ARM/Thumb interworking
b99bd4ef 28995
278df34e 28996 -m[no-]warn-deprecated Warn about deprecated features
8b2d793c 28997 -m[no-]warn-syms Warn when symbols match instructions
267bf995 28998
c19d1205 28999 For now we will also provide support for:
b99bd4ef 29000
c19d1205
ZW
29001 -mapcs-32 32-bit Program counter
29002 -mapcs-26 26-bit Program counter
29003 -macps-float Floats passed in FP registers
29004 -mapcs-reentrant Reentrant code
29005 -matpcs
29006 (sometime these will probably be replaced with -mapcs=<list of options>
29007 and -matpcs=<list of options>)
b99bd4ef 29008
c19d1205
ZW
29009 The remaining options are only supported for back-wards compatibility.
29010 Cpu variants, the arm part is optional:
29011 -m[arm]1 Currently not supported.
29012 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
29013 -m[arm]3 Arm 3 processor
29014 -m[arm]6[xx], Arm 6 processors
29015 -m[arm]7[xx][t][[d]m] Arm 7 processors
29016 -m[arm]8[10] Arm 8 processors
29017 -m[arm]9[20][tdmi] Arm 9 processors
29018 -mstrongarm[110[0]] StrongARM processors
29019 -mxscale XScale processors
29020 -m[arm]v[2345[t[e]]] Arm architectures
29021 -mall All (except the ARM1)
29022 FP variants:
29023 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
29024 -mfpe-old (No float load/store multiples)
29025 -mvfpxd VFP Single precision
29026 -mvfp All VFP
29027 -mno-fpu Disable all floating point instructions
b99bd4ef 29028
c19d1205
ZW
29029 The following CPU names are recognized:
29030 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
29031 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
29032 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
29033 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
29034 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
29035 arm10t arm10e, arm1020t, arm1020e, arm10200e,
29036 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
b99bd4ef 29037
c19d1205 29038 */
b99bd4ef 29039
c19d1205 29040const char * md_shortopts = "m:k";
b99bd4ef 29041
c19d1205
ZW
29042#ifdef ARM_BI_ENDIAN
29043#define OPTION_EB (OPTION_MD_BASE + 0)
29044#define OPTION_EL (OPTION_MD_BASE + 1)
b99bd4ef 29045#else
c19d1205
ZW
29046#if TARGET_BYTES_BIG_ENDIAN
29047#define OPTION_EB (OPTION_MD_BASE + 0)
b99bd4ef 29048#else
c19d1205
ZW
29049#define OPTION_EL (OPTION_MD_BASE + 1)
29050#endif
b99bd4ef 29051#endif
845b51d6 29052#define OPTION_FIX_V4BX (OPTION_MD_BASE + 2)
18a20338 29053#define OPTION_FDPIC (OPTION_MD_BASE + 3)
b99bd4ef 29054
c19d1205 29055struct option md_longopts[] =
b99bd4ef 29056{
c19d1205
ZW
29057#ifdef OPTION_EB
29058 {"EB", no_argument, NULL, OPTION_EB},
29059#endif
29060#ifdef OPTION_EL
29061 {"EL", no_argument, NULL, OPTION_EL},
b99bd4ef 29062#endif
845b51d6 29063 {"fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
18a20338
CL
29064#ifdef OBJ_ELF
29065 {"fdpic", no_argument, NULL, OPTION_FDPIC},
29066#endif
c19d1205
ZW
29067 {NULL, no_argument, NULL, 0}
29068};
b99bd4ef 29069
c19d1205 29070size_t md_longopts_size = sizeof (md_longopts);
b99bd4ef 29071
c19d1205 29072struct arm_option_table
b99bd4ef 29073{
0198d5e6
TC
29074 const char * option; /* Option name to match. */
29075 const char * help; /* Help information. */
29076 int * var; /* Variable to change. */
29077 int value; /* What to change it to. */
29078 const char * deprecated; /* If non-null, print this message. */
c19d1205 29079};
b99bd4ef 29080
c19d1205
ZW
29081struct arm_option_table arm_opts[] =
29082{
29083 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
29084 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
29085 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
29086 &support_interwork, 1, NULL},
29087 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
29088 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
29089 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
29090 1, NULL},
29091 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
29092 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
29093 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
29094 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
29095 NULL},
b99bd4ef 29096
c19d1205
ZW
29097 /* These are recognized by the assembler, but have no affect on code. */
29098 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
29099 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
278df34e
NS
29100
29101 {"mwarn-deprecated", NULL, &warn_on_deprecated, 1, NULL},
29102 {"mno-warn-deprecated", N_("do not warn on use of deprecated feature"),
29103 &warn_on_deprecated, 0, NULL},
8b2d793c
NC
29104 {"mwarn-syms", N_("warn about symbols that match instruction names [default]"), (int *) (& flag_warn_syms), TRUE, NULL},
29105 {"mno-warn-syms", N_("disable warnings about symobls that match instructions"), (int *) (& flag_warn_syms), FALSE, NULL},
e74cfd16
PB
29106 {NULL, NULL, NULL, 0, NULL}
29107};
29108
29109struct arm_legacy_option_table
29110{
0198d5e6
TC
29111 const char * option; /* Option name to match. */
29112 const arm_feature_set ** var; /* Variable to change. */
29113 const arm_feature_set value; /* What to change it to. */
29114 const char * deprecated; /* If non-null, print this message. */
e74cfd16 29115};
b99bd4ef 29116
e74cfd16
PB
29117const struct arm_legacy_option_table arm_legacy_opts[] =
29118{
c19d1205
ZW
29119 /* DON'T add any new processors to this list -- we want the whole list
29120 to go away... Add them to the processors table instead. */
e74cfd16
PB
29121 {"marm1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
29122 {"m1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
29123 {"marm2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
29124 {"m2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
29125 {"marm250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
29126 {"m250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
29127 {"marm3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
29128 {"m3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
29129 {"marm6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
29130 {"m6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
29131 {"marm600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
29132 {"m600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
29133 {"marm610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
29134 {"m610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
29135 {"marm620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
29136 {"m620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
29137 {"marm7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
29138 {"m7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
29139 {"marm70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
29140 {"m70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
29141 {"marm700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
29142 {"m700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
29143 {"marm700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
29144 {"m700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
29145 {"marm710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
29146 {"m710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
29147 {"marm710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
29148 {"m710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
29149 {"marm720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
29150 {"m720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
29151 {"marm7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
29152 {"m7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
29153 {"marm7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
29154 {"m7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
29155 {"marm7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
29156 {"m7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
29157 {"marm7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
29158 {"m7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
29159 {"marm7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
29160 {"m7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
29161 {"marm7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
29162 {"m7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
29163 {"marm7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
29164 {"m7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
29165 {"marm7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
29166 {"m7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
29167 {"marm7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29168 {"m7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29169 {"marm7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29170 {"m7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
29171 {"marm710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
29172 {"m710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
29173 {"marm720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
29174 {"m720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
29175 {"marm740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
29176 {"m740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
29177 {"marm8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
29178 {"m8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
29179 {"marm810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
29180 {"m810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
29181 {"marm9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
29182 {"m9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
29183 {"marm9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
29184 {"m9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
29185 {"marm920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
29186 {"m920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
29187 {"marm940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
29188 {"m940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
29189 {"mstrongarm", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
29190 {"mstrongarm110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 29191 N_("use -mcpu=strongarm110")},
e74cfd16 29192 {"mstrongarm1100", &legacy_cpu, ARM_ARCH_V4,
c19d1205 29193 N_("use -mcpu=strongarm1100")},
e74cfd16 29194 {"mstrongarm1110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 29195 N_("use -mcpu=strongarm1110")},
e74cfd16
PB
29196 {"mxscale", &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
29197 {"miwmmxt", &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
29198 {"mall", &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
7ed4c4c5 29199
c19d1205 29200 /* Architecture variants -- don't add any more to this list either. */
e74cfd16
PB
29201 {"mv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
29202 {"marmv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
29203 {"mv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
29204 {"marmv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
29205 {"mv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
29206 {"marmv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
29207 {"mv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
29208 {"marmv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
29209 {"mv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
29210 {"marmv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
29211 {"mv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
29212 {"marmv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
29213 {"mv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
29214 {"marmv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
29215 {"mv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
29216 {"marmv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
29217 {"mv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
29218 {"marmv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
7ed4c4c5 29219
c19d1205 29220 /* Floating point variants -- don't add any more to this list either. */
0198d5e6
TC
29221 {"mfpe-old", &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
29222 {"mfpa10", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
29223 {"mfpa11", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
29224 {"mno-fpu", &legacy_fpu, ARM_ARCH_NONE,
c19d1205 29225 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
7ed4c4c5 29226
e74cfd16 29227 {NULL, NULL, ARM_ARCH_NONE, NULL}
c19d1205 29228};
7ed4c4c5 29229
c19d1205 29230struct arm_cpu_option_table
7ed4c4c5 29231{
0198d5e6
TC
29232 const char * name;
29233 size_t name_len;
29234 const arm_feature_set value;
29235 const arm_feature_set ext;
c19d1205
ZW
29236 /* For some CPUs we assume an FPU unless the user explicitly sets
29237 -mfpu=... */
0198d5e6 29238 const arm_feature_set default_fpu;
ee065d83
PB
29239 /* The canonical name of the CPU, or NULL to use NAME converted to upper
29240 case. */
0198d5e6 29241 const char * canonical_name;
c19d1205 29242};
7ed4c4c5 29243
c19d1205
ZW
29244/* This list should, at a minimum, contain all the cpu names
29245 recognized by GCC. */
996b5569 29246#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
0198d5e6 29247
e74cfd16 29248static const struct arm_cpu_option_table arm_cpus[] =
c19d1205 29249{
996b5569
TP
29250 ARM_CPU_OPT ("all", NULL, ARM_ANY,
29251 ARM_ARCH_NONE,
29252 FPU_ARCH_FPA),
29253 ARM_CPU_OPT ("arm1", NULL, ARM_ARCH_V1,
29254 ARM_ARCH_NONE,
29255 FPU_ARCH_FPA),
29256 ARM_CPU_OPT ("arm2", NULL, ARM_ARCH_V2,
29257 ARM_ARCH_NONE,
29258 FPU_ARCH_FPA),
29259 ARM_CPU_OPT ("arm250", NULL, ARM_ARCH_V2S,
29260 ARM_ARCH_NONE,
29261 FPU_ARCH_FPA),
29262 ARM_CPU_OPT ("arm3", NULL, ARM_ARCH_V2S,
29263 ARM_ARCH_NONE,
29264 FPU_ARCH_FPA),
29265 ARM_CPU_OPT ("arm6", NULL, ARM_ARCH_V3,
29266 ARM_ARCH_NONE,
29267 FPU_ARCH_FPA),
29268 ARM_CPU_OPT ("arm60", NULL, ARM_ARCH_V3,
29269 ARM_ARCH_NONE,
29270 FPU_ARCH_FPA),
29271 ARM_CPU_OPT ("arm600", NULL, ARM_ARCH_V3,
29272 ARM_ARCH_NONE,
29273 FPU_ARCH_FPA),
29274 ARM_CPU_OPT ("arm610", NULL, ARM_ARCH_V3,
29275 ARM_ARCH_NONE,
29276 FPU_ARCH_FPA),
29277 ARM_CPU_OPT ("arm620", NULL, ARM_ARCH_V3,
29278 ARM_ARCH_NONE,
29279 FPU_ARCH_FPA),
29280 ARM_CPU_OPT ("arm7", NULL, ARM_ARCH_V3,
29281 ARM_ARCH_NONE,
29282 FPU_ARCH_FPA),
29283 ARM_CPU_OPT ("arm7m", NULL, ARM_ARCH_V3M,
29284 ARM_ARCH_NONE,
29285 FPU_ARCH_FPA),
29286 ARM_CPU_OPT ("arm7d", NULL, ARM_ARCH_V3,
29287 ARM_ARCH_NONE,
29288 FPU_ARCH_FPA),
29289 ARM_CPU_OPT ("arm7dm", NULL, ARM_ARCH_V3M,
29290 ARM_ARCH_NONE,
29291 FPU_ARCH_FPA),
29292 ARM_CPU_OPT ("arm7di", NULL, ARM_ARCH_V3,
29293 ARM_ARCH_NONE,
29294 FPU_ARCH_FPA),
29295 ARM_CPU_OPT ("arm7dmi", NULL, ARM_ARCH_V3M,
29296 ARM_ARCH_NONE,
29297 FPU_ARCH_FPA),
29298 ARM_CPU_OPT ("arm70", NULL, ARM_ARCH_V3,
29299 ARM_ARCH_NONE,
29300 FPU_ARCH_FPA),
29301 ARM_CPU_OPT ("arm700", NULL, ARM_ARCH_V3,
29302 ARM_ARCH_NONE,
29303 FPU_ARCH_FPA),
29304 ARM_CPU_OPT ("arm700i", NULL, ARM_ARCH_V3,
29305 ARM_ARCH_NONE,
29306 FPU_ARCH_FPA),
29307 ARM_CPU_OPT ("arm710", NULL, ARM_ARCH_V3,
29308 ARM_ARCH_NONE,
29309 FPU_ARCH_FPA),
29310 ARM_CPU_OPT ("arm710t", NULL, ARM_ARCH_V4T,
29311 ARM_ARCH_NONE,
29312 FPU_ARCH_FPA),
29313 ARM_CPU_OPT ("arm720", NULL, ARM_ARCH_V3,
29314 ARM_ARCH_NONE,
29315 FPU_ARCH_FPA),
29316 ARM_CPU_OPT ("arm720t", NULL, ARM_ARCH_V4T,
29317 ARM_ARCH_NONE,
29318 FPU_ARCH_FPA),
29319 ARM_CPU_OPT ("arm740t", NULL, ARM_ARCH_V4T,
29320 ARM_ARCH_NONE,
29321 FPU_ARCH_FPA),
29322 ARM_CPU_OPT ("arm710c", NULL, ARM_ARCH_V3,
29323 ARM_ARCH_NONE,
29324 FPU_ARCH_FPA),
29325 ARM_CPU_OPT ("arm7100", NULL, ARM_ARCH_V3,
29326 ARM_ARCH_NONE,
29327 FPU_ARCH_FPA),
29328 ARM_CPU_OPT ("arm7500", NULL, ARM_ARCH_V3,
29329 ARM_ARCH_NONE,
29330 FPU_ARCH_FPA),
29331 ARM_CPU_OPT ("arm7500fe", NULL, ARM_ARCH_V3,
29332 ARM_ARCH_NONE,
29333 FPU_ARCH_FPA),
29334 ARM_CPU_OPT ("arm7t", NULL, ARM_ARCH_V4T,
29335 ARM_ARCH_NONE,
29336 FPU_ARCH_FPA),
29337 ARM_CPU_OPT ("arm7tdmi", NULL, ARM_ARCH_V4T,
29338 ARM_ARCH_NONE,
29339 FPU_ARCH_FPA),
29340 ARM_CPU_OPT ("arm7tdmi-s", NULL, ARM_ARCH_V4T,
29341 ARM_ARCH_NONE,
29342 FPU_ARCH_FPA),
29343 ARM_CPU_OPT ("arm8", NULL, ARM_ARCH_V4,
29344 ARM_ARCH_NONE,
29345 FPU_ARCH_FPA),
29346 ARM_CPU_OPT ("arm810", NULL, ARM_ARCH_V4,
29347 ARM_ARCH_NONE,
29348 FPU_ARCH_FPA),
29349 ARM_CPU_OPT ("strongarm", NULL, ARM_ARCH_V4,
29350 ARM_ARCH_NONE,
29351 FPU_ARCH_FPA),
29352 ARM_CPU_OPT ("strongarm1", NULL, ARM_ARCH_V4,
29353 ARM_ARCH_NONE,
29354 FPU_ARCH_FPA),
29355 ARM_CPU_OPT ("strongarm110", NULL, ARM_ARCH_V4,
29356 ARM_ARCH_NONE,
29357 FPU_ARCH_FPA),
29358 ARM_CPU_OPT ("strongarm1100", NULL, ARM_ARCH_V4,
29359 ARM_ARCH_NONE,
29360 FPU_ARCH_FPA),
29361 ARM_CPU_OPT ("strongarm1110", NULL, ARM_ARCH_V4,
29362 ARM_ARCH_NONE,
29363 FPU_ARCH_FPA),
29364 ARM_CPU_OPT ("arm9", NULL, ARM_ARCH_V4T,
29365 ARM_ARCH_NONE,
29366 FPU_ARCH_FPA),
29367 ARM_CPU_OPT ("arm920", "ARM920T", ARM_ARCH_V4T,
29368 ARM_ARCH_NONE,
29369 FPU_ARCH_FPA),
29370 ARM_CPU_OPT ("arm920t", NULL, ARM_ARCH_V4T,
29371 ARM_ARCH_NONE,
29372 FPU_ARCH_FPA),
29373 ARM_CPU_OPT ("arm922t", NULL, ARM_ARCH_V4T,
29374 ARM_ARCH_NONE,
29375 FPU_ARCH_FPA),
29376 ARM_CPU_OPT ("arm940t", NULL, ARM_ARCH_V4T,
29377 ARM_ARCH_NONE,
29378 FPU_ARCH_FPA),
29379 ARM_CPU_OPT ("arm9tdmi", NULL, ARM_ARCH_V4T,
29380 ARM_ARCH_NONE,
29381 FPU_ARCH_FPA),
29382 ARM_CPU_OPT ("fa526", NULL, ARM_ARCH_V4,
29383 ARM_ARCH_NONE,
29384 FPU_ARCH_FPA),
29385 ARM_CPU_OPT ("fa626", NULL, ARM_ARCH_V4,
29386 ARM_ARCH_NONE,
29387 FPU_ARCH_FPA),
29388
c19d1205
ZW
29389 /* For V5 or later processors we default to using VFP; but the user
29390 should really set the FPU type explicitly. */
996b5569
TP
29391 ARM_CPU_OPT ("arm9e-r0", NULL, ARM_ARCH_V5TExP,
29392 ARM_ARCH_NONE,
29393 FPU_ARCH_VFP_V2),
29394 ARM_CPU_OPT ("arm9e", NULL, ARM_ARCH_V5TE,
29395 ARM_ARCH_NONE,
29396 FPU_ARCH_VFP_V2),
29397 ARM_CPU_OPT ("arm926ej", "ARM926EJ-S", ARM_ARCH_V5TEJ,
29398 ARM_ARCH_NONE,
29399 FPU_ARCH_VFP_V2),
29400 ARM_CPU_OPT ("arm926ejs", "ARM926EJ-S", ARM_ARCH_V5TEJ,
29401 ARM_ARCH_NONE,
29402 FPU_ARCH_VFP_V2),
29403 ARM_CPU_OPT ("arm926ej-s", NULL, ARM_ARCH_V5TEJ,
29404 ARM_ARCH_NONE,
29405 FPU_ARCH_VFP_V2),
29406 ARM_CPU_OPT ("arm946e-r0", NULL, ARM_ARCH_V5TExP,
29407 ARM_ARCH_NONE,
29408 FPU_ARCH_VFP_V2),
29409 ARM_CPU_OPT ("arm946e", "ARM946E-S", ARM_ARCH_V5TE,
29410 ARM_ARCH_NONE,
29411 FPU_ARCH_VFP_V2),
29412 ARM_CPU_OPT ("arm946e-s", NULL, ARM_ARCH_V5TE,
29413 ARM_ARCH_NONE,
29414 FPU_ARCH_VFP_V2),
29415 ARM_CPU_OPT ("arm966e-r0", NULL, ARM_ARCH_V5TExP,
29416 ARM_ARCH_NONE,
29417 FPU_ARCH_VFP_V2),
29418 ARM_CPU_OPT ("arm966e", "ARM966E-S", ARM_ARCH_V5TE,
29419 ARM_ARCH_NONE,
29420 FPU_ARCH_VFP_V2),
29421 ARM_CPU_OPT ("arm966e-s", NULL, ARM_ARCH_V5TE,
29422 ARM_ARCH_NONE,
29423 FPU_ARCH_VFP_V2),
29424 ARM_CPU_OPT ("arm968e-s", NULL, ARM_ARCH_V5TE,
29425 ARM_ARCH_NONE,
29426 FPU_ARCH_VFP_V2),
29427 ARM_CPU_OPT ("arm10t", NULL, ARM_ARCH_V5T,
29428 ARM_ARCH_NONE,
29429 FPU_ARCH_VFP_V1),
29430 ARM_CPU_OPT ("arm10tdmi", NULL, ARM_ARCH_V5T,
29431 ARM_ARCH_NONE,
29432 FPU_ARCH_VFP_V1),
29433 ARM_CPU_OPT ("arm10e", NULL, ARM_ARCH_V5TE,
29434 ARM_ARCH_NONE,
29435 FPU_ARCH_VFP_V2),
29436 ARM_CPU_OPT ("arm1020", "ARM1020E", ARM_ARCH_V5TE,
29437 ARM_ARCH_NONE,
29438 FPU_ARCH_VFP_V2),
29439 ARM_CPU_OPT ("arm1020t", NULL, ARM_ARCH_V5T,
29440 ARM_ARCH_NONE,
29441 FPU_ARCH_VFP_V1),
29442 ARM_CPU_OPT ("arm1020e", NULL, ARM_ARCH_V5TE,
29443 ARM_ARCH_NONE,
29444 FPU_ARCH_VFP_V2),
29445 ARM_CPU_OPT ("arm1022e", NULL, ARM_ARCH_V5TE,
29446 ARM_ARCH_NONE,
29447 FPU_ARCH_VFP_V2),
29448 ARM_CPU_OPT ("arm1026ejs", "ARM1026EJ-S", ARM_ARCH_V5TEJ,
29449 ARM_ARCH_NONE,
29450 FPU_ARCH_VFP_V2),
29451 ARM_CPU_OPT ("arm1026ej-s", NULL, ARM_ARCH_V5TEJ,
29452 ARM_ARCH_NONE,
29453 FPU_ARCH_VFP_V2),
29454 ARM_CPU_OPT ("fa606te", NULL, ARM_ARCH_V5TE,
29455 ARM_ARCH_NONE,
29456 FPU_ARCH_VFP_V2),
29457 ARM_CPU_OPT ("fa616te", NULL, ARM_ARCH_V5TE,
29458 ARM_ARCH_NONE,
29459 FPU_ARCH_VFP_V2),
29460 ARM_CPU_OPT ("fa626te", NULL, ARM_ARCH_V5TE,
29461 ARM_ARCH_NONE,
29462 FPU_ARCH_VFP_V2),
29463 ARM_CPU_OPT ("fmp626", NULL, ARM_ARCH_V5TE,
29464 ARM_ARCH_NONE,
29465 FPU_ARCH_VFP_V2),
29466 ARM_CPU_OPT ("fa726te", NULL, ARM_ARCH_V5TE,
29467 ARM_ARCH_NONE,
29468 FPU_ARCH_VFP_V2),
29469 ARM_CPU_OPT ("arm1136js", "ARM1136J-S", ARM_ARCH_V6,
29470 ARM_ARCH_NONE,
29471 FPU_NONE),
29472 ARM_CPU_OPT ("arm1136j-s", NULL, ARM_ARCH_V6,
29473 ARM_ARCH_NONE,
29474 FPU_NONE),
29475 ARM_CPU_OPT ("arm1136jfs", "ARM1136JF-S", ARM_ARCH_V6,
29476 ARM_ARCH_NONE,
29477 FPU_ARCH_VFP_V2),
29478 ARM_CPU_OPT ("arm1136jf-s", NULL, ARM_ARCH_V6,
29479 ARM_ARCH_NONE,
29480 FPU_ARCH_VFP_V2),
29481 ARM_CPU_OPT ("mpcore", "MPCore", ARM_ARCH_V6K,
29482 ARM_ARCH_NONE,
29483 FPU_ARCH_VFP_V2),
29484 ARM_CPU_OPT ("mpcorenovfp", "MPCore", ARM_ARCH_V6K,
29485 ARM_ARCH_NONE,
29486 FPU_NONE),
29487 ARM_CPU_OPT ("arm1156t2-s", NULL, ARM_ARCH_V6T2,
29488 ARM_ARCH_NONE,
29489 FPU_NONE),
29490 ARM_CPU_OPT ("arm1156t2f-s", NULL, ARM_ARCH_V6T2,
29491 ARM_ARCH_NONE,
29492 FPU_ARCH_VFP_V2),
29493 ARM_CPU_OPT ("arm1176jz-s", NULL, ARM_ARCH_V6KZ,
29494 ARM_ARCH_NONE,
29495 FPU_NONE),
29496 ARM_CPU_OPT ("arm1176jzf-s", NULL, ARM_ARCH_V6KZ,
29497 ARM_ARCH_NONE,
29498 FPU_ARCH_VFP_V2),
29499 ARM_CPU_OPT ("cortex-a5", "Cortex-A5", ARM_ARCH_V7A,
29500 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
29501 FPU_NONE),
29502 ARM_CPU_OPT ("cortex-a7", "Cortex-A7", ARM_ARCH_V7VE,
29503 ARM_ARCH_NONE,
29504 FPU_ARCH_NEON_VFP_V4),
29505 ARM_CPU_OPT ("cortex-a8", "Cortex-A8", ARM_ARCH_V7A,
29506 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
29507 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
29508 ARM_CPU_OPT ("cortex-a9", "Cortex-A9", ARM_ARCH_V7A,
29509 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
29510 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
29511 ARM_CPU_OPT ("cortex-a12", "Cortex-A12", ARM_ARCH_V7VE,
29512 ARM_ARCH_NONE,
29513 FPU_ARCH_NEON_VFP_V4),
29514 ARM_CPU_OPT ("cortex-a15", "Cortex-A15", ARM_ARCH_V7VE,
29515 ARM_ARCH_NONE,
29516 FPU_ARCH_NEON_VFP_V4),
29517 ARM_CPU_OPT ("cortex-a17", "Cortex-A17", ARM_ARCH_V7VE,
29518 ARM_ARCH_NONE,
29519 FPU_ARCH_NEON_VFP_V4),
29520 ARM_CPU_OPT ("cortex-a32", "Cortex-A32", ARM_ARCH_V8A,
29521 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29522 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29523 ARM_CPU_OPT ("cortex-a35", "Cortex-A35", ARM_ARCH_V8A,
29524 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29525 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29526 ARM_CPU_OPT ("cortex-a53", "Cortex-A53", ARM_ARCH_V8A,
29527 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29528 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
29529 ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A,
29530 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 29531 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
29532 ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A,
29533 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29534 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29535 ARM_CPU_OPT ("cortex-a72", "Cortex-A72", ARM_ARCH_V8A,
29536 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29537 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29538 ARM_CPU_OPT ("cortex-a73", "Cortex-A73", ARM_ARCH_V8A,
29539 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29540 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
29541 ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A,
29542 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 29543 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
7ebd1359 29544 ARM_CPU_OPT ("cortex-a76", "Cortex-A76", ARM_ARCH_V8_2A,
29545 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
29546 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
ef8df4ca
KT
29547 ARM_CPU_OPT ("ares", "Ares", ARM_ARCH_V8_2A,
29548 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
29549 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
29550 ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R,
29551 ARM_ARCH_NONE,
29552 FPU_NONE),
29553 ARM_CPU_OPT ("cortex-r4f", "Cortex-R4F", ARM_ARCH_V7R,
29554 ARM_ARCH_NONE,
29555 FPU_ARCH_VFP_V3D16),
29556 ARM_CPU_OPT ("cortex-r5", "Cortex-R5", ARM_ARCH_V7R,
29557 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
29558 FPU_NONE),
29559 ARM_CPU_OPT ("cortex-r7", "Cortex-R7", ARM_ARCH_V7R,
29560 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
29561 FPU_ARCH_VFP_V3D16),
29562 ARM_CPU_OPT ("cortex-r8", "Cortex-R8", ARM_ARCH_V7R,
29563 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
29564 FPU_ARCH_VFP_V3D16),
0cda1e19
TP
29565 ARM_CPU_OPT ("cortex-r52", "Cortex-R52", ARM_ARCH_V8R,
29566 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29567 FPU_ARCH_NEON_VFP_ARMV8),
996b5569
TP
29568 ARM_CPU_OPT ("cortex-m33", "Cortex-M33", ARM_ARCH_V8M_MAIN,
29569 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
29570 FPU_NONE),
29571 ARM_CPU_OPT ("cortex-m23", "Cortex-M23", ARM_ARCH_V8M_BASE,
29572 ARM_ARCH_NONE,
29573 FPU_NONE),
29574 ARM_CPU_OPT ("cortex-m7", "Cortex-M7", ARM_ARCH_V7EM,
29575 ARM_ARCH_NONE,
29576 FPU_NONE),
29577 ARM_CPU_OPT ("cortex-m4", "Cortex-M4", ARM_ARCH_V7EM,
29578 ARM_ARCH_NONE,
29579 FPU_NONE),
29580 ARM_CPU_OPT ("cortex-m3", "Cortex-M3", ARM_ARCH_V7M,
29581 ARM_ARCH_NONE,
29582 FPU_NONE),
29583 ARM_CPU_OPT ("cortex-m1", "Cortex-M1", ARM_ARCH_V6SM,
29584 ARM_ARCH_NONE,
29585 FPU_NONE),
29586 ARM_CPU_OPT ("cortex-m0", "Cortex-M0", ARM_ARCH_V6SM,
29587 ARM_ARCH_NONE,
29588 FPU_NONE),
29589 ARM_CPU_OPT ("cortex-m0plus", "Cortex-M0+", ARM_ARCH_V6SM,
29590 ARM_ARCH_NONE,
29591 FPU_NONE),
29592 ARM_CPU_OPT ("exynos-m1", "Samsung Exynos M1", ARM_ARCH_V8A,
29593 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29594 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
83f43c83
KT
29595 ARM_CPU_OPT ("neoverse-n1", "Neoverse N1", ARM_ARCH_V8_2A,
29596 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
29597 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
c19d1205 29598 /* ??? XSCALE is really an architecture. */
996b5569
TP
29599 ARM_CPU_OPT ("xscale", NULL, ARM_ARCH_XSCALE,
29600 ARM_ARCH_NONE,
29601 FPU_ARCH_VFP_V2),
29602
c19d1205 29603 /* ??? iwmmxt is not a processor. */
996b5569
TP
29604 ARM_CPU_OPT ("iwmmxt", NULL, ARM_ARCH_IWMMXT,
29605 ARM_ARCH_NONE,
29606 FPU_ARCH_VFP_V2),
29607 ARM_CPU_OPT ("iwmmxt2", NULL, ARM_ARCH_IWMMXT2,
29608 ARM_ARCH_NONE,
29609 FPU_ARCH_VFP_V2),
29610 ARM_CPU_OPT ("i80200", NULL, ARM_ARCH_XSCALE,
29611 ARM_ARCH_NONE,
29612 FPU_ARCH_VFP_V2),
29613
0198d5e6 29614 /* Maverick. */
996b5569
TP
29615 ARM_CPU_OPT ("ep9312", "ARM920T",
29616 ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
29617 ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
29618
da4339ed 29619 /* Marvell processors. */
996b5569
TP
29620 ARM_CPU_OPT ("marvell-pj4", NULL, ARM_ARCH_V7A,
29621 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
29622 FPU_ARCH_VFP_V3D16),
29623 ARM_CPU_OPT ("marvell-whitney", NULL, ARM_ARCH_V7A,
29624 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
29625 FPU_ARCH_NEON_VFP_V4),
da4339ed 29626
996b5569
TP
29627 /* APM X-Gene family. */
29628 ARM_CPU_OPT ("xgene1", "APM X-Gene 1", ARM_ARCH_V8A,
29629 ARM_ARCH_NONE,
29630 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29631 ARM_CPU_OPT ("xgene2", "APM X-Gene 2", ARM_ARCH_V8A,
29632 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29633 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
29634
29635 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 29636};
f3bad469 29637#undef ARM_CPU_OPT
7ed4c4c5 29638
34ef62f4
AV
29639struct arm_ext_table
29640{
29641 const char * name;
29642 size_t name_len;
29643 const arm_feature_set merge;
29644 const arm_feature_set clear;
29645};
29646
c19d1205 29647struct arm_arch_option_table
7ed4c4c5 29648{
34ef62f4
AV
29649 const char * name;
29650 size_t name_len;
29651 const arm_feature_set value;
29652 const arm_feature_set default_fpu;
29653 const struct arm_ext_table * ext_table;
29654};
29655
29656/* Used to add support for +E and +noE extension. */
29657#define ARM_EXT(E, M, C) { E, sizeof (E) - 1, M, C }
29658/* Used to add support for a +E extension. */
29659#define ARM_ADD(E, M) { E, sizeof(E) - 1, M, ARM_ARCH_NONE }
29660/* Used to add support for a +noE extension. */
29661#define ARM_REMOVE(E, C) { E, sizeof(E) -1, ARM_ARCH_NONE, C }
29662
29663#define ALL_FP ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_FP16_FML, \
29664 ~0 & ~FPU_ENDIAN_PURE)
29665
29666static const struct arm_ext_table armv5te_ext_table[] =
29667{
29668 ARM_EXT ("fp", FPU_ARCH_VFP_V2, ALL_FP),
29669 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29670};
29671
29672static const struct arm_ext_table armv7_ext_table[] =
29673{
29674 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
29675 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29676};
29677
29678static const struct arm_ext_table armv7ve_ext_table[] =
29679{
29680 ARM_EXT ("fp", FPU_ARCH_VFP_V4D16, ALL_FP),
29681 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16),
29682 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
29683 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
29684 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
29685 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), /* Alias for +fp. */
29686 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
29687
29688 ARM_EXT ("simd", FPU_ARCH_NEON_VFP_V4,
29689 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
29690
29691 /* Aliases for +simd. */
29692 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
29693
29694 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
29695 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
29696 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
29697
29698 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29699};
29700
29701static const struct arm_ext_table armv7a_ext_table[] =
29702{
29703 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
29704 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
29705 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
29706 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
29707 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
29708 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16),
29709 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
29710
29711 ARM_EXT ("simd", FPU_ARCH_VFP_V3_PLUS_NEON_V1,
29712 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
29713
29714 /* Aliases for +simd. */
29715 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
29716 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
29717
29718 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
29719 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
29720
29721 ARM_ADD ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP)),
29722 ARM_ADD ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC)),
29723 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29724};
29725
29726static const struct arm_ext_table armv7r_ext_table[] =
29727{
29728 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V3xD),
29729 ARM_ADD ("vfpv3xd", FPU_ARCH_VFP_V3xD), /* Alias for +fp.sp. */
29730 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
29731 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
29732 ARM_ADD ("vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16),
29733 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
29734 ARM_EXT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
29735 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV)),
29736 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29737};
29738
29739static const struct arm_ext_table armv7em_ext_table[] =
29740{
29741 ARM_EXT ("fp", FPU_ARCH_VFP_V4_SP_D16, ALL_FP),
29742 /* Alias for +fp, used to be known as fpv4-sp-d16. */
29743 ARM_ADD ("vfpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16),
29744 ARM_ADD ("fpv5", FPU_ARCH_VFP_V5_SP_D16),
29745 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
29746 ARM_ADD ("fpv5-d16", FPU_ARCH_VFP_V5D16),
29747 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29748};
29749
29750static const struct arm_ext_table armv8a_ext_table[] =
29751{
29752 ARM_ADD ("crc", ARCH_CRC_ARMV8),
29753 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
29754 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
29755 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
29756
29757 /* Armv8-a does not allow an FP implementation without SIMD, so the user
29758 should use the +simd option to turn on FP. */
29759 ARM_REMOVE ("fp", ALL_FP),
29760 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
29761 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
29762 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29763};
29764
29765
29766static const struct arm_ext_table armv81a_ext_table[] =
29767{
29768 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
29769 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
29770 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
29771
29772 /* Armv8-a does not allow an FP implementation without SIMD, so the user
29773 should use the +simd option to turn on FP. */
29774 ARM_REMOVE ("fp", ALL_FP),
29775 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
29776 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
29777 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29778};
29779
29780static const struct arm_ext_table armv82a_ext_table[] =
29781{
29782 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
29783 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_2_FP16),
29784 ARM_ADD ("fp16fml", FPU_ARCH_NEON_VFP_ARMV8_2_FP16FML),
29785 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
29786 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
29787 ARM_ADD ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
29788
29789 /* Armv8-a does not allow an FP implementation without SIMD, so the user
29790 should use the +simd option to turn on FP. */
29791 ARM_REMOVE ("fp", ALL_FP),
29792 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
29793 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
29794 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29795};
29796
29797static const struct arm_ext_table armv84a_ext_table[] =
29798{
29799 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
29800 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
29801 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
29802 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
29803
29804 /* Armv8-a does not allow an FP implementation without SIMD, so the user
29805 should use the +simd option to turn on FP. */
29806 ARM_REMOVE ("fp", ALL_FP),
29807 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
29808 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
29809 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29810};
29811
29812static const struct arm_ext_table armv85a_ext_table[] =
29813{
29814 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
29815 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
29816 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
29817 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
29818
29819 /* Armv8-a does not allow an FP implementation without SIMD, so the user
29820 should use the +simd option to turn on FP. */
29821 ARM_REMOVE ("fp", ALL_FP),
29822 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29823};
29824
29825static const struct arm_ext_table armv8m_main_ext_table[] =
29826{
29827 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
29828 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
29829 ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP),
29830 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
29831 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29832};
29833
e0991585
AV
29834static const struct arm_ext_table armv8_1m_main_ext_table[] =
29835{
29836 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
29837 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
29838 ARM_EXT ("fp",
29839 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
29840 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA),
29841 ALL_FP),
29842 ARM_ADD ("fp.dp",
29843 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
29844 FPU_VFP_V5D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
a7ad558c
AV
29845 ARM_EXT ("mve", ARM_FEATURE_COPROC (FPU_MVE),
29846 ARM_FEATURE_COPROC (FPU_MVE | FPU_MVE_FP)),
29847 ARM_ADD ("mve.fp",
29848 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
29849 FPU_MVE | FPU_MVE_FP | FPU_VFP_V5_SP_D16 |
29850 FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
e0991585
AV
29851 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
29852};
29853
34ef62f4
AV
29854static const struct arm_ext_table armv8r_ext_table[] =
29855{
29856 ARM_ADD ("crc", ARCH_CRC_ARMV8),
29857 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
29858 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
29859 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
29860 ARM_REMOVE ("fp", ALL_FP),
29861 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V5_SP_D16),
29862 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
c19d1205 29863};
7ed4c4c5 29864
c19d1205
ZW
29865/* This list should, at a minimum, contain all the architecture names
29866 recognized by GCC. */
34ef62f4
AV
29867#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF, NULL }
29868#define ARM_ARCH_OPT2(N, V, DF, ext) \
29869 { N, sizeof (N) - 1, V, DF, ext##_ext_table }
0198d5e6 29870
e74cfd16 29871static const struct arm_arch_option_table arm_archs[] =
c19d1205 29872{
497d849d
TP
29873 ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
29874 ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
29875 ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
29876 ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
29877 ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
29878 ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
29879 ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
29880 ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
29881 ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
29882 ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
29883 ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
29884 ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
29885 ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
29886 ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
34ef62f4
AV
29887 ARM_ARCH_OPT2 ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP, armv5te),
29888 ARM_ARCH_OPT2 ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP, armv5te),
29889 ARM_ARCH_OPT2 ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP, armv5te),
29890 ARM_ARCH_OPT2 ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
29891 ARM_ARCH_OPT2 ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
29892 ARM_ARCH_OPT2 ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP, armv5te),
29893 ARM_ARCH_OPT2 ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP, armv5te),
f33026a9
MW
29894 /* The official spelling of this variant is ARMv6KZ, the name "armv6zk" is
29895 kept to preserve existing behaviour. */
34ef62f4
AV
29896 ARM_ARCH_OPT2 ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
29897 ARM_ARCH_OPT2 ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
29898 ARM_ARCH_OPT2 ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP, armv5te),
29899 ARM_ARCH_OPT2 ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP, armv5te),
29900 ARM_ARCH_OPT2 ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP, armv5te),
f33026a9
MW
29901 /* The official spelling of this variant is ARMv6KZ, the name "armv6zkt2" is
29902 kept to preserve existing behaviour. */
34ef62f4
AV
29903 ARM_ARCH_OPT2 ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
29904 ARM_ARCH_OPT2 ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
497d849d
TP
29905 ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
29906 ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
34ef62f4 29907 ARM_ARCH_OPT2 ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP, armv7),
c450d570
PB
29908 /* The official spelling of the ARMv7 profile variants is the dashed form.
29909 Accept the non-dashed form for compatibility with old toolchains. */
34ef62f4
AV
29910 ARM_ARCH_OPT2 ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
29911 ARM_ARCH_OPT2 ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP, armv7ve),
29912 ARM_ARCH_OPT2 ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 29913 ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4
AV
29914 ARM_ARCH_OPT2 ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
29915 ARM_ARCH_OPT2 ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 29916 ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4 29917 ARM_ARCH_OPT2 ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP, armv7em),
497d849d 29918 ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP),
34ef62f4
AV
29919 ARM_ARCH_OPT2 ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP,
29920 armv8m_main),
e0991585
AV
29921 ARM_ARCH_OPT2 ("armv8.1-m.main", ARM_ARCH_V8_1M_MAIN, FPU_ARCH_VFP,
29922 armv8_1m_main),
34ef62f4
AV
29923 ARM_ARCH_OPT2 ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP, armv8a),
29924 ARM_ARCH_OPT2 ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP, armv81a),
29925 ARM_ARCH_OPT2 ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP, armv82a),
29926 ARM_ARCH_OPT2 ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP, armv82a),
29927 ARM_ARCH_OPT2 ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP, armv8r),
29928 ARM_ARCH_OPT2 ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP, armv84a),
29929 ARM_ARCH_OPT2 ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP, armv85a),
497d849d
TP
29930 ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
29931 ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
29932 ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP),
34ef62f4 29933 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 29934};
f3bad469 29935#undef ARM_ARCH_OPT
7ed4c4c5 29936
69133863 29937/* ISA extensions in the co-processor and main instruction set space. */
0198d5e6 29938
69133863 29939struct arm_option_extension_value_table
c19d1205 29940{
0198d5e6
TC
29941 const char * name;
29942 size_t name_len;
29943 const arm_feature_set merge_value;
29944 const arm_feature_set clear_value;
d942732e
TP
29945 /* List of architectures for which an extension is available. ARM_ARCH_NONE
29946 indicates that an extension is available for all architectures while
29947 ARM_ANY marks an empty entry. */
0198d5e6 29948 const arm_feature_set allowed_archs[2];
c19d1205 29949};
7ed4c4c5 29950
0198d5e6
TC
29951/* The following table must be in alphabetical order with a NULL last entry. */
29952
d942732e
TP
29953#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
29954#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
0198d5e6 29955
34ef62f4
AV
29956/* DEPRECATED: Refrain from using this table to add any new extensions, instead
29957 use the context sensitive approach using arm_ext_table's. */
69133863 29958static const struct arm_option_extension_value_table arm_extensions[] =
c19d1205 29959{
823d2571
TG
29960 ARM_EXT_OPT ("crc", ARCH_CRC_ARMV8, ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
29961 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
bca38921 29962 ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
823d2571
TG
29963 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
29964 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
c604a79a
JW
29965 ARM_EXT_OPT ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8,
29966 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
29967 ARM_ARCH_V8_2A),
15afaa63
TP
29968 ARM_EXT_OPT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
29969 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
29970 ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
823d2571
TG
29971 ARM_EXT_OPT ("fp", FPU_ARCH_VFP_ARMV8, ARM_FEATURE_COPROC (FPU_VFP_ARMV8),
29972 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
b8ec4e87
JW
29973 ARM_EXT_OPT ("fp16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
29974 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
29975 ARM_ARCH_V8_2A),
01f48020
TC
29976 ARM_EXT_OPT ("fp16fml", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
29977 | ARM_EXT2_FP16_FML),
29978 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
29979 | ARM_EXT2_FP16_FML),
29980 ARM_ARCH_V8_2A),
d942732e 29981 ARM_EXT_OPT2 ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
823d2571 29982 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
d942732e
TP
29983 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
29984 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
3d030cdb
TP
29985 /* Duplicate entry for the purpose of allowing ARMv7 to match in presence of
29986 Thumb divide instruction. Due to this having the same name as the
29987 previous entry, this will be ignored when doing command-line parsing and
29988 only considered by build attribute selection code. */
29989 ARM_EXT_OPT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
29990 ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
29991 ARM_FEATURE_CORE_LOW (ARM_EXT_V7)),
823d2571 29992 ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
d942732e 29993 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
823d2571 29994 ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
d942732e 29995 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ARCH_NONE),
823d2571 29996 ARM_EXT_OPT ("maverick", ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK),
d942732e
TP
29997 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ARCH_NONE),
29998 ARM_EXT_OPT2 ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
823d2571 29999 ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
d942732e
TP
30000 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
30001 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
823d2571
TG
30002 ARM_EXT_OPT ("os", ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
30003 ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
30004 ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
ddfded2f
MW
30005 ARM_EXT_OPT ("pan", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
30006 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
ced40572 30007 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
dad0c3bf
SD
30008 ARM_EXT_OPT ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
30009 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
30010 ARM_ARCH_V8A),
4d1464f2
MW
30011 ARM_EXT_OPT ("ras", ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
30012 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
ced40572 30013 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
643afb90
MW
30014 ARM_EXT_OPT ("rdma", FPU_ARCH_NEON_VFP_ARMV8_1,
30015 ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
ced40572 30016 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
7fadb25d
SD
30017 ARM_EXT_OPT ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
30018 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
30019 ARM_ARCH_V8A),
d942732e 30020 ARM_EXT_OPT2 ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
823d2571 30021 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
d942732e
TP
30022 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
30023 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
643afb90
MW
30024 ARM_EXT_OPT ("simd", FPU_ARCH_NEON_VFP_ARMV8,
30025 ARM_FEATURE_COPROC (FPU_NEON_ARMV8),
30026 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
823d2571
TG
30027 ARM_EXT_OPT ("virt", ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT | ARM_EXT_ADIV
30028 | ARM_EXT_DIV),
30029 ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT),
30030 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
30031 ARM_EXT_OPT ("xscale",ARM_FEATURE_COPROC (ARM_CEXT_XSCALE),
d942732e
TP
30032 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ARCH_NONE),
30033 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, { ARM_ARCH_NONE, ARM_ARCH_NONE } }
69133863 30034};
f3bad469 30035#undef ARM_EXT_OPT
69133863
MGD
30036
30037/* ISA floating-point and Advanced SIMD extensions. */
30038struct arm_option_fpu_value_table
30039{
0198d5e6
TC
30040 const char * name;
30041 const arm_feature_set value;
c19d1205 30042};
7ed4c4c5 30043
c19d1205
ZW
30044/* This list should, at a minimum, contain all the fpu names
30045 recognized by GCC. */
69133863 30046static const struct arm_option_fpu_value_table arm_fpus[] =
c19d1205
ZW
30047{
30048 {"softfpa", FPU_NONE},
30049 {"fpe", FPU_ARCH_FPE},
30050 {"fpe2", FPU_ARCH_FPE},
30051 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
30052 {"fpa", FPU_ARCH_FPA},
30053 {"fpa10", FPU_ARCH_FPA},
30054 {"fpa11", FPU_ARCH_FPA},
30055 {"arm7500fe", FPU_ARCH_FPA},
30056 {"softvfp", FPU_ARCH_VFP},
30057 {"softvfp+vfp", FPU_ARCH_VFP_V2},
30058 {"vfp", FPU_ARCH_VFP_V2},
30059 {"vfp9", FPU_ARCH_VFP_V2},
d5e0ba9c 30060 {"vfp3", FPU_ARCH_VFP_V3}, /* Undocumented, use vfpv3. */
c19d1205
ZW
30061 {"vfp10", FPU_ARCH_VFP_V2},
30062 {"vfp10-r0", FPU_ARCH_VFP_V1},
30063 {"vfpxd", FPU_ARCH_VFP_V1xD},
b1cc4aeb
PB
30064 {"vfpv2", FPU_ARCH_VFP_V2},
30065 {"vfpv3", FPU_ARCH_VFP_V3},
62f3b8c8 30066 {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16},
b1cc4aeb 30067 {"vfpv3-d16", FPU_ARCH_VFP_V3D16},
62f3b8c8
PB
30068 {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16},
30069 {"vfpv3xd", FPU_ARCH_VFP_V3xD},
30070 {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16},
c19d1205
ZW
30071 {"arm1020t", FPU_ARCH_VFP_V1},
30072 {"arm1020e", FPU_ARCH_VFP_V2},
d5e0ba9c 30073 {"arm1136jfs", FPU_ARCH_VFP_V2}, /* Undocumented, use arm1136jf-s. */
c19d1205
ZW
30074 {"arm1136jf-s", FPU_ARCH_VFP_V2},
30075 {"maverick", FPU_ARCH_MAVERICK},
d5e0ba9c 30076 {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
d3375ddd 30077 {"neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
8e79c3df 30078 {"neon-fp16", FPU_ARCH_NEON_FP16},
62f3b8c8
PB
30079 {"vfpv4", FPU_ARCH_VFP_V4},
30080 {"vfpv4-d16", FPU_ARCH_VFP_V4D16},
ada65aa3 30081 {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16},
a715796b
TG
30082 {"fpv5-d16", FPU_ARCH_VFP_V5D16},
30083 {"fpv5-sp-d16", FPU_ARCH_VFP_V5_SP_D16},
62f3b8c8 30084 {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4},
bca38921
MGD
30085 {"fp-armv8", FPU_ARCH_VFP_ARMV8},
30086 {"neon-fp-armv8", FPU_ARCH_NEON_VFP_ARMV8},
30087 {"crypto-neon-fp-armv8",
30088 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8},
d6b4b13e 30089 {"neon-fp-armv8.1", FPU_ARCH_NEON_VFP_ARMV8_1},
081e4c7d
MW
30090 {"crypto-neon-fp-armv8.1",
30091 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1},
e74cfd16
PB
30092 {NULL, ARM_ARCH_NONE}
30093};
30094
30095struct arm_option_value_table
30096{
e0471c16 30097 const char *name;
e74cfd16 30098 long value;
c19d1205 30099};
7ed4c4c5 30100
e74cfd16 30101static const struct arm_option_value_table arm_float_abis[] =
c19d1205
ZW
30102{
30103 {"hard", ARM_FLOAT_ABI_HARD},
30104 {"softfp", ARM_FLOAT_ABI_SOFTFP},
30105 {"soft", ARM_FLOAT_ABI_SOFT},
e74cfd16 30106 {NULL, 0}
c19d1205 30107};
7ed4c4c5 30108
c19d1205 30109#ifdef OBJ_ELF
3a4a14e9 30110/* We only know how to output GNU and ver 4/5 (AAELF) formats. */
e74cfd16 30111static const struct arm_option_value_table arm_eabis[] =
c19d1205
ZW
30112{
30113 {"gnu", EF_ARM_EABI_UNKNOWN},
30114 {"4", EF_ARM_EABI_VER4},
3a4a14e9 30115 {"5", EF_ARM_EABI_VER5},
e74cfd16 30116 {NULL, 0}
c19d1205
ZW
30117};
30118#endif
7ed4c4c5 30119
c19d1205
ZW
30120struct arm_long_option_table
30121{
0198d5e6 30122 const char * option; /* Substring to match. */
e0471c16 30123 const char * help; /* Help information. */
17b9d67d 30124 int (* func) (const char * subopt); /* Function to decode sub-option. */
e0471c16 30125 const char * deprecated; /* If non-null, print this message. */
c19d1205 30126};
7ed4c4c5 30127
c921be7d 30128static bfd_boolean
c168ce07 30129arm_parse_extension (const char *str, const arm_feature_set *opt_set,
34ef62f4
AV
30130 arm_feature_set *ext_set,
30131 const struct arm_ext_table *ext_table)
7ed4c4c5 30132{
69133863 30133 /* We insist on extensions being specified in alphabetical order, and with
fa94de6b
RM
30134 extensions being added before being removed. We achieve this by having
30135 the global ARM_EXTENSIONS table in alphabetical order, and using the
69133863 30136 ADDING_VALUE variable to indicate whether we are adding an extension (1)
fa94de6b 30137 or removing it (0) and only allowing it to change in the order
69133863
MGD
30138 -1 -> 1 -> 0. */
30139 const struct arm_option_extension_value_table * opt = NULL;
d942732e 30140 const arm_feature_set arm_any = ARM_ANY;
69133863
MGD
30141 int adding_value = -1;
30142
c19d1205 30143 while (str != NULL && *str != 0)
7ed4c4c5 30144 {
82b8a785 30145 const char *ext;
f3bad469 30146 size_t len;
7ed4c4c5 30147
c19d1205
ZW
30148 if (*str != '+')
30149 {
30150 as_bad (_("invalid architectural extension"));
c921be7d 30151 return FALSE;
c19d1205 30152 }
7ed4c4c5 30153
c19d1205
ZW
30154 str++;
30155 ext = strchr (str, '+');
7ed4c4c5 30156
c19d1205 30157 if (ext != NULL)
f3bad469 30158 len = ext - str;
c19d1205 30159 else
f3bad469 30160 len = strlen (str);
7ed4c4c5 30161
f3bad469 30162 if (len >= 2 && strncmp (str, "no", 2) == 0)
69133863
MGD
30163 {
30164 if (adding_value != 0)
30165 {
30166 adding_value = 0;
30167 opt = arm_extensions;
30168 }
30169
f3bad469 30170 len -= 2;
69133863
MGD
30171 str += 2;
30172 }
f3bad469 30173 else if (len > 0)
69133863
MGD
30174 {
30175 if (adding_value == -1)
30176 {
30177 adding_value = 1;
30178 opt = arm_extensions;
30179 }
30180 else if (adding_value != 1)
30181 {
30182 as_bad (_("must specify extensions to add before specifying "
30183 "those to remove"));
30184 return FALSE;
30185 }
30186 }
30187
f3bad469 30188 if (len == 0)
c19d1205
ZW
30189 {
30190 as_bad (_("missing architectural extension"));
c921be7d 30191 return FALSE;
c19d1205 30192 }
7ed4c4c5 30193
69133863
MGD
30194 gas_assert (adding_value != -1);
30195 gas_assert (opt != NULL);
30196
34ef62f4
AV
30197 if (ext_table != NULL)
30198 {
30199 const struct arm_ext_table * ext_opt = ext_table;
30200 bfd_boolean found = FALSE;
30201 for (; ext_opt->name != NULL; ext_opt++)
30202 if (ext_opt->name_len == len
30203 && strncmp (ext_opt->name, str, len) == 0)
30204 {
30205 if (adding_value)
30206 {
30207 if (ARM_FEATURE_ZERO (ext_opt->merge))
30208 /* TODO: Option not supported. When we remove the
30209 legacy table this case should error out. */
30210 continue;
30211
30212 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, ext_opt->merge);
30213 }
30214 else
30215 {
30216 if (ARM_FEATURE_ZERO (ext_opt->clear))
30217 /* TODO: Option not supported. When we remove the
30218 legacy table this case should error out. */
30219 continue;
30220 ARM_CLEAR_FEATURE (*ext_set, *ext_set, ext_opt->clear);
30221 }
30222 found = TRUE;
30223 break;
30224 }
30225 if (found)
30226 {
30227 str = ext;
30228 continue;
30229 }
30230 }
30231
69133863
MGD
30232 /* Scan over the options table trying to find an exact match. */
30233 for (; opt->name != NULL; opt++)
f3bad469 30234 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 30235 {
d942732e
TP
30236 int i, nb_allowed_archs =
30237 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
69133863 30238 /* Check we can apply the extension to this architecture. */
d942732e
TP
30239 for (i = 0; i < nb_allowed_archs; i++)
30240 {
30241 /* Empty entry. */
30242 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
30243 continue;
c168ce07 30244 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set))
d942732e
TP
30245 break;
30246 }
30247 if (i == nb_allowed_archs)
69133863
MGD
30248 {
30249 as_bad (_("extension does not apply to the base architecture"));
30250 return FALSE;
30251 }
30252
30253 /* Add or remove the extension. */
30254 if (adding_value)
4d354d8b 30255 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value);
69133863 30256 else
4d354d8b 30257 ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value);
69133863 30258
3d030cdb
TP
30259 /* Allowing Thumb division instructions for ARMv7 in autodetection
30260 rely on this break so that duplicate extensions (extensions
30261 with the same name as a previous extension in the list) are not
30262 considered for command-line parsing. */
c19d1205
ZW
30263 break;
30264 }
7ed4c4c5 30265
c19d1205
ZW
30266 if (opt->name == NULL)
30267 {
69133863
MGD
30268 /* Did we fail to find an extension because it wasn't specified in
30269 alphabetical order, or because it does not exist? */
30270
30271 for (opt = arm_extensions; opt->name != NULL; opt++)
f3bad469 30272 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
69133863
MGD
30273 break;
30274
30275 if (opt->name == NULL)
30276 as_bad (_("unknown architectural extension `%s'"), str);
30277 else
30278 as_bad (_("architectural extensions must be specified in "
30279 "alphabetical order"));
30280
c921be7d 30281 return FALSE;
c19d1205 30282 }
69133863
MGD
30283 else
30284 {
30285 /* We should skip the extension we've just matched the next time
30286 round. */
30287 opt++;
30288 }
7ed4c4c5 30289
c19d1205
ZW
30290 str = ext;
30291 };
7ed4c4c5 30292
c921be7d 30293 return TRUE;
c19d1205 30294}
7ed4c4c5 30295
c921be7d 30296static bfd_boolean
17b9d67d 30297arm_parse_cpu (const char *str)
7ed4c4c5 30298{
f3bad469 30299 const struct arm_cpu_option_table *opt;
82b8a785 30300 const char *ext = strchr (str, '+');
f3bad469 30301 size_t len;
7ed4c4c5 30302
c19d1205 30303 if (ext != NULL)
f3bad469 30304 len = ext - str;
7ed4c4c5 30305 else
f3bad469 30306 len = strlen (str);
7ed4c4c5 30307
f3bad469 30308 if (len == 0)
7ed4c4c5 30309 {
c19d1205 30310 as_bad (_("missing cpu name `%s'"), str);
c921be7d 30311 return FALSE;
7ed4c4c5
NC
30312 }
30313
c19d1205 30314 for (opt = arm_cpus; opt->name != NULL; opt++)
f3bad469 30315 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 30316 {
c168ce07 30317 mcpu_cpu_opt = &opt->value;
4d354d8b
TP
30318 if (mcpu_ext_opt == NULL)
30319 mcpu_ext_opt = XNEW (arm_feature_set);
30320 *mcpu_ext_opt = opt->ext;
e74cfd16 30321 mcpu_fpu_opt = &opt->default_fpu;
ee065d83 30322 if (opt->canonical_name)
ef8e6722
JW
30323 {
30324 gas_assert (sizeof selected_cpu_name > strlen (opt->canonical_name));
30325 strcpy (selected_cpu_name, opt->canonical_name);
30326 }
ee065d83
PB
30327 else
30328 {
f3bad469 30329 size_t i;
c921be7d 30330
ef8e6722
JW
30331 if (len >= sizeof selected_cpu_name)
30332 len = (sizeof selected_cpu_name) - 1;
30333
f3bad469 30334 for (i = 0; i < len; i++)
ee065d83
PB
30335 selected_cpu_name[i] = TOUPPER (opt->name[i]);
30336 selected_cpu_name[i] = 0;
30337 }
7ed4c4c5 30338
c19d1205 30339 if (ext != NULL)
34ef62f4 30340 return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt, NULL);
7ed4c4c5 30341
c921be7d 30342 return TRUE;
c19d1205 30343 }
7ed4c4c5 30344
c19d1205 30345 as_bad (_("unknown cpu `%s'"), str);
c921be7d 30346 return FALSE;
7ed4c4c5
NC
30347}
30348
c921be7d 30349static bfd_boolean
17b9d67d 30350arm_parse_arch (const char *str)
7ed4c4c5 30351{
e74cfd16 30352 const struct arm_arch_option_table *opt;
82b8a785 30353 const char *ext = strchr (str, '+');
f3bad469 30354 size_t len;
7ed4c4c5 30355
c19d1205 30356 if (ext != NULL)
f3bad469 30357 len = ext - str;
7ed4c4c5 30358 else
f3bad469 30359 len = strlen (str);
7ed4c4c5 30360
f3bad469 30361 if (len == 0)
7ed4c4c5 30362 {
c19d1205 30363 as_bad (_("missing architecture name `%s'"), str);
c921be7d 30364 return FALSE;
7ed4c4c5
NC
30365 }
30366
c19d1205 30367 for (opt = arm_archs; opt->name != NULL; opt++)
f3bad469 30368 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 30369 {
e74cfd16 30370 march_cpu_opt = &opt->value;
4d354d8b
TP
30371 if (march_ext_opt == NULL)
30372 march_ext_opt = XNEW (arm_feature_set);
30373 *march_ext_opt = arm_arch_none;
e74cfd16 30374 march_fpu_opt = &opt->default_fpu;
5f4273c7 30375 strcpy (selected_cpu_name, opt->name);
7ed4c4c5 30376
c19d1205 30377 if (ext != NULL)
34ef62f4
AV
30378 return arm_parse_extension (ext, march_cpu_opt, march_ext_opt,
30379 opt->ext_table);
7ed4c4c5 30380
c921be7d 30381 return TRUE;
c19d1205
ZW
30382 }
30383
30384 as_bad (_("unknown architecture `%s'\n"), str);
c921be7d 30385 return FALSE;
7ed4c4c5 30386}
eb043451 30387
c921be7d 30388static bfd_boolean
17b9d67d 30389arm_parse_fpu (const char * str)
c19d1205 30390{
69133863 30391 const struct arm_option_fpu_value_table * opt;
b99bd4ef 30392
c19d1205
ZW
30393 for (opt = arm_fpus; opt->name != NULL; opt++)
30394 if (streq (opt->name, str))
30395 {
e74cfd16 30396 mfpu_opt = &opt->value;
c921be7d 30397 return TRUE;
c19d1205 30398 }
b99bd4ef 30399
c19d1205 30400 as_bad (_("unknown floating point format `%s'\n"), str);
c921be7d 30401 return FALSE;
c19d1205
ZW
30402}
30403
c921be7d 30404static bfd_boolean
17b9d67d 30405arm_parse_float_abi (const char * str)
b99bd4ef 30406{
e74cfd16 30407 const struct arm_option_value_table * opt;
b99bd4ef 30408
c19d1205
ZW
30409 for (opt = arm_float_abis; opt->name != NULL; opt++)
30410 if (streq (opt->name, str))
30411 {
30412 mfloat_abi_opt = opt->value;
c921be7d 30413 return TRUE;
c19d1205 30414 }
cc8a6dd0 30415
c19d1205 30416 as_bad (_("unknown floating point abi `%s'\n"), str);
c921be7d 30417 return FALSE;
c19d1205 30418}
b99bd4ef 30419
c19d1205 30420#ifdef OBJ_ELF
c921be7d 30421static bfd_boolean
17b9d67d 30422arm_parse_eabi (const char * str)
c19d1205 30423{
e74cfd16 30424 const struct arm_option_value_table *opt;
cc8a6dd0 30425
c19d1205
ZW
30426 for (opt = arm_eabis; opt->name != NULL; opt++)
30427 if (streq (opt->name, str))
30428 {
30429 meabi_flags = opt->value;
c921be7d 30430 return TRUE;
c19d1205
ZW
30431 }
30432 as_bad (_("unknown EABI `%s'\n"), str);
c921be7d 30433 return FALSE;
c19d1205
ZW
30434}
30435#endif
cc8a6dd0 30436
c921be7d 30437static bfd_boolean
17b9d67d 30438arm_parse_it_mode (const char * str)
e07e6e58 30439{
c921be7d 30440 bfd_boolean ret = TRUE;
e07e6e58
NC
30441
30442 if (streq ("arm", str))
30443 implicit_it_mode = IMPLICIT_IT_MODE_ARM;
30444 else if (streq ("thumb", str))
30445 implicit_it_mode = IMPLICIT_IT_MODE_THUMB;
30446 else if (streq ("always", str))
30447 implicit_it_mode = IMPLICIT_IT_MODE_ALWAYS;
30448 else if (streq ("never", str))
30449 implicit_it_mode = IMPLICIT_IT_MODE_NEVER;
30450 else
30451 {
30452 as_bad (_("unknown implicit IT mode `%s', should be "\
477330fc 30453 "arm, thumb, always, or never."), str);
c921be7d 30454 ret = FALSE;
e07e6e58
NC
30455 }
30456
30457 return ret;
30458}
30459
2e6976a8 30460static bfd_boolean
17b9d67d 30461arm_ccs_mode (const char * unused ATTRIBUTE_UNUSED)
2e6976a8
DG
30462{
30463 codecomposer_syntax = TRUE;
30464 arm_comment_chars[0] = ';';
30465 arm_line_separator_chars[0] = 0;
30466 return TRUE;
30467}
30468
c19d1205
ZW
30469struct arm_long_option_table arm_long_opts[] =
30470{
30471 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
30472 arm_parse_cpu, NULL},
30473 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
30474 arm_parse_arch, NULL},
30475 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
30476 arm_parse_fpu, NULL},
30477 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
30478 arm_parse_float_abi, NULL},
30479#ifdef OBJ_ELF
7fac0536 30480 {"meabi=", N_("<ver>\t\t assemble for eabi version <ver>"),
c19d1205
ZW
30481 arm_parse_eabi, NULL},
30482#endif
e07e6e58
NC
30483 {"mimplicit-it=", N_("<mode>\t controls implicit insertion of IT instructions"),
30484 arm_parse_it_mode, NULL},
2e6976a8
DG
30485 {"mccs", N_("\t\t\t TI CodeComposer Studio syntax compatibility mode"),
30486 arm_ccs_mode, NULL},
c19d1205
ZW
30487 {NULL, NULL, 0, NULL}
30488};
cc8a6dd0 30489
c19d1205 30490int
17b9d67d 30491md_parse_option (int c, const char * arg)
c19d1205
ZW
30492{
30493 struct arm_option_table *opt;
e74cfd16 30494 const struct arm_legacy_option_table *fopt;
c19d1205 30495 struct arm_long_option_table *lopt;
b99bd4ef 30496
c19d1205 30497 switch (c)
b99bd4ef 30498 {
c19d1205
ZW
30499#ifdef OPTION_EB
30500 case OPTION_EB:
30501 target_big_endian = 1;
30502 break;
30503#endif
cc8a6dd0 30504
c19d1205
ZW
30505#ifdef OPTION_EL
30506 case OPTION_EL:
30507 target_big_endian = 0;
30508 break;
30509#endif
b99bd4ef 30510
845b51d6
PB
30511 case OPTION_FIX_V4BX:
30512 fix_v4bx = TRUE;
30513 break;
30514
18a20338
CL
30515#ifdef OBJ_ELF
30516 case OPTION_FDPIC:
30517 arm_fdpic = TRUE;
30518 break;
30519#endif /* OBJ_ELF */
30520
c19d1205
ZW
30521 case 'a':
30522 /* Listing option. Just ignore these, we don't support additional
30523 ones. */
30524 return 0;
b99bd4ef 30525
c19d1205
ZW
30526 default:
30527 for (opt = arm_opts; opt->option != NULL; opt++)
30528 {
30529 if (c == opt->option[0]
30530 && ((arg == NULL && opt->option[1] == 0)
30531 || streq (arg, opt->option + 1)))
30532 {
c19d1205 30533 /* If the option is deprecated, tell the user. */
278df34e 30534 if (warn_on_deprecated && opt->deprecated != NULL)
c19d1205
ZW
30535 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
30536 arg ? arg : "", _(opt->deprecated));
b99bd4ef 30537
c19d1205
ZW
30538 if (opt->var != NULL)
30539 *opt->var = opt->value;
cc8a6dd0 30540
c19d1205
ZW
30541 return 1;
30542 }
30543 }
b99bd4ef 30544
e74cfd16
PB
30545 for (fopt = arm_legacy_opts; fopt->option != NULL; fopt++)
30546 {
30547 if (c == fopt->option[0]
30548 && ((arg == NULL && fopt->option[1] == 0)
30549 || streq (arg, fopt->option + 1)))
30550 {
e74cfd16 30551 /* If the option is deprecated, tell the user. */
278df34e 30552 if (warn_on_deprecated && fopt->deprecated != NULL)
e74cfd16
PB
30553 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
30554 arg ? arg : "", _(fopt->deprecated));
e74cfd16
PB
30555
30556 if (fopt->var != NULL)
30557 *fopt->var = &fopt->value;
30558
30559 return 1;
30560 }
30561 }
30562
c19d1205
ZW
30563 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
30564 {
30565 /* These options are expected to have an argument. */
30566 if (c == lopt->option[0]
30567 && arg != NULL
30568 && strncmp (arg, lopt->option + 1,
30569 strlen (lopt->option + 1)) == 0)
30570 {
c19d1205 30571 /* If the option is deprecated, tell the user. */
278df34e 30572 if (warn_on_deprecated && lopt->deprecated != NULL)
c19d1205
ZW
30573 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
30574 _(lopt->deprecated));
b99bd4ef 30575
c19d1205
ZW
30576 /* Call the sup-option parser. */
30577 return lopt->func (arg + strlen (lopt->option) - 1);
30578 }
30579 }
a737bd4d 30580
c19d1205
ZW
30581 return 0;
30582 }
a394c00f 30583
c19d1205
ZW
30584 return 1;
30585}
a394c00f 30586
c19d1205
ZW
30587void
30588md_show_usage (FILE * fp)
a394c00f 30589{
c19d1205
ZW
30590 struct arm_option_table *opt;
30591 struct arm_long_option_table *lopt;
a394c00f 30592
c19d1205 30593 fprintf (fp, _(" ARM-specific assembler options:\n"));
a394c00f 30594
c19d1205
ZW
30595 for (opt = arm_opts; opt->option != NULL; opt++)
30596 if (opt->help != NULL)
30597 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
a394c00f 30598
c19d1205
ZW
30599 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
30600 if (lopt->help != NULL)
30601 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
a394c00f 30602
c19d1205
ZW
30603#ifdef OPTION_EB
30604 fprintf (fp, _("\
30605 -EB assemble code for a big-endian cpu\n"));
a394c00f
NC
30606#endif
30607
c19d1205
ZW
30608#ifdef OPTION_EL
30609 fprintf (fp, _("\
30610 -EL assemble code for a little-endian cpu\n"));
a737bd4d 30611#endif
845b51d6
PB
30612
30613 fprintf (fp, _("\
30614 --fix-v4bx Allow BX in ARMv4 code\n"));
18a20338
CL
30615
30616#ifdef OBJ_ELF
30617 fprintf (fp, _("\
30618 --fdpic generate an FDPIC object file\n"));
30619#endif /* OBJ_ELF */
c19d1205 30620}
ee065d83 30621
ee065d83 30622#ifdef OBJ_ELF
0198d5e6 30623
62b3e311
PB
30624typedef struct
30625{
30626 int val;
30627 arm_feature_set flags;
30628} cpu_arch_ver_table;
30629
2c6b98ea
TP
30630/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
30631 chronologically for architectures, with an exception for ARMv6-M and
30632 ARMv6S-M due to legacy reasons. No new architecture should have a
30633 special case. This allows for build attribute selection results to be
30634 stable when new architectures are added. */
62b3e311
PB
30635static const cpu_arch_ver_table cpu_arch_ver[] =
30636{
031254f2
AV
30637 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V1},
30638 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2},
30639 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2S},
30640 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3},
30641 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3M},
30642 {TAG_CPU_ARCH_V4, ARM_ARCH_V4xM},
30643 {TAG_CPU_ARCH_V4, ARM_ARCH_V4},
30644 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4TxM},
30645 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4T},
30646 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5xM},
30647 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5},
30648 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5TxM},
30649 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5T},
30650 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TExP},
30651 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TE},
30652 {TAG_CPU_ARCH_V5TEJ, ARM_ARCH_V5TEJ},
30653 {TAG_CPU_ARCH_V6, ARM_ARCH_V6},
30654 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6Z},
30655 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6KZ},
30656 {TAG_CPU_ARCH_V6K, ARM_ARCH_V6K},
30657 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6T2},
30658 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KT2},
30659 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6ZT2},
30660 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KZT2},
2c6b98ea
TP
30661
30662 /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
30663 always selected build attributes to match those of ARMv6-M
30664 (resp. ARMv6S-M). However, due to these architectures being a strict
30665 subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
30666 would be selected when fully respecting chronology of architectures.
30667 It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
30668 move them before ARMv7 architectures. */
031254f2
AV
30669 {TAG_CPU_ARCH_V6_M, ARM_ARCH_V6M},
30670 {TAG_CPU_ARCH_V6S_M, ARM_ARCH_V6SM},
30671
30672 {TAG_CPU_ARCH_V7, ARM_ARCH_V7},
30673 {TAG_CPU_ARCH_V7, ARM_ARCH_V7A},
30674 {TAG_CPU_ARCH_V7, ARM_ARCH_V7R},
30675 {TAG_CPU_ARCH_V7, ARM_ARCH_V7M},
30676 {TAG_CPU_ARCH_V7, ARM_ARCH_V7VE},
30677 {TAG_CPU_ARCH_V7E_M, ARM_ARCH_V7EM},
30678 {TAG_CPU_ARCH_V8, ARM_ARCH_V8A},
30679 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_1A},
30680 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_2A},
30681 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_3A},
30682 {TAG_CPU_ARCH_V8M_BASE, ARM_ARCH_V8M_BASE},
30683 {TAG_CPU_ARCH_V8M_MAIN, ARM_ARCH_V8M_MAIN},
30684 {TAG_CPU_ARCH_V8R, ARM_ARCH_V8R},
30685 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_4A},
30686 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_5A},
30687 {TAG_CPU_ARCH_V8_1M_MAIN, ARM_ARCH_V8_1M_MAIN},
30688 {-1, ARM_ARCH_NONE}
62b3e311
PB
30689};
30690
ee3c0378 30691/* Set an attribute if it has not already been set by the user. */
0198d5e6 30692
ee3c0378
AS
30693static void
30694aeabi_set_attribute_int (int tag, int value)
30695{
30696 if (tag < 1
30697 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
30698 || !attributes_set_explicitly[tag])
30699 bfd_elf_add_proc_attr_int (stdoutput, tag, value);
30700}
30701
30702static void
30703aeabi_set_attribute_string (int tag, const char *value)
30704{
30705 if (tag < 1
30706 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
30707 || !attributes_set_explicitly[tag])
30708 bfd_elf_add_proc_attr_string (stdoutput, tag, value);
30709}
30710
2c6b98ea
TP
30711/* Return whether features in the *NEEDED feature set are available via
30712 extensions for the architecture whose feature set is *ARCH_FSET. */
0198d5e6 30713
2c6b98ea
TP
30714static bfd_boolean
30715have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
30716 const arm_feature_set *needed)
30717{
30718 int i, nb_allowed_archs;
30719 arm_feature_set ext_fset;
30720 const struct arm_option_extension_value_table *opt;
30721
30722 ext_fset = arm_arch_none;
30723 for (opt = arm_extensions; opt->name != NULL; opt++)
30724 {
30725 /* Extension does not provide any feature we need. */
30726 if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
30727 continue;
30728
30729 nb_allowed_archs =
30730 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
30731 for (i = 0; i < nb_allowed_archs; i++)
30732 {
30733 /* Empty entry. */
30734 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
30735 break;
30736
30737 /* Extension is available, add it. */
30738 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
30739 ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
30740 }
30741 }
30742
30743 /* Can we enable all features in *needed? */
30744 return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
30745}
30746
30747/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
30748 a given architecture feature set *ARCH_EXT_FSET including extension feature
30749 set *EXT_FSET. Selection logic used depend on EXACT_MATCH:
30750 - if true, check for an exact match of the architecture modulo extensions;
30751 - otherwise, select build attribute value of the first superset
30752 architecture released so that results remains stable when new architectures
30753 are added.
30754 For -march/-mcpu=all the build attribute value of the most featureful
30755 architecture is returned. Tag_CPU_arch_profile result is returned in
30756 PROFILE. */
0198d5e6 30757
2c6b98ea
TP
30758static int
30759get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
30760 const arm_feature_set *ext_fset,
30761 char *profile, int exact_match)
30762{
30763 arm_feature_set arch_fset;
30764 const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
30765
30766 /* Select most featureful architecture with all its extensions if building
30767 for -march=all as the feature sets used to set build attributes. */
30768 if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
30769 {
30770 /* Force revisiting of decision for each new architecture. */
031254f2 30771 gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V8_1M_MAIN);
2c6b98ea
TP
30772 *profile = 'A';
30773 return TAG_CPU_ARCH_V8;
30774 }
30775
30776 ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
30777
30778 for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
30779 {
30780 arm_feature_set known_arch_fset;
30781
30782 ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
30783 if (exact_match)
30784 {
30785 /* Base architecture match user-specified architecture and
30786 extensions, eg. ARMv6S-M matching -march=armv6-m+os. */
30787 if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
30788 {
30789 p_ver_ret = p_ver;
30790 goto found;
30791 }
30792 /* Base architecture match user-specified architecture only
30793 (eg. ARMv6-M in the same case as above). Record it in case we
30794 find a match with above condition. */
30795 else if (p_ver_ret == NULL
30796 && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
30797 p_ver_ret = p_ver;
30798 }
30799 else
30800 {
30801
30802 /* Architecture has all features wanted. */
30803 if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
30804 {
30805 arm_feature_set added_fset;
30806
30807 /* Compute features added by this architecture over the one
30808 recorded in p_ver_ret. */
30809 if (p_ver_ret != NULL)
30810 ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
30811 p_ver_ret->flags);
30812 /* First architecture that match incl. with extensions, or the
30813 only difference in features over the recorded match is
30814 features that were optional and are now mandatory. */
30815 if (p_ver_ret == NULL
30816 || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
30817 {
30818 p_ver_ret = p_ver;
30819 goto found;
30820 }
30821 }
30822 else if (p_ver_ret == NULL)
30823 {
30824 arm_feature_set needed_ext_fset;
30825
30826 ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
30827
30828 /* Architecture has all features needed when using some
30829 extensions. Record it and continue searching in case there
30830 exist an architecture providing all needed features without
30831 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
30832 OS extension). */
30833 if (have_ext_for_needed_feat_p (&known_arch_fset,
30834 &needed_ext_fset))
30835 p_ver_ret = p_ver;
30836 }
30837 }
30838 }
30839
30840 if (p_ver_ret == NULL)
30841 return -1;
30842
30843found:
30844 /* Tag_CPU_arch_profile. */
30845 if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
30846 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
30847 || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
30848 && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only)))
30849 *profile = 'A';
30850 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r))
30851 *profile = 'R';
30852 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
30853 *profile = 'M';
30854 else
30855 *profile = '\0';
30856 return p_ver_ret->val;
30857}
30858
ee065d83 30859/* Set the public EABI object attributes. */
0198d5e6 30860
c168ce07 30861static void
ee065d83
PB
30862aeabi_set_public_attributes (void)
30863{
b90d5ba0 30864 char profile = '\0';
2c6b98ea 30865 int arch = -1;
90ec0d68 30866 int virt_sec = 0;
bca38921 30867 int fp16_optional = 0;
2c6b98ea
TP
30868 int skip_exact_match = 0;
30869 arm_feature_set flags, flags_arch, flags_ext;
ee065d83 30870
54bab281
TP
30871 /* Autodetection mode, choose the architecture based the instructions
30872 actually used. */
30873 if (no_cpu_selected ())
30874 {
30875 ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
ddd7f988 30876
54bab281
TP
30877 if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
30878 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
ddd7f988 30879
54bab281
TP
30880 if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
30881 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
ddd7f988 30882
54bab281 30883 /* Code run during relaxation relies on selected_cpu being set. */
4d354d8b
TP
30884 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
30885 flags_ext = arm_arch_none;
30886 ARM_CLEAR_FEATURE (selected_arch, flags_arch, flags_ext);
30887 selected_ext = flags_ext;
54bab281
TP
30888 selected_cpu = flags;
30889 }
30890 /* Otherwise, choose the architecture based on the capabilities of the
30891 requested cpu. */
30892 else
4d354d8b
TP
30893 {
30894 ARM_MERGE_FEATURE_SETS (flags_arch, selected_arch, selected_ext);
30895 ARM_CLEAR_FEATURE (flags_arch, flags_arch, fpu_any);
30896 flags_ext = selected_ext;
30897 flags = selected_cpu;
30898 }
30899 ARM_MERGE_FEATURE_SETS (flags, flags, selected_fpu);
7f78eb34 30900
ddd7f988 30901 /* Allow the user to override the reported architecture. */
4d354d8b 30902 if (!ARM_FEATURE_ZERO (selected_object_arch))
7a1d4c38 30903 {
4d354d8b 30904 ARM_CLEAR_FEATURE (flags_arch, selected_object_arch, fpu_any);
2c6b98ea 30905 flags_ext = arm_arch_none;
7a1d4c38 30906 }
2c6b98ea 30907 else
4d354d8b 30908 skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
2c6b98ea
TP
30909
30910 /* When this function is run again after relaxation has happened there is no
30911 way to determine whether an architecture or CPU was specified by the user:
30912 - selected_cpu is set above for relaxation to work;
30913 - march_cpu_opt is not set if only -mcpu or .cpu is used;
30914 - mcpu_cpu_opt is set to arm_arch_any for autodetection.
30915 Therefore, if not in -march=all case we first try an exact match and fall
30916 back to autodetection. */
30917 if (!skip_exact_match)
30918 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
30919 if (arch == -1)
30920 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
30921 if (arch == -1)
30922 as_bad (_("no architecture contains all the instructions used\n"));
9e3c6df6 30923
ee065d83
PB
30924 /* Tag_CPU_name. */
30925 if (selected_cpu_name[0])
30926 {
91d6fa6a 30927 char *q;
ee065d83 30928
91d6fa6a
NC
30929 q = selected_cpu_name;
30930 if (strncmp (q, "armv", 4) == 0)
ee065d83
PB
30931 {
30932 int i;
5f4273c7 30933
91d6fa6a
NC
30934 q += 4;
30935 for (i = 0; q[i]; i++)
30936 q[i] = TOUPPER (q[i]);
ee065d83 30937 }
91d6fa6a 30938 aeabi_set_attribute_string (Tag_CPU_name, q);
ee065d83 30939 }
62f3b8c8 30940
ee065d83 30941 /* Tag_CPU_arch. */
ee3c0378 30942 aeabi_set_attribute_int (Tag_CPU_arch, arch);
62f3b8c8 30943
62b3e311 30944 /* Tag_CPU_arch_profile. */
69239280
MGD
30945 if (profile != '\0')
30946 aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
62f3b8c8 30947
15afaa63 30948 /* Tag_DSP_extension. */
4d354d8b 30949 if (ARM_CPU_HAS_FEATURE (selected_ext, arm_ext_dsp))
6c290d53 30950 aeabi_set_attribute_int (Tag_DSP_extension, 1);
15afaa63 30951
2c6b98ea 30952 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
ee065d83 30953 /* Tag_ARM_ISA_use. */
ee3c0378 30954 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
2c6b98ea 30955 || ARM_FEATURE_ZERO (flags_arch))
ee3c0378 30956 aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
62f3b8c8 30957
ee065d83 30958 /* Tag_THUMB_ISA_use. */
ee3c0378 30959 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
2c6b98ea 30960 || ARM_FEATURE_ZERO (flags_arch))
4ed7ed8d
TP
30961 {
30962 int thumb_isa_use;
30963
30964 if (!ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
16a1fa25 30965 && ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only))
4ed7ed8d
TP
30966 thumb_isa_use = 3;
30967 else if (ARM_CPU_HAS_FEATURE (flags, arm_arch_t2))
30968 thumb_isa_use = 2;
30969 else
30970 thumb_isa_use = 1;
30971 aeabi_set_attribute_int (Tag_THUMB_ISA_use, thumb_isa_use);
30972 }
62f3b8c8 30973
ee065d83 30974 /* Tag_VFP_arch. */
a715796b
TG
30975 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_armv8xd))
30976 aeabi_set_attribute_int (Tag_VFP_arch,
30977 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
30978 ? 7 : 8);
bca38921 30979 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_fma))
62f3b8c8
PB
30980 aeabi_set_attribute_int (Tag_VFP_arch,
30981 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
30982 ? 5 : 6);
30983 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32))
bca38921
MGD
30984 {
30985 fp16_optional = 1;
30986 aeabi_set_attribute_int (Tag_VFP_arch, 3);
30987 }
ada65aa3 30988 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v3xd))
bca38921
MGD
30989 {
30990 aeabi_set_attribute_int (Tag_VFP_arch, 4);
30991 fp16_optional = 1;
30992 }
ee3c0378
AS
30993 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v2))
30994 aeabi_set_attribute_int (Tag_VFP_arch, 2);
30995 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1)
477330fc 30996 || ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd))
ee3c0378 30997 aeabi_set_attribute_int (Tag_VFP_arch, 1);
62f3b8c8 30998
4547cb56
NC
30999 /* Tag_ABI_HardFP_use. */
31000 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd)
31001 && !ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1))
31002 aeabi_set_attribute_int (Tag_ABI_HardFP_use, 1);
31003
ee065d83 31004 /* Tag_WMMX_arch. */
ee3c0378
AS
31005 if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt2))
31006 aeabi_set_attribute_int (Tag_WMMX_arch, 2);
31007 else if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt))
31008 aeabi_set_attribute_int (Tag_WMMX_arch, 1);
62f3b8c8 31009
ee3c0378 31010 /* Tag_Advanced_SIMD_arch (formerly Tag_NEON_arch). */
9411fd44
MW
31011 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v8_1))
31012 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 4);
31013 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_armv8))
bca38921
MGD
31014 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 3);
31015 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v1))
31016 {
31017 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_fma))
31018 {
31019 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 2);
31020 }
31021 else
31022 {
31023 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 1);
31024 fp16_optional = 1;
31025 }
31026 }
fa94de6b 31027
a7ad558c
AV
31028 if (ARM_CPU_HAS_FEATURE (flags, mve_fp_ext))
31029 aeabi_set_attribute_int (Tag_MVE_arch, 2);
31030 else if (ARM_CPU_HAS_FEATURE (flags, mve_ext))
31031 aeabi_set_attribute_int (Tag_MVE_arch, 1);
31032
ee3c0378 31033 /* Tag_VFP_HP_extension (formerly Tag_NEON_FP16_arch). */
bca38921 31034 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_fp16) && fp16_optional)
ee3c0378 31035 aeabi_set_attribute_int (Tag_VFP_HP_extension, 1);
4547cb56 31036
69239280
MGD
31037 /* Tag_DIV_use.
31038
31039 We set Tag_DIV_use to two when integer divide instructions have been used
31040 in ARM state, or when Thumb integer divide instructions have been used,
31041 but we have no architecture profile set, nor have we any ARM instructions.
31042
4ed7ed8d
TP
31043 For ARMv8-A and ARMv8-M we set the tag to 0 as integer divide is implied
31044 by the base architecture.
bca38921 31045
69239280 31046 For new architectures we will have to check these tests. */
031254f2 31047 gas_assert (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
4ed7ed8d
TP
31048 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
31049 || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
bca38921
MGD
31050 aeabi_set_attribute_int (Tag_DIV_use, 0);
31051 else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_adiv)
31052 || (profile == '\0'
31053 && ARM_CPU_HAS_FEATURE (flags, arm_ext_div)
31054 && !ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any)))
eea54501 31055 aeabi_set_attribute_int (Tag_DIV_use, 2);
60e5ef9f
MGD
31056
31057 /* Tag_MP_extension_use. */
31058 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_mp))
31059 aeabi_set_attribute_int (Tag_MPextension_use, 1);
f4c65163
MGD
31060
31061 /* Tag Virtualization_use. */
31062 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_sec))
90ec0d68
MGD
31063 virt_sec |= 1;
31064 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_virt))
31065 virt_sec |= 2;
31066 if (virt_sec != 0)
31067 aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
ee065d83
PB
31068}
31069
c168ce07
TP
31070/* Post relaxation hook. Recompute ARM attributes now that relaxation is
31071 finished and free extension feature bits which will not be used anymore. */
0198d5e6 31072
c168ce07
TP
31073void
31074arm_md_post_relax (void)
31075{
31076 aeabi_set_public_attributes ();
4d354d8b
TP
31077 XDELETE (mcpu_ext_opt);
31078 mcpu_ext_opt = NULL;
31079 XDELETE (march_ext_opt);
31080 march_ext_opt = NULL;
c168ce07
TP
31081}
31082
104d59d1 31083/* Add the default contents for the .ARM.attributes section. */
0198d5e6 31084
ee065d83
PB
31085void
31086arm_md_end (void)
31087{
ee065d83
PB
31088 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
31089 return;
31090
31091 aeabi_set_public_attributes ();
ee065d83 31092}
8463be01 31093#endif /* OBJ_ELF */
ee065d83 31094
ee065d83
PB
31095/* Parse a .cpu directive. */
31096
31097static void
31098s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
31099{
e74cfd16 31100 const struct arm_cpu_option_table *opt;
ee065d83
PB
31101 char *name;
31102 char saved_char;
31103
31104 name = input_line_pointer;
5f4273c7 31105 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
31106 input_line_pointer++;
31107 saved_char = *input_line_pointer;
31108 *input_line_pointer = 0;
31109
31110 /* Skip the first "all" entry. */
31111 for (opt = arm_cpus + 1; opt->name != NULL; opt++)
31112 if (streq (opt->name, name))
31113 {
4d354d8b
TP
31114 selected_arch = opt->value;
31115 selected_ext = opt->ext;
31116 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
ee065d83 31117 if (opt->canonical_name)
5f4273c7 31118 strcpy (selected_cpu_name, opt->canonical_name);
ee065d83
PB
31119 else
31120 {
31121 int i;
31122 for (i = 0; opt->name[i]; i++)
31123 selected_cpu_name[i] = TOUPPER (opt->name[i]);
f3bad469 31124
ee065d83
PB
31125 selected_cpu_name[i] = 0;
31126 }
4d354d8b
TP
31127 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
31128
ee065d83
PB
31129 *input_line_pointer = saved_char;
31130 demand_empty_rest_of_line ();
31131 return;
31132 }
31133 as_bad (_("unknown cpu `%s'"), name);
31134 *input_line_pointer = saved_char;
31135 ignore_rest_of_line ();
31136}
31137
ee065d83
PB
31138/* Parse a .arch directive. */
31139
31140static void
31141s_arm_arch (int ignored ATTRIBUTE_UNUSED)
31142{
e74cfd16 31143 const struct arm_arch_option_table *opt;
ee065d83
PB
31144 char saved_char;
31145 char *name;
31146
31147 name = input_line_pointer;
5f4273c7 31148 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
31149 input_line_pointer++;
31150 saved_char = *input_line_pointer;
31151 *input_line_pointer = 0;
31152
31153 /* Skip the first "all" entry. */
31154 for (opt = arm_archs + 1; opt->name != NULL; opt++)
31155 if (streq (opt->name, name))
31156 {
4d354d8b
TP
31157 selected_arch = opt->value;
31158 selected_ext = arm_arch_none;
31159 selected_cpu = selected_arch;
5f4273c7 31160 strcpy (selected_cpu_name, opt->name);
4d354d8b 31161 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
31162 *input_line_pointer = saved_char;
31163 demand_empty_rest_of_line ();
31164 return;
31165 }
31166
31167 as_bad (_("unknown architecture `%s'\n"), name);
31168 *input_line_pointer = saved_char;
31169 ignore_rest_of_line ();
31170}
31171
7a1d4c38
PB
31172/* Parse a .object_arch directive. */
31173
31174static void
31175s_arm_object_arch (int ignored ATTRIBUTE_UNUSED)
31176{
31177 const struct arm_arch_option_table *opt;
31178 char saved_char;
31179 char *name;
31180
31181 name = input_line_pointer;
5f4273c7 31182 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
7a1d4c38
PB
31183 input_line_pointer++;
31184 saved_char = *input_line_pointer;
31185 *input_line_pointer = 0;
31186
31187 /* Skip the first "all" entry. */
31188 for (opt = arm_archs + 1; opt->name != NULL; opt++)
31189 if (streq (opt->name, name))
31190 {
4d354d8b 31191 selected_object_arch = opt->value;
7a1d4c38
PB
31192 *input_line_pointer = saved_char;
31193 demand_empty_rest_of_line ();
31194 return;
31195 }
31196
31197 as_bad (_("unknown architecture `%s'\n"), name);
31198 *input_line_pointer = saved_char;
31199 ignore_rest_of_line ();
31200}
31201
69133863
MGD
31202/* Parse a .arch_extension directive. */
31203
31204static void
31205s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
31206{
31207 const struct arm_option_extension_value_table *opt;
31208 char saved_char;
31209 char *name;
31210 int adding_value = 1;
31211
31212 name = input_line_pointer;
31213 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
31214 input_line_pointer++;
31215 saved_char = *input_line_pointer;
31216 *input_line_pointer = 0;
31217
31218 if (strlen (name) >= 2
31219 && strncmp (name, "no", 2) == 0)
31220 {
31221 adding_value = 0;
31222 name += 2;
31223 }
31224
31225 for (opt = arm_extensions; opt->name != NULL; opt++)
31226 if (streq (opt->name, name))
31227 {
d942732e
TP
31228 int i, nb_allowed_archs =
31229 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[i]);
31230 for (i = 0; i < nb_allowed_archs; i++)
31231 {
31232 /* Empty entry. */
4d354d8b 31233 if (ARM_CPU_IS_ANY (opt->allowed_archs[i]))
d942732e 31234 continue;
4d354d8b 31235 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], selected_arch))
d942732e
TP
31236 break;
31237 }
31238
31239 if (i == nb_allowed_archs)
69133863
MGD
31240 {
31241 as_bad (_("architectural extension `%s' is not allowed for the "
31242 "current base architecture"), name);
31243 break;
31244 }
31245
31246 if (adding_value)
4d354d8b 31247 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
5a70a223 31248 opt->merge_value);
69133863 31249 else
4d354d8b 31250 ARM_CLEAR_FEATURE (selected_ext, selected_ext, opt->clear_value);
69133863 31251
4d354d8b
TP
31252 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
31253 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
69133863
MGD
31254 *input_line_pointer = saved_char;
31255 demand_empty_rest_of_line ();
3d030cdb
TP
31256 /* Allowing Thumb division instructions for ARMv7 in autodetection rely
31257 on this return so that duplicate extensions (extensions with the
31258 same name as a previous extension in the list) are not considered
31259 for command-line parsing. */
69133863
MGD
31260 return;
31261 }
31262
31263 if (opt->name == NULL)
e673710a 31264 as_bad (_("unknown architecture extension `%s'\n"), name);
69133863
MGD
31265
31266 *input_line_pointer = saved_char;
31267 ignore_rest_of_line ();
31268}
31269
ee065d83
PB
31270/* Parse a .fpu directive. */
31271
31272static void
31273s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
31274{
69133863 31275 const struct arm_option_fpu_value_table *opt;
ee065d83
PB
31276 char saved_char;
31277 char *name;
31278
31279 name = input_line_pointer;
5f4273c7 31280 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
31281 input_line_pointer++;
31282 saved_char = *input_line_pointer;
31283 *input_line_pointer = 0;
5f4273c7 31284
ee065d83
PB
31285 for (opt = arm_fpus; opt->name != NULL; opt++)
31286 if (streq (opt->name, name))
31287 {
4d354d8b
TP
31288 selected_fpu = opt->value;
31289#ifndef CPU_DEFAULT
31290 if (no_cpu_selected ())
31291 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
31292 else
31293#endif
31294 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
31295 *input_line_pointer = saved_char;
31296 demand_empty_rest_of_line ();
31297 return;
31298 }
31299
31300 as_bad (_("unknown floating point format `%s'\n"), name);
31301 *input_line_pointer = saved_char;
31302 ignore_rest_of_line ();
31303}
ee065d83 31304
794ba86a 31305/* Copy symbol information. */
f31fef98 31306
794ba86a
DJ
31307void
31308arm_copy_symbol_attributes (symbolS *dest, symbolS *src)
31309{
31310 ARM_GET_FLAG (dest) = ARM_GET_FLAG (src);
31311}
e04befd0 31312
f31fef98 31313#ifdef OBJ_ELF
e04befd0
AS
31314/* Given a symbolic attribute NAME, return the proper integer value.
31315 Returns -1 if the attribute is not known. */
f31fef98 31316
e04befd0
AS
31317int
31318arm_convert_symbolic_attribute (const char *name)
31319{
f31fef98
NC
31320 static const struct
31321 {
31322 const char * name;
31323 const int tag;
31324 }
31325 attribute_table[] =
31326 {
31327 /* When you modify this table you should
31328 also modify the list in doc/c-arm.texi. */
e04befd0 31329#define T(tag) {#tag, tag}
f31fef98
NC
31330 T (Tag_CPU_raw_name),
31331 T (Tag_CPU_name),
31332 T (Tag_CPU_arch),
31333 T (Tag_CPU_arch_profile),
31334 T (Tag_ARM_ISA_use),
31335 T (Tag_THUMB_ISA_use),
75375b3e 31336 T (Tag_FP_arch),
f31fef98
NC
31337 T (Tag_VFP_arch),
31338 T (Tag_WMMX_arch),
31339 T (Tag_Advanced_SIMD_arch),
31340 T (Tag_PCS_config),
31341 T (Tag_ABI_PCS_R9_use),
31342 T (Tag_ABI_PCS_RW_data),
31343 T (Tag_ABI_PCS_RO_data),
31344 T (Tag_ABI_PCS_GOT_use),
31345 T (Tag_ABI_PCS_wchar_t),
31346 T (Tag_ABI_FP_rounding),
31347 T (Tag_ABI_FP_denormal),
31348 T (Tag_ABI_FP_exceptions),
31349 T (Tag_ABI_FP_user_exceptions),
31350 T (Tag_ABI_FP_number_model),
75375b3e 31351 T (Tag_ABI_align_needed),
f31fef98 31352 T (Tag_ABI_align8_needed),
75375b3e 31353 T (Tag_ABI_align_preserved),
f31fef98
NC
31354 T (Tag_ABI_align8_preserved),
31355 T (Tag_ABI_enum_size),
31356 T (Tag_ABI_HardFP_use),
31357 T (Tag_ABI_VFP_args),
31358 T (Tag_ABI_WMMX_args),
31359 T (Tag_ABI_optimization_goals),
31360 T (Tag_ABI_FP_optimization_goals),
31361 T (Tag_compatibility),
31362 T (Tag_CPU_unaligned_access),
75375b3e 31363 T (Tag_FP_HP_extension),
f31fef98
NC
31364 T (Tag_VFP_HP_extension),
31365 T (Tag_ABI_FP_16bit_format),
cd21e546
MGD
31366 T (Tag_MPextension_use),
31367 T (Tag_DIV_use),
f31fef98
NC
31368 T (Tag_nodefaults),
31369 T (Tag_also_compatible_with),
31370 T (Tag_conformance),
31371 T (Tag_T2EE_use),
31372 T (Tag_Virtualization_use),
15afaa63 31373 T (Tag_DSP_extension),
a7ad558c 31374 T (Tag_MVE_arch),
cd21e546 31375 /* We deliberately do not include Tag_MPextension_use_legacy. */
e04befd0 31376#undef T
f31fef98 31377 };
e04befd0
AS
31378 unsigned int i;
31379
31380 if (name == NULL)
31381 return -1;
31382
f31fef98 31383 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
c921be7d 31384 if (streq (name, attribute_table[i].name))
e04befd0
AS
31385 return attribute_table[i].tag;
31386
31387 return -1;
31388}
267bf995 31389
93ef582d
NC
31390/* Apply sym value for relocations only in the case that they are for
31391 local symbols in the same segment as the fixup and you have the
31392 respective architectural feature for blx and simple switches. */
0198d5e6 31393
267bf995 31394int
93ef582d 31395arm_apply_sym_value (struct fix * fixP, segT this_seg)
267bf995
RR
31396{
31397 if (fixP->fx_addsy
31398 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
93ef582d
NC
31399 /* PR 17444: If the local symbol is in a different section then a reloc
31400 will always be generated for it, so applying the symbol value now
31401 will result in a double offset being stored in the relocation. */
31402 && (S_GET_SEGMENT (fixP->fx_addsy) == this_seg)
34e77a92 31403 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE))
267bf995
RR
31404 {
31405 switch (fixP->fx_r_type)
31406 {
31407 case BFD_RELOC_ARM_PCREL_BLX:
31408 case BFD_RELOC_THUMB_PCREL_BRANCH23:
31409 if (ARM_IS_FUNC (fixP->fx_addsy))
31410 return 1;
31411 break;
31412
31413 case BFD_RELOC_ARM_PCREL_CALL:
31414 case BFD_RELOC_THUMB_PCREL_BLX:
31415 if (THUMB_IS_FUNC (fixP->fx_addsy))
93ef582d 31416 return 1;
267bf995
RR
31417 break;
31418
31419 default:
31420 break;
31421 }
31422
31423 }
31424 return 0;
31425}
f31fef98 31426#endif /* OBJ_ELF */
This page took 4.324972 seconds and 4 git commands to generate.